void archreset(void) { static int beenhere; if (beenhere) return; beenhere = 1; /* conservative temporary values until archconfinit runs */ m->cpuhz = 1000 * Mhz; /* trimslice speed */ m->delayloop = m->cpuhz/2000; /* initial estimate */ prcachecfg(); clockson(); /* all partitions were powered up by u-boot, so needn't do anything */ archconfinit(); // resetusb(); fpon(); if (irqtooearly) panic("archreset: too early for irqenable"); irqenable(Cpu0irq, sgintr, nil, "cpu0"); irqenable(Cpu1irq, sgintr, nil, "cpu1"); /* ... */ }
/* * math coprocessor error */ static void matherror(Ureg *ur, void*) { ulong status, pc; /* * a write cycle to port 0xF0 clears the interrupt latch attached * to the error# line from the 387 */ if(!(m->cpuiddx & Fpuonchip)) outb(0xF0, 0xFF); /* * save floating point state to check out error */ fpenv(&up->fpsave); /* result ignored, but masks fp exceptions */ fpsave(&up->fpsave); /* also turns fpu off */ fpon(); mathnote(); if((ur->pc & 0xf0000000) == KZERO){ mathstate(&status, &pc, nil); panic("fp: status %#lux fppc=%#lux pc=%#lux", status, pc, ur->pc); } }
void archreset(void) { fpon(); }
/* * called on a cpu other than 0 from cpureset in l.s, * from _vrst in lexception.s. * mmu and l1 (and system-wide l2) caches and coherency (smpon) are on, * but interrupts are disabled. * our mmu is using an exact copy of cpu0's l1 page table * as it was after userinit ran. */ void cpustart(void) { int ms; ulong *evp; Power *pwr; up = nil; if (active.machs & (1<<m->machno)) { serialputc('?'); serialputc('r'); panic("cpu%d: resetting after start", m->machno); } assert(m->machno != 0); errata(); cortexa9cachecfg(); memdiag(&testmem); machinit(); /* bumps nmach, adds bit to machs */ machoff(m->machno); /* not ready to go yet */ /* clock signals and scu are system-wide and already on */ clockshutdown(); /* kill any watch-dog timer */ trapinit(); clockinit(); /* sets loop delay */ timersinit(); cpuidprint(); /* * notify cpu0 that we're up so it can proceed to l1diag. */ evp = (ulong *)soc.exceptvec; /* magic */ *evp = m->machno; coherence(); l1diag(); /* contend with other cpus to verify sanity */ /* * pwr->noiopwr == 0 * pwr->detect == 0x1ff (default, all disabled) */ pwr = (Power *)soc.power; assert(pwr->gatests == MASK(7)); /* everything has power */ /* * 8169 has to initialise before we get past this, thus cpu0 * has to schedule processes first. */ if (Debug) iprint("cpu%d: waiting for 8169\n", m->machno); for (ms = 0; !l1ptstable.word && ms < 5000; ms += 10) { delay(10); cachedinvse(&l1ptstable.word, sizeof l1ptstable.word); } if (!l1ptstable.word) iprint("cpu%d: 8169 unreasonably slow; proceeding\n", m->machno); /* now safe to copy cpu0's l1 pt in mmuinit */ mmuinit(); /* update our l1 pt from cpu0's */ fpon(); machon(m->machno); /* now ready to go and be scheduled */ if (Debug) iprint("cpu%d: scheding\n", m->machno); schedinit(); panic("cpu%d: schedinit returned", m->machno); }