Subversion Repositories HelenOS

Rev

Rev 4346 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
431 jermar 1
/*
2071 jermar 2
 * Copyright (c) 2005 Jakub Jermar
3
 * Copyright (c) 2005 Jakub Vana
431 jermar 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
 *
10
 * - Redistributions of source code must retain the above copyright
11
 *   notice, this list of conditions and the following disclaimer.
12
 * - Redistributions in binary form must reproduce the above copyright
13
 *   notice, this list of conditions and the following disclaimer in the
14
 *   documentation and/or other materials provided with the distribution.
15
 * - The name of the author may not be used to endorse or promote products
16
 *   derived from this software without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1702 cejka 28
 */
29
 
1705 cejka 30
/** @addtogroup ia64interrupt
1702 cejka 31
 * @{
32
 */
33
/** @file
431 jermar 34
 */
35
 
36
#include <arch/interrupt.h>
1942 jermar 37
#include <interrupt.h>
38
#include <ddi/irq.h>
431 jermar 39
#include <panic.h>
433 jermar 40
#include <print.h>
1942 jermar 41
#include <debug.h>
583 jermar 42
#include <console/console.h>
431 jermar 43
#include <arch/types.h>
44
#include <arch/asm.h>
45
#include <arch/barrier.h>
432 jermar 46
#include <arch/register.h>
433 jermar 47
#include <arch.h>
921 jermar 48
#include <syscall/syscall.h>
49
#include <print.h>
1023 vana 50
#include <proc/scheduler.h>
1265 jermar 51
#include <ipc/sysipc.h>
1507 vana 52
#include <ipc/irq.h>
53
#include <ipc/ipc.h>
1942 jermar 54
#include <synch/spinlock.h>
3674 svoboda 55
#include <mm/tlb.h>
4346 svoboda 56
#include <symtab.h>
4348 svoboda 57
#include <putchar.h>
431 jermar 58
 
470 jermar 59
#define VECTORS_64_BUNDLE	20
60
#define VECTORS_16_BUNDLE	48
61
#define VECTORS_16_BUNDLE_START	0x5000
62
#define VECTOR_MAX		0x7f00
63
 
64
#define BUNDLE_SIZE		16
65
 
66
char *vector_names_64_bundle[VECTORS_64_BUNDLE] = {
67
	"VHPT Translation vector",
68
	"Instruction TLB vector",
69
	"Data TLB vector",
70
	"Alternate Instruction TLB vector",
71
	"Alternate Data TLB vector",
72
	"Data Nested TLB vector",
73
	"Instruction Key Miss vector",
74
	"Data Key Miss vector",
75
	"Dirty-Bit vector",
76
	"Instruction Access-Bit vector",
77
	"Data Access-Bit vector"
78
	"Break Instruction vector",
79
	"External Interrupt vector"
80
	"Reserved",
81
	"Reserved",
82
	"Reserved",
83
	"Reserved",
84
	"Reserved",
85
	"Reserved",
86
	"Reserved"
87
};
88
 
89
char *vector_names_16_bundle[VECTORS_16_BUNDLE] = {
90
	"Page Not Present vector",
91
	"Key Permission vector",
92
	"Instruction Access rights vector",
93
	"Data Access Rights vector",
94
	"General Exception vector",
95
	"Disabled FP-Register vector",
96
	"NaT Consumption vector",
97
	"Speculation vector",
98
	"Reserved",
99
	"Debug vector",
100
	"Unaligned Reference vector",
101
	"Unsupported Data Reference vector",
102
	"Floating-point Fault vector",
103
	"Floating-point Trap vector",
104
	"Lower-Privilege Transfer Trap vector",
105
	"Taken Branch Trap vector",
2060 jermar 106
	"Single Step Trap vector",
470 jermar 107
	"Reserved",
108
	"Reserved",
109
	"Reserved",
110
	"Reserved",
111
	"Reserved",
112
	"Reserved",
113
	"Reserved",
114
	"Reserved",
115
	"IA-32 Exception vector",
116
	"IA-32 Intercept vector",
117
	"IA-32 Interrupt vector",
118
	"Reserved",
119
	"Reserved",
120
	"Reserved"
121
};
122
 
