@samitouri / QOSamiQemu / commits / 02cfe21f6a

hw/dma/soc_dma: Remove soc_dma_port_fifo support

Our current single OMAP SoC doesn't call the soc_dma_port_add_fifo(), soc_dma_port_add_fifo_in() or soc_dma_port_add_fifo_out() functions. Remove them, plus the soc_dma_port_fifo handling that only those functions needed. The motivation for this is that it removes a lot of code that is careless about the fact that the largest possible DMA transfer is more bits than will fit into an "int" variable, and which does direct accesses to host memory pointers into guest backing RAM without doing bounds checks. Deleting this code means we don't have to audit and update it. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> Message-id: 20260710105907.2570621-2-peter.maydell@linaro.org

Peter Maydell committed Jul 20, 2026 at 19:05 UTC 02cfe21f6a251df1229077af3b1c5583020a33bf
2 files changed +5 -124
hw/dma/soc_dma.c
+1 -104
@@ -29,33 +29,6 @@ static void transfer_mem2mem(struct soc_dma_ch_s *ch)
29 ch->paddr[1] += ch->bytes;
30 }
31
32 -static void transfer_mem2fifo(struct soc_dma_ch_s *ch)
33 -{
34 - ch->io_fn[1](ch->io_opaque[1], ch->paddr[0], ch->bytes);
35 - ch->paddr[0] += ch->bytes;
36 -}
37 -
38 -static void transfer_fifo2mem(struct soc_dma_ch_s *ch)
39 -{
40 - ch->io_fn[0](ch->io_opaque[0], ch->paddr[1], ch->bytes);
41 - ch->paddr[1] += ch->bytes;
42 -}
43 -
44 -/* This is further optimisable but isn't very important because often
45 - * DMA peripherals forbid this kind of transfers and even when they don't,
46 - * oprating systems may not need to use them. */
47 -static void *fifo_buf;
48 -static int fifo_size;
49 -static void transfer_fifo2fifo(struct soc_dma_ch_s *ch)
50 -{
51 - if (ch->bytes > fifo_size)
52 - fifo_buf = g_realloc(fifo_buf, fifo_size = ch->bytes);
53 -
54 - /* Implement as transfer_fifo2linear + transfer_linear2fifo. */
55 - ch->io_fn[0](ch->io_opaque[0], fifo_buf, ch->bytes);
56 - ch->io_fn[1](ch->io_opaque[1], fifo_buf, ch->bytes);
57 -}
58 -
32 struct dma_s {
33 struct soc_dma_s soc;
34 int chnum;
@@ -67,11 +40,6 @@ struct dma_s {
40 enum soc_dma_port_type type;
41 hwaddr addr;
42 union {
70 - struct {
71 - void *opaque;
72 - soc_dma_io_t fn;
73 - int out;
74 - } fifo;
43 struct {
44 void *base;
45 size_t size;
@@ -129,20 +97,7 @@ static inline enum soc_dma_port_type soc_dma_ch_update_type(
97 struct dma_s *dma = (struct dma_s *) ch->dma;
98 struct memmap_entry_s *entry = soc_dma_lookup(dma, ch->vaddr[port]);
99
132 - if (entry->type == soc_dma_port_fifo) {
133 - while (entry < dma->memmap + dma->memmap_size &&
134 - entry->u.fifo.out != port)
135 - entry ++;
136 - if (entry->addr != ch->vaddr[port] || entry->u.fifo.out != port)
137 - return soc_dma_port_other;
138 -
139 - if (ch->type[port] != soc_dma_access_const)
140 - return soc_dma_port_other;
141 -
142 - ch->io_fn[port] = entry->u.fifo.fn;
143 - ch->io_opaque[port] = entry->u.fifo.opaque;
144 - return soc_dma_port_fifo;
145 - } else if (entry->type == soc_dma_port_mem) {
100 + if (entry->type == soc_dma_port_mem) {
101 if (entry->addr > ch->vaddr[port] ||
102 entry->addr + entry->u.mem.size <= ch->vaddr[port])
103 return soc_dma_port_other;
@@ -173,15 +128,8 @@ void soc_dma_ch_update(struct soc_dma_ch_s *ch)
128 }
129 dst = soc_dma_ch_update_type(ch, 1);
130
176 - /* TODO: use src and dst as array indices. */
131 if (src == soc_dma_port_mem && dst == soc_dma_port_mem)
132 ch->transfer_fn = transfer_mem2mem;
179 - else if (src == soc_dma_port_mem && dst == soc_dma_port_fifo)
180 - ch->transfer_fn = transfer_mem2fifo;
181 - else if (src == soc_dma_port_fifo && dst == soc_dma_port_mem)
182 - ch->transfer_fn = transfer_fifo2mem;
183 - else if (src == soc_dma_port_fifo && dst == soc_dma_port_fifo)
184 - ch->transfer_fn = transfer_fifo2fifo;
133 else
134 ch->transfer_fn = ch->dma->transfer_fn;
135
@@ -251,61 +199,10 @@ struct soc_dma_s *soc_dma_init(int n)
199 }
200
201 soc_dma_reset(&s->soc);
254 - fifo_size = 0;
202
203 return &s->soc;
204 }
205
259 -void soc_dma_port_add_fifo(struct soc_dma_s *soc, hwaddr virt_base,
260 - soc_dma_io_t fn, void *opaque, int out)
261 -{
262 - struct memmap_entry_s *entry;
263 - struct dma_s *dma = (struct dma_s *) soc;
264 -
265 - dma->memmap = g_realloc(dma->memmap, sizeof(*entry) *
266 - (dma->memmap_size + 1));
267 - entry = soc_dma_lookup(dma, virt_base);
268 -
269 - if (dma->memmap_size) {
270 - if (entry->type == soc_dma_port_mem) {
271 - if (entry->addr <= virt_base &&
272 - entry->addr + entry->u.mem.size > virt_base) {
273 - error_report("%s: FIFO at %"PRIx64
274 - " collides with RAM region at %"PRIx64
275 - "-%"PRIx64, __func__,
276 - virt_base, entry->addr,
277 - (entry->addr + entry->u.mem.size));
278 - exit(-1);
279 - }
280 -
281 - if (entry->addr <= virt_base)
282 - entry ++;
283 - } else
284 - while (entry < dma->memmap + dma->memmap_size &&
285 - entry->addr <= virt_base) {
286 - if (entry->addr == virt_base && entry->u.fifo.out == out) {
287 - error_report("%s: FIFO at %"PRIx64
288 - " collides FIFO at %"PRIx64,
289 - __func__, virt_base, entry->addr);
290 - exit(-1);
291 - }
292 -
293 - entry ++;
294 - }
295 -
296 - memmove(entry + 1, entry,
297 - (uint8_t *) (dma->memmap + dma->memmap_size ++) -
298 - (uint8_t *) entry);
299 - } else
300 - dma->memmap_size ++;
301 -
302 - entry->addr = virt_base;
303 - entry->type = soc_dma_port_fifo;
304 - entry->u.fifo.fn = fn;
305 - entry->u.fifo.opaque = opaque;
306 - entry->u.fifo.out = out;
307 -}
308 -
206 void soc_dma_port_add_mem(struct soc_dma_s *soc, uint8_t *phys_base,
207 hwaddr virt_base, size_t size)
208 {
include/hw/arm/soc_dma.h
+4 -20
@@ -25,12 +25,10 @@
25
26 struct soc_dma_s;
27 struct soc_dma_ch_s;
28 -typedef void (*soc_dma_io_t)(void *opaque, uint8_t *buf, int len);
28 typedef void (*soc_dma_transfer_t)(struct soc_dma_ch_s *ch);
29
30 enum soc_dma_port_type {
31 soc_dma_port_mem,
33 - soc_dma_port_fifo,
32 soc_dma_port_other,
33 };
34
@@ -57,8 +55,6 @@ struct soc_dma_ch_s {
55 hwaddr vaddr[2]; /* Updated by .transfer_fn(). */
56 /* Private */
57 void *paddr[2];
60 - soc_dma_io_t io_fn[2];
61 - void *io_opaque[2];
58
59 int running;
60 soc_dma_transfer_t transfer_fn;
@@ -82,33 +78,21 @@ struct soc_dma_s {
78
79 /* Call to activate or stop a DMA channel. */
80 void soc_dma_set_request(struct soc_dma_ch_s *ch, int level);
85 -/* Call after every write to one of the following fields and before
81 +/*
82 + * Call after every write to one of the following fields and before
83 * calling soc_dma_set_request(ch, 1):
84 * ch->type[0...1],
85 * ch->vaddr[0...1],
86 * ch->paddr[0...1],
90 - * or after a soc_dma_port_add_fifo() or soc_dma_port_add_mem(). */
87 + * or after a soc_dma_port_add_mem().
88 + */
89 void soc_dma_ch_update(struct soc_dma_ch_s *ch);
90
91 /* The SoC should call this when the DMA module is being reset. */
92 void soc_dma_reset(struct soc_dma_s *s);
93 struct soc_dma_s *soc_dma_init(int n);
94
97 -void soc_dma_port_add_fifo(struct soc_dma_s *dma, hwaddr virt_base,
98 - soc_dma_io_t fn, void *opaque, int out);
95 void soc_dma_port_add_mem(struct soc_dma_s *dma, uint8_t *phys_base,
96 hwaddr virt_base, size_t size);
97
102 -static inline void soc_dma_port_add_fifo_in(struct soc_dma_s *dma,
103 - hwaddr virt_base, soc_dma_io_t fn, void *opaque)
104 -{
105 - return soc_dma_port_add_fifo(dma, virt_base, fn, opaque, 0);
106 -}
107 -
108 -static inline void soc_dma_port_add_fifo_out(struct soc_dma_s *dma,
109 - hwaddr virt_base, soc_dma_io_t fn, void *opaque)
110 -{
111 - return soc_dma_port_add_fifo(dma, virt_base, fn, opaque, 1);
112 -}
113 -
98 #endif