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