1780 jermar 123
static char *vector_to_string(uint16_t vector);
958 jermar 124
static void dump_interrupted_context(istate_t *istate);
470 jermar 125
 
1780 jermar 126
char *vector_to_string(uint16_t vector)
431 jermar 127
{
470 jermar 128
	ASSERT(vector <= VECTOR_MAX);
129
 
130
	if (vector >= VECTORS_16_BUNDLE_START)
2608 jermar 131
		return vector_names_16_bundle[(vector -
132
		    VECTORS_16_BUNDLE_START) / (16 * BUNDLE_SIZE)];
470 jermar 133
	else
2608 jermar 134
		return vector_names_64_bundle[vector / (64 * BUNDLE_SIZE)];
470 jermar 135
}
136
 
958 jermar 137
void dump_interrupted_context(istate_t *istate)
470 jermar 138
{
139
	char *ifa, *iipa, *iip;
140
 
4346 svoboda 141
	ifa = symtab_fmt_name_lookup(istate->cr_ifa);
142
	iipa = symtab_fmt_name_lookup(istate->cr_iipa);
143
	iip = symtab_fmt_name_lookup(istate->cr_iip);
470 jermar 144
 
145
	putchar('\n');
472 jermar 146
	printf("Interrupted context dump:\n");
2608 jermar 147
	printf("ar.bsp=%p\tar.bspstore=%p\n", istate->ar_bsp,
148
	    istate->ar_bspstore);
149
	printf("ar.rnat=%#018llx\tar.rsc=%#018llx\n", istate->ar_rnat,
150
	    istate->ar_rsc);
151
	printf("ar.ifs=%#018llx\tar.pfs=%#018llx\n", istate->ar_ifs,
152
	    istate->ar_pfs);
153
	printf("cr.isr=%#018llx\tcr.ipsr=%#018llx\t\n", istate->cr_isr.value,
154
	    istate->cr_ipsr);
470 jermar 155
 
2608 jermar 156
	printf("cr.iip=%#018llx, #%d\t(%s)\n", istate->cr_iip,
157
	    istate->cr_isr.ei, iip);
1507 vana 158
	printf("cr.iipa=%#018llx\t(%s)\n", istate->cr_iipa, iipa);
159
	printf("cr.ifa=%#018llx\t(%s)\n", istate->cr_ifa, ifa);
470 jermar 160
}
161
 
1780 jermar 162
void general_exception(uint64_t vector, istate_t *istate)
470 jermar 163
{
472 jermar 164
	char *desc = "";
165
 
958 jermar 166
	switch (istate->cr_isr.ge_code) {
1882 jermar 167
	case GE_ILLEGALOP:
472 jermar 168
		desc = "Illegal Operation fault";
169
		break;
1882 jermar 170
	case GE_PRIVOP:
472 jermar 171
		desc = "Privileged Operation fault";
172
		break;
1882 jermar 173
	case GE_PRIVREG:
472 jermar 174
		desc = "Privileged Register fault";
175
		break;
1882 jermar 176
	case GE_RESREGFLD:
472 jermar 177
		desc = "Reserved Register/Field fault";
178
		break;
1882 jermar 179
	case GE_DISBLDISTRAN:
472 jermar 180
		desc = "Disabled Instruction Set Transition fault";
181
		break;
1882 jermar 182
	case GE_ILLEGALDEP:
472 jermar 183
		desc = "Illegal Dependency fault";
184
		break;
1882 jermar 185
	default:
186
		desc = "unknown";
472 jermar 187
		break;
188
	}
189
 
4339 svoboda 190
	fault_if_from_uspace(istate, "General Exception (%s).", desc);
1595 palkovsky 191
 
192
	dump_interrupted_context(istate);
4339 svoboda 193
	panic("General Exception (%s).", desc);
470 jermar 194
}
195
 
1780 jermar 196
void disabled_fp_register(uint64_t vector, istate_t *istate)
1023 vana 197
{
4342 svoboda 198
#ifdef CONFIG_FPU_LAZY
199
	scheduler_fpu_lazy_request();
1053 vana 200
#else
4339 svoboda 201
	fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
2608 jermar 202
	    (uint16_t) vector, vector_to_string(vector));
1053 vana 203
	dump_interrupted_context(istate);
4339 svoboda 204
	panic("Interruption: %#hx (%s).", (uint16_t) vector,
2608 jermar 205
	    vector_to_string(vector));
