1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2019 Joyent, Inc. 14 */ 15 16 /* 17 * ISA-independent utility functions for the x86 architecture 18 */ 19 20 #include <mdb/mdb_modapi.h> 21 #include <mdb/mdb_x86util.h> 22 23 #include <sys/controlregs.h> 24 #include <inttypes.h> 25 26 #define MMU_PAGESHIFT 12 27 #define MMU_PAGESIZE (1 << MMU_PAGESHIFT) 28 #define MMU_PAGEOFFSET (MMU_PAGESIZE - 1) 29 #define MMU_PAGEMASK (~MMU_PAGEOFFSET) 30 31 #ifndef _KMDB 32 static void 33 mdb_x86_print_desc(const char *name, const mdb_x86_desc_t *desc, uint_t width) 34 { 35 const char *type; 36 const mdb_bitmask_t *bits; 37 38 static const mdb_bitmask_t mem_desc_flag_bits[] = { 39 { "P", 0x80, 0x80 }, 40 { "16b", 0x6000, 0x0 }, 41 { "32b", 0x6000, 0x4000 }, 42 { "64b", 0x6000, 0x2000 }, 43 { "G", 0x8000, 0x8000 }, 44 { "A", 0x1, 0x1 }, 45 { NULL, 0, 0 }, 46 }; 47 48 static const char *mem_desc_types[] = { 49 "data, up, read-only", 50 "data, up, read-write", 51 "data, down, read-only", 52 "data, down, read-write", 53 "code, non-conforming, execute-only", 54 "code, non-conforming, execute-read", 55 "code, conforming, execute-only", 56 "code, conforming, execute-read" 57 }; 58 59 static const mdb_bitmask_t sys_desc_flag_bits[] = { 60 { "P", 0x80, 0x80 }, 61 { "16b", 0x6000, 0x0 }, 62 { "32b", 0x6000, 0x4000 }, 63 { "64b", 0x6000, 0x2000 }, 64 { "G", 0x8000, 0x8000 }, 65 { NULL, 0, 0 }, 66 }; 67 68 static const char *sys_desc_types[] = { 69 "reserved", 70 "16b TSS, available", 71 "LDT", 72 "16b TSS, busy", 73 "16b call gate", 74 "task gate", 75 "16b interrupt gate", 76 "16b trap gate", 77 "reserved", 78 "32b/64b TSS, available", 79 "reserved", 80 "32b/64b TSS, busy", 81 "32b/64b call gate", 82 "reserved", 83 "32b/64b interrupt gate" 84 "32b/64b trap gate", 85 }; 86 87 if (desc->d_acc & 0x10) { 88 type = mem_desc_types[(desc->d_acc >> 1) & 7]; 89 bits = mem_desc_flag_bits; 90 } else { 91 type = sys_desc_types[desc->d_acc & 0xf]; 92 bits = sys_desc_flag_bits; 93 } 94 95 mdb_printf("%%%s = 0x%0*lx/0x%0*x 0x%05x " 96 "<%susable, %s, dpl %d, flags: %b>\n", 97 name, width, desc->d_base, width / 2, desc->d_lim, desc->d_acc, 98 (desc->d_acc >> 16) & 1 ? "un" : "", type, 99 (desc->d_acc >> 5) & 3, desc->d_acc, bits); 100 } 101 #endif 102 103 void 104 mdb_x86_print_sysregs(struct sysregs *sregs, boolean_t long_mode) 105 { 106 const uint_t width = 107 2 * (long_mode ? sizeof (uint64_t) : sizeof (uint32_t)); 108 109 110 #ifndef _KMDB 111 static const mdb_bitmask_t efer_flag_bits[] = { 112 { "SCE", AMD_EFER_SCE, AMD_EFER_SCE }, 113 { "LME", AMD_EFER_LME, AMD_EFER_LME }, 114 { "LMA", AMD_EFER_LMA, AMD_EFER_LMA }, 115 { "NXE", AMD_EFER_NXE, AMD_EFER_NXE }, 116 { "SVME", AMD_EFER_SVME, AMD_EFER_SVME }, 117 { "LMSLE", AMD_EFER_LMSLE, AMD_EFER_LMSLE }, 118 { "FFXSR", AMD_EFER_FFXSR, AMD_EFER_FFXSR }, 119 { "TCE", AMD_EFER_TCE, AMD_EFER_TCE }, 120 { NULL, 0, 0 } 121 }; 122 #endif 123 124 static const mdb_bitmask_t cr0_flag_bits[] = { 125 { "PE", CR0_PE, CR0_PE }, 126 { "MP", CR0_MP, CR0_MP }, 127 { "EM", CR0_EM, CR0_EM }, 128 { "TS", CR0_TS, CR0_TS }, 129 { "ET", CR0_ET, CR0_ET }, 130 { "NE", CR0_NE, CR0_NE }, 131 { "WP", CR0_WP, CR0_WP }, 132 { "AM", CR0_AM, CR0_AM }, 133 { "NW", CR0_NW, CR0_NW }, 134 { "CD", CR0_CD, CR0_CD }, 135 { "PG", CR0_PG, CR0_PG }, 136 { NULL, 0, 0 } 137 }; 138 139 static const mdb_bitmask_t cr3_flag_bits[] = { 140 { "PCD", CR3_PCD, CR3_PCD }, 141 { "PWT", CR3_PWT, CR3_PWT }, 142 { NULL, 0, 0, } 143 }; 144 145 static const mdb_bitmask_t cr4_flag_bits[] = { 146 { "VME", CR4_VME, CR4_VME }, 147 { "PVI", CR4_PVI, CR4_PVI }, 148 { "TSD", CR4_TSD, CR4_TSD }, 149 { "DE", CR4_DE, CR4_DE }, 150 { "PSE", CR4_PSE, CR4_PSE }, 151 { "PAE", CR4_PAE, CR4_PAE }, 152 { "MCE", CR4_MCE, CR4_MCE }, 153 { "PGE", CR4_PGE, CR4_PGE }, 154 { "PCE", CR4_PCE, CR4_PCE }, 155 { "OSFXSR", CR4_OSFXSR, CR4_OSFXSR }, 156 { "OSXMMEXCPT", CR4_OSXMMEXCPT, CR4_OSXMMEXCPT }, 157 { "UMIP", CR4_UMIP, CR4_UMIP }, 158 { "VMXE", CR4_VMXE, CR4_VMXE }, 159 { "SMXE", CR4_SMXE, CR4_SMXE }, 160 { "FSGSBASE", CR4_FSGSBASE, CR4_FSGSBASE }, 161 { "PCIDE", CR4_PCIDE, CR4_PCIDE }, 162 { "OSXSAVE", CR4_OSXSAVE, CR4_OSXSAVE }, 163 { "SMEP", CR4_SMEP, CR4_SMEP }, 164 { "SMAP", CR4_SMAP, CR4_SMAP }, 165 { "PKE", CR4_PKE, CR4_PKE }, 166 { NULL, 0, 0 } 167 }; 168 169 #ifndef _KMDB 170 mdb_printf("%%efer = 0x%0lx <%b>\n", 171 sregs->sr_efer, sregs->sr_efer, efer_flag_bits); 172 #endif 173 mdb_printf("%%cr0 = 0x%0lx <%b>\n", 174 sregs->sr_cr0, sregs->sr_cr0, cr0_flag_bits); 175 mdb_printf("%%cr2 = 0x%0*x <%a>\n", width, 176 sregs->sr_cr2, sregs->sr_cr2); 177 mdb_printf("%%cr3 = 0x%0lx <pfn:0x%lx ", 178 sregs->sr_cr3, sregs->sr_cr3 >> MMU_PAGESHIFT); 179 if (sregs->sr_cr4 & CR4_PCIDE) 180 mdb_printf("pcid:%lu>\n", sregs->sr_cr3 & MMU_PAGEOFFSET); 181 else 182 mdb_printf("flags:%b>\n", sregs->sr_cr3, cr3_flag_bits); 183 mdb_printf("%%cr4 = 0x%0lx <%b>\n", 184 sregs->sr_cr4, sregs->sr_cr4, cr4_flag_bits); 185 186 #ifndef _KMDB 187 mdb_printf("\n"); 188 mdb_printf("%%pdpte0 = 0x%0?lx\t%%pdpte2 = 0x%0?lx\n", 189 sregs->sr_pdpte0, sregs->sr_pdpte2); 190 mdb_printf("%%pdpte1 = 0x%0?lx\t%%pdpte3 = 0x%0?lx\n", 191 sregs->sr_pdpte1, sregs->sr_pdpte3); 192 mdb_printf("\n"); 193 194 mdb_printf("%%gdtr = 0x%0*lx/0x%hx\n", 195 width, sregs->sr_gdtr.d_base, sregs->sr_gdtr.d_lim); 196 #else 197 mdb_printf("%%gdtr.base = 0x%0*lx, %%gdtr.limit = 0x%hx\n", 198 width, sregs->sr_gdtr.d_base, sregs->sr_gdtr.d_lim); 199 #endif 200 #ifndef _KMDB 201 mdb_printf("%%idtr = 0x%0*lx/0x%hx\n", 202 width, sregs->sr_idtr.d_base, sregs->sr_idtr.d_lim); 203 mdb_x86_print_desc("ldtr", &sregs->sr_ldtr, width); 204 mdb_x86_print_desc("tr ", &sregs->sr_tr, width); 205 mdb_x86_print_desc("cs ", &sregs->sr_cs, width); 206 mdb_x86_print_desc("ss ", &sregs->sr_ss, width); 207 mdb_x86_print_desc("ds ", &sregs->sr_ds, width); 208 mdb_x86_print_desc("es ", &sregs->sr_es, width); 209 mdb_x86_print_desc("fs ", &sregs->sr_fs, width); 210 mdb_x86_print_desc("gs ", &sregs->sr_gs, width); 211 212 mdb_printf("%%intr_shadow = 0x%lx\n", 213 sregs->sr_intr_shadow); 214 #endif 215 } 216