Example #1
0
/** Perform sparc64 specific steps before scheduling a thread.
 *
 * For userspace threads, initialize pointer to the kernel stack and for the
 * userspace window buffer.
 */
void before_thread_runs_arch(void)
{
	if (THREAD->uspace) {
		uint64_t sp = (uintptr_t) THREAD->kstack + STACK_SIZE -
		    (STACK_BIAS + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT));
		asi_u64_write(ASI_SCRATCHPAD, SCRATCHPAD_KSTACK, sp);
		asi_u64_write(ASI_SCRATCHPAD, SCRATCHPAD_WBUF,
		    (uintptr_t) THREAD->arch.uspace_window_buffer);
	}
}
Example #2
0
/** Process hardware interrupt.
 *
 * @param n Ignored.
 * @param istate Ignored.
 */
void interrupt(unsigned int n, istate_t *istate)
{
	uint64_t status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0);
	if (status & (!INTR_DISPATCH_STATUS_BUSY))
		panic("Interrupt Dispatch Status busy bit not set\n");
	
	uint64_t intrcv = asi_u64_read(ASI_INTR_RECEIVE, 0);
#if defined (US)
	uint64_t data0 = asi_u64_read(ASI_INTR_R, ASI_UDB_INTR_R_DATA_0);
#elif defined (US3)
	uint64_t data0 = asi_u64_read(ASI_INTR_R, VA_INTR_R_DATA_0);
#endif
	
	irq_t *irq = irq_dispatch_and_lock(data0);
	if (irq) {
		/*
		 * The IRQ handler was found.
		 */
		irq->handler(irq);
		
		/*
		 * See if there is a clear-interrupt-routine and call it.
		 */
		if (irq->cir)
			irq->cir(irq->cir_arg, irq->inr);
		
		irq_spinlock_unlock(&irq->lock, false);
	} else if (data0 > config.base) {
		/*
		 * This is a cross-call.
		 * data0 contains address of the kernel function.
		 * We call the function only after we verify
		 * it is one of the supported ones.
		 */
#ifdef CONFIG_SMP
		if (data0 == (uintptr_t) tlb_shootdown_ipi_recv)
			tlb_shootdown_ipi_recv();
#endif
	} else {
		/*
		 * Spurious interrupt.
		 */
#ifdef CONFIG_DEBUG
		log(LF_ARCH, LVL_DEBUG,
		    "cpu%u: spurious interrupt (intrcv=%#" PRIx64 ", data0=%#"
		    PRIx64 ")", CPU->id, intrcv, data0);
#else
		(void) intrcv;
#endif
	}
	
	membar();
	asi_u64_write(ASI_INTR_RECEIVE, 0, 0);
}