Add support for ACPI 2.x and the XSDT.
Submitted by: marcel
This commit is contained in:
parent
8e6a8737d7
commit
a74172ab68
@ -27,8 +27,8 @@
|
|||||||
* $FreeBSD$
|
* $FreeBSD$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/endian.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -60,11 +60,15 @@ static void acpi_print_sdt(struct ACPIsdt *sdp, int endcomment);
|
|||||||
static void acpi_print_fadt(struct FADTbody *fadt);
|
static void acpi_print_fadt(struct FADTbody *fadt);
|
||||||
static void acpi_print_facs(struct FACSbody *facs);
|
static void acpi_print_facs(struct FACSbody *facs);
|
||||||
static void acpi_print_dsdt(struct ACPIsdt *dsdp);
|
static void acpi_print_dsdt(struct ACPIsdt *dsdp);
|
||||||
static struct ACPIsdt *
|
static struct ACPIsdt *acpi_map_sdt(vm_offset_t pa);
|
||||||
acpi_map_sdt(vm_offset_t pa);
|
|
||||||
static void acpi_print_rsd_ptr(struct ACPIrsdp *rp);
|
static void acpi_print_rsd_ptr(struct ACPIrsdp *rp);
|
||||||
static void acpi_handle_rsdt(struct ACPIsdt *rsdp);
|
static void acpi_handle_rsdt(struct ACPIsdt *rsdp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up.
|
||||||
|
*/
|
||||||
|
static int addr_size;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
acpi_print_string(char *s, size_t length)
|
acpi_print_string(char *s, size_t length)
|
||||||
{
|
{
|
||||||
@ -341,14 +345,26 @@ static void
|
|||||||
acpi_print_rsdt(struct ACPIsdt *rsdp)
|
acpi_print_rsdt(struct ACPIsdt *rsdp)
|
||||||
{
|
{
|
||||||
int i, entries;
|
int i, entries;
|
||||||
|
u_long addr;
|
||||||
|
|
||||||
acpi_print_sdt(rsdp, /*endcomment*/0);
|
acpi_print_sdt(rsdp, /*endcomment*/0);
|
||||||
entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t);
|
entries = (rsdp->len - SIZEOF_SDT_HDR) / addr_size;
|
||||||
printf("\tEntries={ ");
|
printf("\tEntries={ ");
|
||||||
for (i = 0; i < entries; i++) {
|
for (i = 0; i < entries; i++) {
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
printf(", ");
|
printf(", ");
|
||||||
printf("0x%08x", rsdp->body[i]);
|
switch (addr_size) {
|
||||||
|
case 4:
|
||||||
|
addr = le32dec((char*)rsdp->body + i * addr_size);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
addr = le64dec((char*)rsdp->body + i * addr_size);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
addr = 0;
|
||||||
|
}
|
||||||
|
assert(addr != 0);
|
||||||
|
printf("0x%08lx", addr);
|
||||||
}
|
}
|
||||||
printf(" }\n");
|
printf(" }\n");
|
||||||
printf(END_COMMENT);
|
printf(END_COMMENT);
|
||||||
@ -528,25 +544,42 @@ acpi_map_sdt(vm_offset_t pa)
|
|||||||
static void
|
static void
|
||||||
acpi_print_rsd_ptr(struct ACPIrsdp *rp)
|
acpi_print_rsd_ptr(struct ACPIrsdp *rp)
|
||||||
{
|
{
|
||||||
|
|
||||||
printf(BEGIN_COMMENT);
|
printf(BEGIN_COMMENT);
|
||||||
printf(" RSD PTR: Checksum=%d, OEMID=", rp->sum);
|
printf(" RSD PTR: OEM=");
|
||||||
acpi_print_string(rp->oem, 6);
|
acpi_print_string(rp->oem, 6);
|
||||||
printf(", RsdtAddress=0x%08x\n", rp->rsdt_addr);
|
printf(", ACPI_Rev=%s (%d)\n", rp->revision < 2 ? "1.x" : "2.x",
|
||||||
|
rp->revision);
|
||||||
|
if (rp->revision < 2) {
|
||||||
|
printf("\tRSDT=0x%08x, cksum=%u\n", rp->rsdt_addr, rp->sum);
|
||||||
|
} else {
|
||||||
|
printf("\tXSDT=0x%08lx, length=%u, cksum=%u\n",
|
||||||
|
(u_long)rp->xsdt_addr, rp->length, rp->xsum);
|
||||||
|
}
|
||||||
printf(END_COMMENT);
|
printf(END_COMMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
acpi_handle_rsdt(struct ACPIsdt *rsdp)
|
acpi_handle_rsdt(struct ACPIsdt *rsdp)
|
||||||
{
|
{
|
||||||
int i;
|
struct ACPIsdt *sdp;
|
||||||
int entries;
|
vm_offset_t addr;
|
||||||
struct ACPIsdt *sdp;
|
int entries, i;
|
||||||
|
|
||||||
entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t);
|
|
||||||
acpi_print_rsdt(rsdp);
|
acpi_print_rsdt(rsdp);
|
||||||
|
entries = (rsdp->len - SIZEOF_SDT_HDR) / addr_size;
|
||||||
for (i = 0; i < entries; i++) {
|
for (i = 0; i < entries; i++) {
|
||||||
sdp = (struct ACPIsdt *)acpi_map_sdt(rsdp->body[i]);
|
switch (addr_size) {
|
||||||
|
case 4:
|
||||||
|
addr = le32dec((char*)rsdp->body + i * addr_size);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
addr = le64dec((char*)rsdp->body + i * addr_size);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert((addr = 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
sdp = (struct ACPIsdt *)acpi_map_sdt(addr);
|
||||||
if (acpi_checksum(sdp, sdp->len))
|
if (acpi_checksum(sdp, sdp->len))
|
||||||
errx(1, "RSDT entry %d is corrupt", i);
|
errx(1, "RSDT entry %d is corrupt", i);
|
||||||
if (!memcmp(sdp->signature, "FACP", 4))
|
if (!memcmp(sdp->signature, "FACP", 4))
|
||||||
@ -572,11 +605,19 @@ sdt_load_devmem()
|
|||||||
|
|
||||||
if (tflag)
|
if (tflag)
|
||||||
acpi_print_rsd_ptr(rp);
|
acpi_print_rsd_ptr(rp);
|
||||||
rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->rsdt_addr);
|
if (rp->revision < 2) {
|
||||||
if (memcmp(rsdp->signature, "RSDT", 4) != 0 ||
|
rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->rsdt_addr);
|
||||||
acpi_checksum(rsdp, rsdp->len) != 0)
|
if (memcmp(rsdp->signature, "RSDT", 4) != 0 ||
|
||||||
errx(1, "RSDT is corrupted");
|
acpi_checksum(rsdp, rsdp->len) != 0)
|
||||||
|
errx(1, "RSDT is corrupted");
|
||||||
|
addr_size = sizeof(uint32_t);
|
||||||
|
} else {
|
||||||
|
rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->xsdt_addr);
|
||||||
|
if (memcmp(rsdp->signature, "XSDT", 4) != 0 ||
|
||||||
|
acpi_checksum(rsdp, rsdp->len) != 0)
|
||||||
|
errx(1, "XSDT is corrupted");
|
||||||
|
addr_size = sizeof(uint64_t);
|
||||||
|
}
|
||||||
return (rsdp);
|
return (rsdp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -651,17 +692,28 @@ sdt_print_all(struct ACPIsdt *rsdp)
|
|||||||
struct ACPIsdt *
|
struct ACPIsdt *
|
||||||
sdt_from_rsdt(struct ACPIsdt *rsdt, const char *sig)
|
sdt_from_rsdt(struct ACPIsdt *rsdt, const char *sig)
|
||||||
{
|
{
|
||||||
int i;
|
struct ACPIsdt *sdt;
|
||||||
int entries;
|
vm_offset_t addr;
|
||||||
struct ACPIsdt *sdt;
|
int entries, i;
|
||||||
|
|
||||||
entries = (rsdt->len - SIZEOF_SDT_HDR) / sizeof(uint32_t);
|
entries = (rsdt->len - SIZEOF_SDT_HDR) / addr_size;
|
||||||
for (i = 0; i < entries; i++) {
|
for (i = 0; i < entries; i++) {
|
||||||
sdt = (struct ACPIsdt *)acpi_map_sdt(rsdt->body[i]);
|
switch (addr_size) {
|
||||||
|
case 4:
|
||||||
|
addr = le32dec((char*)rsdt->body + i * addr_size);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
addr = le64dec((char*)rsdt->body + i * addr_size);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert((addr = 0));
|
||||||
|
}
|
||||||
|
sdt = (struct ACPIsdt *)acpi_map_sdt(addr);
|
||||||
|
if (memcmp(sdt->signature, sig, strlen(sig)))
|
||||||
|
continue;
|
||||||
if (acpi_checksum(sdt, sdt->len))
|
if (acpi_checksum(sdt, sdt->len))
|
||||||
errx(1, "RSDT entry %d is corrupt", i);
|
errx(1, "RSDT entry %d is corrupt", i);
|
||||||
if (!memcmp(sdt->signature, sig, strlen(sig)))
|
return (sdt);
|
||||||
return (sdt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
Loading…
Reference in New Issue
Block a user