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