This source file includes following definitions.
- acpi_map
- acpi_unmap
- acpi_scan
- acpi_probe
- acpi_attach_machdep
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/kernel.h>
21 #include <sys/device.h>
22 #include <sys/malloc.h>
23
24 #include <uvm/uvm_extern.h>
25
26 #include <machine/bus.h>
27 #include <i386/isa/isa_machdep.h>
28
29 #include <dev/isa/isareg.h>
30 #include <dev/acpi/acpireg.h>
31 #include <dev/acpi/acpivar.h>
32
33 #include "bios.h"
34 #include "apm.h"
35
36 #if NBIOS > 0
37 #include <machine/biosvar.h>
38 #endif
39
40 #define ACPI_BIOS_RSDP_WINDOW_BASE 0xe0000
41 #define ACPI_BIOS_RSDP_WINDOW_SIZE 0x20000
42
43 #if NAPM > 0 && NBIOS > 0
44 extern bios_apminfo_t *apm;
45 #endif
46
47 u_int8_t *acpi_scan(struct acpi_mem_map *, paddr_t, size_t);
48
49 int
50 acpi_map(paddr_t pa, size_t len, struct acpi_mem_map *handle)
51 {
52 paddr_t pgpa = trunc_page(pa);
53 paddr_t endpa = round_page(pa + len);
54 vaddr_t va = uvm_km_valloc(kernel_map, endpa - pgpa);
55
56 if (va == 0)
57 return (ENOMEM);
58
59 handle->baseva = va;
60 handle->va = (u_int8_t *)(va + (u_long)(pa & PGOFSET));
61 handle->vsize = endpa - pgpa;
62 handle->pa = pa;
63
64 do {
65 pmap_kenter_pa(va, pgpa, VM_PROT_READ | VM_PROT_WRITE);
66 va += NBPG;
67 pgpa += NBPG;
68 } while (pgpa < endpa);
69
70 return 0;
71 }
72
73 void
74 acpi_unmap(struct acpi_mem_map *handle)
75 {
76 pmap_kremove(handle->baseva, handle->vsize);
77 uvm_km_free(kernel_map, handle->baseva, handle->vsize);
78 }
79
80 u_int8_t *
81 acpi_scan(struct acpi_mem_map *handle, paddr_t pa, size_t len)
82 {
83 size_t i;
84 u_int8_t *ptr;
85 struct acpi_rsdp1 *rsdp;
86
87 if (acpi_map(pa, len, handle))
88 return (NULL);
89 for (ptr = handle->va, i = 0;
90 i < len;
91 ptr += 16, i += 16)
92 if (memcmp(ptr, RSDP_SIG, sizeof(RSDP_SIG) - 1) == 0) {
93 rsdp = (struct acpi_rsdp1 *)ptr;
94
95
96
97
98 if (rsdp->revision == 0 &&
99 acpi_checksum(ptr, sizeof(struct acpi_rsdp1)) == 0)
100 return (ptr);
101 else if (rsdp->revision == 2 &&
102 acpi_checksum(ptr, sizeof(struct acpi_rsdp)) == 0)
103 return (ptr);
104 }
105 acpi_unmap(handle);
106
107 return (NULL);
108 }
109
110 int
111 acpi_probe(struct device *parent, struct cfdata *match, struct acpi_attach_args *aaa)
112 {
113 struct acpi_mem_map handle;
114 u_int8_t *ptr;
115 paddr_t ebda;
116 #if NAPM > 0
117 extern int apm_attached;
118
119 if (apm_attached)
120 return (0);
121 #endif
122 #if NBIOS > 0
123 {
124 bios_memmap_t *im;
125
126
127
128
129 for (im = bios_memmap; im->type != BIOS_MAP_END; im++)
130 if (im->type == BIOS_MAP_ACPI) {
131 if ((ptr = acpi_scan(&handle, im->addr, im->size)))
132 goto havebase;
133 }
134 }
135 #endif
136
137
138
139
140 if (acpi_map(0, NBPG, &handle))
141 printf("acpi: failed to map BIOS data area\n");
142 else {
143 ebda = *(const u_int16_t *)(&handle.va[0x40e]);
144 ebda <<= 4;
145 acpi_unmap(&handle);
146
147 if (ebda && ebda < IOM_BEGIN) {
148 if ((ptr = acpi_scan(&handle, ebda, 1024)))
149 goto havebase;
150 }
151 }
152
153
154
155
156
157 if ((ptr = acpi_scan(&handle, ACPI_BIOS_RSDP_WINDOW_BASE,
158 ACPI_BIOS_RSDP_WINDOW_SIZE)))
159 goto havebase;
160
161 return (0);
162
163 havebase:
164 aaa->aaa_pbase = ptr - handle.va + handle.pa;
165 acpi_unmap(&handle);
166
167 return (1);
168 }
169
170 void
171 acpi_attach_machdep(struct acpi_softc *sc)
172 {
173 #ifdef ACPI_ENABLE
174 sc->sc_interrupt = isa_intr_establish(NULL, sc->sc_fadt->sci_int,
175 IST_LEVEL, IPL_TTY, acpi_interrupt, sc, "acpi");
176 #endif
177 }