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