Exemple #1
0
/*
 * Set interrupt target.
 * Return previous value.
 */
u_int
setitr(u_int mid)
{
#if defined(MULTIPROCESSOR)
	u_int v;

	if (!CPU_ISSUN4M || sparc_ncpus <= 1)
		return (0);

	v = *((u_int *)ICR_ITR);
	*((u_int *)ICR_ITR) = CPU_MID2CPUNO(mid);
	return (v + 8);
#else
	return (0);
#endif
}
/*
 * On sun4ms we have to do some nasty stuff here. We need to map
 * in the interrupt registers (since we need to find out where
 * they are from the PROM, since they aren't in a fixed place), and
 * disable all interrupts. We can't do this easily from locore
 * since the PROM is ugly to use from assembly. We also need to map
 * in the counter registers because we can't disable the level 14
 * (statclock) interrupt, so we need a handler early on (ugh).
 *
 * NOTE: We *demand* the psl to stay at splhigh() at least until
 * we get here. The system _cannot_ take interrupts until we map
 * the interrupt registers.
 */
static void
bootstrap4m(void)
{
	int node;
	int nvaddrs, *vaddrs, vstore[10];
	u_int pte;
	int i;
	extern void setpte4m(u_int, u_int);

	if ((node = prom_opennode("/obio/interrupt")) == 0
	    && (node = prom_finddevice("/obio/interrupt")) == 0)
		panic("bootstrap: could not get interrupt "
		      "node from prom");

	vaddrs = vstore;
	nvaddrs = sizeof(vstore)/sizeof(vstore[0]);
	if (prom_getprop(node, "address", sizeof(int),
		    &nvaddrs, &vaddrs) != 0) {
		printf("bootstrap: could not get interrupt properties");
		prom_halt();
	}
	if (nvaddrs < 2 || nvaddrs > 5) {
		printf("bootstrap: cannot handle %d interrupt regs\n",
		       nvaddrs);
		prom_halt();
	}

	for (i = 0; i < nvaddrs - 1; i++) {
		pte = getpte4m((u_int)vaddrs[i]);
		if ((pte & SRMMU_TETYPE) != SRMMU_TEPTE) {
			panic("bootstrap: PROM has invalid mapping for "
			      "processor interrupt register %d",i);
			prom_halt();
		}
		pte |= PPROT_S;

		/* Duplicate existing mapping */
		setpte4m(PI_INTR_VA + (_MAXNBPG * i), pte);
	}
	cpuinfo.intreg_4m = (struct icr_pi *)
		(PI_INTR_VA + (_MAXNBPG * CPU_MID2CPUNO(bootmid)));

	/*
	 * That was the processor register...now get system register;
	 * it is the last returned by the PROM
	 */
	pte = getpte4m((u_int)vaddrs[i]);
	if ((pte & SRMMU_TETYPE) != SRMMU_TEPTE)
		panic("bootstrap: PROM has invalid mapping for system "
		      "interrupt register");
	pte |= PPROT_S;

	setpte4m(SI_INTR_VA, pte);

	/* Now disable interrupts */
	icr_si_bis(SINTR_MA);

	/* Send all interrupts to primary processor */
	*((u_int *)ICR_ITR) = CPU_MID2CPUNO(bootmid);

#ifdef DEBUG
/*	printf("SINTR: mask: 0x%x, pend: 0x%x\n", *(int*)ICR_SI_MASK,
	       *(int*)ICR_SI_PEND);
*/
#endif
}