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