2 * Copyright (c) 2001 Michael Smith <msmith@freebsd.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 #include <sys/cdefs.h>
30 #include <machine/stdarg.h>
31 #include <bootstrap.h>
35 #include "platform/acfreebsd.h"
37 #define ACPI_SYSTEM_XFACE
42 * Detect ACPI and export information about the ACPI BIOS into the
46 static ACPI_TABLE_RSDP
*biosacpi_find_rsdp(void);
47 static ACPI_TABLE_RSDP
*biosacpi_search_rsdp(char *base
, int length
);
49 #define RSDP_CHECKSUM_LENGTH 20
54 ACPI_TABLE_RSDP
*rsdp
;
58 /* locate and validate the RSDP */
59 if ((rsdp
= biosacpi_find_rsdp()) == NULL
)
62 /* export values from the RSDP */
63 sprintf(buf
, "0x%08x", (unsigned int)VTOP(rsdp
));
64 setenv("acpi.rsdp", buf
, 1);
65 revision
= rsdp
->Revision
;
68 sprintf(buf
, "%d", revision
);
69 setenv("acpi.revision", buf
, 1);
70 strncpy(buf
, rsdp
->OemId
, sizeof(rsdp
->OemId
));
71 buf
[sizeof(rsdp
->OemId
)] = '\0';
72 setenv("acpi.oem", buf
, 1);
73 sprintf(buf
, "0x%08x", rsdp
->RsdtPhysicalAddress
);
74 setenv("acpi.rsdt", buf
, 1);
76 /* XXX extended checksum? */
77 sprintf(buf
, "0x%016llx",
78 (unsigned long long)rsdp
->XsdtPhysicalAddress
);
79 setenv("acpi.xsdt", buf
, 1);
80 sprintf(buf
, "%d", rsdp
->Length
);
81 setenv("acpi.xsdt_length", buf
, 1);
86 * Find the RSDP in low memory. See section 5.2.2 of the ACPI spec.
88 static ACPI_TABLE_RSDP
*
89 biosacpi_find_rsdp(void)
91 ACPI_TABLE_RSDP
*rsdp
;
94 /* EBDA is the 1 KB addressed by the 16 bit pointer at 0x40E. */
95 addr
= (uint16_t *)PTOV(0x40E);
96 rsdp
= biosacpi_search_rsdp((char *)(intptr_t)(*addr
<< 4), 0x400);
100 /* Check the upper memory BIOS space, 0xe0000 - 0xfffff. */
101 if ((rsdp
= biosacpi_search_rsdp((char *)0xe0000, 0x20000)) != NULL
)
107 static ACPI_TABLE_RSDP
*
108 biosacpi_search_rsdp(char *base
, int length
)
110 ACPI_TABLE_RSDP
*rsdp
;
114 /* search on 16-byte boundaries */
115 for (ofs
= 0; ofs
< length
; ofs
+= 16) {
116 rsdp
= (ACPI_TABLE_RSDP
*)PTOV(base
+ ofs
);
118 /* compare signature, validate checksum */
119 if (!strncmp(rsdp
->Signature
, ACPI_SIG_RSDP
, strlen(ACPI_SIG_RSDP
))) {
120 cp
= (u_int8_t
*)rsdp
;
122 for (idx
= 0; idx
< RSDP_CHECKSUM_LENGTH
; idx
++)