Ejemplo n.º 1
0
/*
 * Determine mass storage and memory configuration for a machine.
 * We get the PROM's root device and make sure we understand it, then
 * attach it as `mainbus0'.  We also set up to handle the PROM `sync'
 * command.
 */
void
cpu_configure(void)
{
	
	if (CPU_ISSUN4V)
		mdesc_init();
	
	bool userconf = (boothowto & RB_USERCONF) != 0;

	/* fetch boot device settings */
	get_bootpath_from_prom();
	if (((boothowto & RB_USERCONF) != 0) && !userconf)
		/*
		 * Old bootloaders do not pass boothowto, and MI code
		 * has already handled userconfig before we get here
		 * and finally fetch the right options. So if we missed
		 * it, just do it here.
 		 */
		userconf_prompt();

	/* block clock interrupts and anything below */
	splclock();
	/* Enable device interrupts */
        setpstate(getpstate()|PSTATE_IE);

	if (config_rootfound("mainbus", NULL) == NULL)
		panic("mainbus not configured");

	/* Enable device interrupts */
        setpstate(getpstate()|PSTATE_IE);

	(void)spl0();
}
Ejemplo n.º 2
0
/*
 * Start secondary processors in motion.
 */
void
cpu_boot_secondary_processors()
{
	int i, pstate;
	struct cpu_info *ci;

	sparc64_ipi_init();

	for (ci = cpus; ci != NULL; ci = ci->ci_next) {
		if (ci->ci_cpuid == CPU_UPAID)
			continue;

		cpu_pmap_prepare(ci, false);
		cpu_args->cb_node = ci->ci_node;
		cpu_args->cb_cpuinfo = ci->ci_paddr;
		membar_sync();

		/* Disable interrupts and start another CPU. */
		pstate = getpstate();
		setpstate(PSTATE_KERN);

		prom_startcpu(ci->ci_node, (void *)cpu_spinup_trampoline, 0);

		for (i = 0; i < 2000; i++) {
			membar_sync();
			if (CPUSET_HAS(cpus_active, ci->ci_index))
				break;
			delay(10000);
		}
		setpstate(pstate);

		if (!CPUSET_HAS(cpus_active, ci->ci_index))
			printf("cpu%d: startup failed\n", ci->ci_cpuid);
	}
}
Ejemplo n.º 3
0
/*
 * Determine mass storage and memory configuration for a machine.
 * We get the PROM's root device and make sure we understand it, then
 * attach it as `mainbus0'.  We also set up to handle the PROM `sync'
 * command.
 */
void
cpu_configure(void)
{

	/* fetch boot device settings */
	get_bootpath_from_prom();

	/* block clock interrupts and anything below */
	splclock();
	/* Enable device interrupts */
        setpstate(getpstate()|PSTATE_IE);

	if (config_rootfound("mainbus", NULL) == NULL)
		panic("mainbus not configured");

	/* Enable device interrupts */
        setpstate(getpstate()|PSTATE_IE);

	(void)spl0();
}
Ejemplo n.º 4
0
/*
 * Start secondary processors in motion.
 */
void
cpu_boot_secondary_processors(void)
{
	int i, pstate;
	struct cpu_info *ci;

	sync_tick = 0;

	sparc64_ipi_init();

	if (boothowto & RB_MD1) {
		cpus[0].ci_next = NULL;
		sparc_ncpus = ncpu = ncpuonline = 1;
		return;
	}

	for (ci = cpus; ci != NULL; ci = ci->ci_next) {
		if (ci->ci_cpuid == CPU_UPAID)
			continue;

		cpu_pmap_prepare(ci, false);
		cpu_args->cb_node = ci->ci_node;
		cpu_args->cb_cpuinfo = ci->ci_paddr;
		membar_Sync();

		/* Disable interrupts and start another CPU. */
		pstate = getpstate();
		setpstate(PSTATE_KERN);

		prom_startcpu(ci->ci_node, (void *)cpu_spinup_trampoline, 0);

		for (i = 0; i < 2000; i++) {
			membar_Sync();
			if (CPUSET_HAS(cpus_active, ci->ci_index))
				break;
			delay(10000);
		}

		/* synchronize %tick ( to some degree at least ) */
		delay(1000);
		sync_tick = 1;
		membar_Sync();
		settick(0);
		if (ci->ci_system_clockrate[0] != 0)
			setstick(0);

		setpstate(pstate);

		if (!CPUSET_HAS(cpus_active, ci->ci_index))
			printf("cpu%d: startup failed\n", ci->ci_cpuid);
	}
}
Ejemplo n.º 5
0
/*
 * Write necessary machine dependent information to cpr state file,
 * eg. sun4u mmu ctx secondary for the current running process (cpr) ...
 */
