summaryrefslogtreecommitdiff
path: root/usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c')
-rw-r--r--usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c117
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 }
};