#include "intr_common.h"
#ifdef _KMDB
#define APIC_READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix, ipin) \
apic_ioapic_read(ioapic_ix, APIC_RDT_CMD + (2 * (ipin)))
#define APIC_READ_IOAPIC_RDT_ENTRY_HIGH_DWORD(ioapic_ix, ipin) \
apic_ioapic_read(ioapic_ix, APIC_RDT_CMD2 + (2 * (ipin)))
static uint32_t *ioapic_adr[MAX_IO_APIC];
static uint32_t
apic_ioapic_read(int ioapic_ix, uint32_t reg)
{
volatile uint32_t *ioapic;
ioapic = ioapic_adr[ioapic_ix];
ioapic[APIC_IO_REG] = reg;
return (ioapic[APIC_IO_DATA]);
}
int
ioapic(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
uint32_t apic_io_max;
int reg;
int reg_max;
int i;
if ((flags & DCMD_ADDRSPEC) || argc != 0)
return (DCMD_USAGE);
if (mdb_readvar(&ioapic_adr, "apicioadr") == -1) {
mdb_warn("failed to read ioapicadr");
return (DCMD_ERR);
}
if (mdb_readvar(&apic_io_max, "apic_io_max") == -1) {
mdb_warn("failed to read apic_io_max");
return (DCMD_ERR);
}
mdb_printf("ioapicadr\t%p\n", ioapic_adr);
for (i = 0; i < apic_io_max; i++) {
reg_max = apic_ioapic_read(i, APIC_VERS_CMD);
reg_max = (reg_max >> 16) & 0xff;
mdb_printf("%4s %8s %8s\n", "reg", "high", " low");
for (reg = 0; reg <= reg_max; reg++) {
uint32_t high, low;
high = APIC_READ_IOAPIC_RDT_ENTRY_HIGH_DWORD(i, reg);
low = APIC_READ_IOAPIC_RDT_ENTRY_LOW_DWORD(i, reg);
mdb_printf("%2d %8x %8x\n", reg, high, low);
}
mdb_printf("\n");
}
return (DCMD_OK);
}
int
apic(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
uint32_t *papic;
if ((flags & DCMD_ADDRSPEC) || argc != 0)
return (DCMD_USAGE);
if (mdb_readvar(&papic, "apicadr") == -1) {
mdb_warn("failed to read apicadr");
return (DCMD_ERR);
}
mdb_printf("apicadr\t%p\n", papic);
mdb_printf("as_task_reg\t%x\n", papic[APIC_TASK_REG]);
mdb_printf("as_dest_reg\t%x\n", papic[APIC_DEST_REG]);
mdb_printf("as_format_reg\t%x\n", papic[APIC_FORMAT_REG]);
mdb_printf("as_local_timer\t%x\n", papic[APIC_LOCAL_TIMER]);
mdb_printf("as_pcint_vect\t%x\n", papic[APIC_PCINT_VECT]);
mdb_printf("as_int_vect0\t%x\n", papic[APIC_INT_VECT0]);
mdb_printf("as_int_vect1\t%x\n", papic[APIC_INT_VECT1]);
mdb_printf("as_err_vect\t%x\n", papic[APIC_ERR_VECT]);
mdb_printf("as_init_count\t%x\n", papic[APIC_INIT_COUNT]);
mdb_printf("as_divide_reg\t%x\n", papic[APIC_DIVIDE_REG]);
mdb_printf("as_spur_int_reg\t%x\n", papic[APIC_SPUR_INT_REG]);
return (DCMD_OK);
}
#endif