1 ///////////////////////////////////////////////////////////////////////// 2 // $Id: descriptor.h 14086 2021-01-30 08:35:35Z sshwarts $ 3 ///////////////////////////////////////////////////////////////////////// 4 // 5 // Copyright (c) 2007-2015 Stanislav Shwartsman 6 // Written by Stanislav Shwartsman [sshwarts at sourceforge net] 7 // 8 // This library is free software; you can redistribute it and/or 9 // modify it under the terms of the GNU Lesser General Public 10 // License as published by the Free Software Foundation; either 11 // version 2 of the License, or (at your option) any later version. 12 // 13 // This library is distributed in the hope that it will be useful, 14 // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 // Lesser General Public License for more details. 17 // 18 // You should have received a copy of the GNU Lesser General Public 19 // License along with this library; if not, write to the Free Software 20 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA 21 ///////////////////////////////////////////////////////////////////////// 22 23 #ifndef BX_DESCRIPTOR_H 24 #define BX_DESCRIPTOR_H 25 26 // 27 // |---------------------------------------------| 28 // | Segment Descriptor | 29 // |---------------------------------------------| 30 // |33222222|2|2|2|2| 11 11 |1|11|1|11 | | 31 // |10987654|3|2|1|0| 98 76 |5|43|2|1098|76543210| 32 // |--------|-|-|-|-|-------|-|--|-|----|--------| 33 // |Base |G|D|L|A|Limit |P|D |S|Type|Base | 34 // |[31-24] | |/| |V|[19-16]| |P | | |[23-16] | 35 // | | |B| |L| | |L | | | | 36 // |------------------------|--------------------| 37 // | Base [15-0] | Limit [15-0] | 38 // |------------------------|--------------------| 39 // 40 41 typedef struct { /* bx_selector_t */ 42 Bit16u value; /* the 16bit value of the selector */ 43 /* the following fields are extracted from the value field in protected 44 mode only. They're used for sake of efficiency */ 45 Bit16u index; /* 13bit index extracted from value in protected mode */ 46 Bit8u ti; /* table indicator bit extracted from value */ 47 Bit8u rpl; /* RPL extracted from value */ 48 } bx_selector_t; 49 50 #define BX_SELECTOR_RPL(selector) ((selector) & 0x03) 51 #define BX_SELECTOR_RPL_MASK (0xfffc) 52 53 typedef struct 54 { 55 56 #define SegValidCache (0x01) 57 #define SegAccessROK (0x02) 58 #define SegAccessWOK (0x04) 59 #define SegAccessROK4G (0x08) 60 #define SegAccessWOK4G (0x10) 61 unsigned valid; // Holds above values, Or'd together. Used to 62 // hold only 0 or 1 once. 63 64 bool p; /* present */ 65 Bit8u dpl; /* descriptor privilege level 0..3 */ 66 bool segment; /* 0 = system/gate, 1 = data/code segment */ 67 Bit8u type; /* For system & gate descriptors: 68 * 0 = invalid descriptor (reserved) 69 * 1 = 286 available Task State Segment (TSS) 70 * 2 = LDT descriptor 71 * 3 = 286 busy Task State Segment (TSS) 72 * 4 = 286 call gate 73 * 5 = task gate 74 * 6 = 286 interrupt gate 75 * 7 = 286 trap gate 76 * 8 = (reserved) 77 * 9 = 386 available TSS 78 * 10 = (reserved) 79 * 11 = 386 busy TSS 80 * 12 = 386 call gate 81 * 13 = (reserved) 82 * 14 = 386 interrupt gate 83 * 15 = 386 trap gate */ 84 85 // For system & gate descriptors: 86 87 #define BX_GATE_TYPE_NONE (0x0) 88 #define BX_SYS_SEGMENT_AVAIL_286_TSS (0x1) 89 #define BX_SYS_SEGMENT_LDT (0x2) 90 #define BX_SYS_SEGMENT_BUSY_286_TSS (0x3) 91 #define BX_286_CALL_GATE (0x4) 92 #define BX_TASK_GATE (0x5) 93 #define BX_286_INTERRUPT_GATE (0x6) 94 #define BX_286_TRAP_GATE (0x7) 95 /* 0x8 reserved */ 96 #define BX_SYS_SEGMENT_AVAIL_386_TSS (0x9) 97 /* 0xa reserved */ 98 #define BX_SYS_SEGMENT_BUSY_386_TSS (0xb) 99 #define BX_386_CALL_GATE (0xc) 100 /* 0xd reserved */ 101 #define BX_386_INTERRUPT_GATE (0xe) 102 #define BX_386_TRAP_GATE (0xf) 103 104 // For data/code descriptors: 105 106 #define BX_DATA_READ_ONLY (0x0) 107 #define BX_DATA_READ_ONLY_ACCESSED (0x1) 108 #define BX_DATA_READ_WRITE (0x2) 109 #define BX_DATA_READ_WRITE_ACCESSED (0x3) 110 #define BX_DATA_READ_ONLY_EXPAND_DOWN (0x4) 111 #define BX_DATA_READ_ONLY_EXPAND_DOWN_ACCESSED (0x5) 112 #define BX_DATA_READ_WRITE_EXPAND_DOWN (0x6) 113 #define BX_DATA_READ_WRITE_EXPAND_DOWN_ACCESSED (0x7) 114 #define BX_CODE_EXEC_ONLY (0x8) 115 #define BX_CODE_EXEC_ONLY_ACCESSED (0x9) 116 #define BX_CODE_EXEC_READ (0xa) 117 #define BX_CODE_EXEC_READ_ACCESSED (0xb) 118 #define BX_CODE_EXEC_ONLY_CONFORMING (0xc) 119 #define BX_CODE_EXEC_ONLY_CONFORMING_ACCESSED (0xd) 120 #define BX_CODE_EXEC_READ_CONFORMING (0xe) 121 #define BX_CODE_EXEC_READ_CONFORMING_ACCESSED (0xf) 122 123 union { 124 struct { 125 bx_address base; /* base address: 286=24bits, 386=32bits, long=64 */ 126 Bit32u limit_scaled; /* for efficiency, this contrived field is set to 127 * limit for byte granular, and 128 * (limit << 12) | 0xfff for page granular seg's 129 */ 130 bool g; /* granularity: 0=byte, 1=4K (page) */ 131 bool d_b; /* default size: 0=16bit, 1=32bit */ 132 #if BX_SUPPORT_X86_64 133 bool l; /* long mode: 0=compat, 1=64 bit */ 134 #endif 135 bool avl; /* available for use by system */ 136 } segment; 137 struct { 138 Bit8u param_count; /* 5bits (0..31) #words/dword to copy from caller's 139 * stack to called procedure's stack. */ 140 Bit16u dest_selector; 141 Bit32u dest_offset; 142 } gate; 143 struct { /* type 5: Task Gate Descriptor */ 144 Bit16u tss_selector; /* TSS segment selector */ 145 } taskgate; 146 } u; 147 148 } bx_descriptor_t; 149 150 #define IS_PRESENT(descriptor) (descriptor.p) 151 152 #if BX_SUPPORT_X86_64 153 #define IS_LONG64_SEGMENT(descriptor) (descriptor.u.segment.l) 154 #else 155 #define IS_LONG64_SEGMENT(descriptor) (0) 156 #endif 157 158 #define BX_SEGMENT_CODE (0x8) 159 #define BX_SEGMENT_DATA_EXPAND_DOWN (0x4) 160 #define BX_SEGMENT_CODE_CONFORMING (0x4) 161 #define BX_SEGMENT_DATA_WRITE (0x2) 162 #define BX_SEGMENT_CODE_READ (0x2) 163 #define BX_SEGMENT_ACCESSED (0x1) 164 165 #define IS_CODE_SEGMENT(type) ((type) & BX_SEGMENT_CODE) 166 #define IS_CODE_SEGMENT_CONFORMING(type) ((type) & BX_SEGMENT_CODE_CONFORMING) 167 #define IS_DATA_SEGMENT_EXPAND_DOWN(type) ((type) & BX_SEGMENT_DATA_EXPAND_DOWN) 168 #define IS_CODE_SEGMENT_READABLE(type) ((type) & BX_SEGMENT_CODE_READ) 169 #define IS_DATA_SEGMENT_WRITEABLE(type) ((type) & BX_SEGMENT_DATA_WRITE) 170 #define IS_SEGMENT_ACCESSED(type) ((type) & BX_SEGMENT_ACCESSED) 171 172 #define IS_DATA_SEGMENT(type) (! IS_CODE_SEGMENT(type)) 173 #define IS_CODE_SEGMENT_NON_CONFORMING(type) \ 174 (! IS_CODE_SEGMENT_CONFORMING(type)) 175 176 typedef struct { 177 bx_selector_t selector; 178 bx_descriptor_t cache; 179 } bx_segment_reg_t; 180 181 typedef struct { 182 bx_address base; /* base address: 24bits=286,32bits=386,64bits=x86-64 */ 183 Bit16u limit; /* limit, 16bits */ 184 } bx_global_segment_reg_t; 185 186 void parse_selector(Bit16u raw_selector, bx_selector_t *selector); 187 Bit8u get_ar_byte(const bx_descriptor_t *d); 188 void set_ar_byte(bx_descriptor_t *d, Bit8u ar_byte); 189 void parse_descriptor(Bit32u dword1, Bit32u dword2, bx_descriptor_t *temp); 190 191 #endif 192