1023 vana 206
#endif
207
}
208
 
1780 jermar 209
void nop_handler(uint64_t vector, istate_t *istate)
1023 vana 210
{
211
}
212
 
921 jermar 213
/** Handle syscall. */
1780 jermar 214
int break_instruction(uint64_t vector, istate_t *istate)
470 jermar 215
{
921 jermar 216
	/*
217
	 * Move to next instruction after BREAK.
218
	 */
958 jermar 219
	if (istate->cr_ipsr.ri == 2) {
220
		istate->cr_ipsr.ri = 0;
221
		istate->cr_iip += 16;
921 jermar 222
	} else {
958 jermar 223
		istate->cr_ipsr.ri++;
921 jermar 224
	}
225
 
2608 jermar 226
	return syscall_handler(istate->in0, istate->in1, istate->in2,
227
	    istate->in3, istate->in4, istate->in5, istate->in6);
470 jermar 228
}
229
 
1780 jermar 230
void universal_handler(uint64_t vector, istate_t *istate)
470 jermar 231
{
4339 svoboda 232
	fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
2608 jermar 233
	    (uint16_t) vector, vector_to_string(vector));
958 jermar 234
	dump_interrupted_context(istate);
4339 svoboda 235
	panic("Interruption: %#hx (%s).", (uint16_t) vector,
2608 jermar 236
	    vector_to_string(vector));
470 jermar 237
}
238
 
3674 svoboda 239
static void end_of_local_irq(void)
240
{
241
	asm volatile ("mov cr.eoi=r0;;");
242
}
243
 
244
 
1780 jermar 245
void external_interrupt(uint64_t vector, istate_t *istate)
470 jermar 246
{
433 jermar 247
	cr_ivr_t ivr;
4338 svoboda 248
	irq_t *irq;
431 jermar 249
 
433 jermar 250
	ivr.value = ivr_read();
431 jermar 251
	srlz_d();
444 vana 252
 
4338 svoboda 253
	switch (ivr.vector) {
254
	case INTERRUPT_SPURIOUS:
1942 jermar 255
#ifdef CONFIG_DEBUG
4338 svoboda 256
 		printf("cpu%d: spurious interrupt\n", CPU->id);
1942 jermar 257
#endif
4338 svoboda 258
		break;
1265 jermar 259
 
3674 svoboda 260
#ifdef CONFIG_SMP
4338 svoboda 261
	case VECTOR_TLB_SHOOTDOWN_IPI:
262
		tlb_shootdown_ipi_recv();
263
		end_of_local_irq();
264
		break;
3674 svoboda 265
#endif
266
 
4338 svoboda 267
	case INTERRUPT_TIMER:
268
		irq = irq_dispatch_and_lock(ivr.vector);
269
		if (irq) {
4343 svoboda 270
			irq->handler(irq);
4338 svoboda 271
			spinlock_unlock(&irq->lock);
272
		} else {
4339 svoboda 273
			panic("Unhandled Internal Timer Interrupt (%d).",
4338 svoboda 274
			    ivr.vector);
275
		}
276
		break;
277
	default:
278
		irq = irq_dispatch_and_lock(ivr.vector);
279
		if (irq) {
280
			/*
281
			 * The IRQ handler was found.
282
			 */
283
			if (irq->preack) {
284
				/* Send EOI before processing the interrupt */
285
				end_of_local_irq();
286
			}
4343 svoboda 287
			irq->handler(irq);
4338 svoboda 288
			if (!irq->preack)
289
				end_of_local_irq();
290
			spinlock_unlock(&irq->lock);
291
		} else {
292
			/*
293
			 * Unhandled interrupt.
294
			 */
295
			end_of_local_irq();
3674 svoboda 296
#ifdef CONFIG_DEBUG
4338 svoboda 297
			printf("\nUnhandled External Interrupt Vector %d\n",
298
			    ivr.vector);
3674 svoboda 299
#endif
1942 jermar 300
		}
4338 svoboda 301
		break;
302
	}
1507 vana 303
}
304
 
4342 svoboda 305
void trap_virtual_enable_irqs(uint16_t irqmask)
306
{
307
}
308
 
1703 jermar 309
/** @}
1702 cejka 310
 */