1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
@page page_device_ofw_io OFW addressing and MMIO
# Addressing and I/O (`io.c`)
Decode **`reg`**, follow **`ranges` / `dma-ranges`**, and **`ioremap`**. Header: **`drivers/ofw_io.h`**.
---
## Address cells
| API | Role |
| --- | --- |
| **`rt_ofw_bus_addr_cells` / `rt_ofw_bus_size_cells`** | Walk parents for bus **`#address-cells`** |
| **`rt_ofw_io_addr_cells` / `rt_ofw_io_size_cells`** | Parent cells used to decode this node's **`reg`** |
**`rt_ofw_get_address`** applies **`rt_ofw_translate_address`** so returned CPU physical addresses include parent **`ranges`**.
---
## `reg` decoding
| API | Role |
| --- | --- |
| **`rt_ofw_get_address_count`** | Number of **`reg`** tuples |
| **`rt_ofw_get_address(np, index, &addr, &size)`** | One tuple (translated base + size) |
| **`rt_ofw_get_address_by_name`** | Match **`reg-names`** |
| **`rt_ofw_get_address_array`** | Batch decode |
Example in **`probe`**:
```c
rt_uint64_t base, size;
if (rt_ofw_get_address(np, 0, &base, &size) != RT_EOK)
return -RT_ERROR;
pdev->iomem = rt_dm_dev_iomap(np, 0); /* or rt_ofw_iomap(np, 0) */
```
---
## Translation
| API | Role |
| --- | --- |
| **`rt_ofw_translate_address(np, range_type, addr)`** | Follow **`ranges`** or **`dma-ranges`** (**`range_type`** = **`"ranges"`** / **`"dma-ranges"`**, or **`RT_NULL`**) |
| **`rt_ofw_reverse_address`** | Child → parent bus address |
| **`rt_ofw_translate_dma2cpu`** | DMA bus → CPU physical (inline) |
| **`rt_ofw_translate_cpu2dma`** | CPU → DMA bus (inline) |
**`io.c`** caches up to **`RT_USING_OFW_BUS_RANGES_NUMBER`** **`ranges`** tables for performance.
---
## MMIO map
| API | Role |
| --- | --- |
| **`rt_ofw_iomap(np, index)`** | **`ioremap`** for **`reg`** index |
| **`rt_ofw_iomap_by_name`** | Named **`reg-names`** segment |
Prefer **`rt_dm_dev_iomap`** in DM drivers when **`struct rt_device`** is available (@ref page_device_dm).
---
## Pitfalls
| Issue | Mitigation |
| --- | --- |
| Wrong **`#address-cells`** | Always use **`rt_ofw_io_*`**, not constants |
| **`reg` without `ranges` on bus** | Translation may be identity — verify DTS |
| Multiple **`reg`** | Index 0 is not always the only MMIO bank |
| **`reg-names` mismatch** | **`rt_ofw_get_address_by_name`** returns **`-RT_EEMPTY`** |
## See also
- @ref page_device_ofw
- @ref page_device_ofw_base
- @ref page_device_ofw_boot
- @ref page_device_platform
|