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));
121 Acpi_rsdt const *Acpi::_rsdt;
122 Acpi_xsdt const *Acpi::_xsdt;
123 bool Acpi::_init_done;
133 printf("ACPI-Init\n");
135 Acpi_rsdp const *rsdp = Acpi_rsdp::locate();
138 printf("ACPI: Could not find RSDP, skip init\n");
142 printf("ACPI: RSDP = %p pRSDT = %08x pXSDT = %16llx\n",
143 rsdp, rsdp->rsdt_phys, rsdp->xsdt_phys);
144 printf("ACPI: OEM: %c%c%c%c%c%c\n",
145 rsdp->oem[0], rsdp->oem[1], rsdp->oem[2],
146 rsdp->oem[3], rsdp->oem[4], rsdp->oem[5]);
148 if (rsdp->rev && rsdp->xsdt_phys)
150 Acpi_xsdt const *x = Kmem::dev_map.map((const Acpi_xsdt *)rsdp->xsdt_phys);
151 if (x == (Acpi_xsdt const *)~0UL)
152 printf("ACPI: Could not map XSDT\n");
153 else if (!x->checksum_ok())
154 printf("ACPI: Checksum mismatch in XSDT\n");
161 Acpi_rsdt const *r = Kmem::dev_map.map((const Acpi_rsdt *)rsdp->rsdt_phys);
162 if (r == (Acpi_rsdt const *)~0UL)
163 printf("ACPI: Could not map RSDT\n");
164 else if (!r->checksum_ok())
165 printf("ACPI: Checksum mismatch in RSDT\n");
172 template< typename T >
174 Acpi::find(const char *s)
179 a = static_cast<T>(_xsdt->find(s));
181 a = static_cast<T>(_rsdt->find(s));
187 Acpi_rsdp::rsdt() const
189 return (Acpi_rsdt const*)rsdt_phys;
194 Acpi_rsdp::xsdt() const
198 return (Acpi_xsdt const*)xsdt_phys;
203 Acpi_rsdp::checksum_ok() const
207 for (unsigned i = 0; i < 20; i++)
208 sum += *((Unsigned8 *)this + i);
217 for (unsigned i = 0; i < len && i < 4096; ++i)
218 sum += *((Unsigned8 *)this + i);
225 Acpi_table_head::checksum_ok() const
228 for (unsigned i = 0; i < len && i < 4096; ++i)
229 sum += *((Unsigned8 *)this + i);
235 template< typename T >
236 Acpi_table_head const *
237 Acpi_sdt<T>::find(char const sig[4]) const
239 for (unsigned i = 0; i < ((len-sizeof(Acpi_table_head))/sizeof(ptrs[0])); ++i)
241 Acpi_table_head const *t = Kmem::dev_map.lookup((Acpi_table_head const*)ptrs[i]);
242 if (t == (Acpi_table_head const *)~0UL)
245 if (t->signature[0] == sig[0]
246 && t->signature[1] == sig[1]
247 && t->signature[2] == sig[2]
248 && t->signature[3] == sig[3]
257 Acpi_madt::Apic_head const *
258 Acpi_madt::find(Unsigned8 type, int idx) const
260 for (unsigned i = 0; i < len-sizeof(Acpi_madt);)
262 Apic_head const *a = (Apic_head const *)(data + i);
263 //printf("a=%p, a->type=%u, a->len=%u\n", a, a->type, a->len);
276 // ------------------------------------------------------------------------
277 IMPLEMENTATION [ia32,amd64]:
285 ACPI20_PC99_RSDP_START = 0x0e0000,
286 ACPI20_PC99_RSDP_END = 0x100000
289 for (Address p = ACPI20_PC99_RSDP_START; p < ACPI20_PC99_RSDP_END; p += 16)
291 Acpi_rsdp const* r = (Acpi_rsdp const *)p;
292 if (r->signature[0] == 'R' &&
293 r->signature[1] == 'S' &&
294 r->signature[2] == 'D' &&
295 r->signature[3] == ' ' &&
296 r->signature[4] == 'P' &&
297 r->signature[5] == 'T' &&
298 r->signature[6] == 'R' &&
299 r->signature[7] == ' ' &&