From f27a68a24a3e0980499db8920fc7306dbab7d52d Mon Sep 17 00:00:00 2001 From: kaashoek Date: Wed, 12 Jul 2006 17:00:54 +0000 Subject: [PATCH] extract lapic code from mp.c --- Makefile | 2 +- defs.h | 8 ++- main.c | 5 +- mp.c | 209 ++----------------------------------------------------- 4 files changed, 18 insertions(+), 206 deletions(-) diff --git a/Makefile b/Makefile index 1b2b827..0a5e297 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ OBJS = main.o console.o string.o kalloc.o proc.o trapasm.o trap.o vectors.o \ - syscall.o ide.o picirq.o mp.o spinlock.o fd.o pipe.o swtch.o + syscall.o ide.o picirq.o mp.o lapic.o spinlock.o fd.o pipe.o swtch.o # Cross-compiling (e.g., on Mac OS X) TOOLPREFIX = i386-jos-elf- diff --git a/defs.h b/defs.h index 4561ff6..acb0e04 100644 --- a/defs.h +++ b/defs.h @@ -49,13 +49,17 @@ void pic_init(void); // mp.c void mp_init(void); void mp_startthem(void); -int cpu(void); -int mp_isbcpu(void); +int mp_bcpu(void); + +// lapic +extern uint32_t *lapicaddr; void lapic_init(int); +void lapic_startap(uint8_t, int); void lapic_timerinit(void); void lapic_timerintr(void); void lapic_enableintr(void); void lapic_disableintr(void); +int cpu(void); // spinlock.c struct spinlock; diff --git a/main.c b/main.c index 9015ff7..fe85054 100644 --- a/main.c +++ b/main.c @@ -38,11 +38,14 @@ main() // clear BSS memset(edata, 0, end - edata); - mp_init(); // just set up apic so cpu() works + mp_init(); // collect info about this machine + use_printf_lock = 1; cpus[cpu()].clis = 1; // cpu starts as if we had called cli() + lapic_init(mp_bcpu()); + cprintf("\nxV6\n\n"); pic_init(); // initialize PIC diff --git a/mp.c b/mp.c index 068d036..19e18d1 100644 --- a/mp.c +++ b/mp.c @@ -8,90 +8,6 @@ #include "mmu.h" #include "proc.h" -/* - * Credit: Plan 9 sources, Intel MP spec, and Cliff Frey - */ - -enum { /* Local APIC registers */ - LAPIC_ID = 0x0020, /* ID */ - LAPIC_VER = 0x0030, /* Version */ - LAPIC_TPR = 0x0080, /* Task Priority */ - LAPIC_APR = 0x0090, /* Arbitration Priority */ - LAPIC_PPR = 0x00A0, /* Processor Priority */ - LAPIC_EOI = 0x00B0, /* EOI */ - LAPIC_LDR = 0x00D0, /* Logical Destination */ - LAPIC_DFR = 0x00E0, /* Destination Format */ - LAPIC_SVR = 0x00F0, /* Spurious Interrupt Vector */ - LAPIC_ISR = 0x0100, /* Interrupt Status (8 registers) */ - LAPIC_TMR = 0x0180, /* Trigger Mode (8 registers) */ - LAPIC_IRR = 0x0200, /* Interrupt Request (8 registers) */ - LAPIC_ESR = 0x0280, /* Error Status */ - LAPIC_ICRLO = 0x0300, /* Interrupt Command */ - LAPIC_ICRHI = 0x0310, /* Interrupt Command [63:32] */ - LAPIC_TIMER = 0x0320, /* Local Vector Table 0 (TIMER) */ - LAPIC_PCINT = 0x0340, /* Performance Counter LVT */ - LAPIC_LINT0 = 0x0350, /* Local Vector Table 1 (LINT0) */ - LAPIC_LINT1 = 0x0360, /* Local Vector Table 2 (LINT1) */ - LAPIC_ERROR = 0x0370, /* Local Vector Table 3 (ERROR) */ - LAPIC_TICR = 0x0380, /* Timer Initial Count */ - LAPIC_TCCR = 0x0390, /* Timer Current Count */ - LAPIC_TDCR = 0x03E0, /* Timer Divide Configuration */ -}; - -enum { /* LAPIC_SVR */ - LAPIC_ENABLE = 0x00000100, /* Unit Enable */ - LAPIC_FOCUS = 0x00000200, /* Focus Processor Checking Disable */ -}; - -enum { /* LAPIC_ICRLO */ - /* [14] IPI Trigger Mode Level (RW) */ - LAPIC_DEASSERT = 0x00000000, /* Deassert level-sensitive interrupt */ - LAPIC_ASSERT = 0x00004000, /* Assert level-sensitive interrupt */ - - /* [17:16] Remote Read Status */ - LAPIC_INVALID = 0x00000000, /* Invalid */ - LAPIC_WAIT = 0x00010000, /* In-Progress */ - LAPIC_VALID = 0x00020000, /* Valid */ - - /* [19:18] Destination Shorthand */ - LAPIC_FIELD = 0x00000000, /* No shorthand */ - LAPIC_SELF = 0x00040000, /* Self is single destination */ - LAPIC_ALLINC = 0x00080000, /* All including self */ - LAPIC_ALLEXC = 0x000C0000, /* All Excluding self */ -}; - -enum { /* LAPIC_ESR */ - LAPIC_SENDCS = 0x00000001, /* Send CS Error */ - LAPIC_RCVCS = 0x00000002, /* Receive CS Error */ - LAPIC_SENDACCEPT = 0x00000004, /* Send Accept Error */ - LAPIC_RCVACCEPT = 0x00000008, /* Receive Accept Error */ - LAPIC_SENDVECTOR = 0x00000020, /* Send Illegal Vector */ - LAPIC_RCVVECTOR = 0x00000040, /* Receive Illegal Vector */ - LAPIC_REGISTER = 0x00000080, /* Illegal Register Address */ -}; - -enum { /* LAPIC_TIMER */ - /* [17] Timer Mode (RW) */ - LAPIC_ONESHOT = 0x00000000, /* One-shot */ - LAPIC_PERIODIC = 0x00020000, /* Periodic */ - - /* [19:18] Timer Base (RW) */ - LAPIC_CLKIN = 0x00000000, /* use CLKIN as input */ - LAPIC_TMBASE = 0x00040000, /* use TMBASE */ - LAPIC_DIVIDER = 0x00080000, /* use output of the divider */ -}; - -enum { /* LAPIC_TDCR */ - LAPIC_X2 = 0x00000000, /* divide by 2 */ - LAPIC_X4 = 0x00000001, /* divide by 4 */ - LAPIC_X8 = 0x00000002, /* divide by 8 */ - LAPIC_X16 = 0x00000003, /* divide by 16 */ - LAPIC_X32 = 0x00000008, /* divide by 32 */ - LAPIC_X64 = 0x00000009, /* divide by 64 */ - LAPIC_X128 = 0x0000000A, /* divide by 128 */ - LAPIC_X1 = 0x0000000B, /* divide by 1 */ -}; - static char* buses[] = { "CBUSI ", "CBUSII", @@ -117,119 +33,10 @@ static char* buses[] = { #define APBOOTCODE 0x7000 // XXX hack static struct MP* mp; // The MP floating point structure -static uint32_t *lapicaddr; struct cpu cpus[NCPU]; int ncpu; static struct cpu *bcpu; -static int -lapic_read(int r) -{ - return *(lapicaddr+(r/sizeof(*lapicaddr))); -} - -static void -lapic_write(int r, int data) -{ - *(lapicaddr+(r/sizeof(*lapicaddr))) = data; -} - - -void -lapic_timerinit() -{ - cprintf("%d: init timer\n", cpu()); - lapic_write(LAPIC_TDCR, LAPIC_X1); - lapic_write(LAPIC_TIMER, LAPIC_CLKIN | LAPIC_PERIODIC | (IRQ_OFFSET + IRQ_TIMER)); - lapic_write(LAPIC_TCCR, 10000000); - lapic_write(LAPIC_TICR, 10000000); -} - -void -lapic_timerintr() -{ - cprintf("%d: timer interrupt!\n", cpu()); - lapic_write (LAPIC_EOI, 0); -} - -void -lapic_init(int c) -{ - uint32_t r, lvt; - - cprintf("lapic_init %d\n", c); - - lapic_write(LAPIC_DFR, 0xFFFFFFFF); // set destination format register - r = (lapic_read(LAPIC_ID)>>24) & 0xFF; // read APIC ID - lapic_write(LAPIC_LDR, (1<>16) & 0xFF; - if(lvt >= 4) - lapic_write(LAPIC_PCINT, APIC_IMASK); - lapic_write(LAPIC_ERROR, IRQ_OFFSET+IRQ_ERROR); - lapic_write(LAPIC_ESR, 0); - lapic_read(LAPIC_ESR); - - /* - * Issue an INIT Level De-Assert to synchronise arbitration ID's. - */ - lapic_write(LAPIC_ICRHI, 0); - lapic_write(LAPIC_ICRLO, LAPIC_ALLINC|APIC_LEVEL|LAPIC_DEASSERT|APIC_INIT); - while(lapic_read(LAPIC_ICRLO) & APIC_DELIVS) - ; - - cprintf("Done init of an apic\n"); -} - -void -lapic_enableintr(void) -{ - lapic_write(LAPIC_TPR, 0); -} - -void -lapic_disableintr(void) -{ - lapic_write(LAPIC_TPR, 0xFF); -} - -int -cpu(void) -{ - return (lapic_read(LAPIC_ID)>>24) & 0xFF; -} - -static void -lapic_startap(struct cpu *c, int v) -{ - int crhi, i; - volatile int j = 0; - - crhi = c->apicid<<24; - lapic_write(LAPIC_ICRHI, crhi); - lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_LEVEL|LAPIC_ASSERT|APIC_INIT); - - while (j++ < 10000) {;} - lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_LEVEL|LAPIC_DEASSERT|APIC_INIT); - - while (j++ < 1000000) {;} - - // in p9 code, this was i < 2, which is what the spec says on page B-3 - for(i = 0; i < 1; i++){ - lapic_write(LAPIC_ICRHI, crhi); - lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_EDGE|APIC_STARTUP|(v/PGSIZE)); - while (j++ < 100000) {;} - } -} - static struct MP* mp_scan(uint8_t *addr, int len) { @@ -310,13 +117,6 @@ mp_detect(void) return 0; } -int -mp_isbcpu() -{ - if (bcpu == 0) return 1; - else return 0; -} - void mp_init() { @@ -382,10 +182,15 @@ mp_init() } } - lapic_init(bcpu-cpus); cprintf("ncpu: %d boot %d\n", ncpu, bcpu-cpus); } +int +mp_bcpu(void) +{ + return bcpu-cpus; +} + void mp_startthem() { @@ -401,6 +206,6 @@ mp_startthem() cprintf ("starting processor %d\n", c); *(unsigned *)(APBOOTCODE-4) = (unsigned) (cpus[c].mpstack) + MPSTACK; // tell it what to use for %esp *(unsigned *)(APBOOTCODE-8) = (unsigned)&main; // tell it where to jump to - lapic_startap(cpus + c, (uint32_t) APBOOTCODE); + lapic_startap(cpus[c].apicid, (uint32_t) APBOOTCODE); } }