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
26 * $FreeBSD: src/sys/boot/i386/libi386/biosacpi.c,v 1.7 2003/08/25 23:28:31 obrien Exp $
27 * $DragonFly: src/sys/boot/pc32/libi386/biosacpi.c,v 1.5 2007/01/17 17:31:19 y0netan1 Exp $
31 #include <machine/stdarg.h>
32 #include <bootstrap.h>
34 #include "acdragonfly.h"
36 #define ACPI_SYSTEM_XFACE
41 * Detect ACPI and export information about the APCI BIOS into the
45 static ACPI_TABLE_RSDP
*biosacpi_find_rsdp(void);
46 static ACPI_TABLE_RSDP
*biosacpi_search_rsdp(char *base
, int length
);
48 #define RSDP_CHECKSUM_LENGTH 20
53 ACPI_TABLE_RSDP
*rsdp
;
57 /* XXX check the BIOS datestamp */
59 /* locate and validate the RSDP */
60 if ((rsdp
= biosacpi_find_rsdp()) == NULL
)
63 /* export values from the RSDP */
64 revision
= rsdp
->Revision
;
67 sprintf(buf
, "%d", revision
);
68 setenv("hint.acpi.0.revision", buf
, 1);
69 strncpy(buf
, rsdp
->OemId
, sizeof(rsdp
->OemId
));
70 buf
[sizeof(rsdp
->OemId
)] = '\0';
71 setenv("hint.acpi.0.oem", buf
, 1);
72 sprintf(buf
, "0x%08x", rsdp
->RsdtPhysicalAddress
);
73 setenv("hint.acpi.0.rsdt", buf
, 1);
75 /* XXX extended checksum? */
76 sprintf(buf
, "0x%016llx", rsdp
->XsdtPhysicalAddress
);
77 setenv("hint.acpi.0.xsdt", buf
, 1);
78 sprintf(buf
, "%d", rsdp
->Length
);
79 setenv("hint.acpi.0.xsdt_length", buf
, 1);
81 /* XXX other tables? */
83 setenv("acpi_load", "YES", 1);
87 * Find the RSDP in low memory. See section 5.2.2 of the ACPI spec.
89 static ACPI_TABLE_RSDP
*
90 biosacpi_find_rsdp(void)
92 ACPI_TABLE_RSDP
*rsdp
;
95 /* EBDA is the 1 KB addressed by the 16 bit pointer at 0x40E. */
96 addr
= (uint16_t *)0x40E;
97 if ((rsdp
= biosacpi_search_rsdp((char *)(*addr
<< 4), 0x400)) != NULL
)
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
*)(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
++)
125 printf("acpi: bad RSDP checksum (%d)\n", sum
);