ulong upamalloc(ulong addr, int size, int align) { ulong ae, a; USED(align); if((a = mapalloc(&rmapupa, addr, size, align)) == 0){ memdebug(); return 0; } /* * This is a travesty, but they all are. */ ae = mmukmap(a, 0, size); /* * Should check here that it was all delivered * and put it back and barf if not. */ USED(ae); /* * Be very careful this returns a PHYSICAL address. */ return a; }
/* from 386 */ void* vmap(uintptr pa, usize size) { uintptr pae, va; usize o, osize; /* * XXX - replace with new vm stuff. * Crock after crock - the first 4MB is mapped with 2MB pages * so catch that and return good values because the current mmukmap * will fail. */ if(pa+size < 4*MiB) return UINT2PTR(kseg0|pa); osize = size; o = pa & (BY2PG-1); pa -= o; size += o; size = ROUNDUP(size, BY2PG); va = kseg0|pa; pae = mmukmap(va, pa, size); if(pae == 0 || pae-size != pa) panic("vmap(%#p, %ld) called from %#p: mmukmap fails %#p", pa+o, osize, getcallerpc(&pa), pae); return UINT2PTR(va+o); }
/* * Virtual GPIO - used for ACT LED on pi3 */ void vgpinit(void) { u32int buf[1]; uintptr va; buf[0] = 0; if(vcreq(TagGetGpio, buf, 0, sizeof(buf)) != sizeof buf || buf[0] == 0) return; va = mmukmap(VGPIO, buf[0] & ~0xC0000000, BY2PG); if(va == 0) return; vgpio.counts = (u32int*)va; }
static Apic* mkioapic(PCMPioapic* p) { Apic *apic; if(!(p->flags & PcmpEN) || p->apicno > MaxAPICNO) return 0; /* * Map the I/O APIC. */ if(mmukmap(p->addr, 0, 1024) == 0) return 0; apic = &mpapic[p->apicno]; apic->type = PcmpIOAPIC; apic->apicno = p->apicno; apic->addr = KADDR(p->addr); apic->flags = p->flags; return apic; }
void* fbinit(int set, int *width, int *height, int *depth) { Fbinfo *fi; uintptr va; if(!set) fbdefault(width, height, depth); /* Screen width must be a multiple of 16 */ *width &= ~0xF; fi = (Fbinfo*)(VCBUFFER); memset(fi, 0, sizeof(*fi)); fi->xres = fi->xresvirtual = *width; fi->yres = fi->yresvirtual = *height; fi->bpp = *depth; cachedwbinvse(fi, sizeof(*fi)); vcwrite(ChanFb, DMAADDR(fi)); if(vcread(ChanFb) != 0) return 0; va = mmukmap(FRAMEBUFFER, PADDR(fi->base), fi->screensize); if(va) memset((char*)va, 0x7F, fi->screensize); return (void*)va; }
void mpinit(void) { int ncpu; char *cp; PCMP *pcmp; uchar *e, *p; Apic *apic, *bpapic; i8259init(); syncclock(); if(_mp_ == 0) return; pcmp = KADDR(_mp_->physaddr); /* * Map the local APIC. */ if(mmukmap(pcmp->lapicbase, 0, 1024) == 0) return; bpapic = nil; /* * Run through the table saving information needed for starting * application processors and initialising any I/O APICs. The table * is guaranteed to be in order such that only one pass is necessary. */ p = ((uchar*)pcmp)+sizeof(PCMP); e = ((uchar*)pcmp)+pcmp->length; while(p < e) switch(*p){ default: print("mpinit: unknown PCMP type 0x%uX (e-p 0x%luX)\n", *p, e-p); while(p < e){ print("%uX ", *p); p++; } break; case PcmpPROCESSOR: if(apic = mkprocessor((PCMPprocessor*)p)){ /* * Must take a note of bootstrap processor APIC * now as it will be needed in order to start the * application processors later and there's no * guarantee that the bootstrap processor appears * first in the table before the others. */ apic->addr = KADDR(pcmp->lapicbase); if(apic->flags & PcmpBP) bpapic = apic; } p += sizeof(PCMPprocessor); continue; case PcmpBUS: mkbus((PCMPbus*)p); p += sizeof(PCMPbus); continue; case PcmpIOAPIC: if(apic = mkioapic((PCMPioapic*)p)) ioapicinit(apic, ((PCMPioapic*)p)->apicno); p += sizeof(PCMPioapic); continue; case PcmpIOINTR: mkiointr((PCMPintr*)p); p += sizeof(PCMPintr); continue; case PcmpLINTR: mklintr((PCMPintr*)p); p += sizeof(PCMPintr); continue; } /* * No bootstrap processor, no need to go further. */ if(bpapic == 0) return; lapicinit(bpapic); lock(&mprdthilock); mprdthi |= (1<<bpapic->apicno)<<24; unlock(&mprdthilock); /* * These interrupts are local to the processor * and do not appear in the I/O APIC so it is OK * to set them now. */ intrenable(IrqTIMER, lapicclock, 0, BUSUNKNOWN, "clock"); intrenable(IrqERROR, lapicerror, 0, BUSUNKNOWN, "lapicerror"); intrenable(IrqSPURIOUS, lapicspurious, 0, BUSUNKNOWN, "lapicspurious"); lapiconline(); checkmtrr(); /* * Initialise the application processors. */ if(cp = getconf("*ncpu")){ ncpu = strtol(cp, 0, 0); if(ncpu < 1) ncpu = 1; } else ncpu = MaxAPICNO; memmove((void*)APBOOTSTRAP, apbootstrap, sizeof(apbootstrap)); for(apic = mpapic; apic <= &mpapic[MaxAPICNO]; apic++){ if(ncpu <= 1) break; if((apic->flags & (PcmpBP|PcmpEN)) == PcmpEN && apic->type == PcmpPROCESSOR){ mpstartap(apic); conf.nmach++; ncpu--; } } /* * we don't really know the number of processors till * here. * * set conf.copymode here if nmach > 1. * Should look for an ExtINT line and enable it. */ if(X86FAMILY(m->cpuidax) == 3 || conf.nmach > 1) conf.copymode = 1; }