1176771Sraj/*-
2176771Sraj * Copyright (C) 2006 Semihalf, Rafal Jaworowski <raj@semihalf.com>
3176771Sraj * Copyright 2002 by Peter Grehan.
4176771Sraj * All rights reserved.
5176771Sraj *
6176771Sraj * Redistribution and use in source and binary forms, with or without
7176771Sraj * modification, are permitted provided that the following conditions
8176771Sraj * are met:
9176771Sraj * 1. Redistributions of source code must retain the above copyright
10176771Sraj *    notice, this list of conditions and the following disclaimer.
11176771Sraj * 2. Redistributions in binary form must reproduce the above copyright
12176771Sraj *    notice, this list of conditions and the following disclaimer in the
13176771Sraj *    documentation and/or other materials provided with the distribution.
14176771Sraj * 3. The name of the author may not be used to endorse or promote products
15176771Sraj *    derived from this software without specific prior written permission.
16176771Sraj *
17176771Sraj * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18176771Sraj * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19176771Sraj * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20176771Sraj * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21176771Sraj * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22176771Sraj * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23176771Sraj * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24176771Sraj * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25176771Sraj * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26176771Sraj * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27176771Sraj * SUCH DAMAGE.
28176771Sraj *
29176771Sraj */
30176771Sraj
31176771Sraj/*
32176771Sraj * Interrupts are dispatched to here from locore asm
33176771Sraj */
34176771Sraj
35176771Sraj#include <sys/cdefs.h>                  /* RCS ID & Copyright macro defns */
36176771Sraj__FBSDID("$FreeBSD: releng/10.3/sys/powerpc/booke/interrupt.c 223485 2011-06-23 22:21:28Z nwhitehorn $");
37176771Sraj
38176771Sraj#include <sys/param.h>
39176771Sraj#include <sys/systm.h>
40176771Sraj#include <sys/bus.h>
41176771Sraj#include <sys/interrupt.h>
42176771Sraj#include <sys/kernel.h>
43176771Sraj#include <sys/kthread.h>
44176771Sraj#include <sys/ktr.h>
45176771Sraj#include <sys/lock.h>
46176771Sraj#include <sys/malloc.h>
47176771Sraj#include <sys/mutex.h>
48176771Sraj#include <sys/proc.h>
49176771Sraj#include <sys/smp.h>
50176771Sraj#include <sys/unistd.h>
51176771Sraj#include <sys/vmmeter.h>
52176771Sraj
53176771Sraj#include <machine/cpu.h>
54176771Sraj#include <machine/db_machdep.h>
55176771Sraj#include <machine/frame.h>
56176771Sraj#include <machine/intr_machdep.h>
57176771Sraj#include <machine/md_var.h>
58176771Sraj#include <machine/pcb.h>
59176771Sraj#include <machine/psl.h>
60176771Sraj#include <machine/trap.h>
61176771Sraj
62176771Sraj#include "pic_if.h"
63176771Sraj
64176771Srajextern void decr_intr(struct trapframe *);
65176771Sraj
66176771Srajvoid powerpc_decr_interrupt(struct trapframe *);
67176771Srajvoid powerpc_extr_interrupt(struct trapframe *);
68176771Srajvoid powerpc_crit_interrupt(struct trapframe *);
69176771Srajvoid powerpc_mchk_interrupt(struct trapframe *);
70176771Sraj
71176771Srajstatic void dump_frame(struct trapframe *framep);
72176771Sraj
73176771Srajstatic void
74176771Srajdump_frame(struct trapframe *frame)
75176771Sraj{
76176771Sraj	int i;
77176771Sraj
78176771Sraj	printf("\n*** *** STACK FRAME DUMP *** ***\n");
79176771Sraj	printf("  exc  = 0x%x\n", frame->exc);
80176771Sraj	printf("  srr0 = 0x%08x\n", frame->srr0);
81176771Sraj	printf("  srr1 = 0x%08x\n", frame->srr1);
82176771Sraj	printf("  dear = 0x%08x\n", frame->cpu.booke.dear);
83176771Sraj	printf("  esr  = 0x%08x\n", frame->cpu.booke.esr);
84176771Sraj	printf("  lr   = 0x%08x\n", frame->lr);
85176771Sraj	printf("  cr   = 0x%08x\n", frame->cr);
86176771Sraj	printf("  sp   = 0x%08x\n", frame->fixreg[1]);
87176771Sraj
88176771Sraj	for (i = 0; i < 32; i++) {
89176771Sraj		printf("  R%02d = 0x%08x", i, frame->fixreg[i]);
90176771Sraj		if ((i & 0x3) == 3)
91176771Sraj			printf("\n");
92176771Sraj	}
93176771Sraj	printf("\n");
94176771Sraj}
95176771Sraj
96176771Srajvoid powerpc_crit_interrupt(struct trapframe *framep)
97176771Sraj{
98176771Sraj
99176771Sraj	printf("powerpc_crit_interrupt: critical interrupt!\n");
100176771Sraj	dump_frame(framep);
101176771Sraj	trap(framep);
102176771Sraj}
103176771Sraj
104176771Srajvoid powerpc_mchk_interrupt(struct trapframe *framep)
105176771Sraj{
106176771Sraj
107176771Sraj	printf("powerpc_mchk_interrupt: machine check interrupt!\n");
108176771Sraj	dump_frame(framep);
109176771Sraj	trap(framep);
110176771Sraj}
111176771Sraj
112176771Sraj/*
113176771Sraj * Decrementer interrupt routine
114176771Sraj */
115176771Srajvoid
116176771Srajpowerpc_decr_interrupt(struct trapframe *framep)
117176771Sraj{
118176771Sraj	struct thread *td;
119212453Smav	struct trapframe *oldframe;
120176771Sraj
121223485Snwhitehorn	td = curthread;
122204903Snwhitehorn	critical_enter();
123176771Sraj	atomic_add_int(&td->td_intr_nesting_level, 1);
124212453Smav	oldframe = td->td_intr_frame;
125212453Smav	td->td_intr_frame = framep;
126176771Sraj	decr_intr(framep);
127212453Smav	td->td_intr_frame = oldframe;
128176771Sraj	atomic_subtract_int(&td->td_intr_nesting_level, 1);
129204903Snwhitehorn	critical_exit();
130205527Smarcel	framep->srr1 &= ~PSL_WE;
131176771Sraj}
132176771Sraj
133176771Sraj/*
134176771Sraj * External input interrupt routine
135176771Sraj */
136176771Srajvoid
137176771Srajpowerpc_extr_interrupt(struct trapframe *framep)
138176771Sraj{
139176771Sraj
140204903Snwhitehorn	critical_enter();
141209298Snwhitehorn	PIC_DISPATCH(root_pic, framep);
142204903Snwhitehorn	critical_exit();
143205527Smarcel	framep->srr1 &= ~PSL_WE;
144176771Sraj}
145