8 enum Type { System_mem = 0, System_io = 1, Pci_cfg_mem = 2 };
12 Unsigned8 access_size;
14 } __attribute__((packed));
28 Unsigned32 creator_id;
29 Unsigned32 creator_rev;
31 bool checksum_ok() const;
32 } __attribute__((packed));
35 template< typename T >
36 class Acpi_sdt : public Acpi_table_head
41 } __attribute__((packed));
43 typedef Acpi_sdt<Unsigned32> Acpi_rsdt;
44 typedef Acpi_sdt<Unsigned64> Acpi_xsdt;
56 Unsigned8 ext_chk_sum;
59 Acpi_rsdt const *rsdt() const;
60 Acpi_xsdt const *xsdt() const;
62 bool checksum_ok() const;
64 static Acpi_rsdp const *locate();
65 } __attribute__((packed));
70 static Acpi_rsdt const *rsdt() { return _rsdt; }
71 static Acpi_xsdt const *xsdt() { return _xsdt; }
74 static Acpi_rsdt const *_rsdt;
75 static Acpi_xsdt const *_xsdt;
76 static bool _init_done;
79 class Acpi_madt : public Acpi_table_head
83 { LAPIC, IOAPIC, Irq_src_ovr, NMI, LAPIC_NMI, LAPIC_adr_ovr, IOSAPIC,
90 } __attribute__((packed));
92 struct Io_apic : public Apic_head
98 } __attribute__((packed));
100 struct Irq_source : public Apic_head
106 } __attribute__((packed));
109 Unsigned32 local_apic;
110 Unsigned32 apic_flags;
114 } __attribute__((packed));
122 Acpi_rsdt const *Acpi::_rsdt;
123 Acpi_xsdt const *Acpi::_xsdt;
124 bool Acpi::_init_done;
128 print_acpi_id(char const *id, unsigned len)
131 for (unsigned i = 0; i < len; ++i)
132 ID[i] = isalnum(id[i]) ? id[i] : '.';
133 printf("%.*s", len, ID);
137 Acpi_rsdp::print_info() const
139 printf("ACPI: RSDP[%p]\tr%02x OEM:", this, rev);
140 print_acpi_id(oem, 6);
145 Acpi_table_head::print_info() const
148 print_acpi_id(signature, 4);
149 printf("[%p]\tr%02x OEM:", this, rev);
150 print_acpi_id(oem_id, 6);
152 print_acpi_id(oem_tid, 8);
156 PUBLIC template< typename T >
158 Acpi_sdt<T>::print_summary() const
160 for (unsigned i = 0; i < ((len-sizeof(Acpi_table_head))/sizeof(ptrs[0])); ++i)
162 Acpi_table_head const *t = Kmem::dev_map.map((Acpi_table_head const*)ptrs[i]);
163 if (t == (Acpi_table_head const *)~0UL)
179 printf("ACPI-Init\n");
181 Acpi_rsdp const *rsdp = Acpi_rsdp::locate();
184 printf("ACPI: Could not find RSDP, skip init\n");
190 if (rsdp->rev && rsdp->xsdt_phys)
192 Acpi_xsdt const *x = Kmem::dev_map.map((const Acpi_xsdt *)rsdp->xsdt_phys);
193 if (x == (Acpi_xsdt const *)~0UL)
194 printf("ACPI: Could not map XSDT\n");
195 else if (!x->checksum_ok())
196 printf("ACPI: Checksum mismatch in XSDT\n");
206 Acpi_rsdt const *r = Kmem::dev_map.map((const Acpi_rsdt *)rsdp->rsdt_phys);
207 if (r == (Acpi_rsdt const *)~0UL)
208 printf("ACPI: Could not map RSDT\n");
209 else if (!r->checksum_ok())
210 printf("ACPI: Checksum mismatch in RSDT\n");
219 _xsdt->print_summary();
221 _rsdt->print_summary();
225 template< typename T >
227 Acpi::find(const char *s)
232 a = static_cast<T>(_xsdt->find(s));
234 a = static_cast<T>(_rsdt->find(s));
240 Acpi_rsdp::rsdt() const
242 return (Acpi_rsdt const*)rsdt_phys;
247 Acpi_rsdp::xsdt() const
251 return (Acpi_xsdt const*)xsdt_phys;
256 Acpi_rsdp::checksum_ok() const
260 for (unsigned i = 0; i < 20; i++)
261 sum += *((Unsigned8 *)this + i);
270 for (unsigned i = 0; i < len && i < 4096; ++i)
271 sum += *((Unsigned8 *)this + i);
278 Acpi_table_head::checksum_ok() const
281 for (unsigned i = 0; i < len && i < 4096; ++i)
282 sum += *((Unsigned8 *)this + i);
288 template< typename T >
289 Acpi_table_head const *
290 Acpi_sdt<T>::find(char const sig[4]) const
292 for (unsigned i = 0; i < ((len-sizeof(Acpi_table_head))/sizeof(ptrs[0])); ++i)
294 Acpi_table_head const *t = Kmem::dev_map.map((Acpi_table_head const*)ptrs[i]);
295 if (t == (Acpi_table_head const *)~0UL)
298 if (t->signature[0] == sig[0]
299 && t->signature[1] == sig[1]
300 && t->signature[2] == sig[2]
301 && t->signature[3] == sig[3]
310 Acpi_madt::Apic_head const *
311 Acpi_madt::find(Unsigned8 type, int idx) const
313 for (unsigned i = 0; i < len-sizeof(Acpi_madt);)
315 Apic_head const *a = (Apic_head const *)(data + i);
316 //printf("a=%p, a->type=%u, a->len=%u\n", a, a->type, a->len);
329 // ------------------------------------------------------------------------
330 IMPLEMENTATION [ia32,amd64]:
338 ACPI20_PC99_RSDP_START = 0x0e0000,
339 ACPI20_PC99_RSDP_END = 0x100000
342 for (Address p = ACPI20_PC99_RSDP_START; p < ACPI20_PC99_RSDP_END; p += 16)
344 Acpi_rsdp const* r = (Acpi_rsdp const *)p;
345 if (r->signature[0] == 'R' &&
346 r->signature[1] == 'S' &&
347 r->signature[2] == 'D' &&
348 r->signature[3] == ' ' &&
349 r->signature[4] == 'P' &&
350 r->signature[5] == 'T' &&
351 r->signature[6] == 'R' &&
352 r->signature[7] == ' ' &&