1 |
#include "vl.h" |
#include "vl.h" |
2 |
|
|
|
#define DEBUG_IRQ_COUNT |
|
|
|
|
3 |
#define BIOS_FILENAME "mips_bios.bin" |
#define BIOS_FILENAME "mips_bios.bin" |
4 |
//#define BIOS_FILENAME "system.bin" |
//#define BIOS_FILENAME "system.bin" |
5 |
#define KERNEL_LOAD_ADDR 0x80010000 |
#define KERNEL_LOAD_ADDR 0x80010000 |
6 |
#define INITRD_LOAD_ADDR 0x80800000 |
#define INITRD_LOAD_ADDR 0x80800000 |
7 |
|
|
|
/* MIPS R4K IRQ controler */ |
|
|
#if defined(DEBUG_IRQ_COUNT) |
|
|
static uint64_t irq_count[16]; |
|
|
#endif |
|
|
|
|
8 |
extern FILE *logfile; |
extern FILE *logfile; |
9 |
|
|
10 |
void mips_set_irq (int n_IRQ, int level) |
static void pic_irq_request(void *opaque, int level) |
11 |
{ |
{ |
12 |
uint32_t mask; |
if (level) { |
13 |
|
cpu_single_env->CP0_Cause |= 0x00000400; |
14 |
if (n_IRQ < 0 || n_IRQ >= 8) |
cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); |
|
return; |
|
|
mask = 0x100 << n_IRQ; |
|
|
if (level != 0) { |
|
|
#if 1 |
|
|
if (logfile) { |
|
|
fprintf(logfile, "%s n %d l %d mask %08x %08x\n", |
|
|
__func__, n_IRQ, level, mask, cpu_single_env->CP0_Status); |
|
|
} |
|
|
#endif |
|
|
cpu_single_env->CP0_Cause |= mask; |
|
|
if ((cpu_single_env->CP0_Status & 0x00000001) && |
|
|
(cpu_single_env->CP0_Status & mask)) { |
|
|
#if defined(DEBUG_IRQ_COUNT) |
|
|
irq_count[n_IRQ]++; |
|
|
#endif |
|
|
#if 1 |
|
|
if (logfile) |
|
|
fprintf(logfile, "%s raise IRQ\n", __func__); |
|
|
#endif |
|
|
cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); |
|
|
} |
|
15 |
} else { |
} else { |
16 |
cpu_single_env->CP0_Cause &= ~mask; |
cpu_single_env->CP0_Cause &= ~0x00000400; |
17 |
} |
cpu_reset_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); |
|
} |
|
|
|
|
|
void pic_set_irq (int n_IRQ, int level) |
|
|
{ |
|
|
mips_set_irq(n_IRQ + 2, level); |
|
|
} |
|
|
|
|
|
void pic_info (void) |
|
|
{ |
|
|
term_printf("IRQ asserted: %02x mask: %02x\n", |
|
|
(cpu_single_env->CP0_Cause >> 8) & 0xFF, |
|
|
(cpu_single_env->CP0_Status >> 8) & 0xFF); |
|
|
} |
|
|
|
|
|
void irq_info (void) |
|
|
{ |
|
|
#if !defined(DEBUG_IRQ_COUNT) |
|
|
term_printf("irq statistic code not compiled.\n"); |
|
|
#else |
|
|
int i; |
|
|
int64_t count; |
|
|
|
|
|
term_printf("IRQ statistics:\n"); |
|
|
for (i = 0; i < 8; i++) { |
|
|
count = irq_count[i]; |
|
|
if (count > 0) |
|
|
term_printf("%2d: %lld\n", i, count); |
|
18 |
} |
} |
|
#endif |
|
19 |
} |
} |
20 |
|
|
21 |
void cpu_mips_irqctrl_init (void) |
void cpu_mips_irqctrl_init (void) |
239 |
cpu_register_physical_memory(0x14000000, 0x00010000, io_memory); |
cpu_register_physical_memory(0x14000000, 0x00010000, io_memory); |
240 |
isa_mem_base = 0x10000000; |
isa_mem_base = 0x10000000; |
241 |
|
|
242 |
|
isa_pic = pic_init(pic_irq_request, cpu_single_env); |
243 |
serial_init(0x3f8, 4, serial_hds[0]); |
serial_init(0x3f8, 4, serial_hds[0]); |
244 |
vga_initialize(NULL, ds, phys_ram_base + ram_size, ram_size, |
vga_initialize(NULL, ds, phys_ram_base + ram_size, ram_size, |
245 |
vga_ram_size); |
vga_ram_size); |