Revision 4de9b249
b/Makefile.target | ||
---|---|---|
376 | 376 |
CPPFLAGS += -DHAS_AUDIO |
377 | 377 |
endif |
378 | 378 |
ifeq ($(TARGET_ARCH), mips) |
379 |
VL_OBJS+= mips_r4k.o mips_malta.o mips_timer.o dma.o vga.o serial.o i8254.o i8259.o |
|
379 |
VL_OBJS+= mips_r4k.o mips_malta.o mips_timer.o mips_int.o dma.o vga.o serial.o i8254.o i8259.o
|
|
380 | 380 |
VL_OBJS+= ide.o gt64xxx.o pckbd.o ps2.o fdc.o mc146818rtc.o usb-uhci.o acpi.o |
381 | 381 |
VL_OBJS+= piix_pci.o parallel.o mixeng.o cirrus_vga.o $(SOUND_HW) $(AUDIODRV) |
382 | 382 |
DEFINES += -DHAS_AUDIO |
b/cpu-exec.c | ||
---|---|---|
535 | 535 |
env->exception_index = EXCP_EXT_INTERRUPT; |
536 | 536 |
env->error_code = 0; |
537 | 537 |
do_interrupt(env); |
538 |
env->interrupt_request &= ~CPU_INTERRUPT_HARD; |
|
539 | 538 |
#if defined(__sparc__) && !defined(HOST_SOLARIS) |
540 | 539 |
tmp_T0 = 0; |
541 | 540 |
#else |
b/hw/gt64xxx.c | ||
---|---|---|
1 | 1 |
/* |
2 | 2 |
* QEMU GT64120 PCI host |
3 | 3 |
* |
4 |
* Copyright (c) 2006 Aurelien Jarno |
|
4 |
* Copyright (c) 2006,2007 Aurelien Jarno
|
|
5 | 5 |
* |
6 | 6 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | 7 |
* of this software and associated documentation files (the "Software"), to deal |
... | ... | |
433 | 433 |
val = s->regs[saddr]; |
434 | 434 |
break; |
435 | 435 |
case GT_PCI0_IACK: |
436 |
val = pic_intack_read(isa_pic); |
|
436 |
/* Read the IRQ number */ |
|
437 |
val = pic_read_irq(isa_pic); |
|
437 | 438 |
break; |
438 | 439 |
|
439 | 440 |
/* SDRAM Parameters */ |
b/hw/i8259.c | ||
---|---|---|
161 | 161 |
#endif |
162 | 162 |
s->irq_request(s->irq_request_opaque, 1); |
163 | 163 |
} |
164 |
|
|
165 |
/* all targets should do this rather than acking the IRQ in the cpu */ |
|
166 |
#if defined(TARGET_MIPS) |
|
167 |
else { |
|
168 |
s->irq_request(s->irq_request_opaque, 0); |
|
169 |
} |
|
170 |
#endif |
|
164 | 171 |
} |
165 | 172 |
|
166 | 173 |
#ifdef DEBUG_IRQ_LATENCY |
b/hw/mips_int.c | ||
---|---|---|
1 |
#include "vl.h" |
|
2 |
#include "cpu.h" |
|
3 |
|
|
4 |
/* Raise IRQ to CPU if necessary. It must be called every time the active |
|
5 |
IRQ may change */ |
|
6 |
void cpu_mips_update_irq(CPUState *env) |
|
7 |
{ |
|
8 |
if ((env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) && |
|
9 |
(env->CP0_Status & (1 << CP0St_IE)) && |
|
10 |
!(env->hflags & MIPS_HFLAG_EXL) && |
|
11 |
!(env->hflags & MIPS_HFLAG_ERL) && |
|
12 |
!(env->hflags & MIPS_HFLAG_DM)) { |
|
13 |
if (! (env->interrupt_request & CPU_INTERRUPT_HARD)) { |
|
14 |
cpu_interrupt(env, CPU_INTERRUPT_HARD); |
|
15 |
} |
|
16 |
} else { |
|
17 |
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); |
|
18 |
} |
|
19 |
} |
|
20 |
|
|
21 |
void cpu_mips_irq_request(void *opaque, int irq, int level) |
|
22 |
{ |
|
23 |
CPUState *env = first_cpu; |
|
24 |
|
|
25 |
uint32_t mask; |
|
26 |
|
|
27 |
if (irq >= 16) |
|
28 |
return; |
|
29 |
|
|
30 |
mask = 1 << (irq + CP0Ca_IP); |
|
31 |
|
|
32 |
if (level) { |
|
33 |
env->CP0_Cause |= mask; |
|
34 |
} else { |
|
35 |
env->CP0_Cause &= ~mask; |
|
36 |
} |
|
37 |
cpu_mips_update_irq(env); |
|
38 |
} |
|
39 |
|
b/hw/mips_malta.c | ||
---|---|---|
54 | 54 |
|
55 | 55 |
static PITState *pit; |
56 | 56 |
|
57 |
/* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */ |
|
57 | 58 |
static void pic_irq_request(void *opaque, int level) |
58 | 59 |
{ |
59 |
CPUState *env = first_cpu; |
|
60 |
if (level) { |
|
61 |
env->CP0_Cause |= 0x00000400; |
|
62 |
cpu_interrupt(env, CPU_INTERRUPT_HARD); |
|
63 |
} else { |
|
64 |
env->CP0_Cause &= ~0x00000400; |
|
65 |
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); |
|
66 |
} |
|
60 |
cpu_mips_irq_request(opaque, 2, level); |
|
67 | 61 |
} |
68 | 62 |
|
69 | 63 |
/* Malta FPGA */ |
b/hw/mips_r4k.c | ||
---|---|---|
38 | 38 |
/*The PIC is attached to the MIPS CPU INT0 pin */ |
39 | 39 |
static void pic_irq_request(void *opaque, int level) |
40 | 40 |
{ |
41 |
CPUState *env = first_cpu; |
|
42 |
if (level) { |
|
43 |
env->CP0_Cause |= 0x00000400; |
|
44 |
cpu_interrupt(env, CPU_INTERRUPT_HARD); |
|
45 |
} else { |
|
46 |
env->CP0_Cause &= ~0x00000400; |
|
47 |
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); |
|
48 |
} |
|
41 |
cpu_mips_irq_request(opaque, 2, level); |
|
49 | 42 |
} |
50 | 43 |
|
51 | 44 |
static void mips_qemu_writel (void *opaque, target_phys_addr_t addr, |
b/hw/mips_timer.c | ||
---|---|---|
57 | 57 |
void cpu_mips_store_compare (CPUState *env, uint32_t value) |
58 | 58 |
{ |
59 | 59 |
cpu_mips_update_count(env, cpu_mips_get_count(env), value); |
60 |
env->CP0_Cause &= ~0x00008000; |
|
61 |
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); |
|
60 |
cpu_mips_irq_request(env, 7, 0); |
|
62 | 61 |
} |
63 | 62 |
|
64 | 63 |
static void mips_timer_cb (void *opaque) |
... | ... | |
72 | 71 |
} |
73 | 72 |
#endif |
74 | 73 |
cpu_mips_update_count(env, cpu_mips_get_count(env), env->CP0_Compare); |
75 |
env->CP0_Cause |= 0x00008000; |
|
76 |
cpu_interrupt(env, CPU_INTERRUPT_HARD); |
|
74 |
cpu_mips_irq_request(env, 7, 1); |
|
77 | 75 |
} |
78 | 76 |
|
79 | 77 |
void cpu_mips_clock_init (CPUState *env) |
b/target-mips/cpu.h | ||
---|---|---|
158 | 158 |
#define CP0Ca_IV 23 |
159 | 159 |
#define CP0Ca_WP 22 |
160 | 160 |
#define CP0Ca_IP 8 |
161 |
#define CP0Ca_IP_mask 0x0000FF00 |
|
161 | 162 |
#define CP0Ca_EC 2 |
162 | 163 |
target_ulong CP0_EPC; |
163 | 164 |
int32_t CP0_PRid; |
b/target-mips/exec.h | ||
---|---|---|
164 | 164 |
uint32_t cpu_mips_get_count (CPUState *env); |
165 | 165 |
void cpu_mips_store_count (CPUState *env, uint32_t value); |
166 | 166 |
void cpu_mips_store_compare (CPUState *env, uint32_t value); |
167 |
void cpu_mips_update_irq(CPUState *env); |
|
167 | 168 |
void cpu_mips_clock_init (CPUState *env); |
168 | 169 |
void cpu_mips_tlb_flush (CPUState *env, int flush_global); |
169 | 170 |
|
b/target-mips/op.c | ||
---|---|---|
1357 | 1357 |
|
1358 | 1358 |
void op_mtc0_status (void) |
1359 | 1359 |
{ |
1360 |
uint32_t val, old, mask;
|
|
1360 |
uint32_t val, old; |
|
1361 | 1361 |
|
1362 | 1362 |
val = (int32_t)T0 & 0xFA78FF01; |
1363 | 1363 |
old = env->CP0_Status; |
... | ... | |
1374 | 1374 |
else |
1375 | 1375 |
env->hflags &= ~MIPS_HFLAG_EXL; |
1376 | 1376 |
env->CP0_Status = val; |
1377 |
/* If we unmasked an asserted IRQ, raise it */ |
|
1378 |
mask = 0x0000FF00; |
|
1379 | 1377 |
if (loglevel & CPU_LOG_TB_IN_ASM) |
1380 | 1378 |
CALL_FROM_TB2(do_mtc0_status_debug, old, val); |
1381 |
if ((val & (1 << CP0St_IE)) && !(old & (1 << CP0St_IE)) && |
|
1382 |
!(env->hflags & MIPS_HFLAG_EXL) && |
|
1383 |
!(env->hflags & MIPS_HFLAG_ERL) && |
|
1384 |
!(env->hflags & MIPS_HFLAG_DM) && |
|
1385 |
(env->CP0_Status & env->CP0_Cause & mask)) { |
|
1386 |
env->interrupt_request |= CPU_INTERRUPT_HARD; |
|
1387 |
if (logfile) |
|
1388 |
CALL_FROM_TB0(do_mtc0_status_irqraise_debug); |
|
1389 |
} else if (!(val & (1 << CP0St_IE)) && (old & (1 << CP0St_IE))) { |
|
1390 |
env->interrupt_request &= ~CPU_INTERRUPT_HARD; |
|
1391 |
} |
|
1379 |
CALL_FROM_TB1(cpu_mips_update_irq, env); |
|
1392 | 1380 |
RETURN(); |
1393 | 1381 |
} |
1394 | 1382 |
|
... | ... | |
1415 | 1403 |
|
1416 | 1404 |
void op_mtc0_cause (void) |
1417 | 1405 |
{ |
1418 |
uint32_t val, old;
|
|
1406 |
env->CP0_Cause = (env->CP0_Cause & 0xB000F87C) | (T0 & 0x00C00300);
|
|
1419 | 1407 |
|
1420 |
val = (env->CP0_Cause & 0xB000F87C) | (T0 & 0x00C00300); |
|
1421 |
old = env->CP0_Cause; |
|
1422 |
env->CP0_Cause = val; |
|
1423 |
#if 0 |
|
1424 |
{ |
|
1425 |
int i, mask; |
|
1426 |
/* Check if we ever asserted a software IRQ */ |
|
1427 |
for (i = 0; i < 2; i++) { |
|
1428 |
mask = 0x100 << i; |
|
1429 |
if ((val & mask) & !(old & mask)) |
|
1430 |
CALL_FROM_TB1(mips_set_irq, i); |
|
1431 |
} |
|
1408 |
/* Handle the software interrupt as an hardware one, as they |
|
1409 |
are very similar */ |
|
1410 |
if (T0 & CP0Ca_IP_mask) { |
|
1411 |
CALL_FROM_TB1(cpu_mips_update_irq, env); |
|
1432 | 1412 |
} |
1433 |
#endif |
|
1434 | 1413 |
RETURN(); |
1435 | 1414 |
} |
1436 | 1415 |
|
... | ... | |
2074 | 2053 |
|
2075 | 2054 |
void op_di (void) |
2076 | 2055 |
{ |
2077 |
uint32_t val; |
|
2078 |
|
|
2079 | 2056 |
T0 = env->CP0_Status; |
2080 |
val = T0 & ~(1 << CP0St_IE); |
|
2081 |
if (val != T0) { |
|
2082 |
env->interrupt_request &= ~CPU_INTERRUPT_HARD; |
|
2083 |
env->CP0_Status = val; |
|
2084 |
} |
|
2057 |
env->CP0_Status = T0 & ~(1 << CP0St_IE); |
|
2058 |
CALL_FROM_TB1(cpu_mips_update_irq, env); |
|
2085 | 2059 |
RETURN(); |
2086 | 2060 |
} |
2087 | 2061 |
|
2088 | 2062 |
void op_ei (void) |
2089 | 2063 |
{ |
2090 |
uint32_t val; |
|
2091 |
|
|
2092 | 2064 |
T0 = env->CP0_Status; |
2093 |
val = T0 | (1 << CP0St_IE); |
|
2094 |
if (val != T0) { |
|
2095 |
const uint32_t mask = 0x0000FF00; |
|
2096 |
|
|
2097 |
env->CP0_Status = val; |
|
2098 |
if (!(env->hflags & MIPS_HFLAG_EXL) && |
|
2099 |
!(env->hflags & MIPS_HFLAG_ERL) && |
|
2100 |
!(env->hflags & MIPS_HFLAG_DM) && |
|
2101 |
(env->CP0_Status & env->CP0_Cause & mask)) { |
|
2102 |
env->interrupt_request |= CPU_INTERRUPT_HARD; |
|
2103 |
if (logfile) |
|
2104 |
CALL_FROM_TB0(do_mtc0_status_irqraise_debug); |
|
2105 |
} |
|
2106 |
} |
|
2065 |
env->CP0_Status = T0 | (1 << CP0St_IE); |
|
2066 |
CALL_FROM_TB1(cpu_mips_update_irq, env); |
|
2107 | 2067 |
RETURN(); |
2108 | 2068 |
} |
2109 | 2069 |
|
b/target-mips/op_helper.c | ||
---|---|---|
265 | 265 |
cpu_abort(env, "mtc0 compare\n"); |
266 | 266 |
} |
267 | 267 |
|
268 |
void cpu_mips_update_irq(CPUState *env) |
|
269 |
{ |
|
270 |
cpu_abort(env, "mtc0 status / mtc0 cause\n"); |
|
271 |
} |
|
272 |
|
|
268 | 273 |
void do_mtc0_status_debug(uint32_t old, uint32_t val) |
269 | 274 |
{ |
270 | 275 |
cpu_abort(env, "mtc0 status debug\n"); |
b/vl.h | ||
---|---|---|
1067 | 1067 |
/* mips_malta.c */ |
1068 | 1068 |
extern QEMUMachine mips_malta_machine; |
1069 | 1069 |
|
1070 |
/* mips_int */ |
|
1071 |
extern void cpu_mips_irq_request(void *opaque, int irq, int level); |
|
1072 |
|
|
1070 | 1073 |
/* mips_timer.c */ |
1071 | 1074 |
extern void cpu_mips_clock_init(CPUState *); |
1072 | 1075 |
extern void cpu_mips_irqctrl_init (void); |
Also available in: Unified diff