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 34256542Sjhibbits#include "opt_hwpmc_hooks.h" 35256542Sjhibbits 3699032Sbenno#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 3799032Sbenno 3899032Sbenno#include <sys/param.h> 3999032Sbenno#include <sys/systm.h> 4099032Sbenno#include <sys/bus.h> 4199032Sbenno#include <sys/interrupt.h> 4299032Sbenno#include <sys/kernel.h> 4399032Sbenno#include <sys/kthread.h> 4499032Sbenno#include <sys/ktr.h> 4599032Sbenno#include <sys/lock.h> 4699032Sbenno#include <sys/malloc.h> 4799032Sbenno#include <sys/mutex.h> 48256542Sjhibbits#ifdef HWPMC_HOOKS 49256542Sjhibbits#include <sys/pmckern.h> 50256542Sjhibbits#endif 5199032Sbenno#include <sys/proc.h> 5299032Sbenno#include <sys/smp.h> 5399032Sbenno#include <sys/unistd.h> 5499032Sbenno#include <sys/vmmeter.h> 5599032Sbenno 5699032Sbenno#include <machine/cpu.h> 57171805Smarcel#include <machine/clock.h> 5899032Sbenno#include <machine/db_machdep.h> 5999032Sbenno#include <machine/fpu.h> 6099032Sbenno#include <machine/frame.h> 61171785Smarcel#include <machine/intr_machdep.h> 62171805Smarcel#include <machine/md_var.h> 6399032Sbenno#include <machine/pcb.h> 6499032Sbenno#include <machine/psl.h> 6599032Sbenno#include <machine/trap.h> 6699032Sbenno#include <machine/spr.h> 6799032Sbenno#include <machine/sr.h> 6899032Sbenno 69171805Smarcel#include "pic_if.h" 7099032Sbenno 7199032Sbenno/* 7299032Sbenno * A very short dispatch, to try and maximise assembler code use 7399032Sbenno * between all exception types. Maybe 'true' interrupts should go 7499032Sbenno * here, and the trap code can come in separately 7599032Sbenno */ 7699032Sbennovoid 7799032Sbennopowerpc_interrupt(struct trapframe *framep) 7899032Sbenno{ 79171787Smarcel struct thread *td; 80212453Smav struct trapframe *oldframe; 81171787Smarcel register_t ee; 8299032Sbenno 8399032Sbenno td = curthread; 8499032Sbenno 85182580Smarcel CTR2(KTR_INTR, "%s: EXC=%x", __func__, framep->exc); 86182580Smarcel 8799032Sbenno switch (framep->exc) { 8899032Sbenno case EXC_EXI: 89204903Snwhitehorn critical_enter(); 90209298Snwhitehorn PIC_DISPATCH(root_pic, framep); 91204903Snwhitehorn critical_exit(); 9299032Sbenno break; 9399032Sbenno 9499032Sbenno case EXC_DECR: 95204903Snwhitehorn critical_enter(); 9699032Sbenno atomic_add_int(&td->td_intr_nesting_level, 1); 97212453Smav oldframe = td->td_intr_frame; 98212453Smav td->td_intr_frame = framep; 99153666Sjhb decr_intr(framep); 100212453Smav td->td_intr_frame = oldframe; 101212453Smav atomic_subtract_int(&td->td_intr_nesting_level, 1); 102204903Snwhitehorn critical_exit(); 10399032Sbenno break; 104256581Sjhibbits#ifdef HWPMC_HOOKS 105256542Sjhibbits case EXC_PERF: 106256542Sjhibbits critical_enter(); 107256542Sjhibbits KASSERT(pmc_intr != NULL, ("Performance exception, but no handler!")); 108256542Sjhibbits (*pmc_intr)(PCPU_GET(cpuid), framep); 109256542Sjhibbits if (pmc_hook && (PCPU_GET(curthread)->td_pflags & TDP_CALLCHAIN)) 110256542Sjhibbits pmc_hook(PCPU_GET(curthread), PMC_FN_USER_CALLCHAIN, framep); 111256542Sjhibbits critical_exit(); 112256542Sjhibbits break; 113256581Sjhibbits#endif 11499032Sbenno 11599032Sbenno default: 116171787Smarcel /* Re-enable interrupts if applicable. */ 117171787Smarcel ee = framep->srr1 & PSL_EE; 118222614Snwhitehorn if (ee != 0) 119171787Smarcel mtmsr(mfmsr() | ee); 12099032Sbenno trap(framep); 12199032Sbenno } 12299032Sbenno} 123