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
|
@page page_device_dma_pool DMA memory pools
# DMA coherent / CMA pools
Header: `struct rt_dma_pool` and **`rt_dma_pool_*`** in `components/drivers/include/drivers/dma.h`. Implementation: `components/drivers/dma/dma_pool.c`.
**`rt_dma_alloc` / `rt_dma_free`** (and default **`rt_dma_map_ops`**) allocate from installed pools instead of the generic heap when **`RT_USING_DMA`** and memblock reservations are configured. Controllers and slaves still use **`documentation/6.components/device-driver/dma/dma.md`** for channel programming; pools only back **buffer memory**.
## Driver / BSP quick notes
| Topic | Guidance |
| --- | --- |
| **Boot reservation** | Call **`rt_dma_pool_extract`** early (memblock **`dma-pool`** region) before drivers **`rt_dma_alloc`**. |
| **Coherent vs CMA** | **`coherent_pool`** is carved from the **low** end of the reserved region; **CMA** uses the remainder—**`cma_size` must be ≥ `coherent_pool_size`**. |
| **32-bit DMA** | Pools below **4 GiB** set **`RT_DMA_F_32BITS`** on the pool—devices with limited addressing need buffers from these pools. |
| **`dma-coherent` DT** | **`rt_dma_device_is_coherent(dev)`** reads the property; map ops may skip flush on coherent devices. |
## `struct rt_dma_pool`
| Field | Meaning |
| --- | --- |
| `region` | Physical **`start` / `end`**, optional **`name`**. |
| `map` / `bits` | Page bitmap (**`ARCH_PAGE_SIZE`** granule). |
| `flags` | e.g. **`RT_DMA_F_32BITS`**, **`RT_DMA_F_NOCACHE`**. |
| `list` | Global pool list (internal). |
## Public API
| API | Role |
| --- | --- |
| **`rt_dma_pool_install(region)`** | Register a physical memory region as a pool; returns **`struct rt_dma_pool *`** or **NULL** on error. |
| **`rt_dma_pool_extract(cma_size, coherent_pool_size)`** | Find memblock region named **`dma-pool`**, split into **`coherent-pool`** + **`cma`** sub-regions, install both pools, mark memblock as consumed. Returns **`-RT_EEMPTY`** if no suitable region, **`-RT_EINVAL`** if sizes are inconsistent. |
**`rt_dma_pool_install`** is also used directly when the BSP hands a fixed **`rt_region_t`** without going through memblock extract.
## How allocation uses pools
1. **`rt_dma_alloc(dev, size, &handle, flags)`** walks installed pools (under **`dma_pools_lock`**), picks a pool matching flags (coherent, 32-bit, device, etc.).
2. Default **`rt_dma_map_ops`**:
- **Coherent**: flush on **`sync_out_data`**, invalidate on **`sync_in_data`**.
- **Non-coherent**: physical address via **`rt_kmem_v2p`** without cache maintenance on sync-in.
3. With **`RT_USING_OFW`**, **`rt_dma_device_set_ops`** may install **`ofw_dma_map_*`** that translates CPU ↔ DMA bus addresses via **`rt_ofw_translate_cpu2dma`**.
Slaves should use **`rt_dma_alloc_coherent`** for ring buffers the CPU and DMA both touch.
## Boot flow (typical)
1. Bootloader or memblock code reserves **`dma-pool`** in device tree / memblock.
2. Early init calls **`rt_dma_pool_extract(SIZE_MB(8), SIZE_MB(2))`** (example sizes).
3. Drivers **`probe`** and **`rt_dma_alloc`** for descriptor rings and payload buffers.
## Debugging
With **`RT_USING_CONSOLE`** and **`RT_USING_MSH`**, **`list_dma_pool`** prints installed regions (name, size, base).
## Pitfalls
- **Pool exhausted**: **`rt_dma_alloc`** returns **NULL**—size requests must fit contiguous free pages in a matching pool.
- **CMA smaller than coherent**: **`rt_dma_pool_extract`** rejects **`cma_size < coherent_pool_size`**.
- **High memory only**: if no sub-4G **`dma-pool`** chunk is large enough, extract may fall back with a warning—DMA to peripherals that cannot reach high memory will fail.
- **Double extract**: second call may find memblock already consumed—guard in BSP init.
## See also
- DMA engine and channels: `documentation/6.components/device-driver/dma/dma.md`
- OFW DMA range: `documentation/6.components/device-driver/ofw/ofw.md`
- NUMA / affinity: `documentation/6.components/device-driver/numa/numa.md`
- Source: `components/drivers/dma/dma_pool.c`
- Header: `components/drivers/include/drivers/dma.h`
|