some code written to enter CPU to shutdown state.

finally the shutdown handling should be done exactly as in VmWare - the GUI should ask user if the CPU should reset and go to HLT/IF=0 if user choosed to stay in shutdown mode.
CPU configure option reset-on-triple-failt should be extended to shutdown-reset=0|1
small code cleanups and fixes
This commit is contained in:
Stanislav Shwartsman 2006-04-07 20:47:32 +00:00
parent 97520ff814
commit 45f30f0a4c
5 changed files with 88 additions and 65 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: apic.cc,v 1.81 2006-04-05 17:31:29 sshwarts Exp $
// $Id: apic.cc,v 1.82 2006-04-07 20:47:31 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -660,14 +660,12 @@ bx_bool bx_local_apic_c::deliver(Bit8u vector, Bit8u delivery_mode, Bit8u trig_m
break;
case APIC_DM_SMI:
BX_PANIC(("Delivery of SMI still not implemented !"));
cpu->async_event = 1;
cpu->smi_pending = 1;
return 0;
cpu->deliver_SMI();
return 1;
case APIC_DM_NMI:
BX_PANIC(("Delivery of NMI still not implemented !"));
cpu->async_event = 1;
cpu->nmi_pending = 1;
return 0;
cpu->deliver_NMI();
return 1;
case APIC_DM_INIT:
BX_DEBUG(("Deliver INIT IPI"));
init();
@ -682,7 +680,7 @@ bx_bool bx_local_apic_c::deliver(Bit8u vector, Bit8u delivery_mode, Bit8u trig_m
trigger_irq(vector, trig_mode);
break;
default:
break;
return 0;
}
return 1;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.cc,v 1.142 2006-04-05 17:31:29 sshwarts Exp $
// $Id: cpu.cc,v 1.143 2006-04-07 20:47:31 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -858,6 +858,17 @@ void BX_CPU_C::boundaryFetch(Bit8u *fetchPtr, unsigned remainingInPage, bxInstru
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b, Is64BitMode());
}
void BX_CPU_C::deliver_NMI(void)
{
BX_CPU_THIS_PTR nmi_pending = 1;
BX_CPU_THIS_PTR async_event = 1;
}
void BX_CPU_C::deliver_SMI(void)
{
BX_CPU_THIS_PTR smi_pending = 1;
BX_CPU_THIS_PTR async_event = 1;
}
#if BX_EXTERNAL_DEBUGGER
@ -1049,14 +1060,4 @@ void BX_CPU_C::dbg_take_dma(void)
}
}
void BX_CPU_C::dbg_queue_NMI(void)
{
BX_CPU_THIS_PTR nmi_pending = 1;
}
void BX_CPU_C::dbg_queue_SMI(void)
{
BX_CPU_THIS_PTR smi_pending = 1;
}
#endif // #if BX_DEBUGGER

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.277 2006-04-06 18:30:02 sshwarts Exp $
// $Id: cpu.h,v 1.278 2006-04-07 20:47:32 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -2645,8 +2645,6 @@ public: // for now...
// <TAG-CLASS-CPU-END>
#if BX_DEBUGGER
BX_SMF void dbg_queue_NMI(void);
BX_SMF void dbg_queue_SMI(void);
BX_SMF void dbg_take_irq(void);
BX_SMF void dbg_force_interrupt(unsigned vector);
BX_SMF void dbg_take_dma(void);
@ -2871,6 +2869,8 @@ public: // for now...
BX_SMF void decrementESPForPush(unsigned nBytes, Bit32u *eSP);
BX_SMF void sanity_checks(void);
BX_SMF void enter_system_management_mode(void);
BX_SMF void deliver_NMI(void);
BX_SMF void deliver_SMI(void);
BX_SMF void debug(bx_address offset);
#if BX_DISASM
BX_SMF void debug_disasm_instruction(bx_address offset);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: debugstuff.cc,v 1.63 2006-04-05 17:31:30 sshwarts Exp $
// $Id: debugstuff.cc,v 1.64 2006-04-07 20:47:32 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -35,13 +35,14 @@
void BX_CPU_C::debug_disasm_instruction(bx_address offset)
{
bx_bool valid;
Bit32u phy_addr;
bx_phy_address phy_addr;
Bit8u instr_buf[16];
char char_buf[512];
unsigned isize, i=0;
unsigned i=0;
static char letters[20] = "0123456789ABCDEF";
static char letters[] = "0123456789ABCDEF";
static disassembler bx_disassemble;
unsigned remainsInPage = 0x1000 - (offset & 0xfff);
dbg_xlate_linear2phy(BX_CPU_THIS_PTR get_segment_base(BX_SEG_REG_CS) + offset,
&phy_addr, &valid);
@ -50,21 +51,26 @@ void BX_CPU_C::debug_disasm_instruction(bx_address offset)
char_buf[i++] = '>';
char_buf[i++] = '>';
char_buf[i++] = ' ';
isize = bx_disassemble.disasm(
unsigned isize = bx_disassemble.disasm(
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b,
BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64,
BX_CPU_THIS_PTR get_segment_base(BX_SEG_REG_CS), offset,
instr_buf, char_buf+i);
i=strlen(char_buf);
char_buf[i++] = ' ';
char_buf[i++] = ':';
char_buf[i++] = ' ';
for (unsigned j=0; j<isize; j++) {
char_buf[i++] = letters[(instr_buf[j] >> 4) & 0xf];
char_buf[i++] = letters[(instr_buf[j] >> 0) & 0xf];
if (isize <= remainsInPage) {
i=strlen(char_buf);
char_buf[i++] = ' ';
char_buf[i++] = ':';
char_buf[i++] = ' ';
for (unsigned j=0; j<isize; j++) {
char_buf[i++] = letters[(instr_buf[j] >> 4) & 0xf];
char_buf[i++] = letters[(instr_buf[j] >> 0) & 0xf];
}
char_buf[i] = 0;
BX_INFO(("%s", char_buf));
}
else {
BX_INFO(("(instruction unavailable) page split instruction"));
}
char_buf[i] = 0;
BX_INFO(("%s", char_buf));
}
else {
BX_INFO(("(instruction unavailable) page not present"));
@ -896,6 +902,12 @@ bx_bool BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
BX_CPU_THIS_PTR tr.cache.u.tss386.limit |= (cpu->tr.des_h & 0x000f0000);
BX_CPU_THIS_PTR tr.cache.u.tss386.g = (cpu->tr.des_h >> 23) & 0x01;
BX_CPU_THIS_PTR tr.cache.u.tss386.avl = (cpu->tr.des_h >> 20) & 0x01;
if (temp->u.tss386.g)
BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled =
(BX_CPU_THIS_PTR tr.cache.u.tss386.limit << 12) | 0x0fff;
else
BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled =
(BX_CPU_THIS_PTR tr.cache.u.tss386.limit);
}
// GDTR

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: proc_ctrl.cc,v 1.144 2006-04-05 17:31:32 sshwarts Exp $
// $Id: proc_ctrl.cc,v 1.145 2006-04-07 20:47:32 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -59,9 +59,33 @@ void BX_CPU_C::PREFETCH(bxInstruction_c *i)
#endif
}
//
// The shutdown state is very similar to the state following the exection
// if HLT instruction. In this mode the processor stops executing
// instructions until #NMI, #SMI, #RESET or #INIT is received. If
// shutdown occurs why in NMI interrupt handler or in SMM, a hardware
// reset must be used to restart the processor execution.
//
void BX_CPU_C::shutdown(void)
{
BX_PANIC(("Entering to shutdown state still not implemented"));
BX_CPU_THIS_PTR clear_IF();
// artificial trap bit, why use another variable.
BX_CPU_THIS_PTR debug_trap |= 0x80000000; // artificial trap
BX_CPU_THIS_PTR async_event = 1; // so processor knows to check
// Execution of this instruction completes. The processor
// will remain in a halt state until one of the above conditions
// is met.
BX_INSTR_HLT(BX_CPU_ID);
#if BX_USE_IDLE_HACK
bx_gui->sim_is_idle ();
#endif /* BX_USE_IDLE_HACK */
longjmp(BX_CPU_THIS_PTR jmp_buf_env, 1); // go back to main decode loop
}
void BX_CPU_C::HLT(bxInstruction_c *i)
@ -75,7 +99,7 @@ void BX_CPU_C::HLT(bxInstruction_c *i)
return;
}
if (! BX_CPU_THIS_PTR get_IF ()) {
if (! BX_CPU_THIS_PTR get_IF()) {
BX_INFO(("WARNING: HLT instruction with IF=0!"));
}
@ -941,18 +965,14 @@ void BX_CPU_C::LOADALL(bxInstruction_c *i)
BX_CPU_THIS_PTR cr0.em = (msw & 0x01); msw >>= 1;
BX_CPU_THIS_PTR cr0.ts = (msw & 0x01);
//BX_INFO(("LOADALL: pe=%u, mp=%u, em=%u, ts=%u",
// (unsigned) BX_CPU_THIS_PTR cr0.pe, (unsigned) BX_CPU_THIS_PTR cr0.mp,
// (unsigned) BX_CPU_THIS_PTR cr0.em, (unsigned) BX_CPU_THIS_PTR cr0.ts));
if (BX_CPU_THIS_PTR cr0.pe || BX_CPU_THIS_PTR cr0.mp || BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts)
BX_PANIC(("LOADALL set PE, MP, EM or TS bits in MSW!"));
/* TR */
BX_CPU_THIS_PTR mem->readPhysicalPage(BX_CPU_THIS, 0x816, 2, &tr);
BX_CPU_THIS_PTR tr.selector.value = tr;
BX_CPU_THIS_PTR tr.selector.rpl = (tr & 0x03); tr >>= 2;
BX_CPU_THIS_PTR tr.selector.ti = (tr & 0x01); tr >>= 1;
BX_CPU_THIS_PTR tr.selector.rpl = (tr & 0x03); tr >>= 2;
BX_CPU_THIS_PTR tr.selector.ti = (tr & 0x01); tr >>= 1;
BX_CPU_THIS_PTR tr.selector.index = tr;
BX_CPU_THIS_PTR mem->readPhysicalPage(BX_CPU_THIS, 0x860, 2, &base_15_0);
BX_CPU_THIS_PTR mem->readPhysicalPage(BX_CPU_THIS, 0x862, 1, &base_23_16);
@ -971,26 +991,21 @@ void BX_CPU_C::LOADALL(bxInstruction_c *i)
if ((BX_CPU_THIS_PTR tr.selector.value & 0xfffc) == 0) {
BX_CPU_THIS_PTR tr.cache.valid = 0;
}
if (BX_CPU_THIS_PTR tr.cache.valid == 0) {
}
if (BX_CPU_THIS_PTR tr.cache.u.tss286.limit < 43) {
BX_CPU_THIS_PTR tr.cache.valid = 0;
}
if (BX_CPU_THIS_PTR tr.cache.type != 1) {
BX_CPU_THIS_PTR tr.cache.valid = 0;
}
if (BX_CPU_THIS_PTR tr.cache.segment) {
if (BX_CPU_THIS_PTR tr.cache.u.tss286.limit < 43 ||
BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_AVAIL_286_TSS ||
BX_CPU_THIS_PTR tr.cache.segment)
{
BX_CPU_THIS_PTR tr.cache.valid = 0;
}
if (BX_CPU_THIS_PTR tr.cache.valid==0)
{
BX_CPU_THIS_PTR tr.cache.u.tss286.base = 0;
BX_CPU_THIS_PTR tr.cache.u.tss286.limit = 0;
BX_CPU_THIS_PTR tr.cache.p = 0;
BX_CPU_THIS_PTR tr.selector.value = 0;
BX_CPU_THIS_PTR tr.selector.index = 0;
BX_CPU_THIS_PTR tr.selector.ti = 0;
BX_CPU_THIS_PTR tr.selector.rpl = 0;
BX_CPU_THIS_PTR tr.selector.value = 0;
BX_CPU_THIS_PTR tr.selector.index = 0;
BX_CPU_THIS_PTR tr.selector.ti = 0;
BX_CPU_THIS_PTR tr.selector.rpl = 0;
BX_CPU_THIS_PTR tr.cache.u.tss286.base = 0;
BX_CPU_THIS_PTR tr.cache.u.tss286.limit = 0;
BX_CPU_THIS_PTR tr.cache.p = 0;
}
/* FLAGS */
@ -1004,8 +1019,8 @@ void BX_CPU_C::LOADALL(bxInstruction_c *i)
/* LDTR */
BX_CPU_THIS_PTR mem->readPhysicalPage(BX_CPU_THIS, 0x81c, 2, &ldtr);
BX_CPU_THIS_PTR ldtr.selector.value = ldtr;
BX_CPU_THIS_PTR ldtr.selector.rpl = (ldtr & 0x03); ldtr >>= 2;
BX_CPU_THIS_PTR ldtr.selector.ti = (ldtr & 0x01); ldtr >>= 1;
BX_CPU_THIS_PTR ldtr.selector.rpl = (ldtr & 0x03); ldtr >>= 2;
BX_CPU_THIS_PTR ldtr.selector.ti = (ldtr & 0x01); ldtr >>= 1;
BX_CPU_THIS_PTR ldtr.selector.index = ldtr;
if ((BX_CPU_THIS_PTR ldtr.selector.value & 0xfffc) == 0)
{
@ -1111,9 +1126,6 @@ void BX_CPU_C::LOADALL(bxInstruction_c *i)
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = cs_raw;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = (cs_raw & 0x03); cs_raw >>= 2;
//BX_INFO(("LOADALL: setting cs.selector.rpl to %u",
// (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl));
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti = (cs_raw & 0x01); cs_raw >>= 1;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = cs_raw;
BX_CPU_THIS_PTR mem->readPhysicalPage(BX_CPU_THIS, 0x83c, 2, &base_15_0);