diff options
Diffstat (limited to 'usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c')
-rw-r--r-- | usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c b/usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c index fb8824855a..2e048223ea 100644 --- a/usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c +++ b/usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c @@ -89,6 +89,121 @@ interrupt_dump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) return (DCMD_OK); } +/* Macros for reading/writing the IOAPIC RDT entries */ +#define READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix, ipin) \ + ioapic_read(ioapic_ix, APIC_RDT_CMD + (2 * (ipin))) + +#define READ_IOAPIC_RDT_ENTRY_HIGH_DWORD(ioapic_ix, ipin) \ + ioapic_read(ioapic_ix, APIC_RDT_CMD2 + (2 * (ipin))) + +static uint32_t *ioapic_adr[MAX_IO_APIC]; + +uint32_t +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]); +} + +/* + * ioapic dcmd - Print out the ioapic registers, nicely formatted. + */ +/*ARGSUSED*/ +static 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) { + /* + * If the mdb_warn string does not end in a \n, mdb will + * automatically append the reason for the failure. + */ + mdb_warn("failed to read ioapicadr"); + return (DCMD_ERR); + } + + if (mdb_readvar(&apic_io_max, "apic_io_max") == -1) { + /* + * If the mdb_warn string does not end in a \n, mdb will + * automatically append the reason for the failure. + */ + 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++) { + /* Bits 23-16 define the maximum redirection entries */ + reg_max = 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 = READ_IOAPIC_RDT_ENTRY_HIGH_DWORD(i, reg); + low = READ_IOAPIC_RDT_ENTRY_LOW_DWORD(i, reg); + + mdb_printf("%2d %8x %8x\n", reg, high, low); + } + + mdb_printf("\n"); + + } + + return (DCMD_OK); +} + + +/* + * apic dcmd - Print out the apic registers, nicely formatted. + */ +/*ARGSUSED*/ +static 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) { + /* + * If the mdb_warn string does not end in a \n, mdb will + * automatically append the reason for the failure. + */ + 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); +} + /* * MDB module linkage information: @@ -101,6 +216,8 @@ static const mdb_dcmd_t dcmds[] = { interrupt_help}, { "softint", "?[-d]", "print soft interrupts", soft_interrupt_dump, soft_interrupt_help}, + { "apic", NULL, "print apic register contents", apic }, + { "ioapic", NULL, "print ioapic register contents", ioapic }, { NULL } }; |