l4ka-pistachio/kernel/kdb/generic/acpi.cc

253 lines
7.1 KiB
C++

/*********************************************************************
*
* Copyright (C) 2002, 2003, Karlsruhe University
*
* File path: kdb/generic/acpi.cc
* Description: Kernel deubgger ACPI acccess
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: acpi.cc,v 1.4 2003/09/24 19:05:11 skoglund Exp $
*
********************************************************************/
#include <debug.h>
#include <kdb/kdb.h>
#include <kdb/cmd.h>
#include <kdb/input.h>
#include <acpi.h>
#include INC_GLUE(hwspace.h)
/**
* Root System Descriptor Pointer.
*/
static acpi_rsdp_t * rsdp = NULL;
/**
* Root System Description Table.
*/
static acpi_rsdt_t * rsdt = NULL;
/**
* Extended System Description Table.
*/
static acpi_xsdt_t * xsdt = NULL;
void SECTION (SEC_KDEBUG) dump_apic (acpi_madt_t * madt);
static void SECTION (SEC_KDEBUG)
dump_acpi_header (acpi_thead_t & h, char * prefix = "")
{
printf ("%sOEM: [\"%.6s\", tid: \"%.8s\", rev: %d]\n"
"%sVendor: [id: 0x%x, rev: 0x%x]\n",
prefix, phys_to_virt (&h.oem_id), phys_to_virt (&h.oem_tid),
h.oem_rev,
prefix, h.creator_id, h.creator_rev);
}
/*
* Command group for ACPI commands.
*/
DECLARE_CMD_GROUP (acpi);
DECLARE_CMD (cmd_acpi, arch, 'a', "acpi", "ACPI access");
CMD (cmd_acpi, cg)
{
if (rsdp == NULL)
{
rsdp = acpi_rsdp_t::locate ();
if (rsdp == NULL)
{
printf ("Could not locate ACPI info.\n");
return CMD_NOQUIT;
}
rsdt = rsdp->rsdt ();
xsdt = rsdp->xsdt ();
}
return acpi.interact (cg, "acpi");
}
DECLARE_CMD (cmd_acpi_dump, acpi, 'd', "dump",
"dump system description table");
CMD (cmd_acpi_dump, cg)
{
printf ("ACPI rev: %d, OEM: \"%.6s\"\n", rsdp->rev, rsdp->oemid);
if (rsdt)
{
printf ("RSDT @ %p\n", rsdt);
dump_acpi_header (rsdt->header, " ");
printf ("\n");
word_t num_entries = (xsdt->header.len - sizeof (acpi_thead_t)) /
sizeof (xsdt->ptrs[0]);
for (word_t i = 0; i < num_entries; i++)
{
acpi_thead_t * t = (acpi_thead_t *) ((word_t) xsdt->ptrs[i]);
printf (" %.4s @ %p\n", t->sig, t);
dump_acpi_header (*t, " ");
if (t->sig[0] == 'A' && t->sig[1] == 'P' &&
t->sig[2] == 'I' && t->sig[3] == 'C')
dump_apic ((acpi_madt_t *) t);
}
}
if (xsdt)
{
printf ("XSDT @ %p\n", xsdt);
dump_acpi_header (xsdt->header, " ");
printf ("\n");
word_t num_entries = (xsdt->header.len - sizeof (acpi_thead_t)) /
sizeof (xsdt->ptrs[0]);
for (word_t i = 0; i < num_entries; i++)
{
acpi_thead_t * t = (acpi_thead_t *) ((word_t) xsdt->ptrs[i]);
printf (" %.4s @ %p\n", t->sig, t);
dump_acpi_header (*t, " ");
if (t->sig[0] == 'A' && t->sig[1] == 'P' &&
t->sig[2] == 'I' && t->sig[3] == 'C')
dump_apic ((acpi_madt_t *) t);
}
}
return CMD_NOQUIT;
}
void dump_apic (acpi_madt_t * madt)
{
printf (" Local APIC @ %p\n", madt->local_apic_addr);
for (word_t i = 0; i < (madt->header.len - sizeof (acpi_madt_t));)
{
acpi_madt_hdr_t * h = (acpi_madt_hdr_t *) &madt->data[i];
switch (h->type)
{
case 0:
{
// Local APIC
acpi_madt_lapic_t * lapic = (acpi_madt_lapic_t *) h;
printf (" Local APIC ");
printf ("[Id: 0x%x, CPU Id: 0x%x, %s]\n",
lapic->id, lapic->apic_processor_id,
lapic->flags.enabled ? "enabled" : "disabled");
break;
}
case 1:
{
// I/O Apic
acpi_madt_ioapic_t * ioapic = (acpi_madt_ioapic_t *) h;
printf (" I/O APIC ");
printf ("[Id: 0x%x, IRQ base: %d, Addr: %p]\n",
ioapic->id, ioapic->irq_base, ioapic->address);
break;
}
case 2:
{
// Interrupt Source Override
acpi_madt_irq_t * irq = (acpi_madt_irq_t *) h;
acpi_madt_irq_t::polarity_t p = irq->get_polarity ();
acpi_madt_irq_t::trigger_mode_t t = irq->get_trigger_mode ();
printf (" Interrupt Override ");
printf ("[%s, Bus IRQ: %d, Glob IRQ: %d, Pol: %s, Trigger: %s]\n",
irq->src_bus == 0 ? "ISA" : "unknown bus",
irq->src_irq, irq->dest,
p == acpi_madt_irq_t::conform_polarity ? "conform" :
p == acpi_madt_irq_t::active_high ? "active high" :
p == acpi_madt_irq_t::active_low ? "active low" : "?",
t == acpi_madt_irq_t::conform_trigger ? "conform" :
t == acpi_madt_irq_t::edge ? "edge" :
t == acpi_madt_irq_t::level ? "level" : "?");
break;
}
case 3:
{
// NMI Source
acpi_madt_nmi_t * nmi = (acpi_madt_nmi_t *) h;
acpi_madt_nmi_t::polarity_t p = nmi->get_polarity ();
acpi_madt_nmi_t::trigger_mode_t t = nmi->get_trigger_mode ();
printf (" NMI Source ");
printf ("[Glob IRQ: %d, Pol: %s, Trigger: %s]\n",
nmi->irq,
p == acpi_madt_nmi_t::conform_polarity ? "conform" :
p == acpi_madt_nmi_t::active_high ? "active high" :
p == acpi_madt_nmi_t::active_low ? "active low" : "?",
t == acpi_madt_nmi_t::conform_trigger ? "conform" :
t == acpi_madt_nmi_t::edge ? "edge" :
t == acpi_madt_nmi_t::level ? "level" : "?");
break;
}
case 4:
{
// Local APIC NMI
printf (" Local APIC NMI\n");
break;
}
case 5:
{
// Local APIC Address Override
printf (" Local APIC Address Override\n");
break;
}
case 6:
{
// I/O SAPIC
acpi_madt_iosapic_t * iosapic = (acpi_madt_iosapic_t *) h;
printf (" I/O SAPIC ");
printf ("[Id: 0x%x, IRQ base: %d, Addr: %p]\n", iosapic->id,
iosapic->irq_base, iosapic->address);
break;
}
case 7:
{
// Local SAPIC
acpi_madt_lsapic_t * lsapic = (acpi_madt_lsapic_t *) h;
printf (" Local SAPIC ");
printf ("[Id: 0x%x:0x%x, CPU Id: 0x%x, %s]\n",
lsapic->id, lsapic->eid, lsapic->apic_processor_id,
lsapic->flags.enabled ? "enabled" : "disabled");
break;
}
case 8:
{
// Platform Interrupt Source
printf (" Platform Interrupt Source\n");
break;
}
}
i += h->len;
}
}