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