extract lapic code from mp.c
This commit is contained in:
		
							parent
							
								
									6eb6f10c56
								
							
						
					
					
						commit
						f27a68a24a
					
				
					 4 changed files with 18 additions and 206 deletions
				
			
		
							
								
								
									
										2
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								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- | ||||
|  |  | |||
							
								
								
									
										8
									
								
								defs.h
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								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; | ||||
|  |  | |||
							
								
								
									
										5
									
								
								main.c
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								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
 | ||||
|  |  | |||
							
								
								
									
										209
									
								
								mp.c
									
										
									
									
									
								
							
							
						
						
									
										209
									
								
								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<<r)<<24);  // set logical destination register to r
 | ||||
|   lapic_write(LAPIC_TPR, 0xFF);  // no interrupts for now
 | ||||
|   lapic_write(LAPIC_SVR, LAPIC_ENABLE|(IRQ_OFFSET+IRQ_SPURIOUS));  // enable APIC
 | ||||
| 
 | ||||
|   // in virtual wire mode, set up the LINT0 and LINT1 as follows:
 | ||||
|   lapic_write(LAPIC_LINT0, APIC_IMASK | APIC_EXTINT); | ||||
|   lapic_write(LAPIC_LINT1, APIC_IMASK | APIC_NMI); | ||||
| 
 | ||||
|   lapic_write(LAPIC_EOI, 0); // acknowledge any outstanding interrupts.
 | ||||
| 
 | ||||
|   lvt = (lapic_read(LAPIC_VER)>>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); | ||||
|   } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 kaashoek
						kaashoek