123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #include "u.h"
- #include "../port/lib.h"
- #include "mem.h"
- #include "dat.h"
- #include "fns.h"
- #include "apic.h"
- #undef DBG
- #define DBG print
- #define SIPIHANDLER (KZERO+0x3000)
- void
- sipi(void)
- {
- extern int b1978;
- Apic *apic;
- Mach *mach;
- int apicno, i;
- uint32_t *sipiptr;
- uintmem sipipa;
- uint8_t *alloc, *p;
- extern void squidboy(int);
- /*
- * Move the startup code into place,
- * must be aligned properly.
- */
- sipipa = mmuphysaddr(SIPIHANDLER);
- if((sipipa & (4*KiB - 1)) || sipipa > (1*MiB - 2*4*KiB))
- return;
- sipiptr = UINT2PTR(SIPIHANDLER);
- memmove(sipiptr, &b1978, 4096);
- DBG("sipiptr %#p sipipa %#llx\n", sipiptr, sipipa);
- /*
- * Notes:
- * The Universal Startup Algorithm described in the MP Spec. 1.4.
- * The data needed per-processor is the sum of the stack, page
- * table pages, vsvm page and the Mach page. The layout is similar
- * to that described in data.h for the bootstrap processor, but
- * with any unused space elided.
- */
- for(apicno = 0; apicno < Napic; apicno++){
- apic = &xlapic[apicno];
- if(!apic->useable || apic->Ioapic.addr || apic->Lapic.machno == 0)
- continue;
- /*
- * NOTE: for now, share the page tables with the
- * bootstrap processor, until the lsipi code is worked out,
- * so only the Mach and stack portions are used below.
- */
- alloc = mallocalign(MACHSTKSZ+4*PTSZ+4*KiB+MACHSZ, 4096, 0, 0);
- if(alloc == nil)
- continue;
- memset(alloc, 0, MACHSTKSZ+4*PTSZ+4*KiB+MACHSZ);
- p = alloc+MACHSTKSZ;
- sipiptr[-1] = mmuphysaddr(PTR2UINT(p));
- DBG("p %#p sipiptr[-1] %#x\n", p, sipiptr[-1]);
- p += 4*PTSZ+4*KiB;
- /*
- * Committed. If the AP startup fails, can't safely
- * release the resources, who knows what mischief
- * the AP is up to. Perhaps should try to put it
- * back into the INIT state?
- */
- mach = (Mach*)p;
- mach->machno = apic->Lapic.machno; /* NOT one-to-one... */
- mach->splpc = PTR2UINT(squidboy);
- mach->apicno = apicno;
- mach->stack = PTR2UINT(alloc);
- mach->vsvm = alloc+MACHSTKSZ+4*PTSZ;
- //OH OH mach->pml4 = (PTE*)(alloc+MACHSTKSZ);
- p = KADDR(0x467);
- *p++ = sipipa;
- *p++ = sipipa>>8;
- *p++ = 0;
- *p = 0;
- nvramwrite(0x0f, 0x0a);
- //print("APICSIPI: %d, %p\n", apicno, (void *)sipipa);
- apicsipi(apicno, sipipa);
- for(i = 0; i < 1000; i++){
- if(mach->splpc == 0)
- break;
- millidelay(5);
- }
- nvramwrite(0x0f, 0x00);
- /*DBG("mach %#p (%#p) apicid %d machno %2d %dMHz\n",
- mach, sys->machptr[mach->machno],
- apicno, mach->machno, mach->cpumhz);*/
- }
- }
|