Subversion Repositories HelenOS

Rev

Rev 4343 | Go to most recent revision | 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>
431 jermar 57
 
470 jermar 58
#define VECTORS_64_BUNDLE	20
59
#define VECTORS_16_BUNDLE	48
60
#define VECTORS_16_BUNDLE_START	0x5000
61
#define VECTOR_MAX		0x7f00
62
 
63
#define BUNDLE_SIZE		16
64
 
65
char *vector_names_64_bundle[VECTORS_64_BUNDLE] = {
66
	"VHPT Translation vector",
67
	"Instruction TLB vector",
68
	"Data TLB vector",
69
	"Alternate Instruction TLB vector",
70
	"Alternate Data TLB vector",
71
	"Data Nested TLB vector",
72
	"Instruction Key Miss vector",
73
	"Data Key Miss vector",
74
	"Dirty-Bit vector",
75
	"Instruction Access-Bit vector",
76
	"Data Access-Bit vector"
77
	"Break Instruction vector",
78
	"External Interrupt vector"
79
	"Reserved",
80
	"Reserved",
81
	"Reserved",
82
	"Reserved",
83
	"Reserved",
84
	"Reserved",
85
	"Reserved"
86
};
87
 
88
char *vector_names_16_bundle[VECTORS_16_BUNDLE] = {
89
	"Page Not Present vector",
90
	"Key Permission vector",
91
	"Instruction Access rights vector",
92
	"Data Access Rights vector",
93
	"General Exception vector",
94
	"Disabled FP-Register vector",
95
	"NaT Consumption vector",
96
	"Speculation vector",
97
	"Reserved",
98
	"Debug vector",
99
	"Unaligned Reference vector",
100
	"Unsupported Data Reference vector",
101
	"Floating-point Fault vector",
102
	"Floating-point Trap vector",
103
	"Lower-Privilege Transfer Trap vector",
104
	"Taken Branch Trap vector",
2060 jermar 105
	"Single Step Trap vector",
470 jermar 106
	"Reserved",
107
	"Reserved",
108
	"Reserved",
109
	"Reserved",
110
	"Reserved",
111
	"Reserved",
112
	"Reserved",
113
	"Reserved",
114
	"IA-32 Exception vector",
115
	"IA-32 Intercept vector",
116
	"IA-32 Interrupt vector",
117
	"Reserved",
118
	"Reserved",
119
	"Reserved"
120
};
121
 
1780 jermar 122
static char *vector_to_string(uint16_t vector);
958 jermar 123
static void dump_interrupted_context(istate_t *istate);
470 jermar 124
 
1780 jermar 125
char *vector_to_string(uint16_t vector)
431 jermar 126
{
470 jermar 127
	ASSERT(vector <= VECTOR_MAX);
128
 
129
	if (vector >= VECTORS_16_BUNDLE_START)
2608 jermar 130
		return vector_names_16_bundle[(vector -
131
		    VECTORS_16_BUNDLE_START) / (16 * BUNDLE_SIZE)];
470 jermar 132
	else
2608 jermar 133
		return vector_names_64_bundle[vector / (64 * BUNDLE_SIZE)];
470 jermar 134
}
135
 
958 jermar 136
void dump_interrupted_context(istate_t *istate)
470 jermar 137
{
138
	char *ifa, *iipa, *iip;
139
 
4346 svoboda 140
	ifa = symtab_fmt_name_lookup(istate->cr_ifa);
141
	iipa = symtab_fmt_name_lookup(istate->cr_iipa);
142
	iip = symtab_fmt_name_lookup(istate->cr_iip);
470 jermar 143
 
144
	putchar('\n');
472 jermar 145
	printf("Interrupted context dump:\n");
2608 jermar 146
	printf("ar.bsp=%p\tar.bspstore=%p\n", istate->ar_bsp,
147
	    istate->ar_bspstore);
148
	printf("ar.rnat=%#018llx\tar.rsc=%#018llx\n", istate->ar_rnat,
149
	    istate->ar_rsc);
150
	printf("ar.ifs=%#018llx\tar.pfs=%#018llx\n", istate->ar_ifs,
151
	    istate->ar_pfs);
152
	printf("cr.isr=%#018llx\tcr.ipsr=%#018llx\t\n", istate->cr_isr.value,
153
	    istate->cr_ipsr);
470 jermar 154
 
2608 jermar 155
	printf("cr.iip=%#018llx, #%d\t(%s)\n", istate->cr_iip,
156
	    istate->cr_isr.ei, iip);
1507 vana 157
	printf("cr.iipa=%#018llx\t(%s)\n", istate->cr_iipa, iipa);
158
	printf("cr.ifa=%#018llx\t(%s)\n", istate->cr_ifa, ifa);
470 jermar 159
}
160
 
1780 jermar 161
void general_exception(uint64_t vector, istate_t *istate)
470 jermar 162
{
472 jermar 163
	char *desc = "";
164
 
958 jermar 165
	switch (istate->cr_isr.ge_code) {
1882 jermar 166
	case GE_ILLEGALOP:
472 jermar 167
		desc = "Illegal Operation fault";
168
		break;
1882 jermar 169
	case GE_PRIVOP:
472 jermar 170
		desc = "Privileged Operation fault";
171
		break;
1882 jermar 172
	case GE_PRIVREG:
472 jermar 173
		desc = "Privileged Register fault";
174
		break;
1882 jermar 175
	case GE_RESREGFLD:
472 jermar 176
		desc = "Reserved Register/Field fault";
177
		break;
1882 jermar 178
	case GE_DISBLDISTRAN:
472 jermar 179
		desc = "Disabled Instruction Set Transition fault";
180
		break;
1882 jermar 181
	case GE_ILLEGALDEP:
472 jermar 182
		desc = "Illegal Dependency fault";
183
		break;
1882 jermar 184
	default:
185
		desc = "unknown";
472 jermar 186
		break;
187
	}
188
 
4339 svoboda 189
	fault_if_from_uspace(istate, "General Exception (%s).", desc);
1595 palkovsky 190
 
191
	dump_interrupted_context(istate);
4339 svoboda 192
	panic("General Exception (%s).", desc);
470 jermar 193
}
194
 
