/* * spl0: * * Lower interrupt priority to IPL 0 -- must check for * software interrupts. */ void spl0(void) { if (ssir) { (void) alpha_pal_swpipl(ALPHA_PSL_IPL_SOFT); softintr_dispatch(); } (void) alpha_pal_swpipl(ALPHA_PSL_IPL_0); }
void splassert_check(int wantipl, const char *func) { int curipl = alpha_pal_rdps() & ALPHA_PSL_IPL_MASK; /* * Tell soft interrupts apart from regular levels. */ if (wantipl < 0) wantipl = IPL_SOFTINT; /* * Depending on the system, hardware interrupts may occur either * at level 3 or level 4. Avoid false positives in the former case. */ if (curipl == ALPHA_PSL_IPL_IO - 1) curipl = ALPHA_PSL_IPL_IO; if (curipl < wantipl) { splassert_fail(wantipl, curipl, func); /* * If splassert_ctl is set to not panic, raise the ipl * in a feeble attempt to reduce damage. */ alpha_pal_swpipl(wantipl); } }
/* * softintr_dispatch: * * Process pending software interrupts. */ void softintr_dispatch() { struct alpha_soft_intr *asi; struct alpha_soft_intrhand *sih; u_int64_t n, i; while ((n = atomic_loadlatch_ulong(&ssir, 0)) != 0) { for (i = 0; i < SI_NSOFT; i++) { if ((n & (1 << i)) == 0) continue; asi = &alpha_soft_intrs[i]; for (;;) { (void) alpha_pal_swpipl(ALPHA_PSL_IPL_HIGH); simple_lock(&asi->softintr_slock); sih = TAILQ_FIRST(&asi->softintr_q); if (sih != NULL) { TAILQ_REMOVE(&asi->softintr_q, sih, sih_q); sih->sih_pending = 0; } simple_unlock(&asi->softintr_slock); (void) alpha_pal_swpipl(ALPHA_PSL_IPL_SOFT); if (sih == NULL) break; uvmexp.softs++; (*sih->sih_fn)(sih->sih_arg); } } } }
/* * cpu_configure: * called at boot time, configure all devices on system */ void cpu_configure() { parse_prom_bootdev(); softintr_init(); /* * Disable interrupts during autoconfiguration. splhigh() won't * work, because it simply _raises_ the IPL, so if machine checks * are disabled, they'll stay disabled. Machine checks are needed * during autoconfig. */ (void)alpha_pal_swpipl(ALPHA_PSL_IPL_HIGH); if (config_rootfound("mainbus", "mainbus") == NULL) panic("no mainbus found"); (void)spl0(); hwrpb_restart_setup(); cold = 0; }
/* * cpu_configure: * called at boot time, configure all devices on system */ void cpu_configure(void) { parse_prom_bootdev(); /* * Disable interrupts during autoconfiguration. splhigh() won't * work, because it simply _raises_ the IPL, so if machine checks * are disabled, they'll stay disabled. Machine checks are needed * during autoconfig. */ (void)alpha_pal_swpipl(ALPHA_PSL_IPL_HIGH); if (config_rootfound("mainbus", NULL) == NULL) panic("no mainbus found"); (void)spl0(); /* * Note that bootstrapping is finished, and set the HWRPB up * to do restarts. */ hwrpb_restart_setup(); }
int _splraise(int s) { int cur = alpha_pal_rdps() & ALPHA_PSL_IPL_MASK; return (s > cur ? alpha_pal_swpipl(s) : cur); }