4 #include "kernel/kernel.h"
6 #include "arch_proto.h"
8 typedef int ((* acpi_read_t
)(phys_bytes addr
, void * buff
, size_t size
));
10 struct acpi_rsdp acpi_rsdp
;
12 static acpi_read_t read_func
;
14 #define MAX_RSDT 35 /* ACPI defines 35 signatures */
16 static struct acpi_rsdt
{
17 struct acpi_sdt_header hdr
;
22 char signature
[ACPI_SDT_SIGNATURE_LEN
+ 1];
24 } sdt_trans
[MAX_RSDT
];
28 static int acpi_check_csum(struct acpi_sdt_header
* tb
, size_t size
)
32 for (i
= 0; i
< size
; i
++)
33 total
+= ((unsigned char *)tb
)[i
];
34 return total
== 0 ? 0 : -1;
37 static int acpi_check_signature(const char * orig
, const char * match
)
39 return strncmp(orig
, match
, ACPI_SDT_SIGNATURE_LEN
);
42 static u32_t
acpi_phys2vir(u32_t p
)
45 printf("acpi: returning 0x%lx as vir addr\n", p
);
48 panic("acpi: can't get virtual address of arbitrary physical address");
51 static int acpi_phys_copy(phys_bytes phys
, void *target
, size_t len
)
54 memcpy(target
, (void *) phys
, len
);
57 panic("can't acpi_phys_copy with vm");
60 static int acpi_read_sdt_at(phys_bytes addr
,
61 struct acpi_sdt_header
* tb
,
65 struct acpi_sdt_header hdr
;
67 /* if NULL is supplied, we only return the size of the table */
69 if (read_func(addr
, &hdr
, sizeof(struct acpi_sdt_header
))) {
70 printf("ERROR acpi cannot read %s header\n", name
);
77 if (read_func(addr
, tb
, sizeof(struct acpi_sdt_header
))) {
78 printf("ERROR acpi cannot read %s header\n", name
);
82 if (acpi_check_signature(tb
->signature
, name
)) {
83 printf("ERROR acpi %s signature does not match\n", name
);
87 if (size
< tb
->length
) {
88 printf("ERROR acpi buffer too small for %s\n", name
);
92 if (read_func(addr
, tb
, size
)) {
93 printf("ERROR acpi cannot read %s\n", name
);
97 if (acpi_check_csum(tb
, tb
->length
)) {
98 printf("ERROR acpi %s checksum does not match\n", name
);
105 phys_bytes
acpi_get_table_base(const char * name
)
109 for(i
= 0; i
< sdt_count
; i
++) {
110 if (strncmp(name
, sdt_trans
[i
].signature
,
111 ACPI_SDT_SIGNATURE_LEN
) == 0)
112 return (phys_bytes
) rsdt
.data
[i
];
115 return (phys_bytes
) NULL
;
118 size_t acpi_get_table_length(const char * name
)
122 for(i
= 0; i
< sdt_count
; i
++) {
123 if (strncmp(name
, sdt_trans
[i
].signature
,
124 ACPI_SDT_SIGNATURE_LEN
) == 0)
125 return sdt_trans
[i
].length
;
131 static void * acpi_madt_get_typed_item(struct acpi_madt_hdr
* hdr
,
138 t
= (u8_t
*) hdr
+ sizeof(struct acpi_madt_hdr
);
139 end
= (u8_t
*) hdr
+ hdr
->hdr
.length
;
143 if (type
== ((struct acpi_madt_item_hdr
*) t
)->type
) {
149 t
+= ((struct acpi_madt_item_hdr
*) t
)->length
;
156 static void * acpi_madt_get_item(struct acpi_madt_hdr
* hdr
,
162 t
= (u8_t
*) hdr
+ sizeof(struct acpi_madt_hdr
);
163 end
= (u8_t
*) hdr
+ hdr
->hdr
.length
;
165 for(i
= 0 ; i
<= idx
&& t
< end
; i
++) {
168 t
+= ((struct acpi_madt_item_hdr
*) t
)->length
;
175 static int acpi_rsdp_test(void * buff
)
177 struct acpi_rsdp
* rsdp
= (struct acpi_rsdp
*) buff
;
179 if (!platform_tbl_checksum_ok(buff
, 20))
181 if (strncmp(rsdp
->signature
, "RSD PTR ", 8))
187 static int get_acpi_rsdp(void)
191 * Read 40:0Eh - to find the starting address of the EBDA.
193 acpi_phys_copy (0x40E, &ebda
, sizeof(ebda
));
196 if(platform_tbl_ptr(ebda
, ebda
+ 0x400, 16, &acpi_rsdp
,
197 sizeof(acpi_rsdp
), &machine
.acpi_rsdp
,
202 /* try BIOS read only mem space */
203 if(platform_tbl_ptr(0xE0000, 0x100000, 16, &acpi_rsdp
,
204 sizeof(acpi_rsdp
), &machine
.acpi_rsdp
,
208 machine
.acpi_rsdp
= 0; /* RSDP cannot be found at this address therefore
209 it is a valid negative value */
216 read_func
= acpi_phys_copy
;
218 if (!get_acpi_rsdp()) {
219 printf("WARNING : Cannot configure ACPI\n");
223 s
= acpi_read_sdt_at(acpi_rsdp
.rsdt_addr
, (struct acpi_sdt_header
*) &rsdt
,
224 sizeof(struct acpi_rsdt
), ACPI_SDT_SIGNATURE(RSDT
));
226 sdt_count
= (s
- sizeof(struct acpi_sdt_header
)) / sizeof(u32_t
);
228 for (i
= 0; i
< sdt_count
; i
++) {
229 struct acpi_sdt_header hdr
;
231 if (read_func(rsdt
.data
[i
], &hdr
, sizeof(struct acpi_sdt_header
))) {
232 printf("ERROR acpi cannot read header at 0x%x\n",
237 for (j
= 0 ; j
< ACPI_SDT_SIGNATURE_LEN
; j
++)
238 sdt_trans
[i
].signature
[j
] = hdr
.signature
[j
];
239 sdt_trans
[i
].signature
[ACPI_SDT_SIGNATURE_LEN
] = '\0';
240 sdt_trans
[i
].length
= hdr
.length
;
244 struct acpi_madt_ioapic
* acpi_get_ioapic_next(void)
246 static unsigned idx
= 0;
247 static struct acpi_madt_hdr
* madt_hdr
;
249 struct acpi_madt_ioapic
* ret
;
252 madt_hdr
= (struct acpi_madt_hdr
*)
253 acpi_phys2vir(acpi_get_table_base("APIC"));
254 if (madt_hdr
== NULL
)
258 ret
= (struct acpi_madt_ioapic
*)
259 acpi_madt_get_typed_item(madt_hdr
, ACPI_MADT_TYPE_IOAPIC
, idx
);
266 struct acpi_madt_lapic
* acpi_get_lapic_next(void)
268 static unsigned idx
= 0;
269 static struct acpi_madt_hdr
* madt_hdr
;
271 struct acpi_madt_lapic
* ret
;
274 madt_hdr
= (struct acpi_madt_hdr
*)
275 acpi_phys2vir(acpi_get_table_base("APIC"));
276 if (madt_hdr
== NULL
)
281 ret
= (struct acpi_madt_lapic
*)
282 acpi_madt_get_typed_item(madt_hdr
,
283 ACPI_MADT_TYPE_LAPIC
, idx
);
289 /* report only usable CPUs */