03cd6fa9ad
Mon, 25 Mar 2002 11:47:38 +0200 (SAST) which should correct the compile problems when apic is disabled.
373 lines
9.8 KiB
Plaintext
373 lines
9.8 KiB
Plaintext
Zwane sent another version to the list at
|
|
Mon, 25 Mar 2002 11:47:38 +0200 (SAST)
|
|
which should correct the compile problems when apic is disabled.
|
|
|
|
Updated so that it applies cleanly in cvs as of March 25. -Bryce
|
|
|
|
Notes by Bryce:
|
|
- normal configuration: one CPU and no APIC
|
|
FIXME: does not compile!
|
|
- normal SMP configuration: >1 CPU and APIC
|
|
compiles and works better than before. wli, mwane, bryce have been testing
|
|
in this config.
|
|
- test with one CPU and APIC
|
|
compiles ok
|
|
- test with BX_CPU_LEVEL<5: does it still compile?
|
|
tried --enable-cpu-level=4. compiles ok
|
|
|
|
compile warning:
|
|
proc_ctrl.cc: In method `void bx_cpu_c::WRMSR(struct BxInstruction_t *)':
|
|
proc_ctrl.cc:1273: warning: left shift count >= width of type
|
|
|
|
|
|
-----------------
|
|
I've managed to boot linux 2.2.21-pre1 with this patch, i was having
|
|
problems before when it tried to enable the APIC via the MSR registers.
|
|
Now i just need to fix the TSC skew problems (i managed to workaround it
|
|
by doing the fixups in the linux kernel, but gonna do it via Bochs this
|
|
time).
|
|
|
|
Cheers,
|
|
Zwane Mwaikambo
|
|
|
|
PS this is just the infrastructure, i haven't done all the registers, most
|
|
notably the MTRR stuff.
|
|
|
|
diff -ur /tmp/bochs-1.4.pre2/cpu/apic.cc bochs-1.4.pre2/cpu/apic.cc
|
|
--- /tmp/bochs-1.4.pre2/cpu/apic.cc Wed Oct 3 15:10:38 2001
|
|
+++ bochs-1.4.pre2/cpu/apic.cc Mon Mar 25 12:06:48 2002
|
|
@@ -27,6 +27,14 @@
|
|
{
|
|
}
|
|
|
|
+void bx_local_apic_c::update_msr_apicbase(Bit32u newbase)
|
|
+{
|
|
+ Bit64u val64;
|
|
+ val64 = newbase << 12; /* push the APIC base address to bits 12:35 */
|
|
+ val64 += cpu->msr.apicbase & 0x0900; /* don't modify other apicbase or reserved bits */
|
|
+ cpu->msr.apicbase = val64;
|
|
+}
|
|
+
|
|
void bx_generic_apic_c::set_base (Bit32u newbase)
|
|
{
|
|
BX_INFO(("relocate APIC id=%d to %8x", id, newbase));
|
|
@@ -247,7 +255,8 @@
|
|
BX_INFO(("local apic in %s initializing",
|
|
(cpu && cpu->name) ? cpu->name : "?"));
|
|
// default address for a local APIC, can be moved
|
|
- base_addr = 0xfee00000;
|
|
+ base_addr = APIC_BASE_ADDR;
|
|
+ update_msr_apicbase(base_addr);
|
|
err_status = 0;
|
|
log_dest = 0;
|
|
dest_format = 0xff;
|
|
diff -ur /tmp/bochs-1.4.pre2/cpu/cpu.h bochs-1.4.pre2/cpu/cpu.h
|
|
--- /tmp/bochs-1.4.pre2/cpu/cpu.h Wed Oct 3 21:53:48 2001
|
|
+++ bochs-1.4.pre2/cpu/cpu.h Mon Mar 25 12:08:32 2002
|
|
@@ -195,9 +195,43 @@
|
|
#define BX_MF_EXCEPTION 16
|
|
#define BX_AC_EXCEPTION 17
|
|
|
|
-
|
|
-
|
|
-
|
|
+/* MSR registers */
|
|
+#define BX_MSR_P5_MC_ADDR 0x0000
|
|
+#define BX_MSR_MC_TYPE 0x0001
|
|
+#define BX_MSR_TSC 0x0010
|
|
+#define BX_MSR_CESR 0x0011
|
|
+#define BX_MSR_CTR0 0x0012
|
|
+#define BX_MSR_CTR1 0x0013
|
|
+#define BX_MSR_APICBASE 0x001b
|
|
+#define BX_MSR_EBL_CR_POWERON 0x002a
|
|
+#define BX_MSR_TEST_CTL 0x0033
|
|
+#define BX_MSR_BIOS_UPDT_TRIG 0x0079
|
|
+#define BX_MSR_BBL_CR_D0 0x0088
|
|
+#define BX_MSR_BBL_CR_D1 0x0089
|
|
+#define BX_MSR_BBL_CR_D2 0x008a
|
|
+#define BX_MSR_BBL_CR_D3 0x008b /* = BIOS_SIGN */
|
|
+#define BX_MSR_PERFCTR0 0x00c1
|
|
+#define BX_MSR_PERFCTR1 0x00c2
|
|
+#define BX_MSR_MTRRCAP 0x00fe
|
|
+#define BX_MSR_BBL_CR_ADDR 0x0116
|
|
+#define BX_MSR_BBL_DECC 0x0118
|
|
+#define BX_MSR_BBL_CR_CTL 0x0119
|
|
+#define BX_MSR_BBL_CR_TRIG 0x011a
|
|
+#define BX_MSR_BBL_CR_BUSY 0x011b
|
|
+#define BX_MSR_BBL_CR_CTL3 0x011e
|
|
+#define BX_MSR_MCG_CAP 0x0179
|
|
+#define BX_MSR_MCG_STATUS 0x017a
|
|
+#define BX_MSR_MCG_CTL 0x017b
|
|
+#define BX_MSR_EVNTSEL0 0x0186
|
|
+#define BX_MSR_EVNTSEL1 0x0187
|
|
+#define BX_MSR_DEBUGCTLMSR 0x01d9
|
|
+#define BX_MSR_LASTBRANCHFROMIP 0x01db
|
|
+#define BX_MSR_LASTBRANCHTOIP 0x01dc
|
|
+#define BX_MSR_LASTINTOIP 0x01dd
|
|
+#define BX_MSR_ROB_CR_BKUPTMPDR6 0x01e0
|
|
+#define BX_MSR_MTRRPHYSBASE0 0x0200
|
|
+#define BX_MSR_MTRRPHYSMASK0 0x0201
|
|
+#define BX_MSR_MTRRPHYSBASE1 0x0202
|
|
|
|
typedef struct {
|
|
/* 31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16
|
|
@@ -286,6 +320,18 @@
|
|
} bx_cr0_t;
|
|
#endif
|
|
|
|
+#if BX_CPU_LEVEL >= 5
|
|
+typedef struct {
|
|
+ Bit8u p5_mc_addr;
|
|
+ Bit8u p5_mc_type;
|
|
+ Bit8u tsc;
|
|
+ Bit8u cesr;
|
|
+ Bit8u ctr0;
|
|
+ Bit8u ctr1;
|
|
+ Bit64u apicbase;
|
|
+ /* TODO finish of the others */
|
|
+ } bx_regs_msr_t;
|
|
+#endif
|
|
|
|
typedef struct { /* bx_selector_t */
|
|
Bit16u value; /* the 16bit value of the selector */
|
|
@@ -521,6 +567,8 @@
|
|
APIC_TYPE_LOCAL_APIC
|
|
} bx_apic_type_t;
|
|
|
|
+#define APIC_BASE_ADDR 0xfee00000 // default APIC address
|
|
+
|
|
#if BX_SUPPORT_APIC
|
|
class bx_generic_apic_c : public logfunctions {
|
|
protected:
|
|
@@ -577,7 +625,6 @@
|
|
Bit32u timer_initial, timer_current, timer_divconf;
|
|
Boolean timer_active; // internal state, not accessible from bus
|
|
Bit32u timer_divide_counter, timer_divide_factor;
|
|
- Bit32u apic_base_msr;
|
|
Bit32u icr_high, icr_low;
|
|
Bit32u err_status;
|
|
#define APIC_ERR_ILLEGAL_ADDR 0x80
|
|
@@ -616,6 +663,7 @@
|
|
Bit8u get_apr ();
|
|
void periodic (Bit32u usec_delta);
|
|
void set_divide_configuration (Bit32u value);
|
|
+ virtual void update_msr_apicbase(Bit32u newaddr);
|
|
};
|
|
|
|
#define APIC_MAX_ID 16
|
|
@@ -753,6 +801,10 @@
|
|
Bit32u cr4;
|
|
#endif
|
|
|
|
+#if BX_CPU_LEVEL >= 5
|
|
+ bx_regs_msr_t msr;
|
|
+#endif
|
|
+
|
|
// pointer to the address space that this processor uses.
|
|
BX_MEM_C *mem;
|
|
|
|
@@ -765,6 +817,8 @@
|
|
volatile Boolean async_event;
|
|
volatile Boolean INTR;
|
|
|
|
+ /* wether this CPU is the BSP always set for UP */
|
|
+ Boolean bsp;
|
|
// for accessing registers by index number
|
|
Bit16u *_16bit_base_reg[8];
|
|
Bit16u *_16bit_index_reg[8];
|
|
diff -ur /tmp/bochs-1.4.pre2/cpu/init.cc bochs-1.4.pre2/cpu/init.cc
|
|
--- /tmp/bochs-1.4.pre2/cpu/init.cc Wed Oct 3 15:10:38 2001
|
|
+++ bochs-1.4.pre2/cpu/init.cc Mon Mar 25 12:06:48 2002
|
|
@@ -554,7 +554,11 @@
|
|
BX_CPU_THIS_PTR cr4 = 0;
|
|
#endif
|
|
|
|
-
|
|
+/* initialise MSR registers to defaults */
|
|
+#if BX_CPU_LEVEL >= 5
|
|
+ /* APIC Address, APIC enabled and BSP is default, we'll fill in the rest later */
|
|
+ BX_CPU_THIS_PTR msr.apicbase = (APIC_BASE_ADDR << 12) + 0x900;
|
|
+#endif
|
|
|
|
BX_CPU_THIS_PTR EXT = 0;
|
|
//BX_INTR = 0;
|
|
@@ -593,9 +597,13 @@
|
|
if (BX_BOOTSTRAP_PROCESSOR == apic_id)
|
|
{
|
|
// boot normally
|
|
+ BX_CPU_THIS_PTR bsp = 1;
|
|
+ BX_CPU_THIS_PTR msr.apicbase |= 0x0100; /* set bit 8 BSP */
|
|
BX_INFO(("CPU[%d] is the bootstrap processor", apic_id));
|
|
} else {
|
|
// it's an application processor, halt until IPI is heard.
|
|
+ BX_CPU_THIS_PTR bsp = 0;
|
|
+ BX_CPU_THIS_PTR msr.apicbase &= ~0x0100; /* clear bit 8 BSP */
|
|
BX_INFO(("CPU[%d] is an application processor. Halting until IPI.", apic_id));
|
|
debug_trap |= 0x80000000;
|
|
async_event = 1;
|
|
diff -ur /tmp/bochs-1.4.pre2/cpu/proc_ctrl.cc bochs-1.4.pre2/cpu/proc_ctrl.cc
|
|
--- /tmp/bochs-1.4.pre2/cpu/proc_ctrl.cc Sun Nov 18 18:32:40 2001
|
|
+++ bochs-1.4.pre2/cpu/proc_ctrl.cc Mon Mar 25 12:06:48 2002
|
|
@@ -1147,23 +1147,143 @@
|
|
BX_CPU_C::RDMSR(BxInstruction_t *i)
|
|
{
|
|
#if BX_CPU_LEVEL >= 5
|
|
- BX_ERROR(("RDMSR: not implemented yet"));
|
|
- UndefinedOpcode(i);
|
|
+ invalidate_prefetch_q();
|
|
+
|
|
+ if (v8086_mode()) {
|
|
+ BX_INFO(("RDMSR: Invalid whilst in virtual 8086 mode"));
|
|
+ goto do_exception;
|
|
+ }
|
|
+
|
|
+ if (CPL!= 0) {
|
|
+ BX_INFO(("RDMSR: CPL!= 0"));
|
|
+ goto do_exception;
|
|
+ }
|
|
+
|
|
+ /* We have the requested MSR register in ECX */
|
|
+ switch(ECX) {
|
|
+#if BX_CPU_LEVEL == 5
|
|
+ /* The following registers are defined for Pentium only */
|
|
+ case BX_MSR_P5_MC_ADDR:
|
|
+ case BX_MSR_MC_TYPE:
|
|
+ /* TODO */
|
|
+ return;
|
|
+
|
|
+ case BX_MSR_TSC:
|
|
+ RDTSC(i);
|
|
+ return;
|
|
+
|
|
+ case BX_MSR_CESR:
|
|
+ /* TODO */
|
|
+ return;
|
|
#else
|
|
- UndefinedOpcode(i);
|
|
-#endif
|
|
+ /* These are noops on i686... */
|
|
+ case BX_MSR_P5_MC_ADDR:
|
|
+ case BX_MSR_MC_TYPE:
|
|
+ /* do nothing */
|
|
+ return;
|
|
+
|
|
+ case BX_MSR_TSC:
|
|
+ RDTSC(i);
|
|
+ return;
|
|
+
|
|
+ /* ... And these cause an exception on i686 */
|
|
+ case BX_MSR_CESR:
|
|
+ case BX_MSR_CTR0:
|
|
+ case BX_MSR_CTR1:
|
|
+ goto do_exception;
|
|
+#endif /* BX_CPU_LEVEL == 5 */
|
|
+
|
|
+ /* MSR_APICBASE
|
|
+ 0:7 Reserved
|
|
+ 8 This is set if its the BSP
|
|
+ 9:10 Reserved
|
|
+ 11 APIC Global Enable bit (1=enabled 0=disabled)
|
|
+ 12:35 APIC Base Address
|
|
+ 36:63 Reserved
|
|
+ */
|
|
+ case BX_MSR_APICBASE:
|
|
+ /* we return low 32 bits in EAX, and high in EDX */
|
|
+ EAX = BX_CPU_THIS_PTR msr.apicbase & 0xff;
|
|
+ EDX = BX_CPU_THIS_PTR msr.apicbase >> 32;
|
|
+ BX_INFO(("RDMSR: Read %08x:%08x from MSR_APICBASE", EDX, EAX));
|
|
+ return;
|
|
+
|
|
+ default:
|
|
+ BX_INFO(("RDMSR: Unknown register!"));
|
|
+ goto do_exception;
|
|
+
|
|
+ }
|
|
+#endif /* BX_CPU_LEVEL >= 5 */
|
|
+
|
|
+do_exception:
|
|
+ exception(BX_GP_EXCEPTION, 0, 0);
|
|
}
|
|
|
|
void
|
|
BX_CPU_C::WRMSR(BxInstruction_t *i)
|
|
{
|
|
#if BX_CPU_LEVEL >= 5
|
|
- invalidate_prefetch_q();
|
|
+ invalidate_prefetch_q();
|
|
|
|
- BX_PANIC(( "WRMSR: not implemented yet"));
|
|
+ if (v8086_mode()) {
|
|
+ BX_INFO(("WRMSR: Invalid whilst in virtual 8086 mode"));
|
|
+ goto do_exception;
|
|
+ }
|
|
+
|
|
+ if (CPL!= 0) {
|
|
+ BX_INFO(("WDMSR: CPL!= 0"));
|
|
+ goto do_exception;
|
|
+ }
|
|
+
|
|
+ /* ECX has the MSR to write to */
|
|
+ switch(ECX) {
|
|
+#if BX_CPU_LEVEL == 5
|
|
+ /* The following registers are defined for Pentium only */
|
|
+ case BX_MSR_P5_MC_ADDR:
|
|
+ case BX_MSR_MC_TYPE:
|
|
+ case BX_MSR_TSC:
|
|
+ case BX_MSR_CESR:
|
|
+ /* TODO */
|
|
+ return;
|
|
#else
|
|
- UndefinedOpcode(i);
|
|
-#endif
|
|
+ /* These are noops on i686... */
|
|
+ case BX_MSR_P5_MC_ADDR:
|
|
+ case BX_MSR_MC_TYPE:
|
|
+ case BX_MSR_TSC:
|
|
+ /* do nothing */
|
|
+ return;
|
|
+
|
|
+ /* ... And these cause an exception on i686 */
|
|
+ case BX_MSR_CESR:
|
|
+ case BX_MSR_CTR0:
|
|
+ case BX_MSR_CTR1:
|
|
+ goto do_exception;
|
|
+#endif /* BX_CPU_LEVEL == 5 */
|
|
+
|
|
+ /* MSR_APICBASE
|
|
+ 0:7 Reserved
|
|
+ 8 This is set if its the BSP
|
|
+ 9:10 Reserved
|
|
+ 11 APIC Global Enable bit (1=enabled 0=disabled)
|
|
+ 12:35 APIC Base Address
|
|
+ 36:63 Reserved
|
|
+ */
|
|
+
|
|
+ case BX_MSR_APICBASE:
|
|
+ BX_CPU_THIS_PTR msr.apicbase = (EDX << 32) + EAX;
|
|
+ BX_INFO(("WRMSR: wrote %08x:%08x to MSR_APICBASE", EDX, EAX));
|
|
+ return;
|
|
+
|
|
+ default:
|
|
+ BX_INFO(("WRMSR: Unknown register!"));
|
|
+ goto do_exception;
|
|
+
|
|
+ }
|
|
+#endif /* BX_CPU_LEVEL >= 5 */
|
|
+
|
|
+do_exception:
|
|
+ exception(BX_GP_EXCEPTION, 0, 0);
|
|
+
|
|
}
|
|
|
|
#if BX_X86_DEBUGGER
|
|
|
|
--
|
|
rants : http://function.linuxpower.ca
|
|
|
|
|
|
|
|
_______________________________________________
|
|
bochs-developers mailing list
|
|
bochs-developers@lists.sourceforge.net
|
|
https://lists.sourceforge.net/lists/listinfo/bochs-developers
|