| version 1.2, 2003/12/12 15:06:18 | version 1.13, 2011/12/21 17:32:49 | 
| Line 1 | Line 1 | 
 | /*      $Id$    */ |  | 
 |  |  | 
 | /* | /* | 
 | * Copyright (c) 2003 NONAKA Kimihiro | * Copyright (c) 2003 NONAKA Kimihiro | 
 | * All rights reserved. | * All rights reserved. | 
| Line 12 | Line 10 | 
 | * 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 31  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; /* unused */ | 
| 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) | 
|  | #define CPU_DESC_FLAG_WHOLEADR  (1 << 2) | 
 | } descriptor_t; | } descriptor_t; | 
 |  |  | 
| #define CPU_DESC_H_TYPE         (0xf <<  8) | #define SEG_IS_VALID(sdp)               ((sdp)->valid) | 
|  | #define SEG_IS_PRESENT(sdp)             ((sdp)->p) | 
|  | #define SEG_IS_32BIT(sdp)               ((sdp)->d) | 
|  | #define SEG_IS_SYSTEM(sdp)              (!(sdp)->s) | 
|  | #define SEG_IS_CODE(sdp)                ((sdp)->s && (sdp)->u.seg.c) | 
|  | #define SEG_IS_DATA(sdp)                ((sdp)->s && !(sdp)->u.seg.c) | 
|  | #define SEG_IS_READABLE_CODE(sdp)       ((sdp)->u.seg.wr) | 
|  | #define SEG_IS_WRITABLE_DATA(sdp)       ((sdp)->u.seg.wr) | 
|  | #define SEG_IS_CONFORMING_CODE(sdp)     ((sdp)->u.seg.ec) | 
|  | #define SEG_IS_EXPANDDOWN_DATA(sdp)     ((sdp)->u.seg.ec) | 
|  |  | 
|  | /* | 
|  | * segment descriptor | 
|  | * | 
|  | *  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_SHIFT   8 | 
|  | #define CPU_DESC_H_TYPE         (0xf << CPU_DESC_H_TYPE_SHIFT) | 
 | #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_SHIFT    13 | 
|  | #define CPU_DESC_H_DPL          (  3 << CPU_DESC_H_DPL_SHIFT) | 
 | #define CPU_DESC_H_P            (  1 << 15)     /* exist */ | #define CPU_DESC_H_P            (  1 << 15)     /* exist */ | 
 |  |  | 
 | /* for segment descriptor */ | /* for segment descriptor */ | 
| Line 103  typedef struct { | Line 114  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 143  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_32BIT          0x08 | 
 |  |  | 
 | #define CPU_SYSDESC_TYPE_TSS_BUSY_IND   0x02 | #define CPU_SYSDESC_TYPE_TSS_BUSY_IND   0x02 | 
 |  |  | 
| #define CPU_SET_SEGDESC_DEFAULT(dscp, idx, selector) \ |  | 
| do { \ | STATIC_INLINE void CPUCALL | 
| (dscp)->u.seg.segbase = (DWORD)(selector) << 4; \ | segdesc_clear(descriptor_t *sdp) | 
| (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.g = 0; \ | memset((sdp), 0, sizeof(*sdp)); | 
| (dscp)->valid = 1; \ | } | 
| (dscp)->p = 1; \ |  | 
| (dscp)->type = ((idx) == CPU_CS_INDEX) ? 0x0a : \ | void segdesc_init(int idx, UINT16 sreg, descriptor_t *sdp); | 
| (((idx) == CPU_SS_INDEX) ? 0x06 : 0x02); \ | void segdesc_set_default(int idx, UINT16 selector, descriptor_t *sdp); | 
| (dscp)->dpl = 0; \ | void load_descriptor(descriptor_t *sdp, UINT32 addr); | 
| (dscp)->s = 1;  /* code/data */ \ |  | 
| (dscp)->d = 0; \ | void load_segreg(int idx, UINT16 selector, UINT16 *sregp, descriptor_t *sdp, int exc); | 
| (dscp)->flag = 0; \ | #define LOAD_SEGREG1(idx, selector, e) \ | 
| } while (/*CONSTCOND*/ 0) | load_segreg(idx, selector, &CPU_REGS_SREG(idx), &CPU_STAT_SREG(idx), e) | 
|  | #define LOAD_SEGREG(idx, selector) \ | 
| #define CPU_SET_SEGDESC_POSTPART(dscp) \ | LOAD_SEGREG1((idx), (selector), GP_EXCEPTION) | 
| do { \ | void load_ss(UINT16 selector, const descriptor_t *sdp, int cpl); | 
| if ((dscp)->s) { \ | void load_cs(UINT16 selector, const descriptor_t *sdp, int cpl); | 
| if (!((dscp)->h & CPU_SEGDESC_H_A)) { \ | void load_ldtr(UINT16 selector, int exc); | 
| (dscp)->h |= CPU_SEGDESC_H_A; \ |  | 
| cpu_lmemorywrite_d((dscp)->addr + 4, (dscp)->h); \ |  | 
| } \ | /* | 
| } \ | * segment selector | 
| } while (/*CONSTCOND*/ 0) | */ | 
|  | #define CPU_SEGMENT_SELECTOR_INDEX_MASK (~7) | 
| #define CPU_SET_TASK_BUSY(dscp) \ | #define CPU_SEGMENT_SELECTOR_RPL_MASK   (3) | 
| do { \ | #define CPU_SEGMENT_TABLE_IND           (1 << 2)        /* 0 = GDT, 1 = LDT */ | 
| DWORD h; \ |  | 
| h = cpu_lmemoryread_d((dscp)->addr + 4); \ |  | 
| if (!(h & CPU_TSS_H_BUSY)) { \ |  | 
| (dscp)->type |= CPU_SYSDESC_TYPE_TSS_BUSY_IND; \ |  | 
| h |= CPU_TSS_H_BUSY; \ |  | 
| cpu_lmemorywrite_d((dscp)->addr + 4, h); \ |  | 
| } else { \ |  | 
| ia32_panic("CPU_SET_TASK_BUSY: already busy (%x)", h); \ |  | 
| } \ |  | 
| } while (/*CONSTCOND*/ 0) |  | 
|  |  | 
| #define CPU_SET_TASK_FREE(dscp) \ |  | 
| do { \ |  | 
| DWORD h; \ |  | 
| h = cpu_lmemoryread_d((dscp)->addr + 4); \ |  | 
| if (h & CPU_TSS_H_BUSY) { \ |  | 
| (dscp)->type &= ~CPU_SYSDESC_TYPE_TSS_BUSY_IND; \ |  | 
| h &= ~CPU_TSS_H_BUSY; \ |  | 
| cpu_lmemorywrite_d((dscp)->addr + 4, h); \ |  | 
| } else { \ |  | 
| ia32_panic("CPU_SET_TASK_FREE: already free (%x)", h); \ |  | 
| } \ |  | 
| } while (/*CONSTCOND*/ 0) |  | 
 |  |  | 
 | 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 | 
 | } | } |