1780 jermar 195
void disabled_fp_register(uint64_t vector, istate_t *istate)
1023 vana 196
{
4342 svoboda 197
#ifdef CONFIG_FPU_LAZY
198
	scheduler_fpu_lazy_request();
1053 vana 199
#else
4339 svoboda 200
	fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
2608 jermar 201
	    (uint16_t) vector, vector_to_string(vector));
1053 vana 202
	dump_interrupted_context(istate);
4339 svoboda 203
	panic("Interruption: %#hx (%s).", (uint16_t) vector,
2608 jermar 204
	    vector_to_string(vector));
1023 vana 205
#endif
206
}
207
 
1780 jermar 208
void nop_handler(uint64_t vector, istate_t *istate)
1023 vana 209
{
210
}
211
 
921 jermar 212
/** Handle syscall. */
1780 jermar 213
int break_instruction(uint64_t vector, istate_t *istate)
470 jermar 214
{
921 jermar 215
	/*
216
	 * Move to next instruction after BREAK.
217
	 */
958 jermar 218
	if (istate->cr_ipsr.ri == 2) {
219
		istate->cr_ipsr.ri = 0;
220
		istate->cr_iip += 16;
921 jermar 221
	} else {
958 jermar 222
		istate->cr_ipsr.ri++;
921 jermar 223
	}
224
 
2608 jermar 225
	return syscall_handler(istate->in0, istate->in1, istate->in2,
226
	    istate->in3, istate->in4, istate->in5, istate->in6);
470 jermar 227
}
228
 
1780 jermar 229
void universal_handler(uint64_t vector, istate_t *istate)
470 jermar 230
{
4339 svoboda 231
	fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
2608 jermar 232
	    (uint16_t) vector, vector_to_string(vector));
958 jermar 233
	dump_interrupted_context(istate);
4339 svoboda 234
	panic("Interruption: %#hx (%s).", (uint16_t) vector,
2608 jermar 235
	    vector_to_string(vector));
470 jermar 236
}
237
 
3674 svoboda 238
static void end_of_local_irq(void)
239
{
240
	asm volatile ("mov cr.eoi=r0;;");
241
}
242
 
243
 
1780 jermar 244
void external_interrupt(uint64_t vector, istate_t *istate)
470 jermar 245
{
433 jermar 246
	cr_ivr_t ivr;
4338 svoboda 247
	irq_t *irq;
431 jermar 248
 
433 jermar 249
	ivr.value = ivr_read();
431 jermar 250
	srlz_d();
444 vana 251
 
4338 svoboda 252
	switch (ivr.vector) {
253
	case INTERRUPT_SPURIOUS:
1942 jermar 254
#ifdef CONFIG_DEBUG
4338 svoboda 255
 		printf("cpu%d: spurious interrupt\n", CPU->id);
1942 jermar 256
#endif
4338 svoboda 257
		break;
1265 jermar 258
 
3674 svoboda 259
#ifdef CONFIG_SMP
4338 svoboda 260
	case VECTOR_TLB_SHOOTDOWN_IPI:
261
		tlb_shootdown_ipi_recv();
262
		end_of_local_irq();
263
		break;
3674 svoboda 264
#endif
265
 
4338 svoboda 266
	case INTERRUPT_TIMER:
267
		irq = irq_dispatch_and_lock(ivr.vector);
268
		if (irq) {
4343 svoboda 269
			irq->handler(irq);
4338 svoboda 270
			spinlock_unlock(&irq->lock);
271
		} else {
4339 svoboda 272
			panic("Unhandled Internal Timer Interrupt (%d).",
4338 svoboda 273
			    ivr.vector);
274
		}
275
		break;
276
	default:
277
		irq = irq_dispatch_and_lock(ivr.vector);
278
		if (irq) {
279
			/*
280
			 * The IRQ handler was found.
281
			 */
282
			if (irq->preack) {
283
				/* Send EOI before processing the interrupt */
284
				end_of_local_irq();
285
			}
4343 svoboda 286
			irq->handler(irq);
4338 svoboda 287
			if (!irq->preack)
288
				end_of_local_irq();
289
			spinlock_unlock(&irq->lock);
290
		} else {
291
			/*
292
			 * Unhandled interrupt.
293
			 */
294
			end_of_local_irq();
3674 svoboda 295
#ifdef CONFIG_DEBUG
4338 svoboda 296
			printf("\nUnhandled External Interrupt Vector %d\n",
297
			    ivr.vector);
3674 svoboda 298
#endif
1942 jermar 299
		}
4338 svoboda 300
		break;
301
	}
1507 vana 302
}
303
 
4342 svoboda 304
void trap_virtual_enable_irqs(uint16_t irqmask)
305
{
306
}
307
 
1703 jermar 308
/** @}
1702 cejka 309
 */