Start of x2apic code

上级 abd2d17c
#if defined(HW_ben)
#define lapicstartap x2apicstartap
#define lapiceoi x2apiceoi
#define lapic_tlbflush x2apic_tlbflush
#define lapic_sampconf x2apic_sampconf
#define lapicpc x2apicpc
#define lapicid x2apicid
#define initlapic initx2apic
#else
#define lapicstartap xapicstartap
#define lapiceoi xapiceoi
#define lapic_tlbflush xapic_tlbflush
#define lapic_sampconf xapic_sampconf
#define lapicpc xapicpc
#define lapicid xapicid
#define initlapic initxapic
#endif
// xapic.cc
void xapicstartap(hwid_t, u32 addr);
void xapiceoi(void);
void xapic_tlbflush(hwid_t);
void xapic_sampconf(hwid_t);
void xapicpc(char mask);
hwid_t xapicid(void);
void initxapic(void);
// x2apic.cc
void x2apicstartap(hwid_t, u32 addr);
void x2apiceoi(void);
void x2apic_tlbflush(hwid_t);
void x2apic_sampconf(hwid_t);
void x2apicpc(char mask);
hwid_t x2apicid(void);
void initx2apic(void);
...@@ -141,13 +141,6 @@ void kmemprint(void); ...@@ -141,13 +141,6 @@ void kmemprint(void);
// kbd.c // kbd.c
void kbdintr(void); void kbdintr(void);
// lapic.c
void lapicstartap(hwid_t, u32 addr);
void lapiceoi(void);
void lapic_tlbflush(hwid_t);
void lapic_sampconf(hwid_t);
void lapicpc(char mask);
// main.c // main.c
void halt(void) __attribute__((noreturn)); void halt(void) __attribute__((noreturn));
......
...@@ -121,10 +121,10 @@ struct taskstate ...@@ -121,10 +121,10 @@ struct taskstate
} __attribute__ ((packed, aligned(16))); } __attribute__ ((packed, aligned(16)));
typedef struct hwid { typedef struct hwid {
u8 num; u32 num;
} hwid_t; } hwid_t;
#define HWID(xnum) (struct hwid){ num: (u8)(xnum) } #define HWID(xnum) (struct hwid){ num: (u32)(xnum) }
#endif #endif
#define INT_P (1<<7) /* interrupt descriptor present */ #define INT_P (1<<7) /* interrupt descriptor present */
......
...@@ -16,7 +16,6 @@ OBJS = \ ...@@ -16,7 +16,6 @@ OBJS = \
futex.o \ futex.o \
idle.o \ idle.o \
ioapic.o \ ioapic.o \
lapic.o \
hwvm.o \ hwvm.o \
hz.o \ hz.o \
kalloc.o \ kalloc.o \
...@@ -52,6 +51,8 @@ OBJS = \ ...@@ -52,6 +51,8 @@ OBJS = \
wqkern.o \ wqkern.o \
wqlib.o \ wqlib.o \
script.o \ script.o \
xapic.o \
x2apic.o \
zalloc.o \ zalloc.o \
incbin.o \ incbin.o \
sysvectors.o \ sysvectors.o \
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "proc.hh" #include "proc.hh"
#include "vm.hh" #include "vm.hh"
#include "wq.hh" #include "wq.hh"
#include "apic.hh"
using namespace std; using namespace std;
...@@ -213,8 +214,6 @@ freevm(pgmap *pml4) ...@@ -213,8 +214,6 @@ freevm(pgmap *pml4)
void void
inittls(void) inittls(void)
{ {
extern hwid_t lapicid(void);
struct cpu *c; struct cpu *c;
cpuid_t id = -1; cpuid_t id = -1;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "hwvm.hh" #include "hwvm.hh"
#include "condvar.h" #include "condvar.h"
#include "proc.hh" #include "proc.hh"
#include "apic.hh"
void initpic(void); void initpic(void);
void initioapic(void); void initioapic(void);
...@@ -16,7 +17,6 @@ void initcga(void); ...@@ -16,7 +17,6 @@ void initcga(void);
void initconsole(void); void initconsole(void);
void initpg(void); void initpg(void);
void initmp(void); void initmp(void);
void initlapic(void);
void inittls(void); void inittls(void);
void initnmi(void); void initnmi(void);
void inittrap(void); void inittrap(void);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "cpu.hh" #include "cpu.hh"
#include "sampler.h" #include "sampler.h"
#include "major.h" #include "major.h"
#include "apic.hh"
#define LOGHEADER_SZ (sizeof(struct logheader) + \ #define LOGHEADER_SZ (sizeof(struct logheader) + \
sizeof(((struct logheader*)0)->cpu[0])*NCPU) sizeof(((struct logheader*)0)->cpu[0])*NCPU)
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "kmtrace.hh" #include "kmtrace.hh"
#include "bits.hh" #include "bits.hh"
#include "kalloc.hh" #include "kalloc.hh"
#include "apic.hh"
extern "C" void __uaccess_end(void); extern "C" void __uaccess_end(void);
......
#include "types.h"
#include "amd64.h"
#include "bits.hh"
#include "kernel.hh"
void
x2apicstartap(hwid_t id, u32 addr)
{
panic("x2apicstartap");
}
void
x2apiceoi(void)
{
panic("x2apiceoi");
}
void
x2apic_tlbflush(hwid_t id)
{
panic("x2apic_tlbflush");
}
void
x2apic_sampconf(hwid_t id)
{
panic("x2apic_sampconf");
}
void
x2apicpc(char mask)
{
panic("x2apicpc");
}
hwid_t
x2apicid(void)
{
panic("x2apicid");
return HWID(0);
}
void
initx2apic(void)
{
panic("initx2apic");
}
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "traps.h" #include "traps.h"
#include "bits.hh" #include "bits.hh"
#include "cpu.hh" #include "cpu.hh"
#include "apic.hh"
// Local APIC registers, divided by 4 for use as uint[] indices. // Local APIC registers, divided by 4 for use as uint[] indices.
#define ID (0x0020/4) // ID #define ID (0x0020/4) // ID
...@@ -43,31 +44,31 @@ ...@@ -43,31 +44,31 @@
#define IO_RTC 0x70 #define IO_RTC 0x70
static volatile u32 *lapic = (u32 *)(KBASE + 0xfee00000); static volatile u32 *xapic = (u32 *)(KBASE + 0xfee00000);
static u64 lapichz; static u64 xapichz;
static void static void
lapicw(int index, int value) xapicw(int index, int value)
{ {
lapic[index] = value; xapic[index] = value;
lapic[ID]; // wait for write to finish, by reading xapic[ID]; // wait for write to finish, by reading
} }
static u32 static u32
lapicr(u32 off) xapicr(u32 off)
{ {
return lapic[off]; return xapic[off];
} }
static int static int
lapicwait() xapicwait()
{ {
int i = 100000; int i = 100000;
while ((lapicr(ICRLO) & BUSY) != 0) { while ((xapicr(ICRLO) & BUSY) != 0) {
nop_pause(); nop_pause();
i--; i--;
if (i == 0) { if (i == 0) {
cprintf("lapicwait: wedged?\n"); cprintf("xapicwait: wedged?\n");
return -1; return -1;
} }
} }
...@@ -75,7 +76,7 @@ lapicwait() ...@@ -75,7 +76,7 @@ lapicwait()
} }
void void
initlapic(void) initxapic(void)
{ {
u64 count; u64 count;
u64 apicbar; u64 apicbar;
...@@ -93,69 +94,69 @@ initlapic(void) ...@@ -93,69 +94,69 @@ initlapic(void)
// Sanity-check.. // Sanity-check..
u32 ebx; u32 ebx;
cpuid(CPUID_FEATURES, 0, &ebx, 0, 0); cpuid(CPUID_FEATURES, 0, &ebx, 0, 0);
assert(lapic[ID]>>24 == FEATURE_EBX_APIC(ebx)); assert(xapic[ID]>>24 == FEATURE_EBX_APIC(ebx));
} }
// Enable local APIC; set spurious interrupt vector. // Enable local APIC; set spurious interrupt vector.
lapicw(SVR, ENABLE | (T_IRQ0 + IRQ_SPURIOUS)); xapicw(SVR, ENABLE | (T_IRQ0 + IRQ_SPURIOUS));
if (lapichz == 0) { if (xapichz == 0) {
// Measure the TICR frequency // Measure the TICR frequency
lapicw(TDCR, X1); xapicw(TDCR, X1);
lapicw(TICR, 0xffffffff); xapicw(TICR, 0xffffffff);
u64 ccr0 = lapicr(TCCR); u64 ccr0 = xapicr(TCCR);
microdelay(10 * 1000); // 1/100th of a second microdelay(10 * 1000); // 1/100th of a second
u64 ccr1 = lapicr(TCCR); u64 ccr1 = xapicr(TCCR);
lapichz = 100 * (ccr0 - ccr1); xapichz = 100 * (ccr0 - ccr1);
} }
count = (QUANTUM*lapichz) / 1000; count = (QUANTUM*xapichz) / 1000;
if (count > 0xffffffff) if (count > 0xffffffff)
panic("initlapic: QUANTUM too large"); panic("initxapic: QUANTUM too large");
// The timer repeatedly counts down at bus frequency // The timer repeatedly counts down at bus frequency
// from lapic[TICR] and then issues an interrupt. // from xapic[TICR] and then issues an interrupt.
lapicw(TDCR, X1); xapicw(TDCR, X1);
lapicw(TIMER, PERIODIC | (T_IRQ0 + IRQ_TIMER)); xapicw(TIMER, PERIODIC | (T_IRQ0 + IRQ_TIMER));
lapicw(TICR, count); xapicw(TICR, count);
// Disable logical interrupt lines. // Disable logical interrupt lines.
lapicw(LINT0, MASKED); xapicw(LINT0, MASKED);
lapicw(LINT1, MASKED); xapicw(LINT1, MASKED);
// Disable performance counter overflow interrupts // Disable performance counter overflow interrupts
// on machines that provide that interrupt entry. // on machines that provide that interrupt entry.
if(((lapic[VER]>>16) & 0xFF) >= 4) if(((xapic[VER]>>16) & 0xFF) >= 4)
lapicpc(0); xapicpc(0);
// Map error interrupt to IRQ_ERROR. // Map error interrupt to IRQ_ERROR.
lapicw(ERROR, T_IRQ0 + IRQ_ERROR); xapicw(ERROR, T_IRQ0 + IRQ_ERROR);
// Clear error status register (requires back-to-back writes). // Clear error status register (requires back-to-back writes).
lapicw(ESR, 0); xapicw(ESR, 0);
lapicw(ESR, 0); xapicw(ESR, 0);
// Ack any outstanding interrupts. // Ack any outstanding interrupts.
lapicw(EOI, 0); xapicw(EOI, 0);
// Send an Init Level De-Assert to synchronise arbitration ID's. // Send an Init Level De-Assert to synchronise arbitration ID's.
lapicw(ICRHI, 0); xapicw(ICRHI, 0);
lapicw(ICRLO, BCAST | INIT | LEVEL); xapicw(ICRLO, BCAST | INIT | LEVEL);
while(lapic[ICRLO] & DELIVS) while(xapic[ICRLO] & DELIVS)
; ;
// Enable interrupts on the APIC (but not on the processor). // Enable interrupts on the APIC (but not on the processor).
lapicw(TPR, 0); xapicw(TPR, 0);
} }
void void
lapicpc(char mask) xapicpc(char mask)
{ {
lapicw(PCINT, mask ? MASKED : MT_NMI); xapicw(PCINT, mask ? MASKED : MT_NMI);
} }
hwid_t hwid_t
lapicid(void) xapicid(void)
{ {
if (readrflags() & FL_IF) { if (readrflags() & FL_IF) {
cli(); cli();
...@@ -171,47 +172,47 @@ lapicid(void) ...@@ -171,47 +172,47 @@ lapicid(void)
#if 0 #if 0
// It should be safe to read from the APIC's MMIO anytime, // It should be safe to read from the APIC's MMIO anytime,
// but it's not. The BIOS might have enabled the x2APIC, // but it's not. The BIOS might have enabled the x2APIC,
// in which case the value of lapic[ID]>>24 is undefined. // in which case the value of xapic[ID]>>24 is undefined.
if (lapic == nullptr) if (xapic == nullptr)
panic("lapicid"); panic("xapicid");
return HWID(lapic[ID]>>24); return HWID(xapic[ID]>>24);
#endif #endif
} }
// Acknowledge interrupt. // Acknowledge interrupt.
void void
lapiceoi(void) xapiceoi(void)
{ {
if(lapic) if(xapic)
lapicw(EOI, 0); xapicw(EOI, 0);
} }
// Send IPI // Send IPI
void void
lapic_ipi(hwid_t hwid, int ino) xapic_ipi(hwid_t hwid, int ino)
{ {
lapicw(ICRHI, hwid.num << 24); xapicw(ICRHI, hwid.num << 24);
lapicw(ICRLO, FIXED | DEASSERT | ino); xapicw(ICRLO, FIXED | DEASSERT | ino);
if (lapicwait() < 0) if (xapicwait() < 0)
panic("lapic_ipi: lapicwait failure"); panic("xapic_ipi: xapicwait failure");
} }
void void
lapic_tlbflush(hwid_t hwid) xapic_tlbflush(hwid_t hwid)
{ {
lapic_ipi(hwid, T_TLBFLUSH); xapic_ipi(hwid, T_TLBFLUSH);
} }
void void
lapic_sampconf(hwid_t hwid) xapic_sampconf(hwid_t hwid)
{ {
lapic_ipi(hwid, T_SAMPCONF); xapic_ipi(hwid, T_SAMPCONF);
} }
// Start additional processor running bootstrap code at addr. // Start additional processor running bootstrap code at addr.
// See Appendix B of MultiProcessor Specification. // See Appendix B of MultiProcessor Specification.
void void
lapicstartap(hwid hwid, u32 addr) xapicstartap(hwid hwid, u32 addr)
{ {
int i; int i;
volatile u16 *wrv; volatile u16 *wrv;
...@@ -227,12 +228,12 @@ lapicstartap(hwid hwid, u32 addr) ...@@ -227,12 +228,12 @@ lapicstartap(hwid hwid, u32 addr)
// "Universal startup algorithm." // "Universal startup algorithm."
// Send INIT (level-triggered) interrupt to reset other CPU. // Send INIT (level-triggered) interrupt to reset other CPU.
lapicw(ICRHI, hwid.num<<24); xapicw(ICRHI, hwid.num<<24);
lapicw(ICRLO, hwid.num | INIT | LEVEL | ASSERT); xapicw(ICRLO, hwid.num | INIT | LEVEL | ASSERT);
lapicwait(); xapicwait();
microdelay(10000); microdelay(10000);
lapicw(ICRLO, hwid.num |INIT | LEVEL); xapicw(ICRLO, hwid.num |INIT | LEVEL);
lapicwait(); xapicwait();
microdelay(10000); // should be 10ms, but too slow in Bochs! microdelay(10000); // should be 10ms, but too slow in Bochs!
// Send startup IPI (twice!) to enter bootstrap code. // Send startup IPI (twice!) to enter bootstrap code.
...@@ -241,8 +242,8 @@ lapicstartap(hwid hwid, u32 addr) ...@@ -241,8 +242,8 @@ lapicstartap(hwid hwid, u32 addr)
// should be ignored, but it is part of the official Intel algorithm. // should be ignored, but it is part of the official Intel algorithm.
// Bochs complains about the second one. Too bad for Bochs. // Bochs complains about the second one. Too bad for Bochs.
for(i = 0; i < 2; i++){ for(i = 0; i < 2; i++){
lapicw(ICRHI, hwid.num<<24); xapicw(ICRHI, hwid.num<<24);
lapicw(ICRLO, STARTUP | (addr>>12)); xapicw(ICRLO, STARTUP | (addr>>12));
microdelay(200); microdelay(200);
} }
} }
...@@ -39,9 +39,15 @@ ...@@ -39,9 +39,15 @@
#define MTRACE 0 #define MTRACE 0
#define PERFSIZE (512<<20ull) #define PERFSIZE (512<<20ull)
#elif defined(HW_tom) #elif defined(HW_tom)
#define DEBUG 0
#define NCPU 48 // maximum number of CPUs #define NCPU 48 // maximum number of CPUs
#define MTRACE 0 #define MTRACE 0
#define PERFSIZE (1<<20ull) #define PERFSIZE (1<<20ull)
#elif defined(HW_ben)
#define DEBUG 0
#define NCPU 80 // maximum number of CPUs
#define MTRACE 0
#define PERFSIZE (1<<20ull)
#elif defined(HW_user) #elif defined(HW_user)
#define NCPU 256 #define NCPU 256
#define MTRACE 0 #define MTRACE 0
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论