Tue Dec 31 11:42:46 2019 UTC ()
The DMA restrictions may not be defined in the direct parent of a device,
so search up the tree for a module device.


(jmcneill)
diff -r1.15 -r1.16 src/sys/arch/arm/acpi/acpi_machdep.c

cvs diff -r1.15 -r1.16 src/sys/arch/arm/acpi/acpi_machdep.c (switch to unified diff)

--- src/sys/arch/arm/acpi/acpi_machdep.c 2019/12/30 19:50:29 1.15
+++ src/sys/arch/arm/acpi/acpi_machdep.c 2019/12/31 11:42:46 1.16
@@ -1,440 +1,461 @@ @@ -1,440 +1,461 @@
1/* $NetBSD: acpi_machdep.c,v 1.15 2019/12/30 19:50:29 jmcneill Exp $ */ 1/* $NetBSD: acpi_machdep.c,v 1.16 2019/12/31 11:42:46 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2018 The NetBSD Foundation, Inc. 4 * Copyright (c) 2018 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jared McNeill <jmcneill@invisible.ca>. 8 * by Jared McNeill <jmcneill@invisible.ca>.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include "pci.h" 32#include "pci.h"
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.15 2019/12/30 19:50:29 jmcneill Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.16 2019/12/31 11:42:46 jmcneill Exp $");
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/systm.h> 38#include <sys/systm.h>
39#include <sys/bus.h> 39#include <sys/bus.h>
40#include <sys/cpu.h> 40#include <sys/cpu.h>
41#include <sys/device.h> 41#include <sys/device.h>
42 42
43#include <uvm/uvm_extern.h> 43#include <uvm/uvm_extern.h>
44 44
45#include <dev/fdt/fdtvar.h> 45#include <dev/fdt/fdtvar.h>
46 46
47#include <dev/acpi/acpica.h> 47#include <dev/acpi/acpica.h>
48#include <dev/acpi/acpivar.h> 48#include <dev/acpi/acpivar.h>
49#if NPCI > 0 49#if NPCI > 0
50#include <dev/acpi/acpi_mcfg.h> 50#include <dev/acpi/acpi_mcfg.h>
51#endif 51#endif
52 52
53#include <arm/arm/efi_runtime.h> 53#include <arm/arm/efi_runtime.h>
54 54
55#include <arm/pic/picvar.h> 55#include <arm/pic/picvar.h>
56 56
57#include <arm/locore.h> 57#include <arm/locore.h>
58 58
59#include <machine/acpi_machdep.h> 59#include <machine/acpi_machdep.h>
60 60
61extern struct bus_space arm_generic_bs_tag; 61extern struct bus_space arm_generic_bs_tag;
62extern struct arm32_bus_dma_tag acpi_coherent_dma_tag; 62extern struct arm32_bus_dma_tag acpi_coherent_dma_tag;
63extern struct arm32_bus_dma_tag arm_generic_dma_tag; 63extern struct arm32_bus_dma_tag arm_generic_dma_tag;
64 64
65bus_dma_tag_t arm_acpi_dma_tag(struct acpi_softc *, struct acpi_devnode *); 65bus_dma_tag_t arm_acpi_dma_tag(struct acpi_softc *, struct acpi_devnode *);
66 66
67static int 67static int
68acpi_md_pmapflags(paddr_t pa) 68acpi_md_pmapflags(paddr_t pa)
69{ 69{
70 int len; 70 int len;
71 71
72 const int chosen = OF_finddevice("/chosen"); 72 const int chosen = OF_finddevice("/chosen");
73 if (chosen == -1) 73 if (chosen == -1)
74 return 0; 74 return 0;
75 75
76 const uint32_t *map = fdtbus_get_prop(chosen, "netbsd,uefi-memmap", &len); 76 const uint32_t *map = fdtbus_get_prop(chosen, "netbsd,uefi-memmap", &len);
77 if (map == NULL) 77 if (map == NULL)
78 return 0; 78 return 0;
79 79
80 while (len >= 28) { 80 while (len >= 28) {
81 const uint32_t type = be32dec(&map[0]); 81 const uint32_t type = be32dec(&map[0]);
82 const uint64_t phys_start = be64dec(&map[1]); 82 const uint64_t phys_start = be64dec(&map[1]);
83 const uint64_t num_pages = be64dec(&map[3]); 83 const uint64_t num_pages = be64dec(&map[3]);
84 const uint64_t attr = be64dec(&map[5]); 84 const uint64_t attr = be64dec(&map[5]);
85 85
86 if (pa >= phys_start && pa < phys_start + (num_pages * EFI_PAGE_SIZE)) { 86 if (pa >= phys_start && pa < phys_start + (num_pages * EFI_PAGE_SIZE)) {
87 switch (type) { 87 switch (type) {
88 case EFI_MD_TYPE_RECLAIM: 88 case EFI_MD_TYPE_RECLAIM:
89 /* ACPI table memory */ 89 /* ACPI table memory */
90 return PMAP_WRITE_BACK; 90 return PMAP_WRITE_BACK;
91 91
92 case EFI_MD_TYPE_IOMEM: 92 case EFI_MD_TYPE_IOMEM:
93 case EFI_MD_TYPE_IOPORT: 93 case EFI_MD_TYPE_IOPORT:
94 return PMAP_DEV; 94 return PMAP_DEV;
95 95
96 default: 96 default:
97 if ((attr & EFI_MD_ATTR_WB) != 0) 97 if ((attr & EFI_MD_ATTR_WB) != 0)
98 return PMAP_WRITE_BACK; 98 return PMAP_WRITE_BACK;
99 else if ((attr & EFI_MD_ATTR_WC) != 0) 99 else if ((attr & EFI_MD_ATTR_WC) != 0)
100 return PMAP_WRITE_COMBINE; 100 return PMAP_WRITE_COMBINE;
101 else if ((attr & EFI_MD_ATTR_WT) != 0) 101 else if ((attr & EFI_MD_ATTR_WT) != 0)
102 return 0; /* XXX */ 102 return 0; /* XXX */
103 103
104 return PMAP_DEV; 104 return PMAP_DEV;
105 } 105 }
106 } 106 }
107 107
108 map += 7; 108 map += 7;
109 len -= 28; 109 len -= 28;
110 } 110 }
111 111
112 /* Not found; assume device memory */ 112 /* Not found; assume device memory */
113 return PMAP_DEV; 113 return PMAP_DEV;
114} 114}
115 115
116ACPI_STATUS 116ACPI_STATUS
117acpi_md_OsInitialize(void) 117acpi_md_OsInitialize(void)
118{ 118{
119 return AE_OK; 119 return AE_OK;
120} 120}
121 121
122ACPI_PHYSICAL_ADDRESS 122ACPI_PHYSICAL_ADDRESS
123acpi_md_OsGetRootPointer(void) 123acpi_md_OsGetRootPointer(void)
124{ 124{
125 uint64_t pa; 125 uint64_t pa;
126 126
127 const int chosen = OF_finddevice("/chosen"); 127 const int chosen = OF_finddevice("/chosen");
128 if (chosen == -1) 128 if (chosen == -1)
129 return 0; 129 return 0;
130 130
131 if (of_getprop_uint64(chosen, "netbsd,acpi-root-table", &pa) != 0) 131 if (of_getprop_uint64(chosen, "netbsd,acpi-root-table", &pa) != 0)
132 return 0; 132 return 0;
133 133
134 return (ACPI_PHYSICAL_ADDRESS)pa; 134 return (ACPI_PHYSICAL_ADDRESS)pa;
135} 135}
136 136
137ACPI_STATUS 137ACPI_STATUS
138acpi_md_OsInstallInterruptHandler(UINT32 irq, ACPI_OSD_HANDLER handler, void *context, 138acpi_md_OsInstallInterruptHandler(UINT32 irq, ACPI_OSD_HANDLER handler, void *context,
139 void **cookiep, const char *xname) 139 void **cookiep, const char *xname)
140{ 140{
141 return AE_NOT_IMPLEMENTED; 141 return AE_NOT_IMPLEMENTED;
142} 142}
143 143
144void 144void
145acpi_md_OsRemoveInterruptHandler(void *cookie) 145acpi_md_OsRemoveInterruptHandler(void *cookie)
146{ 146{
147 intr_disestablish(cookie); 147 intr_disestablish(cookie);
148} 148}
149 149
150ACPI_STATUS 150ACPI_STATUS
151acpi_md_OsMapMemory(ACPI_PHYSICAL_ADDRESS pa, UINT32 size, void **vap) 151acpi_md_OsMapMemory(ACPI_PHYSICAL_ADDRESS pa, UINT32 size, void **vap)
152{ 152{
153 paddr_t spa, epa, curpa; 153 paddr_t spa, epa, curpa;
154 vaddr_t va, curva; 154 vaddr_t va, curva;
155 155
156 spa = trunc_page(pa); 156 spa = trunc_page(pa);
157 epa = round_page(pa + size); 157 epa = round_page(pa + size);
158 158
159 va = uvm_km_alloc(kernel_map, epa - spa, 0, UVM_KMF_VAONLY); 159 va = uvm_km_alloc(kernel_map, epa - spa, 0, UVM_KMF_VAONLY);
160 if (va == 0) 160 if (va == 0)
161 return AE_NO_MEMORY; 161 return AE_NO_MEMORY;
162 162
163 const int pmapflags = acpi_md_pmapflags(spa); 163 const int pmapflags = acpi_md_pmapflags(spa);
164 164
165 aprint_debug("%s: 0x%lx 0x%x flags = %#x\n", __func__, pa, size, pmapflags); 165 aprint_debug("%s: 0x%lx 0x%x flags = %#x\n", __func__, pa, size, pmapflags);
166 166
167 for (curpa = spa, curva = va; curpa < epa; curpa += PAGE_SIZE, curva += PAGE_SIZE) 167 for (curpa = spa, curva = va; curpa < epa; curpa += PAGE_SIZE, curva += PAGE_SIZE)
168 pmap_kenter_pa(curva, curpa, VM_PROT_READ | VM_PROT_WRITE, pmapflags); 168 pmap_kenter_pa(curva, curpa, VM_PROT_READ | VM_PROT_WRITE, pmapflags);
169 pmap_update(pmap_kernel()); 169 pmap_update(pmap_kernel());
170 170
171 *vap = (void *)(va + (pa - spa)); 171 *vap = (void *)(va + (pa - spa));
172 172
173 return AE_OK; 173 return AE_OK;
174} 174}
175 175
176void 176void
177acpi_md_OsUnmapMemory(void *va, UINT32 size) 177acpi_md_OsUnmapMemory(void *va, UINT32 size)
178{ 178{
179 vaddr_t ova; 179 vaddr_t ova;
180 vsize_t osz; 180 vsize_t osz;
181 181
182 ova = trunc_page((vaddr_t)va); 182 ova = trunc_page((vaddr_t)va);
183 osz = round_page((vaddr_t)va + size) - ova; 183 osz = round_page((vaddr_t)va + size) - ova;
184 184
185 pmap_kremove(ova, osz); 185 pmap_kremove(ova, osz);
186 pmap_update(pmap_kernel()); 186 pmap_update(pmap_kernel());
187 uvm_km_free(kernel_map, ova, osz, UVM_KMF_VAONLY); 187 uvm_km_free(kernel_map, ova, osz, UVM_KMF_VAONLY);
188} 188}
189 189
190ACPI_STATUS 190ACPI_STATUS
191acpi_md_OsGetPhysicalAddress(void *va, ACPI_PHYSICAL_ADDRESS *pap) 191acpi_md_OsGetPhysicalAddress(void *va, ACPI_PHYSICAL_ADDRESS *pap)
192{ 192{
193 paddr_t pa; 193 paddr_t pa;
194 194
195 if (!pmap_extract(pmap_kernel(), (vaddr_t)va, &pa)) 195 if (!pmap_extract(pmap_kernel(), (vaddr_t)va, &pa))
196 return AE_ERROR; 196 return AE_ERROR;
197 197
198 *pap = pa; 198 *pap = pa;
199 199
200 return AE_OK; 200 return AE_OK;
201} 201}
202 202
203BOOLEAN 203BOOLEAN
204acpi_md_OsReadable(void *va, UINT32 len) 204acpi_md_OsReadable(void *va, UINT32 len)
205{ 205{
206 vaddr_t sva, eva; 206 vaddr_t sva, eva;
207 pt_entry_t *pte; 207 pt_entry_t *pte;
208 208
209 sva = trunc_page((vaddr_t)va); 209 sva = trunc_page((vaddr_t)va);
210 eva = round_page((vaddr_t)va + len); 210 eva = round_page((vaddr_t)va + len);
211 211
212 if (sva < VM_MIN_KERNEL_ADDRESS) 212 if (sva < VM_MIN_KERNEL_ADDRESS)
213 return FALSE; 213 return FALSE;
214 214
215 for (; sva < eva; sva += PAGE_SIZE) { 215 for (; sva < eva; sva += PAGE_SIZE) {
216 pte = kvtopte(sva); 216 pte = kvtopte(sva);
217 if ((*pte & (LX_BLKPAG_AF|LX_BLKPAG_AP)) != (LX_BLKPAG_AF|LX_BLKPAG_AP_RO)) 217 if ((*pte & (LX_BLKPAG_AF|LX_BLKPAG_AP)) != (LX_BLKPAG_AF|LX_BLKPAG_AP_RO))
218 return FALSE; 218 return FALSE;
219 } 219 }
220 220
221 return TRUE; 221 return TRUE;
222} 222}
223 223
224BOOLEAN 224BOOLEAN
225acpi_md_OsWritable(void *va, UINT32 len) 225acpi_md_OsWritable(void *va, UINT32 len)
226{ 226{
227 vaddr_t sva, eva; 227 vaddr_t sva, eva;
228 pt_entry_t *pte; 228 pt_entry_t *pte;
229 229
230 sva = trunc_page((vaddr_t)va); 230 sva = trunc_page((vaddr_t)va);
231 eva = round_page((vaddr_t)va + len); 231 eva = round_page((vaddr_t)va + len);
232 232
233 if (sva < VM_MIN_KERNEL_ADDRESS) 233 if (sva < VM_MIN_KERNEL_ADDRESS)
234 return FALSE; 234 return FALSE;
235 235
236 for (; sva < eva; sva += PAGE_SIZE) { 236 for (; sva < eva; sva += PAGE_SIZE) {
237 pte = kvtopte(sva); 237 pte = kvtopte(sva);
238 if ((*pte & (LX_BLKPAG_AF|LX_BLKPAG_AP)) != (LX_BLKPAG_AF|LX_BLKPAG_AP_RW)) 238 if ((*pte & (LX_BLKPAG_AF|LX_BLKPAG_AP)) != (LX_BLKPAG_AF|LX_BLKPAG_AP_RW))
239 return FALSE; 239 return FALSE;
240 } 240 }
241 241
242 return TRUE; 242 return TRUE;
243} 243}
244 244
245void 245void
246acpi_md_OsEnableInterrupt(void) 246acpi_md_OsEnableInterrupt(void)
247{ 247{
248 cpsie(I32_bit); 248 cpsie(I32_bit);
249} 249}
250 250
251void 251void
252acpi_md_OsDisableInterrupt(void) 252acpi_md_OsDisableInterrupt(void)
253{ 253{
254 cpsid(I32_bit); 254 cpsid(I32_bit);
255} 255}
256 256
257void * 257void *
258acpi_md_intr_establish(uint32_t irq, int ipl, int type, int (*handler)(void *), void *arg, bool mpsafe, const char *xname) 258acpi_md_intr_establish(uint32_t irq, int ipl, int type, int (*handler)(void *), void *arg, bool mpsafe, const char *xname)
259{ 259{
260 return intr_establish_xname(irq, ipl, type | (mpsafe ? IST_MPSAFE : 0), handler, arg, xname); 260 return intr_establish_xname(irq, ipl, type | (mpsafe ? IST_MPSAFE : 0), handler, arg, xname);
261} 261}
262 262
263void 263void
264acpi_md_intr_mask(void *ih) 264acpi_md_intr_mask(void *ih)
265{ 265{
266 intr_mask(ih); 266 intr_mask(ih);
267} 267}
268 268
269void 269void
270acpi_md_intr_unmask(void *ih) 270acpi_md_intr_unmask(void *ih)
271{ 271{
272 intr_unmask(ih); 272 intr_unmask(ih);
273} 273}
274 274
275void 275void
276acpi_md_intr_disestablish(void *ih) 276acpi_md_intr_disestablish(void *ih)
277{ 277{
278 intr_disestablish(ih); 278 intr_disestablish(ih);
279} 279}
280 280
281int 281int
282acpi_md_sleep(int state) 282acpi_md_sleep(int state)
283{ 283{
284 printf("ERROR: ACPI sleep not implemented on this platform\n"); 284 printf("ERROR: ACPI sleep not implemented on this platform\n");
285 return -1; 285 return -1;
286} 286}
287 287
288uint32_t 288uint32_t
289acpi_md_pdc(void) 289acpi_md_pdc(void)
290{ 290{
291 return 0; 291 return 0;
292} 292}
293 293
294uint32_t 294uint32_t
295acpi_md_ncpus(void) 295acpi_md_ncpus(void)
296{ 296{
297 return kcpuset_countset(kcpuset_attached); 297 return kcpuset_countset(kcpuset_attached);
298} 298}
299 299
300static ACPI_STATUS 300static ACPI_STATUS
301acpi_md_madt_probe_cpu(ACPI_SUBTABLE_HEADER *hdrp, void *aux) 301acpi_md_madt_probe_cpu(ACPI_SUBTABLE_HEADER *hdrp, void *aux)
302{ 302{
303 struct acpi_softc * const sc = aux; 303 struct acpi_softc * const sc = aux;
304 304
305 if (hdrp->Type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) 305 if (hdrp->Type == ACPI_MADT_TYPE_GENERIC_INTERRUPT)
306 config_found_ia(sc->sc_dev, "acpimadtbus", hdrp, NULL); 306 config_found_ia(sc->sc_dev, "acpimadtbus", hdrp, NULL);
307 307
308 return AE_OK; 308 return AE_OK;
309} 309}
310 310
311static ACPI_STATUS 311static ACPI_STATUS
312acpi_md_madt_probe_gic(ACPI_SUBTABLE_HEADER *hdrp, void *aux) 312acpi_md_madt_probe_gic(ACPI_SUBTABLE_HEADER *hdrp, void *aux)
313{ 313{
314 struct acpi_softc * const sc = aux; 314 struct acpi_softc * const sc = aux;
315 315
316 if (hdrp->Type == ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR) 316 if (hdrp->Type == ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR)
317 config_found_ia(sc->sc_dev, "acpimadtbus", hdrp, NULL); 317 config_found_ia(sc->sc_dev, "acpimadtbus", hdrp, NULL);
318 318
319 return AE_OK; 319 return AE_OK;
320} 320}
321 321
322static ACPI_STATUS 322static ACPI_STATUS
323acpi_md_gtdt_probe(ACPI_GTDT_HEADER *hdrp, void *aux) 323acpi_md_gtdt_probe(ACPI_GTDT_HEADER *hdrp, void *aux)
324{ 324{
325 struct acpi_softc * const sc = aux; 325 struct acpi_softc * const sc = aux;
326 326
327 config_found_ia(sc->sc_dev, "acpigtdtbus", hdrp, NULL); 327 config_found_ia(sc->sc_dev, "acpigtdtbus", hdrp, NULL);
328 328
329 return AE_OK; 329 return AE_OK;
330} 330}
331 331
332#if NPCI > 0 332#if NPCI > 0
333static struct bus_space acpi_md_mcfg_bs_tag; 333static struct bus_space acpi_md_mcfg_bs_tag;
334 334
335static int 335static int
336acpi_md_mcfg_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flag, 336acpi_md_mcfg_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flag,
337 bus_space_handle_t *bshp) 337 bus_space_handle_t *bshp)
338{ 338{
339 return arm_generic_bs_tag.bs_map(t, bpa, size, 339 return arm_generic_bs_tag.bs_map(t, bpa, size,
340 flag | _ARM_BUS_SPACE_MAP_STRONGLY_ORDERED, bshp); 340 flag | _ARM_BUS_SPACE_MAP_STRONGLY_ORDERED, bshp);
341} 341}
342#endif 342#endif
343 343
344void 344void
345acpi_md_callback(struct acpi_softc *sc) 345acpi_md_callback(struct acpi_softc *sc)
346{ 346{
347 ACPI_TABLE_HEADER *hdrp; 347 ACPI_TABLE_HEADER *hdrp;
348 348
349#if NPCI > 0 349#if NPCI > 0
350 acpi_md_mcfg_bs_tag = arm_generic_bs_tag; 350 acpi_md_mcfg_bs_tag = arm_generic_bs_tag;
351 acpi_md_mcfg_bs_tag.bs_map = acpi_md_mcfg_bs_map; 351 acpi_md_mcfg_bs_tag.bs_map = acpi_md_mcfg_bs_map;
352 acpimcfg_init(&acpi_md_mcfg_bs_tag, NULL); 352 acpimcfg_init(&acpi_md_mcfg_bs_tag, NULL);
353#endif 353#endif
354 354
355 if (acpi_madt_map() != AE_OK) 355 if (acpi_madt_map() != AE_OK)
356 panic("Failed to map MADT"); 356 panic("Failed to map MADT");
357 acpi_madt_walk(acpi_md_madt_probe_cpu, sc); 357 acpi_madt_walk(acpi_md_madt_probe_cpu, sc);
358 acpi_madt_walk(acpi_md_madt_probe_gic, sc); 358 acpi_madt_walk(acpi_md_madt_probe_gic, sc);
359 acpi_madt_unmap(); 359 acpi_madt_unmap();
360 360
361 if (acpi_gtdt_map() != AE_OK) 361 if (acpi_gtdt_map() != AE_OK)
362 panic("Failed to map GTDT"); 362 panic("Failed to map GTDT");
363 acpi_gtdt_walk(acpi_md_gtdt_probe, sc); 363 acpi_gtdt_walk(acpi_md_gtdt_probe, sc);
364 acpi_gtdt_unmap(); 364 acpi_gtdt_unmap();
365 365
366 if (ACPI_SUCCESS(AcpiGetTable(ACPI_SIG_GTDT, 0, &hdrp))) 366 if (ACPI_SUCCESS(AcpiGetTable(ACPI_SIG_GTDT, 0, &hdrp)))
367 config_found_ia(sc->sc_dev, "acpisdtbus", hdrp, NULL); 367 config_found_ia(sc->sc_dev, "acpisdtbus", hdrp, NULL);
368} 368}
369 369
370static const char * const module_hid[] = { 370static const char * const module_hid[] = {
371 "ACPI0004", /* Module device */ 371 "ACPI0004", /* Module device */
372 NULL 372 NULL
373}; 373};
374 374
375static bus_dma_tag_t 375static bus_dma_tag_t
376arm_acpi_dma_tag_subregion(struct acpi_softc *sc, bus_dma_tag_t dmat, 376arm_acpi_dma_tag_subregion(struct acpi_softc *sc, bus_dma_tag_t dmat,
377 ACPI_HANDLE handle) 377 ACPI_HANDLE handle)
378{ 378{
379 struct acpi_resources res; 379 struct acpi_resources res;
380 struct acpi_mem *mem; 380 struct acpi_mem *mem;
381 bus_dma_tag_t newtag; 381 bus_dma_tag_t newtag;
382 ACPI_STATUS rv; 382 ACPI_STATUS rv;
383 int error; 383 int error;
384 384
385 rv = acpi_resource_parse(sc->sc_dev, handle, "_DMA", &res, 385 rv = acpi_resource_parse(sc->sc_dev, handle, "_DMA", &res,
386 &acpi_resource_parse_ops_quiet); 386 &acpi_resource_parse_ops_quiet);
387 if (ACPI_FAILURE(rv)) 387 if (ACPI_FAILURE(rv))
388 return dmat; /* no translation required */ 388 return dmat; /* no translation required */
389 389
390 mem = acpi_res_mem(&res, 0); 390 mem = acpi_res_mem(&res, 0);
391 if (mem == NULL) 391 if (mem == NULL)
392 goto done; 392 goto done;
393 393
394 aprint_debug_dev(sc->sc_dev, "_DMA range %#lx-%#lx\n", 394 aprint_debug_dev(sc->sc_dev, "_DMA range %#lx-%#lx\n",
395 mem->ar_base, mem->ar_base + mem->ar_length - 1); 395 mem->ar_base, mem->ar_base + mem->ar_length - 1);
396 396
397 error = bus_dmatag_subregion(dmat, 397 error = bus_dmatag_subregion(dmat,
398 mem->ar_base, mem->ar_base + mem->ar_length - 1, 398 mem->ar_base, mem->ar_base + mem->ar_length - 1,
399 &newtag, BUS_DMA_WAITOK); 399 &newtag, BUS_DMA_WAITOK);
400 if (error != 0) { 400 if (error != 0) {
401 aprint_error_dev(sc->sc_dev, 401 aprint_error_dev(sc->sc_dev,
402 "_DMA subregion failed: %d\n", error); 402 "_DMA subregion failed: %d\n", error);
403 goto done; 403 goto done;
404 } 404 }
405 dmat = newtag; 405 dmat = newtag;
406 406
407done: 407done:
408 acpi_resource_cleanup(&res); 408 acpi_resource_cleanup(&res);
409 409
410 return dmat; 410 return dmat;
411} 411}
412 412
 413static ACPI_HANDLE
 414arm_acpi_dma_module(struct acpi_softc *sc, struct acpi_devnode *ad)
 415{
 416 ACPI_HANDLE tmp;
 417 ACPI_STATUS rv;
 418
 419 /*
 420 * Search up the tree for a module device with a _DMA method.
 421 */
 422 for (; ad != NULL; ad = ad->ad_parent) {
 423 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE)
 424 continue;
 425 if (!acpi_match_hid(ad->ad_devinfo, module_hid))
 426 continue;
 427 rv = AcpiGetHandle(ad->ad_handle, "_DMA", &tmp);
 428 if (ACPI_SUCCESS(rv))
 429 return ad->ad_handle;
 430 }
 431
 432 return NULL;
 433}
 434
