2005-02-27 21:14:29 +03:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
2011-02-25 00:54:04 +03:00
|
|
|
// $Id$
|
2005-02-27 21:14:29 +03:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
2015-01-25 23:55:10 +03:00
|
|
|
// Copyright (c) 2007-2015 Stanislav Shwartsman
|
2007-10-16 02:07:52 +04:00
|
|
|
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
|
2005-02-27 21:14:29 +03:00
|
|
|
//
|
|
|
|
// This library is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
// License as published by the Free Software Foundation; either
|
|
|
|
// version 2 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This library is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
// License along with this library; if not, write to the Free Software
|
2009-01-16 21:18:59 +03:00
|
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
|
2005-02-27 21:14:29 +03:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#ifndef BX_DESCRIPTOR_H
|
|
|
|
#define BX_DESCRIPTOR_H
|
|
|
|
|
2008-05-26 22:02:07 +04:00
|
|
|
//
|
|
|
|
// |---------------------------------------------|
|
|
|
|
// | Segment Descriptor |
|
|
|
|
// |---------------------------------------------|
|
|
|
|
// |33222222|2|2|2|2| 11 11 |1|11|1|11 | |
|
|
|
|
// |10987654|3|2|1|0| 98 76 |5|43|2|1098|76543210|
|
|
|
|
// |--------|-|-|-|-|-------|-|--|-|----|--------|
|
|
|
|
// |Base |G|D|L|A|Limit |P|D |S|Type|Base |
|
|
|
|
// |[31-24] | |/| |V|[19-16]| |P | | |[23-16] |
|
|
|
|
// | | |B| |L| | |L | | | |
|
|
|
|
// |------------------------|--------------------|
|
|
|
|
// | Base [15-0] | Limit [15-0] |
|
|
|
|
// |------------------------|--------------------|
|
|
|
|
//
|
|
|
|
|
2005-02-27 21:14:29 +03:00
|
|
|
typedef struct { /* bx_selector_t */
|
|
|
|
Bit16u value; /* the 16bit value of the selector */
|
2010-05-02 19:11:39 +04:00
|
|
|
/* the following fields are extracted from the value field in protected
|
|
|
|
mode only. They're used for sake of efficiency */
|
2005-02-27 21:14:29 +03:00
|
|
|
Bit16u index; /* 13bit index extracted from value in protected mode */
|
|
|
|
Bit8u ti; /* table indicator bit extracted from value */
|
|
|
|
Bit8u rpl; /* RPL extracted from value */
|
|
|
|
} bx_selector_t;
|
|
|
|
|
2005-08-02 01:40:17 +04:00
|
|
|
#define BX_SELECTOR_RPL(selector) ((selector) & 0x03)
|
2005-02-27 21:14:29 +03:00
|
|
|
#define BX_SELECTOR_RPL_MASK (0xfffc)
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
|
2008-05-03 21:33:30 +04:00
|
|
|
#define SegValidCache (0x01)
|
|
|
|
#define SegAccessROK (0x02)
|
|
|
|
#define SegAccessWOK (0x04)
|
2015-01-25 23:55:10 +03:00
|
|
|
#define SegAccessROK4G (0x08)
|
|
|
|
#define SegAccessWOK4G (0x10)
|
|
|
|
unsigned valid; // Holds above values, Or'd together. Used to
|
|
|
|
// hold only 0 or 1 once.
|
2006-02-27 00:44:03 +03:00
|
|
|
|
2021-01-30 11:35:35 +03:00
|
|
|
bool p; /* present */
|
2005-02-27 21:14:29 +03:00
|
|
|
Bit8u dpl; /* descriptor privilege level 0..3 */
|
2021-01-30 11:35:35 +03:00
|
|
|
bool segment; /* 0 = system/gate, 1 = data/code segment */
|
2006-06-12 01:55:39 +04:00
|
|
|
Bit8u type; /* For system & gate descriptors:
|
2005-02-27 21:14:29 +03:00
|
|
|
* 0 = invalid descriptor (reserved)
|
|
|
|
* 1 = 286 available Task State Segment (TSS)
|
|
|
|
* 2 = LDT descriptor
|
|
|
|
* 3 = 286 busy Task State Segment (TSS)
|
|
|
|
* 4 = 286 call gate
|
|
|
|
* 5 = task gate
|
|
|
|
* 6 = 286 interrupt gate
|
|
|
|
* 7 = 286 trap gate
|
|
|
|
* 8 = (reserved)
|
|
|
|
* 9 = 386 available TSS
|
|
|
|
* 10 = (reserved)
|
|
|
|
* 11 = 386 busy TSS
|
|
|
|
* 12 = 386 call gate
|
|
|
|
* 13 = (reserved)
|
|
|
|
* 14 = 386 interrupt gate
|
|
|
|
* 15 = 386 trap gate */
|
|
|
|
|
2005-03-01 23:55:25 +03:00
|
|
|
union {
|
2005-02-27 21:14:29 +03:00
|
|
|
struct {
|
2006-05-22 00:41:48 +04:00
|
|
|
bx_address base; /* base address: 286=24bits, 386=32bits, long=64 */
|
2005-02-27 21:14:29 +03:00
|
|
|
Bit32u limit_scaled; /* for efficiency, this contrived field is set to
|
|
|
|
* limit for byte granular, and
|
|
|
|
* (limit << 12) | 0xfff for page granular seg's
|
|
|
|
*/
|
2021-01-30 11:35:35 +03:00
|
|
|
bool g; /* granularity: 0=byte, 1=4K (page) */
|
|
|
|
bool d_b; /* default size: 0=16bit, 1=32bit */
|
2005-02-27 21:14:29 +03:00
|
|
|
#if BX_SUPPORT_X86_64
|
2021-01-30 11:35:35 +03:00
|
|
|
bool l; /* long mode: 0=compat, 1=64 bit */
|
2005-02-27 21:14:29 +03:00
|
|
|
#endif
|
2021-01-30 11:35:35 +03:00
|
|
|
bool avl; /* available for use by system */
|
2005-02-27 21:14:29 +03:00
|
|
|
} segment;
|
|
|
|
struct {
|
2007-11-06 22:17:42 +03:00
|
|
|
Bit8u param_count; /* 5bits (0..31) #words/dword to copy from caller's
|
|
|
|
* stack to called procedure's stack. */
|
2005-02-27 21:14:29 +03:00
|
|
|
Bit16u dest_selector;
|
|
|
|
Bit32u dest_offset;
|
2007-11-06 22:17:42 +03:00
|
|
|
} gate;
|
2006-05-21 23:31:23 +04:00
|
|
|
struct { /* type 5: Task Gate Descriptor */
|
|
|
|
Bit16u tss_selector; /* TSS segment selector */
|
|
|
|
} taskgate;
|
2005-03-01 23:55:25 +03:00
|
|
|
} u;
|
2005-02-27 21:14:29 +03:00
|
|
|
|
|
|
|
} bx_descriptor_t;
|
|
|
|
|
2022-07-27 23:20:47 +03:00
|
|
|
// For system & gate descriptors:
|
|
|
|
enum {
|
|
|
|
BX_GATE_TYPE_NONE = 0x0,
|
|
|
|
BX_SYS_SEGMENT_AVAIL_286_TSS = 0x1,
|
|
|
|
BX_SYS_SEGMENT_LDT = 0x2,
|
|
|
|
BX_SYS_SEGMENT_BUSY_286_TSS = 0x3,
|
|
|
|
BX_286_CALL_GATE = 0x4,
|
|
|
|
BX_TASK_GATE = 0x5,
|
|
|
|
BX_286_INTERRUPT_GATE = 0x6,
|
|
|
|
BX_286_TRAP_GATE = 0x7,
|
|
|
|
/* 0x8 reserved */
|
|
|
|
BX_SYS_SEGMENT_AVAIL_386_TSS = 0x9,
|
|
|
|
/* 0xa reserved */
|
|
|
|
BX_SYS_SEGMENT_BUSY_386_TSS = 0xb,
|
|
|
|
BX_386_CALL_GATE = 0xc,
|
|
|
|
/* 0xd reserved */
|
|
|
|
BX_386_INTERRUPT_GATE = 0xe,
|
|
|
|
BX_386_TRAP_GATE = 0xf,
|
|
|
|
};
|
|
|
|
|
|
|
|
// For data/code descriptors:
|
|
|
|
enum {
|
|
|
|
BX_DATA_READ_ONLY = 0x0,
|
|
|
|
BX_DATA_READ_ONLY_ACCESSED = 0x1,
|
|
|
|
BX_DATA_READ_WRITE = 0x2,
|
|
|
|
BX_DATA_READ_WRITE_ACCESSED = 0x3,
|
|
|
|
BX_DATA_READ_ONLY_EXPAND_DOWN = 0x4,
|
|
|
|
BX_DATA_READ_ONLY_EXPAND_DOWN_ACCESSED = 0x5,
|
|
|
|
BX_DATA_READ_WRITE_EXPAND_DOWN = 0x6,
|
|
|
|
BX_DATA_READ_WRITE_EXPAND_DOWN_ACCESSED = 0x7,
|
|
|
|
BX_CODE_EXEC_ONLY = 0x8,
|
|
|
|
BX_CODE_EXEC_ONLY_ACCESSED = 0x9,
|
|
|
|
BX_CODE_EXEC_READ = 0xa,
|
|
|
|
BX_CODE_EXEC_READ_ACCESSED = 0xb,
|
|
|
|
BX_CODE_EXEC_ONLY_CONFORMING = 0xc,
|
|
|
|
BX_CODE_EXEC_ONLY_CONFORMING_ACCESSED = 0xd,
|
|
|
|
BX_CODE_EXEC_READ_CONFORMING = 0xe,
|
|
|
|
BX_CODE_EXEC_READ_CONFORMING_ACCESSED = 0xf
|
|
|
|
};
|
|
|
|
|
2005-07-11 00:32:32 +04:00
|
|
|
#define IS_PRESENT(descriptor) (descriptor.p)
|
2005-05-19 23:46:20 +04:00
|
|
|
|
|
|
|
#if BX_SUPPORT_X86_64
|
2006-06-12 20:58:27 +04:00
|
|
|
#define IS_LONG64_SEGMENT(descriptor) (descriptor.u.segment.l)
|
2005-05-19 23:46:20 +04:00
|
|
|
#else
|
2006-06-12 20:58:27 +04:00
|
|
|
#define IS_LONG64_SEGMENT(descriptor) (0)
|
2005-05-19 23:46:20 +04:00
|
|
|
#endif
|
|
|
|
|
2022-07-27 23:20:47 +03:00
|
|
|
enum {
|
|
|
|
BX_SEGMENT_CODE = 0x8,
|
|
|
|
BX_SEGMENT_DATA_EXPAND_DOWN = 0x4,
|
|
|
|
BX_SEGMENT_CODE_CONFORMING = 0x4,
|
|
|
|
BX_SEGMENT_DATA_WRITE = 0x2,
|
|
|
|
BX_SEGMENT_CODE_READ = 0x2,
|
|
|
|
BX_SEGMENT_ACCESSED = 0x1
|
|
|
|
};
|
2006-06-12 20:58:27 +04:00
|
|
|
|
2012-06-14 22:56:47 +04:00
|
|
|
#define IS_CODE_SEGMENT(type) ((type) & BX_SEGMENT_CODE)
|
|
|
|
#define IS_CODE_SEGMENT_CONFORMING(type) ((type) & BX_SEGMENT_CODE_CONFORMING)
|
|
|
|
#define IS_DATA_SEGMENT_EXPAND_DOWN(type) ((type) & BX_SEGMENT_DATA_EXPAND_DOWN)
|
|
|
|
#define IS_CODE_SEGMENT_READABLE(type) ((type) & BX_SEGMENT_CODE_READ)
|
|
|
|
#define IS_DATA_SEGMENT_WRITEABLE(type) ((type) & BX_SEGMENT_DATA_WRITE)
|
|
|
|
#define IS_SEGMENT_ACCESSED(type) ((type) & BX_SEGMENT_ACCESSED)
|
|
|
|
|
2006-06-12 20:58:27 +04:00
|
|
|
#define IS_DATA_SEGMENT(type) (! IS_CODE_SEGMENT(type))
|
|
|
|
#define IS_CODE_SEGMENT_NON_CONFORMING(type) \
|
|
|
|
(! IS_CODE_SEGMENT_CONFORMING(type))
|
|
|
|
|
2005-02-27 21:14:29 +03:00
|
|
|
typedef struct {
|
2005-03-05 00:03:22 +03:00
|
|
|
bx_selector_t selector;
|
2005-02-27 21:14:29 +03:00
|
|
|
bx_descriptor_t cache;
|
|
|
|
} bx_segment_reg_t;
|
|
|
|
|
|
|
|
typedef struct {
|
2005-04-13 21:13:05 +04:00
|
|
|
bx_address base; /* base address: 24bits=286,32bits=386,64bits=x86-64 */
|
|
|
|
Bit16u limit; /* limit, 16bits */
|
|
|
|
} bx_global_segment_reg_t;
|
2009-12-27 19:38:09 +03:00
|
|
|
|
2009-12-27 19:53:35 +03:00
|
|
|
void parse_selector(Bit16u raw_selector, bx_selector_t *selector);
|
|
|
|
Bit8u get_ar_byte(const bx_descriptor_t *d);
|
|
|
|
void set_ar_byte(bx_descriptor_t *d, Bit8u ar_byte);
|
2009-12-28 12:26:22 +03:00
|
|
|
void parse_descriptor(Bit32u dword1, Bit32u dword2, bx_descriptor_t *temp);
|
2005-02-27 21:14:29 +03:00
|
|
|
|
|
|
|
#endif
|