From b968c4e5c80dafa2ee0b892db0ec75b83cc140fb Mon Sep 17 00:00:00 2001 From: Peter Tattam Date: Tue, 8 Oct 2002 14:43:18 +0000 Subject: [PATCH] Latest round of patches/fixups to get 64 bit emulation further. This is an interim update to allow others to test. We have userland code running!!! (up to a point) Able to start executing "sash" as /sbin/init in userland from linux 64 bit kernel until it crashes trying to access a null pointer. No kernel panics though, just a segfault loop. --- bochs/cpu/cpu.h | 5 ++++- bochs/cpu/exception.cc | 5 ++++- bochs/cpu/fetchdecode64.cc | 12 ++++++------ bochs/cpu/paging.cc | 16 +++++++++++++++- bochs/cpu/proc_ctrl.cc | 16 ++++++++++++++-- bochs/cpu/protect_ctrl.cc | 24 ++++++++++++------------ bochs/cpu/tasking.cc | 4 ++-- 7 files changed, 57 insertions(+), 25 deletions(-) diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index 1dfb4cf5e..47eb095a2 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: cpu.h,v 1.100 2002-10-07 22:51:57 kevinlawton Exp $ +// $Id: cpu.h,v 1.101 2002-10-08 14:43:18 ptrumpet Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -2294,6 +2294,9 @@ union { BX_SMF void JCXZ64_Jb(bxInstruction_c *); #endif // #if BX_SUPPORT_X86_64 + BX_SMF void FXSAVE(bxInstruction_c *i); + BX_SMF void FXRSTOR(bxInstruction_c *i); + // mch added BX_SMF void INVLPG(bxInstruction_c *); BX_SMF void wait_for_interrupt(); diff --git a/bochs/cpu/exception.cc b/bochs/cpu/exception.cc index a8761a247..7b1032375 100644 --- a/bochs/cpu/exception.cc +++ b/bochs/cpu/exception.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: exception.cc,v 1.27 2002-10-06 22:08:18 kevinlawton Exp $ +// $Id: exception.cc,v 1.28 2002-10-08 14:43:18 ptrumpet Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -238,6 +238,9 @@ BX_CPU_THIS_PTR save_esp = ESP; // load new CS:IP values from gate // set CPL to new code segment DPL + + CPL = cs_descriptor.dpl; + // set RPL of CS to CPL // push long pointer to old stack onto new stack diff --git a/bochs/cpu/fetchdecode64.cc b/bochs/cpu/fetchdecode64.cc index f5adaebd5..88a7220f2 100644 --- a/bochs/cpu/fetchdecode64.cc +++ b/bochs/cpu/fetchdecode64.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: fetchdecode64.cc,v 1.22 2002-10-04 17:04:32 kevinlawton Exp $ +// $Id: fetchdecode64.cc,v 1.23 2002-10-08 14:43:18 ptrumpet Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -509,8 +509,8 @@ static BxOpcodeInfo_t BxOpcodeInfo64G9[8] = { }; static BxOpcodeInfo_t BxOpcodeInfo64G15[8] = { - /* 0 */ { 0, &BX_CPU_C::BxError }, - /* 1 */ { 0, &BX_CPU_C::BxError }, + /* 0 */ { 0, &BX_CPU_C::FXSAVE }, + /* 1 */ { 0, &BX_CPU_C::FXRSTOR }, /* 2 */ { 0, &BX_CPU_C::BxError }, /* 3 */ { 0, &BX_CPU_C::BxError }, /* 4 */ { 0, &BX_CPU_C::BxError }, @@ -1055,7 +1055,7 @@ static BxOpcodeInfo_t BxOpcodeInfo64[512*3] = { /* 0F E4 */ { 0, &BX_CPU_C::BxError }, /* 0F E5 */ { BxAnotherMMX, &BX_CPU_C::PMULHW_PqQq }, /* MMX */ /* 0F E6 */ { 0, &BX_CPU_C::BxError }, - /* 0F E7 */ { 0, &BX_CPU_C::BxError }, + /* 0F E7 */ { BxAnother, &BX_CPU_C::NOP }, // MOVNTQ /* 0F E8 */ { BxAnotherMMX, &BX_CPU_C::PSUBSB_PqQq }, /* MMX */ /* 0F E9 */ { BxAnotherMMX, &BX_CPU_C::PSUBSW_PqQq }, /* MMX */ /* 0F EA */ { 0, &BX_CPU_C::BxError }, @@ -1577,7 +1577,7 @@ static BxOpcodeInfo_t BxOpcodeInfo64[512*3] = { /* 0F E4 */ { 0, &BX_CPU_C::BxError }, /* 0F E5 */ { BxAnotherMMX, &BX_CPU_C::PMULHW_PqQq }, /* MMX */ /* 0F E6 */ { 0, &BX_CPU_C::BxError }, - /* 0F E7 */ { 0, &BX_CPU_C::BxError }, + /* 0F E7 */ { BxAnother, &BX_CPU_C::NOP }, // MOVNTQ /* 0F E8 */ { BxAnotherMMX, &BX_CPU_C::PSUBSB_PqQq }, /* MMX */ /* 0F E9 */ { BxAnotherMMX, &BX_CPU_C::PSUBSW_PqQq }, /* MMX */ /* 0F EA */ { 0, &BX_CPU_C::BxError }, @@ -2098,7 +2098,7 @@ static BxOpcodeInfo_t BxOpcodeInfo64[512*3] = { /* 0F E4 */ { 0, &BX_CPU_C::BxError }, /* 0F E5 */ { BxAnotherMMX, &BX_CPU_C::PMULHW_PqQq }, /* MMX */ /* 0F E6 */ { 0, &BX_CPU_C::BxError }, - /* 0F E7 */ { 0, &BX_CPU_C::BxError }, + /* 0F E7 */ { BxAnother, &BX_CPU_C::NOP }, // MOVNTQ /* 0F E8 */ { BxAnotherMMX, &BX_CPU_C::PSUBSB_PqQq }, /* MMX */ /* 0F E9 */ { BxAnotherMMX, &BX_CPU_C::PSUBSW_PqQq }, /* MMX */ /* 0F EA */ { 0, &BX_CPU_C::BxError }, diff --git a/bochs/cpu/paging.cc b/bochs/cpu/paging.cc index 7982a622a..32cefa4f5 100644 --- a/bochs/cpu/paging.cc +++ b/bochs/cpu/paging.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: paging.cc,v 1.32 2002-10-03 04:53:53 bdenney Exp $ +// $Id: paging.cc,v 1.33 2002-10-08 14:43:18 ptrumpet Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -524,6 +524,17 @@ BX_CPU_C::INVLPG(bxInstruction_c* i) // Operand must not be a register if (i->modC0()) { + +#if BX_SUPPORT_X86_64 + if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) { +#warning PRT: check this is right. instruction is "0F 01 F8" see AMD manual. + if ((i->rm() == 0) && (i->nnn() == 7)) { + BX_CPU_THIS_PTR SWAPGS(i); + return; + } + } +#endif + BX_INFO(("INVLPG: op is a register")); UndefinedOpcode(i); } @@ -964,6 +975,9 @@ page_fault_not_present: BX_CPU_THIS_PTR cr2 = laddr; // Invalidate TLB entry. BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf = BX_INVALID_TLB_ENTRY; +#if BX_EXTERNAL_DEBUGGER + printf("page fault for address %08x%08x\n",(Bit32u)(laddr >> 32),(Bit32u)(laddr & 0xffffffff)); +#endif exception(BX_PF_EXCEPTION, error_code, 0); return(0); // keep compiler happy } diff --git a/bochs/cpu/proc_ctrl.cc b/bochs/cpu/proc_ctrl.cc index ba14c7f3c..c6aa2ef67 100644 --- a/bochs/cpu/proc_ctrl.cc +++ b/bochs/cpu/proc_ctrl.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: proc_ctrl.cc,v 1.55 2002-10-04 17:04:33 kevinlawton Exp $ +// $Id: proc_ctrl.cc,v 1.56 2002-10-08 14:43:18 ptrumpet Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -1919,7 +1919,7 @@ BX_CPU_C::SWAPGS(bxInstruction_c *i) } temp_GS_base = MSR_GSBASE; MSR_GSBASE = MSR_KERNELGSBASE; - MSR_KERNELGSBASE = MSR_GSBASE; + MSR_KERNELGSBASE = temp_GS_base; } #endif @@ -2019,3 +2019,15 @@ BX_CPU_C::hwdebug_compare(Bit32u laddr_0, unsigned size, return(0); } #endif + + + void +BX_CPU_C::FXSAVE(bxInstruction_c *i) +{ + BX_ERROR(("FXSAVE is only a stub.")); +} + void +BX_CPU_C::FXRSTOR(bxInstruction_c *i) +{ + BX_ERROR(("FXRSTOR is only a stub.")); +} diff --git a/bochs/cpu/protect_ctrl.cc b/bochs/cpu/protect_ctrl.cc index 49b90b4f4..02ddfb11a 100644 --- a/bochs/cpu/protect_ctrl.cc +++ b/bochs/cpu/protect_ctrl.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: protect_ctrl.cc,v 1.16 2002-09-25 14:09:08 ptrumpet Exp $ +// $Id: protect_ctrl.cc,v 1.17 2002-10-08 14:43:18 ptrumpet Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -459,7 +459,7 @@ BX_CPU_C::LTR_Ew(bxInstruction_c *i) bx_descriptor_t descriptor; bx_selector_t selector; Bit16u raw_selector; - Bit32u dword1, dword2; + Bit32u dword1, dword2, dword3; /* #GP(0) if the current privilege level is not 0 */ @@ -499,6 +499,16 @@ BX_CPU_C::LTR_Ew(bxInstruction_c *i) parse_descriptor(dword1, dword2, &descriptor); +#if BX_SUPPORT_X86_64 + if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) { + // set upper 32 bits of tss base + access_linear(BX_CPU_THIS_PTR gdtr.base + selector.index*8 + 8, 4, 0, + BX_READ, &dword3); + descriptor.u.tss386.base |= ((Bit64u)dword3 << 32); + } +#endif + + /* #GP(selector) if object is not a TSS or is already busy */ if ( (descriptor.valid==0) || descriptor.segment || (descriptor.type!=1 && descriptor.type!=9) ) { @@ -730,16 +740,6 @@ BX_CPU_C::SGDT_Ms(bxInstruction_c *i) /* op1 is a register or memory reference */ if (i->modC0()) { -#if BX_SUPPORT_X86_64 - if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) { -#warning PRT: check this is right. instruction is "0F 01 F8" see AMD manual. - if ((i->rm() == 0) && (i->nnn() == 7)) { - BX_CPU_THIS_PTR SWAPGS(i); - return; - } - } -#endif - /* undefined opcode exception */ BX_PANIC(("SGDT_Ms: use of register is undefined opcode.")); UndefinedOpcode(i); diff --git a/bochs/cpu/tasking.cc b/bochs/cpu/tasking.cc index 1bbbf249a..18031ccc8 100644 --- a/bochs/cpu/tasking.cc +++ b/bochs/cpu/tasking.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: tasking.cc,v 1.15 2002-09-28 00:54:05 kevinlawton Exp $ +// $Id: tasking.cc,v 1.16 2002-10-08 14:43:18 ptrumpet Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -984,7 +984,7 @@ BX_CPU_C::get_RSP_from_TSS(unsigned pl, Bit64u *rsp) BX_PANIC(("get_RSP_from_TSS: TR.cache invalid")); // 32-bit TSS - Bit32u TSSstackaddr, save_upper; + Bit32u TSSstackaddr; TSSstackaddr = 8*pl + 4; if ( (TSSstackaddr+7) >