413bus_dma_tag_t 435bus_dma_tag_t
414arm_acpi_dma_tag(struct acpi_softc *sc, struct acpi_devnode *ad) 436arm_acpi_dma_tag(struct acpi_softc *sc, struct acpi_devnode *ad)
415{ 437{
 438 ACPI_HANDLE module;
416 ACPI_INTEGER cca; 439 ACPI_INTEGER cca;
417 bus_dma_tag_t dmat; 440 bus_dma_tag_t dmat;
418 441
419 if (ACPI_FAILURE(acpi_eval_integer(ad->ad_handle, "_CCA", &cca))) 442 if (ACPI_FAILURE(acpi_eval_integer(ad->ad_handle, "_CCA", &cca)))
420 cca = 1; 443 cca = 1;
421 444
422 if (cca) 445 if (cca)
423 dmat = &acpi_coherent_dma_tag; 446 dmat = &acpi_coherent_dma_tag;
424 else 447 else
425 dmat = &arm_generic_dma_tag; 448 dmat = &arm_generic_dma_tag;
426 449
427 /* 450 /*
428 * If the parent device is a bus, it may define valid DMA ranges 451 * If a parent device is a bus, it may define valid DMA ranges
429 * and translations for child nodes. 452 * and translations for child nodes.
430 */ 453 */
431 if (ad->ad_parent != NULL && 454 module = arm_acpi_dma_module(sc, ad);
432 acpi_match_hid(ad->ad_parent->ad_devinfo, module_hid)) { 455 if (module != NULL)
433 dmat = arm_acpi_dma_tag_subregion(sc, dmat, 456 dmat = arm_acpi_dma_tag_subregion(sc, dmat, module);
434 ad->ad_parent->ad_handle); 
435 } 
436 457
437 return dmat; 458 return dmat;
438} 459}
439__strong_alias(acpi_get_dma_tag,arm_acpi_dma_tag); 460__strong_alias(acpi_get_dma_tag,arm_acpi_dma_tag);
440__strong_alias(acpi_get_dma64_tag,arm_acpi_dma_tag); 461__strong_alias(acpi_get_dma64_tag,arm_acpi_dma_tag);