/* * Called on the boot CPU during startup. */ void kcpc_hw_init(void) { if (cpc_has_overflow_intr) { cpc_level15_inum = add_softintr(PIL_15, kcpc_hw_overflow_intr, NULL, SOFTINT_MT); } /* * Make sure the boot CPU gets set up. */ kcpc_hw_startup_cpu(CPU->cpu_flags); }
/* * Startup function executed on 'other' CPUs. This is the first * C function after cpu_start sets up the cpu registers. */ static void slave_startup(void) { struct cpu *cp = CPU; ushort_t original_flags = cp->cpu_flags; mach_htraptrace_configure(cp->cpu_id); cpu_intrq_register(CPU); cp->cpu_m.mutex_ready = 1; /* acknowledge that we are done with initialization */ CPUSET_ADD(proxy_ready_set, cp->cpu_id); /* synchronize STICK */ sticksync_slave(); if (boothowto & RB_DEBUG) kdi_dvec_cpu_init(cp); /* * the slave will wait here forever -- assuming that the master * will get back to us. if it doesn't we've got bigger problems * than a master not replying to this slave. * the small delay improves the slave's responsiveness to the * master's ack and decreases the time window between master and * slave operations. */ while (!CPU_IN_SET(cpu_ready_set, cp->cpu_id)) DELAY(1); /* * The CPU is now in cpu_ready_set, safely able to take pokes. */ cp->cpu_m.poke_cpu_outstanding = B_FALSE; /* enable interrupts */ (void) spl0(); /* * Signature block update to indicate that this CPU is in OS now. * This needs to be done after the PIL is lowered since on * some platforms the update code may block. */ CPU_SIGNATURE(OS_SIG, SIGST_RUN, SIGSUBST_NULL, cp->cpu_id); /* * park the slave thread in a safe/quiet state and wait for the master * to finish configuring this CPU before proceeding to thread_exit(). */ while (((volatile ushort_t)cp->cpu_flags) & CPU_QUIESCED) DELAY(1); /* * Initialize CPC CPU state. */ kcpc_hw_startup_cpu(original_flags); /* * Notify the PG subsystem that the CPU has started */ pg_cmt_cpu_startup(CPU); /* * Now we are done with the startup thread, so free it up. */ thread_exit(); cmn_err(CE_PANIC, "slave_startup: cannot return"); /*NOTREACHED*/ }