1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 #include "intr_common.h" 26 27 #ifdef _KMDB 28 29 /* Macros for reading/writing the IOAPIC RDT entries */ 30 #define APIC_READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix, ipin) \ 31 apic_ioapic_read(ioapic_ix, APIC_RDT_CMD + (2 * (ipin))) 32 33 #define APIC_READ_IOAPIC_RDT_ENTRY_HIGH_DWORD(ioapic_ix, ipin) \ 34 apic_ioapic_read(ioapic_ix, APIC_RDT_CMD2 + (2 * (ipin))) 35 36 static uint32_t *ioapic_adr[MAX_IO_APIC]; 37 38 static uint32_t 39 apic_ioapic_read(int ioapic_ix, uint32_t reg) 40 { 41 volatile uint32_t *ioapic; 42 43 ioapic = ioapic_adr[ioapic_ix]; 44 ioapic[APIC_IO_REG] = reg; 45 return (ioapic[APIC_IO_DATA]); 46 } 47 48 /* 49 * ioapic dcmd - Print out the ioapic registers, nicely formatted. 50 */ 51 /*ARGSUSED*/ 52 int 53 ioapic(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 54 { 55 uint32_t apic_io_max; 56 int reg; 57 int reg_max; 58 int i; 59 60 61 if ((flags & DCMD_ADDRSPEC) || argc != 0) 62 return (DCMD_USAGE); 63 64 if (mdb_readvar(&ioapic_adr, "apicioadr") == -1) { 65 /* 66 * If the mdb_warn string does not end in a \n, mdb will 67 * automatically append the reason for the failure. 68 */ 69 mdb_warn("failed to read ioapicadr"); 70 return (DCMD_ERR); 71 } 72 73 if (mdb_readvar(&apic_io_max, "apic_io_max") == -1) { 74 /* 75 * If the mdb_warn string does not end in a \n, mdb will 76 * automatically append the reason for the failure. 77 */ 78 mdb_warn("failed to read apic_io_max"); 79 return (DCMD_ERR); 80 } 81 82 mdb_printf("ioapicadr\t%p\n", ioapic_adr); 83 84 for (i = 0; i < apic_io_max; i++) { 85 /* Bits 23-16 define the maximum redirection entries */ 86 reg_max = apic_ioapic_read(i, APIC_VERS_CMD); 87 reg_max = (reg_max >> 16) & 0xff; 88 89 mdb_printf("%4s %8s %8s\n", "reg", "high", " low"); 90 for (reg = 0; reg <= reg_max; reg++) { 91 uint32_t high, low; 92 93 high = APIC_READ_IOAPIC_RDT_ENTRY_HIGH_DWORD(i, reg); 94 low = APIC_READ_IOAPIC_RDT_ENTRY_LOW_DWORD(i, reg); 95 96 mdb_printf("%2d %8x %8x\n", reg, high, low); 97 } 98 99 mdb_printf("\n"); 100 101 } 102 103 return (DCMD_OK); 104 } 105 106 107 /* 108 * apic dcmd - Print out the apic registers, nicely formatted. 109 */ 110 /*ARGSUSED*/ 111 int 112 apic(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 113 { 114 uint32_t *papic; 115 116 if ((flags & DCMD_ADDRSPEC) || argc != 0) 117 return (DCMD_USAGE); 118 119 if (mdb_readvar(&papic, "apicadr") == -1) { 120 /* 121 * If the mdb_warn string does not end in a \n, mdb will 122 * automatically append the reason for the failure. 123 */ 124 mdb_warn("failed to read apicadr"); 125 return (DCMD_ERR); 126 } 127 128 mdb_printf("apicadr\t%p\n", papic); 129 mdb_printf("as_task_reg\t%x\n", papic[APIC_TASK_REG]); 130 mdb_printf("as_dest_reg\t%x\n", papic[APIC_DEST_REG]); 131 mdb_printf("as_format_reg\t%x\n", papic[APIC_FORMAT_REG]); 132 mdb_printf("as_local_timer\t%x\n", papic[APIC_LOCAL_TIMER]); 133 mdb_printf("as_pcint_vect\t%x\n", papic[APIC_PCINT_VECT]); 134 mdb_printf("as_int_vect0\t%x\n", papic[APIC_INT_VECT0]); 135 mdb_printf("as_int_vect1\t%x\n", papic[APIC_INT_VECT1]); 136 mdb_printf("as_err_vect\t%x\n", papic[APIC_ERR_VECT]); 137 mdb_printf("as_init_count\t%x\n", papic[APIC_INIT_COUNT]); 138 mdb_printf("as_divide_reg\t%x\n", papic[APIC_DIVIDE_REG]); 139 mdb_printf("as_spur_int_reg\t%x\n", papic[APIC_SPUR_INT_REG]); 140 141 return (DCMD_OK); 142 } 143 144 #endif /* _KMDB */ 145