Handle granularity field for LDT
Next step - fix code duplication with TSS
This commit is contained in:
parent
59962a4438
commit
65082e4a4f
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.302 2006-08-11 17:23:36 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.303 2006-08-25 19:56:03 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -2830,7 +2830,6 @@ public: // for now...
|
||||
BX_SMF Bit16u get_segment_ar_data(const bx_descriptor_t *d) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF bx_bool set_segment_ar_data(bx_segment_reg_t *seg, Bit16u raw_selector,
|
||||
bx_address base, Bit32u limit, Bit16u ar_data);
|
||||
BX_SMF void load_ldtr(bx_selector_t *selector, bx_descriptor_t *descriptor);
|
||||
BX_SMF void check_cs(bx_descriptor_t *descriptor, Bit16u cs_raw, Bit8u check_rpl, Bit8u check_cpl);
|
||||
BX_SMF void load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cpl) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF void load_ss(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cpl) BX_CPP_AttrRegparmN(3);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: debugstuff.cc,v 1.72 2006-06-17 12:09:55 sshwarts Exp $
|
||||
// $Id: debugstuff.cc,v 1.73 2006-08-25 19:56:03 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -771,6 +771,16 @@ bx_bool BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.base |= (cpu->ldtr.des_h & 0xff) << 16;
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.base |= (cpu->ldtr.des_h & 0xff000000);
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit = (cpu->ldtr.des_l & 0xffff);
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit |= (cpu->ldtr.des_h & 0x000f0000);
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.g = (cpu->ldtr.des_h >> 23) & 0x01;
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.avl = (cpu->ldtr.des_h >> 20) & 0x01;
|
||||
|
||||
if (BX_CPU_THIS_PTR ldtr.cache.u.ldt.g)
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit_scaled =
|
||||
(BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit << 12) | 0x0fff;
|
||||
else
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit_scaled =
|
||||
(BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit);
|
||||
|
||||
// TR
|
||||
type = (cpu->tr.des_h >> 8) & 0x0f;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: descriptor.h,v 1.15 2006-08-22 19:06:03 sshwarts Exp $
|
||||
// $Id: descriptor.h,v 1.16 2006-08-25 19:56:03 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -147,7 +147,7 @@ union {
|
||||
} taskgate;
|
||||
struct {
|
||||
bx_address base; /* 24 (tss286) or 32/64 (tss386) bit TSS base */
|
||||
Bit32u limit; /* 16 (tss286) or 20 (tss386) bit TSS limit */
|
||||
Bit32u limit; /* 16/32 bit TSS limit */
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
Bit32u limit_scaled; // Same notes as for 'segment' field
|
||||
bx_bool g; /* granularity: 0=byte, 1=4K (page) */
|
||||
@ -155,8 +155,13 @@ union {
|
||||
#endif
|
||||
} tss;
|
||||
struct {
|
||||
bx_address base; /* 286=24 386+ =32/64 bit LDT base */
|
||||
Bit32u limit; /* 286+ =16 bit LDT limit */
|
||||
bx_address base; /* 286=24 386+ = 32/64 bit LDT base */
|
||||
Bit32u limit; /* 286+ = 16/32 bit LDT limit */
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
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 */
|
||||
#endif
|
||||
} ldt;
|
||||
} u;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: init.cc,v 1.118 2006-06-12 16:58:27 sshwarts Exp $
|
||||
// $Id: init.cc,v 1.119 2006-08-25 19:56:03 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -466,7 +466,10 @@ void BX_CPU_C::register_state(void)
|
||||
BXRS_PARAM_SPECIAL16(LDTR, selector, param_save_handler, param_restore_handler);
|
||||
BXRS_HEX_PARAM_FIELD(LDTR, base, ldtr.cache.u.ldt.base);
|
||||
BXRS_HEX_PARAM_FIELD(LDTR, limit, ldtr.cache.u.ldt.limit);
|
||||
BXRS_HEX_PARAM_FIELD(LDTR, limit_scaled, ldtr.cache.u.ldt.limit);
|
||||
BXRS_PARAM_SPECIAL8 (LDTR, ar_byte, param_save_handler, param_restore_handler);
|
||||
BXRS_PARAM_BOOL(LDTR, granularity, ldtr.cache.u.ldt.g);
|
||||
BXRS_PARAM_BOOL(LDTR, avl, ldtr.cache.u.ldt.avl);
|
||||
|
||||
bx_list_c *TR = new bx_list_c (list, "TR", 7);
|
||||
BXRS_PARAM_SPECIAL16(TR, selector, param_save_handler, param_restore_handler);
|
||||
@ -856,9 +859,13 @@ void BX_CPU_C::reset(unsigned source)
|
||||
BX_CPU_THIS_PTR ldtr.cache.dpl = 0; /* field not used */
|
||||
BX_CPU_THIS_PTR ldtr.cache.segment = 0; /* system segment */
|
||||
BX_CPU_THIS_PTR ldtr.cache.type = BX_SYS_SEGMENT_LDT;
|
||||
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.base = 0x00000000;
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit = 0xFFFF;
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.base = 0x00000000;
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit = 0xFFFF;
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
BX_CPU_THIS_PTR tr.cache.u.ldt.limit_scaled = 0xFFFF;
|
||||
BX_CPU_THIS_PTR tr.cache.u.ldt.avl = 0;
|
||||
BX_CPU_THIS_PTR tr.cache.u.ldt.g = 0; /* byte granular */
|
||||
#endif
|
||||
|
||||
/* TR (Task Register) */
|
||||
BX_CPU_THIS_PTR tr.selector.value = 0x0000;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: proc_ctrl.cc,v 1.156 2006-08-11 17:23:36 sshwarts Exp $
|
||||
// $Id: proc_ctrl.cc,v 1.157 2006-08-25 19:56:03 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -1052,8 +1052,8 @@ void BX_CPU_C::LOADALL(bxInstruction_c *i)
|
||||
BX_INFO((" AR byte = %02x", (unsigned) access));
|
||||
BX_PANIC(("loadall: LDTR descriptor cache loaded with non system segment"));
|
||||
}
|
||||
if (BX_CPU_THIS_PTR ldtr.cache.type != 2) {
|
||||
BX_PANIC(("loadall: LDTR.type(%u) != 2", (unsigned) (access & 0x0f)));
|
||||
if (BX_CPU_THIS_PTR ldtr.cache.type != BX_SYS_SEGMENT_LDT) {
|
||||
BX_PANIC(("loadall: LDTR.type(%u) != LDT", (unsigned) (access & 0x0f)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: segment_ctrl_pro.cc,v 1.66 2006-08-22 19:06:03 sshwarts Exp $
|
||||
// $Id: segment_ctrl_pro.cc,v 1.67 2006-08-25 19:56:03 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -429,6 +429,8 @@ BX_CPU_C::get_descriptor_h(const bx_descriptor_t *d)
|
||||
(d->dpl << 13) |
|
||||
(d->p << 15) |
|
||||
(d->u.ldt.limit & 0xf0000) |
|
||||
(d->u.ldt.avl << 20) |
|
||||
(d->u.ldt.g << 23) |
|
||||
(d->u.ldt.base & 0xff000000);
|
||||
return(val);
|
||||
|
||||
@ -461,6 +463,12 @@ BX_CPU_C::get_segment_ar_data(const bx_descriptor_t *d) // used for SMM
|
||||
|
||||
switch (d->type) {
|
||||
case BX_SYS_SEGMENT_LDT:
|
||||
val = (d->type) |
|
||||
(d->dpl << 5) |
|
||||
(d->p << 7) |
|
||||
(d->u.ldt.avl << 12) |
|
||||
(d->u.ldt.g << 15);
|
||||
return(val);
|
||||
case BX_SYS_SEGMENT_AVAIL_286_TSS:
|
||||
case BX_SYS_SEGMENT_BUSY_286_TSS:
|
||||
val = (d->type) |
|
||||
@ -520,8 +528,14 @@ bx_bool BX_CPU_C::set_segment_ar_data(bx_segment_reg_t *seg,
|
||||
switch(d->type) {
|
||||
case BX_SYS_SEGMENT_LDT:
|
||||
d->valid = 1;
|
||||
d->u.ldt.avl = (ar_data >> 12) & 0x01;
|
||||
d->u.ldt.g = (ar_data >> 15) & 0x01;
|
||||
d->u.ldt.base = base;
|
||||
d->u.ldt.limit = limit;
|
||||
if (d->u.ldt.g)
|
||||
d->u.ldt.limit_scaled = (d->u.ldt.limit << 12) | 0x0fff;
|
||||
else
|
||||
d->u.ldt.limit_scaled = (d->u.ldt.limit);
|
||||
break;
|
||||
|
||||
case BX_SYS_SEGMENT_AVAIL_286_TSS:
|
||||
@ -614,6 +628,12 @@ BX_CPU_C::parse_descriptor(Bit32u dword1, Bit32u dword2, bx_descriptor_t *temp)
|
||||
temp->u.ldt.base = (dword1 >> 16) |
|
||||
((dword2 & 0xff) << 16) | (dword2 & 0xff000000);
|
||||
temp->u.ldt.limit = (dword1 & 0x0000ffff) | (dword2 & 0x000f0000);
|
||||
temp->u.ldt.g = (dword2 & 0x00800000) > 0;
|
||||
temp->u.ldt.avl = (dword2 & 0x00100000) > 0;
|
||||
if (temp->u.ldt.g)
|
||||
temp->u.ldt.limit_scaled = (temp->u.ldt.limit << 12) | 0x0fff;
|
||||
else
|
||||
temp->u.ldt.limit_scaled = (temp->u.ldt.limit);
|
||||
temp->valid = 1;
|
||||
break;
|
||||
case BX_286_CALL_GATE:
|
||||
@ -640,7 +660,7 @@ BX_CPU_C::parse_descriptor(Bit32u dword1, Bit32u dword2, bx_descriptor_t *temp)
|
||||
if (temp->u.tss.g)
|
||||
temp->u.tss.limit_scaled = (temp->u.tss.limit << 12) | 0x0fff;
|
||||
else
|
||||
temp->u.tss.limit_scaled = temp->u.tss.limit;
|
||||
temp->u.tss.limit_scaled = (temp->u.tss.limit);
|
||||
temp->valid = 1;
|
||||
break;
|
||||
|
||||
@ -662,28 +682,6 @@ BX_CPU_C::parse_descriptor(Bit32u dword1, Bit32u dword2, bx_descriptor_t *temp)
|
||||
}
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(2)
|
||||
BX_CPU_C::load_ldtr(bx_selector_t *selector, bx_descriptor_t *descriptor)
|
||||
{
|
||||
/* check for null selector, if so invalidate LDTR */
|
||||
if ( (selector->value & 0xfffc)==0 ) {
|
||||
BX_CPU_THIS_PTR ldtr.selector = *selector;
|
||||
BX_CPU_THIS_PTR ldtr.cache.valid = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!descriptor)
|
||||
BX_PANIC(("load_ldtr(): descriptor == NULL !"));
|
||||
|
||||
BX_CPU_THIS_PTR ldtr.cache = *descriptor; /* whole structure copy */
|
||||
BX_CPU_THIS_PTR ldtr.selector = *selector;
|
||||
|
||||
if (BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit < 7)
|
||||
BX_PANIC(("load_ldtr(): ldtr.limit < 7"));
|
||||
|
||||
BX_CPU_THIS_PTR ldtr.cache.valid = 1;
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(3)
|
||||
BX_CPU_C::load_ss(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cpl)
|
||||
{
|
||||
@ -715,7 +713,7 @@ BX_CPU_C::fetch_raw_descriptor(const bx_selector_t *selector,
|
||||
if (selector->ti == 0) { /* GDT */
|
||||
if ((index*8 + 7) > BX_CPU_THIS_PTR gdtr.limit) {
|
||||
BX_ERROR(("fetch_raw_descriptor: GDT: index (%x)%x > limit (%x)",
|
||||
(selector->index*8 + 7), index, BX_CPU_THIS_PTR gdtr.limit));
|
||||
index*8 + 7, index, BX_CPU_THIS_PTR gdtr.limit));
|
||||
exception(exception_no, selector->value & 0xfffc, 0);
|
||||
}
|
||||
bx_address offset = BX_CPU_THIS_PTR gdtr.base + index*8;
|
||||
@ -727,9 +725,9 @@ BX_CPU_C::fetch_raw_descriptor(const bx_selector_t *selector,
|
||||
BX_PANIC(("fetch_raw_descriptor: LDTR.valid=0"));
|
||||
debug(BX_CPU_THIS_PTR prev_eip);
|
||||
}
|
||||
if ((index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit) {
|
||||
if ((index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit_scaled) {
|
||||
BX_ERROR(("fetch_raw_descriptor: LDT: index (%x)%x > limit (%x)",
|
||||
(index*8 + 7), index, BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit));
|
||||
index*8 + 7, index, BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit_scaled));
|
||||
exception(exception_no, selector->value & 0xfffc, 0);
|
||||
}
|
||||
bx_address offset = BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + index*8;
|
||||
@ -756,7 +754,7 @@ BX_CPU_C::fetch_raw_descriptor2(const bx_selector_t *selector, Bit32u *dword1, B
|
||||
BX_PANIC(("fetch_raw_descriptor2: LDTR.valid=0"));
|
||||
return(0);
|
||||
}
|
||||
if ((index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit)
|
||||
if ((index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit_scaled)
|
||||
return(0);
|
||||
bx_address offset = BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + index*8;
|
||||
access_linear(offset, 4, 0, BX_READ, dword1);
|
||||
@ -775,7 +773,7 @@ void BX_CPU_C::fetch_raw_descriptor64(const bx_selector_t *selector,
|
||||
if (selector->ti == 0) { /* GDT */
|
||||
if ((index*8 + 15) > BX_CPU_THIS_PTR gdtr.limit) {
|
||||
BX_ERROR(("fetch_raw_descriptor64: GDT: index (%x)%x > limit (%x)",
|
||||
(index*8 + 15), index, BX_CPU_THIS_PTR gdtr.limit));
|
||||
index*8 + 15, index, BX_CPU_THIS_PTR gdtr.limit));
|
||||
exception(exception_no, selector->value & 0xfffc, 0);
|
||||
}
|
||||
bx_address offset = BX_CPU_THIS_PTR gdtr.base + index*8;
|
||||
@ -789,9 +787,9 @@ void BX_CPU_C::fetch_raw_descriptor64(const bx_selector_t *selector,
|
||||
BX_PANIC(("fetch_raw_descriptor: LDTR.valid=0"));
|
||||
debug(BX_CPU_THIS_PTR prev_eip);
|
||||
}
|
||||
if ((index*8 + 15) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit) {
|
||||
if ((index*8 + 15) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit_scaled) {
|
||||
BX_ERROR(("fetch_raw_descriptor64: LDT: index (%x)%x > limit (%x)",
|
||||
(index*8 + 15), index, BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit));
|
||||
index*8 + 15, index, BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit_scaled));
|
||||
exception(exception_no, selector->value & 0xfffc, 0);
|
||||
}
|
||||
bx_address offset = BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + index*8;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: tasking.cc,v 1.35 2006-06-12 16:58:27 sshwarts Exp $
|
||||
// $Id: tasking.cc,v 1.36 2006-08-25 19:56:03 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -471,6 +471,7 @@ void BX_CPU_C::task_switch(bx_selector_t *tss_selector,
|
||||
// with values only as they are validated.
|
||||
BX_CPU_THIS_PTR ldtr.cache.valid = 0;
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit = 0;
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit_scaled = 0;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid = 0;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 0;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user