|
|
| version 1.1, 2003/12/08 00:55:31 | version 1.10, 2005/03/12 12:32:54 |
|---|---|
| Line 12 | Line 12 |
| * 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the | * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. | * documentation and/or other materials provided with the distribution. |
| * 3. The name of the author may not be used to endorse or promote products | |
| * derived from this software without specific prior written permission. | |
| * | * |
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| Line 35 extern "C" { | Line 33 extern "C" { |
| #endif | #endif |
| /* | /* |
| * segment selector | |
| */ | |
| #define CPU_SEGMENT_SELECTOR_INDEX_MASK ~7 | |
| #define CPU_SEGMENT_SELECTOR_RPL_MASK 3 | |
| #define CPU_SEGMENT_TABLE_IND (1 << 2) /* 0 = GDT, 1 = LDT */ | |
| /* | |
| * segment descriptor | * segment descriptor |
| */ | */ |
| typedef struct { | typedef struct { |
| union { | union { |
| struct { | struct { |
| DWORD segbase; | UINT32 segbase; |
| DWORD segend; | UINT32 segend; |
| DWORD limit; | UINT32 limit; |
| BYTE c; /* 0 = data, 1 = code */ | UINT8 c; /* 0 = data, 1 = code */ |
| BYTE g; /* 4k base */ | UINT8 g; /* 4k base */ |
| BYTE wr; /* readable/writable */ | UINT8 wr; /* readable/writable */ |
| BYTE ec; /* expand down/conforming */ | UINT8 ec; /* expand down/conforming */ |
| } seg; | } seg; |
| struct { | struct { |
| WORD selector; | UINT16 selector; |
| WORD w_pad; | UINT16 w_pad; |
| DWORD offset; | UINT32 offset; |
| BYTE count; /* parameter count:call gate */ | UINT8 count; /* parameter count:call gate */ |
| BYTE b_pad[7]; | UINT8 b_pad[7]; |
| } gate; | } gate; |
| } u; | } u; |
| DWORD addr; /* descriptor addr */ | UINT8 valid; /* descriptor valid flag */ |
| DWORD l; /* low dword cache */ | UINT8 p; /* avail flag */ |
| DWORD h; /* high dword cache */ | |
| BYTE valid; /* descriptor valid flag */ | |
| BYTE p; /* avail flag */ | |
| BYTE type; /* descriptor type */ | |
| BYTE dpl; /* DPL */ | |
| BYTE s; /* 0 = system, 1 = code/data */ | |
| BYTE d; /* 0 = 16bit, 1 = 32bit */ | |
| BYTE flag; | |
| #define CPU_DESC_READABLE (1 << 0) | |
| #define CPU_DESC_WRITABLE (1 << 1) | |
| BYTE b_pad; | UINT8 type; /* descriptor type */ |
| UINT8 dpl; /* DPL */ | |
| UINT8 rpl; /* RPL */ | |
| UINT8 s; /* 0 = system, 1 = code/data */ | |
| UINT8 d; /* 0 = 16bit, 1 = 32bit */ | |
| UINT8 flag; | |
| #define CPU_DESC_FLAG_READABLE (1 << 0) | |
| #define CPU_DESC_FLAG_WRITABLE (1 << 1) | |
| } descriptor_t; | } descriptor_t; |
| /* | |
| * セグメント・ディスクリプタ | |
| * | |
| * 31 24 23 22 21 20 19 16 15 14 13 12 11 8 7 0 | |
| * +----------------+--+--+--+--+-------+--+-----+--+-------+---------------+ | |
| * | Base 31..16 | G|DB| 0| A|limit_h| P| DPL | S| type | Base 23:16 | 4 | |
| * +----------------+--+--+--+--+-------+--+-----+--+-------+---------------+ | |
| * 31 16 15 0 | |
| * +------------------------------------+-----------------------------------+ | |
| * | Base 15..00 | limit 15..0 | 0 | |
| * +------------------------------------+-----------------------------------+ | |
| */ | |
| /* descriptor common */ | |
| #define CPU_DESC_H_TYPE (0xf << 8) | #define CPU_DESC_H_TYPE (0xf << 8) |
| #define CPU_DESC_H_S ( 1 << 12) /* 0 = system, 1 = code/data */ | #define CPU_DESC_H_S ( 1 << 12) /* 0 = system, 1 = code/data */ |
| #define CPU_DESC_H_DPL ( 3 << 13) | #define CPU_DESC_H_DPL ( 3 << 13) |
| Line 103 typedef struct { | Line 103 typedef struct { |
| #define CPU_GATEDESC_H_D ( 1 << 11) | #define CPU_GATEDESC_H_D ( 1 << 11) |
| /* for tss descriptor */ | /* for tss descriptor */ |
| #define CPU_TSS_H_BUSY ( 1 << 10) | #define CPU_TSS_H_BUSY ( 1 << 9) |
| /* | /* |
| * descriptor type | * descriptor type |
| Line 132 typedef struct { | Line 132 typedef struct { |
| /* CPU_SYSDESC_TYPE_TASK 0x05 */ | /* CPU_SYSDESC_TYPE_TASK 0x05 */ |
| #define CPU_SYSDESC_TYPE_INTR 0x06 | #define CPU_SYSDESC_TYPE_INTR 0x06 |
| #define CPU_SYSDESC_TYPE_TRAP 0x07 | #define CPU_SYSDESC_TYPE_TRAP 0x07 |
| #define CPU_SYSDESC_TYPE_MASKBIT 0x07 | |
| #define CPU_SYSDESC_TYPE_TSS_BUSY_IND 0x02 | #define CPU_SYSDESC_TYPE_TSS_BUSY_IND 0x02 |
| #define CPU_SET_SEGDESC_DEFAULT(dscp, idx, selector) \ | #define CPU_SET_SEGDESC_DEFAULT(dscp, idx, selector) \ |
| do { \ | do { \ |
| (dscp)->u.seg.segbase = (DWORD)(selector) << 4; \ | (dscp)->u.seg.segbase = (UINT32)(selector) << 4; \ |
| (dscp)->u.seg.segend = (dscp)->u.seg.segbase + (dscp)->u.seg.limit; \ | (dscp)->u.seg.segend = (dscp)->u.seg.segbase + (dscp)->u.seg.limit; \ |
| (dscp)->u.seg.c = ((idx) == CPU_CS_INDEX) ? 1 : 0; \ | (dscp)->u.seg.c = ((idx) == CPU_CS_INDEX) ? 1 : 0; \ |
| (dscp)->u.seg.g = 0; \ | (dscp)->u.seg.g = 0; \ |
| (dscp)->u.seg.wr = 1; \ | |
| (dscp)->valid = 1; \ | (dscp)->valid = 1; \ |
| (dscp)->p = 1; \ | (dscp)->p = 1; \ |
| (dscp)->type = ((idx) == CPU_CS_INDEX) ? 0x0a : \ | (dscp)->type = 0x02; /* writable */ \ |
| (((idx) == CPU_SS_INDEX) ? 0x06 : 0x02); \ | |
| (dscp)->dpl = 0; \ | (dscp)->dpl = 0; \ |
| (dscp)->s = 1; /* code/data */ \ | (dscp)->s = 1; /* code/data */ \ |
| (dscp)->d = 0; \ | (dscp)->d = 0; /* 16bit */ \ |
| (dscp)->flag = 0; \ | (dscp)->flag = CPU_DESC_FLAG_READABLE|CPU_DESC_FLAG_WRITABLE; \ |
| } while (/*CONSTCOND*/ 0) | |
| #define CPU_SET_SEGDESC_POSTPART(dscp) \ | |
| do { \ | |
| if ((dscp)->s) { \ | |
| if (!((dscp)->h & CPU_SEGDESC_H_A)) { \ | |
| (dscp)->h |= CPU_SEGDESC_H_A; \ | |
| cpu_memorywrite_d((dscp)->addr + 4, (dscp)->h); \ | |
| } \ | |
| } \ | |
| } while (/*CONSTCOND*/ 0) | } while (/*CONSTCOND*/ 0) |
| #define CPU_SET_TASK_BUSY(dscp) \ | #define CPU_SET_TASK_BUSY(selector, dscp) \ |
| do { \ | do { \ |
| DWORD h; \ | UINT32 addr; \ |
| h = cpu_memoryread_d((dscp)->addr + 4); \ | UINT32 h; \ |
| addr = CPU_GDTR_BASE + ((selector) & CPU_SEGMENT_SELECTOR_INDEX_MASK); \ | |
| h = cpu_kmemoryread_d(addr + 4); \ | |
| if (!(h & CPU_TSS_H_BUSY)) { \ | if (!(h & CPU_TSS_H_BUSY)) { \ |
| (dscp)->type |= CPU_SYSDESC_TYPE_TSS_BUSY_IND; \ | (dscp)->type |= CPU_SYSDESC_TYPE_TSS_BUSY_IND; \ |
| h |= CPU_TSS_H_BUSY; \ | h |= CPU_TSS_H_BUSY; \ |
| cpu_memorywrite_d((dscp)->addr + 4, h); \ | cpu_kmemorywrite_d(addr + 4, h); \ |
| } else { \ | } else { \ |
| ia32_panic("CPU_SET_TASK_BUSY: already busy (%x)", h); \ | ia32_panic("CPU_SET_TASK_BUSY: already busy (%04x:%08x)", selector, h); \ |
| } \ | } \ |
| } while (/*CONSTCOND*/ 0) | } while (/*CONSTCOND*/ 0) |
| #define CPU_SET_TASK_FREE(dscp) \ | #define CPU_SET_TASK_FREE(selector, dscp) \ |
| do { \ | do { \ |
| DWORD h; \ | UINT32 addr; \ |
| h = cpu_memoryread_d((dscp)->addr + 4); \ | UINT32 h; \ |
| addr = CPU_GDTR_BASE + ((selector) & CPU_SEGMENT_SELECTOR_INDEX_MASK); \ | |
| h = cpu_kmemoryread_d(addr + 4); \ | |
| if (h & CPU_TSS_H_BUSY) { \ | if (h & CPU_TSS_H_BUSY) { \ |
| (dscp)->type &= ~CPU_SYSDESC_TYPE_TSS_BUSY_IND; \ | (dscp)->type &= ~CPU_SYSDESC_TYPE_TSS_BUSY_IND; \ |
| h &= ~CPU_TSS_H_BUSY; \ | h &= ~CPU_TSS_H_BUSY; \ |
| cpu_memorywrite_d((dscp)->addr + 4, h); \ | cpu_kmemorywrite_d(addr + 4, h); \ |
| } else { \ | } else { \ |
| ia32_panic("CPU_SET_TASK_FREE: already free (%x)", h); \ | ia32_panic("CPU_SET_TASK_FREE: already free (%04x:%08x)", selector, h); \ |
| } \ | } \ |
| } while (/*CONSTCOND*/ 0) | } while (/*CONSTCOND*/ 0) |
| void load_descriptor(descriptor_t *descp, UINT32 addr); | |
| #define CPU_SET_SEGREG(idx, selector) load_segreg(idx, selector, GP_EXCEPTION) | |
| void load_segreg(int idx, UINT16 selector, int exc); | |
| void load_ss(UINT16 selector, const descriptor_t *sd, UINT cpl); | |
| void load_cs(UINT16 selector, const descriptor_t *sd, UINT cpl); | |
| void load_ldtr(UINT16 selector, int exc); | |
| /* | |
| * segment selector | |
| */ | |
| #define CPU_SEGMENT_SELECTOR_INDEX_MASK (~7) | |
| #define CPU_SEGMENT_SELECTOR_RPL_MASK (3) | |
| #define CPU_SEGMENT_TABLE_IND (1 << 2) /* 0 = GDT, 1 = LDT */ | |
| typedef struct { | typedef struct { |
| WORD selector; | UINT16 selector; |
| WORD idx; | UINT16 idx; |
| WORD rpl; | UINT16 rpl; |
| BYTE ldt; | UINT8 ldt; |
| BYTE pad; | UINT8 pad; |
| UINT32 addr; /* descriptor linear address */ | |
| descriptor_t desc; | descriptor_t desc; |
| } selector_t; | } selector_t; |
| int parse_selector(selector_t* ssp, WORD selector); | int parse_selector(selector_t *ssp, UINT16 selector); |
| int selector_is_not_present(selector_t* ssp); | int selector_is_not_present(const selector_t *ssp); |
| #define CPU_SET_SEGDESC(descp, addr) load_descriptor(descp, addr) | |
| #define CPU_SET_GATEDESC(descp, addr) load_descriptor(descp, addr) | |
| void load_descriptor(descriptor_t* descp, DWORD addr); | |
| #define CPU_SET_SEGREG(idx, selector) load_segreg(idx, selector, GP_EXCEPTION) | |
| void load_segreg(int idx, WORD selector, int exc); | |
| void load_ss(WORD selector, descriptor_t* sdp, BYTE cpl); | |
| void load_cs(WORD selector, descriptor_t* sdp, BYTE cpl); | |
| void load_ldtr(WORD selector, int exc); | |
| #ifdef __cplusplus | #ifdef __cplusplus |
| } | } |