1/*-
2 * Copyright (C) 2006 Semihalf, Rafal Jaworowski <raj@semihalf.com>
3 * Copyright 2002 by Peter Grehan.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30
31/*
32 * Interrupts are dispatched to here from locore asm
33 */
34
35#include <sys/cdefs.h>                  /* RCS ID & Copyright macro defns */
36__FBSDID("$FreeBSD$");
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/bus.h>
41#include <sys/interrupt.h>
42#include <sys/kernel.h>
43#include <sys/kthread.h>
44#include <sys/ktr.h>
45#include <sys/lock.h>
46#include <sys/malloc.h>
47#include <sys/mutex.h>
48#include <sys/proc.h>
49#include <sys/smp.h>
50#include <sys/unistd.h>
51#include <sys/vmmeter.h>
52
53#include <machine/cpu.h>
54#include <machine/db_machdep.h>
55#include <machine/frame.h>
56#include <machine/intr_machdep.h>
57#include <machine/md_var.h>
58#include <machine/pcb.h>
59#include <machine/psl.h>
60#include <machine/trap.h>
61
62#include "pic_if.h"
63
64extern void decr_intr(struct trapframe *);
65
66void powerpc_decr_interrupt(struct trapframe *);
67void powerpc_extr_interrupt(struct trapframe *);
68void powerpc_crit_interrupt(struct trapframe *);
69void powerpc_mchk_interrupt(struct trapframe *);
70
71static void dump_frame(struct trapframe *framep);
72
73static void
74dump_frame(struct trapframe *frame)
75{
76	int i;
77
78	printf("\n*** *** STACK FRAME DUMP *** ***\n");
79	printf("  exc  = 0x%x\n", frame->exc);
80	printf("  srr0 = 0x%08x\n", frame->srr0);
81	printf("  srr1 = 0x%08x\n", frame->srr1);
82	printf("  dear = 0x%08x\n", frame->cpu.booke.dear);
83	printf("  esr  = 0x%08x\n", frame->cpu.booke.esr);
84	printf("  lr   = 0x%08x\n", frame->lr);
85	printf("  cr   = 0x%08x\n", frame->cr);
86	printf("  sp   = 0x%08x\n", frame->fixreg[1]);
87
88	for (i = 0; i < 32; i++) {
89		printf("  R%02d = 0x%08x", i, frame->fixreg[i]);
90		if ((i & 0x3) == 3)
91			printf("\n");
92	}
93	printf("\n");
94}
95
96void powerpc_crit_interrupt(struct trapframe *framep)
97{
98
99	printf("powerpc_crit_interrupt: critical interrupt!\n");
100	dump_frame(framep);
101	trap(framep);
102}
103
104void powerpc_mchk_interrupt(struct trapframe *framep)
105{
106
107	printf("powerpc_mchk_interrupt: machine check interrupt!\n");
108	dump_frame(framep);
109	trap(framep);
110}
111
112/*
113 * Decrementer interrupt routine
114 */
115void
116powerpc_decr_interrupt(struct trapframe *framep)
117{
118	struct thread *td;
119	struct trapframe *oldframe;
120
121	td = curthread;
122	critical_enter();
123	atomic_add_int(&td->td_intr_nesting_level, 1);
124	oldframe = td->td_intr_frame;
125	td->td_intr_frame = framep;
126	decr_intr(framep);
127	td->td_intr_frame = oldframe;
128	atomic_subtract_int(&td->td_intr_nesting_level, 1);
129	critical_exit();
130	framep->srr1 &= ~PSL_WE;
131}
132
133/*
134 * External input interrupt routine
135 */
136void
137powerpc_extr_interrupt(struct trapframe *framep)
138{
139
140	critical_enter();
141	PIC_DISPATCH(root_pic, framep);
142	critical_exit();
143	framep->srr1 &= ~PSL_WE;
144}
145