///////////////////////////////////////////////////////////////////////// // $Id: descriptor.h,v 1.10 2006-02-26 21:44:03 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. // // MandrakeSoft S.A. // 43, rue d'Aboukir // 75002 Paris - France // http://www.linux-mandrake.com/ // http://www.mandrakesoft.com/ // // 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 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ///////////////////////////////////////////////////////////////////////// #ifndef BX_DESCRIPTOR_H #define BX_DESCRIPTOR_H typedef struct { /* bx_selector_t */ Bit16u value; /* the 16bit value of the selector */ #if BX_CPU_LEVEL >= 2 /* the following fields are extracted from the value field in protected mode only. They're used for sake of efficiency */ Bit16u index; /* 13bit index extracted from value in protected mode */ Bit8u ti; /* table indicator bit extracted from value */ Bit8u rpl; /* RPL extracted from value */ #endif } bx_selector_t; #define BX_SELECTOR_RPL(selector) ((selector) & 0x03) #define BX_SELECTOR_RPL_MASK (0xfffc) typedef struct { #define SegValidCache (0x1) #define SegAccessROK (0x2) #define SegAccessWOK (0x4) unsigned valid; // Holds above values, Or'd together. Used to // hold only 0 or 1. bx_bool p; /* present */ Bit8u dpl; /* descriptor privilege level 0..3 */ bx_bool segment; /* 0 = system/gate, 1 = data/code segment */ Bit8u type; /* For system & gate descriptors, only * 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 */ #define BX_GATE_TYPE_NONE (0x0) #define BX_SYS_SEGMENT_AVAIL_286_TSS (0x1) #define BX_SYS_SEGMENT_LDT (0x2) #define BX_SYS_SEGMENT_BUSY_286_TSS (0x3) #define BX_286_CALL_GATE (0x4) #define BX_TASK_GATE (0x5) #define BX_286_INTERRUPT_GATE (0x6) #define BX_286_TRAP_GATE (0x7) /* 0x8 reserved */ #define BX_SYS_SEGMENT_AVAIL_386_TSS (0x9) /* 0xa reserved */ #define BX_SYS_SEGMENT_BUSY_386_TSS (0xb) #define BX_386_CALL_GATE (0xc) /* 0xd reserved */ #define BX_386_INTERRUPT_GATE (0xe) #define BX_386_TRAP_GATE (0xf) union { struct { bx_bool executable; /* 1=code, 0=data or stack segment */ bx_bool c_ed; /* for code: 1=conforming, for data/stack: 1=expand down */ bx_bool r_w; /* for code: readable?, for data/stack: writeable? */ bx_bool a; /* accessed? */ bx_address base; /* base address: 286=24bits, 386=32bits, long=64 */ Bit32u limit; /* limit: 286=16bits, 386=20bits */ Bit32u limit_scaled; /* for efficiency, this contrived field is set to * limit for byte granular, and * (limit << 12) | 0xfff for page granular seg's */ #if BX_CPU_LEVEL >= 3 bx_bool g; /* granularity: 0=byte, 1=4K (page) */ bx_bool d_b; /* default size: 0=16bit, 1=32bit */ #if BX_SUPPORT_X86_64 bx_bool l; /* long mode: 0=compat, 1=64 bit */ #endif bx_bool avl; /* available for use by system */ #endif } segment; struct { Bit8u word_count; /* 5bits (0..31) #words to copy from caller's stack * to called procedure's stack. (call gates only)*/ Bit16u dest_selector; Bit16u dest_offset; } gate286; struct { /* type 5: Task Gate Descriptor */ Bit16u tss_selector; /* TSS segment selector */ } taskgate; #if BX_CPU_LEVEL >= 3 struct { Bit8u dword_count; /* 5bits (0..31) #dwords to copy from caller's stack * to called procedure's stack. (call gates only) */ Bit16u dest_selector; Bit32u dest_offset; } gate386; #endif struct { Bit32u base; /* 24 bit 286 TSS base */ Bit16u limit; /* 16 bit 286 TSS limit */ } tss286; #if BX_CPU_LEVEL >= 3 struct { bx_address base; /* 32/64 bit 386 TSS base */ Bit32u limit; /* 20 bit 386 TSS limit */ Bit32u limit_scaled; // Same notes as for 'segment' field bx_bool g; /* granularity: 0=byte, 1=4K (page) */ bx_bool avl; /* available for use by system */ } tss386; #endif struct { bx_address base; /* 286=24 386+ =32/64 bit LDT base */ Bit16u limit; /* 286+ =16 bit LDT limit */ } ldt; } u; } bx_descriptor_t; #define IS_PRESENT(descriptor) (descriptor.p) #if BX_SUPPORT_X86_64 #define IS_LONG64_SEGMENT(descriptor) (descriptor.u.segment.l) #else #define IS_LONG64_SEGMENT(descriptor) (0) #endif typedef struct { bx_selector_t selector; bx_descriptor_t cache; } bx_segment_reg_t; #if BX_CPU_LEVEL < 2 /* no GDTR or IDTR register in an 8086 */ #else typedef struct { bx_address base; /* base address: 24bits=286,32bits=386,64bits=x86-64 */ Bit16u limit; /* limit, 16bits */ } bx_global_segment_reg_t; #endif #endif