1139825Simp/*- 299032Sbenno * Copyright 2002 by Peter Grehan. All rights reserved. 399032Sbenno * 499032Sbenno * Redistribution and use in source and binary forms, with or without 599032Sbenno * modification, are permitted provided that the following conditions 699032Sbenno * are met: 799032Sbenno * 1. Redistributions of source code must retain the above copyright 899032Sbenno * notice, this list of conditions and the following disclaimer. 999032Sbenno * 2. Redistributions in binary form must reproduce the above copyright 1099032Sbenno * notice, this list of conditions and the following disclaimer in the 1199032Sbenno * documentation and/or other materials provided with the distribution. 1299032Sbenno * 3. The name of the author may not be used to endorse or promote products 1399032Sbenno * derived from this software without specific prior written permission. 1499032Sbenno * 1599032Sbenno * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1699032Sbenno * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1799032Sbenno * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1899032Sbenno * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1999032Sbenno * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2099032Sbenno * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 2199032Sbenno * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2299032Sbenno * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2399032Sbenno * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2499032Sbenno * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2599032Sbenno * SUCH DAMAGE. 2699032Sbenno * 2799032Sbenno * $FreeBSD$ 2899032Sbenno */ 2999032Sbenno 3099032Sbenno/* 3199032Sbenno * Interrupts are dispatched to here from locore asm 3299032Sbenno */ 3399032Sbenno 3499032Sbenno#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 3599032Sbenno 3699032Sbenno#include <sys/param.h> 3799032Sbenno#include <sys/systm.h> 3899032Sbenno#include <sys/bus.h> 3999032Sbenno#include <sys/interrupt.h> 4099032Sbenno#include <sys/kernel.h> 4199032Sbenno#include <sys/kthread.h> 4299032Sbenno#include <sys/ktr.h> 4399032Sbenno#include <sys/lock.h> 4499032Sbenno#include <sys/malloc.h> 4599032Sbenno#include <sys/mutex.h> 4699032Sbenno#include <sys/proc.h> 4799032Sbenno#include <sys/smp.h> 4899032Sbenno#include <sys/unistd.h> 4999032Sbenno#include <sys/vmmeter.h> 5099032Sbenno 5199032Sbenno#include <machine/cpu.h> 52171805Smarcel#include <machine/clock.h> 5399032Sbenno#include <machine/db_machdep.h> 5499032Sbenno#include <machine/fpu.h> 5599032Sbenno#include <machine/frame.h> 56171785Smarcel#include <machine/intr_machdep.h> 57171805Smarcel#include <machine/md_var.h> 5899032Sbenno#include <machine/pcb.h> 5999032Sbenno#include <machine/psl.h> 6099032Sbenno#include <machine/trap.h> 6199032Sbenno#include <machine/spr.h> 6299032Sbenno#include <machine/sr.h> 6399032Sbenno 64171805Smarcel#include "pic_if.h" 6599032Sbenno 6699032Sbenno/* 6799032Sbenno * A very short dispatch, to try and maximise assembler code use 6899032Sbenno * between all exception types. Maybe 'true' interrupts should go 6999032Sbenno * here, and the trap code can come in separately 7099032Sbenno */ 7199032Sbennovoid 7299032Sbennopowerpc_interrupt(struct trapframe *framep) 7399032Sbenno{ 74171787Smarcel struct thread *td; 75212453Smav struct trapframe *oldframe; 76171787Smarcel register_t ee; 7799032Sbenno 7899032Sbenno td = curthread; 7999032Sbenno 80182580Smarcel CTR2(KTR_INTR, "%s: EXC=%x", __func__, framep->exc); 81182580Smarcel 8299032Sbenno switch (framep->exc) { 8399032Sbenno case EXC_EXI: 84204903Snwhitehorn critical_enter(); 85209298Snwhitehorn PIC_DISPATCH(root_pic, framep); 86204903Snwhitehorn critical_exit(); 8799032Sbenno break; 8899032Sbenno 8999032Sbenno case EXC_DECR: 90204903Snwhitehorn critical_enter(); 9199032Sbenno atomic_add_int(&td->td_intr_nesting_level, 1); 92212453Smav oldframe = td->td_intr_frame; 93212453Smav td->td_intr_frame = framep; 94153666Sjhb decr_intr(framep); 95212453Smav td->td_intr_frame = oldframe; 96212453Smav atomic_subtract_int(&td->td_intr_nesting_level, 1); 97204903Snwhitehorn critical_exit(); 9899032Sbenno break; 9999032Sbenno 10099032Sbenno default: 101171787Smarcel /* Re-enable interrupts if applicable. */ 102171787Smarcel ee = framep->srr1 & PSL_EE; 103222614Snwhitehorn if (ee != 0) 104171787Smarcel mtmsr(mfmsr() | ee); 10599032Sbenno trap(framep); 10699032Sbenno } 10799032Sbenno} 108