int
i_cpr_write_machdep(vnode_t *vp)
{
	extern uint_t getpstate(), getwstate();
	extern uint_t i_cpr_tstack_size;
	const char ustr[] = ": unix-tte 2drop false ;";
	uintptr_t tinfo;
	label_t *ltp;
	cmd_t cmach;
	char *fmt;
	int rc;

	/*
	 * ustr[] is used as temporary forth words during
	 * slave startup sequence, see sfmmu_mp_startup()
	 */

	cmach.md_magic = (uint_t)CPR_MACHDEP_MAGIC;
	cmach.md_size = sizeof (m_info) + sizeof (ustr);

	if (rc = cpr_write(vp, (caddr_t)&cmach, sizeof (cmach))) {
		cpr_err(CE_WARN, "Failed to write descriptor.");
		return (rc);
	}

	/*
	 * m_info is now cleared in i_cpr_dump_setup()
	 */
	m_info.ksb = (uint32_t)STACK_BIAS;
	m_info.kpstate = (uint16_t)getpstate();
	m_info.kwstate = (uint16_t)getwstate();
	CPR_DEBUG(CPR_DEBUG1, "stack bias 0x%x, pstate 0x%x, wstate 0x%x\n",
	    m_info.ksb, m_info.kpstate, m_info.kwstate);

	ltp = &ttolwp(curthread)->lwp_qsav;
	m_info.qsav_pc = (cpr_ext)ltp->val[0];
	m_info.qsav_sp = (cpr_ext)ltp->val[1];

	/*
	 * Set secondary context to INVALID_CONTEXT to force the HAT
	 * to re-setup the MMU registers and locked TTEs it needs for
	 * TLB miss handling.
	 */
	m_info.mmu_ctx_sec = INVALID_CONTEXT;
	m_info.mmu_ctx_pri = KCONTEXT;

	tinfo = (uintptr_t)curthread;
	m_info.thrp = (cpr_ptr)tinfo;

	tinfo = (uintptr_t)i_cpr_resume_setup;
	m_info.func = (cpr_ptr)tinfo;

	/*
	 * i_cpr_data_page is comprised of a 4K stack area and a few
	 * trailing data symbols; the page is shared by the prom and
	 * kernel during resume.  the stack size is recorded here
	 * and used by cprboot to set %sp
	 */
	tinfo = (uintptr_t)&i_cpr_data_page;
	m_info.tmp_stack = (cpr_ptr)tinfo;
	m_info.tmp_stacksize = i_cpr_tstack_size;

	m_info.test_mode = cpr_test_mode;

	i_cpr_save_cpu_info();

	if (rc = cpr_write(vp, (caddr_t)&m_info, sizeof (m_info))) {
		cpr_err(CE_WARN, "Failed to write machdep info.");
		return (rc);
	}

	fmt = "error writing %s forth info";
	if (rc = cpr_write(vp, (caddr_t)ustr, sizeof (ustr)))
		cpr_err(CE_WARN, fmt, "unix-tte");

	return (rc);
}
Ejemplo n.º 6
0
void
cpu_lwp_fork(register struct lwp *l1, register struct lwp *l2, void *stack, size_t stacksize, void (*func)(void *), void *arg)
{
    struct pcb *opcb = lwp_getpcb(l1);
    struct pcb *npcb = lwp_getpcb(l2);
    struct trapframe *tf2;
    struct rwindow *rp;

    /*
     * Save all user registers to l1's stack or, in the case of
     * user registers and invalid stack pointers, to opcb.
     * We then copy the whole pcb to l2; when switch() selects l2
     * to run, it will run at the `lwp_trampoline' stub, rather
     * than returning at the copying code below.
     *
     * If process l1 has an FPU state, we must copy it.  If it is
     * the FPU user, we must save the FPU state first.
     */

#ifdef NOTDEF_DEBUG
    printf("cpu_lwp_fork()\n");
#endif
    if (l1 == curlwp) {
        write_user_windows();

        /*
         * We're in the kernel, so we don't really care about
         * %ccr or %asi.  We do want to duplicate %pstate and %cwp.
         */
        opcb->pcb_pstate = getpstate();
        opcb->pcb_cwp = getcwp();
    }
#ifdef DIAGNOSTIC
    else if (l1 != &lwp0)
        panic("cpu_lwp_fork: curlwp");
#endif
#ifdef DEBUG
    /* prevent us from having NULL lastcall */
    opcb->lastcall = cpu_forkname;
#else
    opcb->lastcall = NULL;
#endif
    memcpy(npcb, opcb, sizeof(struct pcb));
    if (l1->l_md.md_fpstate) {
        fpusave_lwp(l1, true);
        l2->l_md.md_fpstate = pool_cache_get(fpstate_cache, PR_WAITOK);
        memcpy(l2->l_md.md_fpstate, l1->l_md.md_fpstate,
               sizeof(struct fpstate64));
    } else
        l2->l_md.md_fpstate = NULL;

    /*
     * Setup (kernel) stack frame that will by-pass the child
     * out of the kernel. (The trap frame invariably resides at
     * the tippity-top of the u. area.)
     */
    tf2 = l2->l_md.md_tf = (struct trapframe *)
                           ((long)npcb + USPACE - sizeof(*tf2));

    /* Copy parent's trapframe */
    *tf2 = *(struct trapframe *)((long)opcb + USPACE - sizeof(*tf2));

    /*
     * If specified, give the child a different stack.
     */
    if (stack != NULL)
        tf2->tf_out[6] = (uint64_t)(u_long)stack + stacksize;

    /*
     * Set return values in child mode and clear condition code,
     * in case we end up running a signal handler before returning
     * to userland.
     */
    tf2->tf_out[0] = 0;
    tf2->tf_out[1] = 1;
    tf2->tf_tstate &= ~TSTATE_CCR;

    /* Construct kernel frame to return to in cpu_switch() */
    rp = (struct rwindow *)((u_long)npcb + TOPFRAMEOFF);
    *rp = *(struct rwindow *)((u_long)opcb + TOPFRAMEOFF);

    rp->rw_local[0] = (long)func;	/* Function to call */
    rp->rw_local[1] = (long)arg;	/* and its argument */
    rp->rw_local[2] = (long)l2;	/* new lwp */

    npcb->pcb_pc = (long)lwp_trampoline - 8;
    npcb->pcb_sp = (long)rp - STACK_OFFSET;
}