Commit e16fe40c87272f0bc081b5a915db54eab2dc74dc
1 parent
7a387fff
Move the MIPS CPU timer in a seperate file, by Alec Voropay.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2225 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
103 additions
and
86 deletions
Makefile.target
| @@ -357,7 +357,7 @@ VL_OBJS+= grackle_pci.o prep_pci.o unin_pci.o | @@ -357,7 +357,7 @@ VL_OBJS+= grackle_pci.o prep_pci.o unin_pci.o | ||
| 357 | DEFINES += -DHAS_AUDIO | 357 | DEFINES += -DHAS_AUDIO |
| 358 | endif | 358 | endif |
| 359 | ifeq ($(TARGET_ARCH), mips) | 359 | ifeq ($(TARGET_ARCH), mips) |
| 360 | -VL_OBJS+= mips_r4k.o dma.o vga.o serial.o i8254.o i8259.o ide.o | 360 | +VL_OBJS+= mips_r4k.o mips_timer.o dma.o vga.o serial.o i8254.o i8259.o ide.o |
| 361 | #VL_OBJS+= #pckbd.o fdc.o m48t59.o | 361 | #VL_OBJS+= #pckbd.o fdc.o m48t59.o |
| 362 | endif | 362 | endif |
| 363 | ifeq ($(TARGET_BASE_ARCH), sparc) | 363 | ifeq ($(TARGET_BASE_ARCH), sparc) |
hw/mips_r4k.c
| 1 | +/* | ||
| 2 | + * QEMU/MIPS pseudo-board | ||
| 3 | + * | ||
| 4 | + * emulates a simple machine with ISA-like bus. | ||
| 5 | + * ISA IO space mapped to the 0x14000000 (PHYS) and | ||
| 6 | + * ISA memory at the 0x10000000 (PHYS, 16Mb in size). | ||
| 7 | + * All peripherial devices are attached to this "bus" with | ||
| 8 | + * the standard PC ISA addresses. | ||
| 9 | +*/ | ||
| 1 | #include "vl.h" | 10 | #include "vl.h" |
| 2 | 11 | ||
| 3 | #define BIOS_FILENAME "mips_bios.bin" | 12 | #define BIOS_FILENAME "mips_bios.bin" |
| @@ -13,8 +22,10 @@ static const int ide_irq[2] = { 14, 15 }; | @@ -13,8 +22,10 @@ static const int ide_irq[2] = { 14, 15 }; | ||
| 13 | 22 | ||
| 14 | extern FILE *logfile; | 23 | extern FILE *logfile; |
| 15 | 24 | ||
| 16 | -static PITState *pit; | 25 | +static PITState *pit; /* PIT i8254 */ |
| 17 | 26 | ||
| 27 | +/*i8254 PIT is attached to the IRQ0 at PIC i8259 */ | ||
| 28 | +/*The PIC is attached to the MIPS CPU INT0 pin */ | ||
| 18 | static void pic_irq_request(void *opaque, int level) | 29 | static void pic_irq_request(void *opaque, int level) |
| 19 | { | 30 | { |
| 20 | CPUState *env = first_cpu; | 31 | CPUState *env = first_cpu; |
| @@ -27,89 +38,6 @@ static void pic_irq_request(void *opaque, int level) | @@ -27,89 +38,6 @@ static void pic_irq_request(void *opaque, int level) | ||
| 27 | } | 38 | } |
| 28 | } | 39 | } |
| 29 | 40 | ||
| 30 | -void cpu_mips_irqctrl_init (void) | ||
| 31 | -{ | ||
| 32 | -} | ||
| 33 | - | ||
| 34 | -/* XXX: do not use a global */ | ||
| 35 | -uint32_t cpu_mips_get_random (CPUState *env) | ||
| 36 | -{ | ||
| 37 | - static uint32_t seed = 0; | ||
| 38 | - uint32_t idx; | ||
| 39 | - seed = seed * 314159 + 1; | ||
| 40 | - idx = (seed >> 16) % (MIPS_TLB_NB - env->CP0_Wired) + env->CP0_Wired; | ||
| 41 | - return idx; | ||
| 42 | -} | ||
| 43 | - | ||
| 44 | -/* MIPS R4K timer */ | ||
| 45 | -uint32_t cpu_mips_get_count (CPUState *env) | ||
| 46 | -{ | ||
| 47 | - return env->CP0_Count + | ||
| 48 | - (uint32_t)muldiv64(qemu_get_clock(vm_clock), | ||
| 49 | - 100 * 1000 * 1000, ticks_per_sec); | ||
| 50 | -} | ||
| 51 | - | ||
| 52 | -static void cpu_mips_update_count (CPUState *env, uint32_t count, | ||
| 53 | - uint32_t compare) | ||
| 54 | -{ | ||
| 55 | - uint64_t now, next; | ||
| 56 | - uint32_t tmp; | ||
| 57 | - | ||
| 58 | - tmp = count; | ||
| 59 | - if (count == compare) | ||
| 60 | - tmp++; | ||
| 61 | - now = qemu_get_clock(vm_clock); | ||
| 62 | - next = now + muldiv64(compare - tmp, ticks_per_sec, 100 * 1000 * 1000); | ||
| 63 | - if (next == now) | ||
| 64 | - next++; | ||
| 65 | -#if 0 | ||
| 66 | - if (logfile) { | ||
| 67 | - fprintf(logfile, "%s: 0x%08" PRIx64 " %08x %08x => 0x%08" PRIx64 "\n", | ||
| 68 | - __func__, now, count, compare, next - now); | ||
| 69 | - } | ||
| 70 | -#endif | ||
| 71 | - /* Store new count and compare registers */ | ||
| 72 | - env->CP0_Compare = compare; | ||
| 73 | - env->CP0_Count = | ||
| 74 | - count - (uint32_t)muldiv64(now, 100 * 1000 * 1000, ticks_per_sec); | ||
| 75 | - /* Adjust timer */ | ||
| 76 | - qemu_mod_timer(env->timer, next); | ||
| 77 | -} | ||
| 78 | - | ||
| 79 | -void cpu_mips_store_count (CPUState *env, uint32_t value) | ||
| 80 | -{ | ||
| 81 | - cpu_mips_update_count(env, value, env->CP0_Compare); | ||
| 82 | -} | ||
| 83 | - | ||
| 84 | -void cpu_mips_store_compare (CPUState *env, uint32_t value) | ||
| 85 | -{ | ||
| 86 | - cpu_mips_update_count(env, cpu_mips_get_count(env), value); | ||
| 87 | - env->CP0_Cause &= ~0x00008000; | ||
| 88 | - cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); | ||
| 89 | -} | ||
| 90 | - | ||
| 91 | -static void mips_timer_cb (void *opaque) | ||
| 92 | -{ | ||
| 93 | - CPUState *env; | ||
| 94 | - | ||
| 95 | - env = opaque; | ||
| 96 | -#if 0 | ||
| 97 | - if (logfile) { | ||
| 98 | - fprintf(logfile, "%s\n", __func__); | ||
| 99 | - } | ||
| 100 | -#endif | ||
| 101 | - cpu_mips_update_count(env, cpu_mips_get_count(env), env->CP0_Compare); | ||
| 102 | - env->CP0_Cause |= 0x00008000; | ||
| 103 | - cpu_interrupt(env, CPU_INTERRUPT_HARD); | ||
| 104 | -} | ||
| 105 | - | ||
| 106 | -void cpu_mips_clock_init (CPUState *env) | ||
| 107 | -{ | ||
| 108 | - env->timer = qemu_new_timer(vm_clock, &mips_timer_cb, env); | ||
| 109 | - env->CP0_Compare = 0; | ||
| 110 | - cpu_mips_update_count(env, 1, 0); | ||
| 111 | -} | ||
| 112 | - | ||
| 113 | static void mips_qemu_writel (void *opaque, target_phys_addr_t addr, | 41 | static void mips_qemu_writel (void *opaque, target_phys_addr_t addr, |
| 114 | uint32_t val) | 42 | uint32_t val) |
| 115 | { | 43 | { |
| @@ -247,7 +175,7 @@ void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device, | @@ -247,7 +175,7 @@ void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device, | ||
| 247 | env->initrd_filename = initrd_filename; | 175 | env->initrd_filename = initrd_filename; |
| 248 | } | 176 | } |
| 249 | 177 | ||
| 250 | - /* Init internal devices */ | 178 | + /* Init CPU internal devices */ |
| 251 | cpu_mips_clock_init(env); | 179 | cpu_mips_clock_init(env); |
| 252 | cpu_mips_irqctrl_init(); | 180 | cpu_mips_irqctrl_init(); |
| 253 | 181 |
hw/mips_timer.c
0 โ 100644
| 1 | +#include "vl.h" | ||
| 2 | + | ||
| 3 | +void cpu_mips_irqctrl_init (void) | ||
| 4 | +{ | ||
| 5 | +} | ||
| 6 | + | ||
| 7 | +/* XXX: do not use a global */ | ||
| 8 | +uint32_t cpu_mips_get_random (CPUState *env) | ||
| 9 | +{ | ||
| 10 | + static uint32_t seed = 0; | ||
| 11 | + uint32_t idx; | ||
| 12 | + seed = seed * 314159 + 1; | ||
| 13 | + idx = (seed >> 16) % (MIPS_TLB_NB - env->CP0_Wired) + env->CP0_Wired; | ||
| 14 | + return idx; | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +/* MIPS R4K timer */ | ||
| 18 | +uint32_t cpu_mips_get_count (CPUState *env) | ||
| 19 | +{ | ||
| 20 | + return env->CP0_Count + | ||
| 21 | + (uint32_t)muldiv64(qemu_get_clock(vm_clock), | ||
| 22 | + 100 * 1000 * 1000, ticks_per_sec); | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +static void cpu_mips_update_count (CPUState *env, uint32_t count, | ||
| 26 | + uint32_t compare) | ||
| 27 | +{ | ||
| 28 | + uint64_t now, next; | ||
| 29 | + uint32_t tmp; | ||
| 30 | + | ||
| 31 | + tmp = count; | ||
| 32 | + if (count == compare) | ||
| 33 | + tmp++; | ||
| 34 | + now = qemu_get_clock(vm_clock); | ||
| 35 | + next = now + muldiv64(compare - tmp, ticks_per_sec, 100 * 1000 * 1000); | ||
| 36 | + if (next == now) | ||
| 37 | + next++; | ||
| 38 | +#if 0 | ||
| 39 | + if (logfile) { | ||
| 40 | + fprintf(logfile, "%s: 0x%08" PRIx64 " %08x %08x => 0x%08" PRIx64 "\n", | ||
| 41 | + __func__, now, count, compare, next - now); | ||
| 42 | + } | ||
| 43 | +#endif | ||
| 44 | + /* Store new count and compare registers */ | ||
| 45 | + env->CP0_Compare = compare; | ||
| 46 | + env->CP0_Count = | ||
| 47 | + count - (uint32_t)muldiv64(now, 100 * 1000 * 1000, ticks_per_sec); | ||
| 48 | + /* Adjust timer */ | ||
| 49 | + qemu_mod_timer(env->timer, next); | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +void cpu_mips_store_count (CPUState *env, uint32_t value) | ||
| 53 | +{ | ||
| 54 | + cpu_mips_update_count(env, value, env->CP0_Compare); | ||
| 55 | +} | ||
| 56 | + | ||
| 57 | +void cpu_mips_store_compare (CPUState *env, uint32_t value) | ||
| 58 | +{ | ||
| 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); | ||
| 62 | +} | ||
| 63 | + | ||
| 64 | +static void mips_timer_cb (void *opaque) | ||
| 65 | +{ | ||
| 66 | + CPUState *env; | ||
| 67 | + | ||
| 68 | + env = opaque; | ||
| 69 | +#if 0 | ||
| 70 | + if (logfile) { | ||
| 71 | + fprintf(logfile, "%s\n", __func__); | ||
| 72 | + } | ||
| 73 | +#endif | ||
| 74 | + 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); | ||
| 77 | +} | ||
| 78 | + | ||
| 79 | +void cpu_mips_clock_init (CPUState *env) | ||
| 80 | +{ | ||
| 81 | + env->timer = qemu_new_timer(vm_clock, &mips_timer_cb, env); | ||
| 82 | + env->CP0_Compare = 0; | ||
| 83 | + cpu_mips_update_count(env, 1, 0); | ||
| 84 | +} | ||
| 85 | + |
vl.h
| @@ -1024,6 +1024,10 @@ extern QEMUMachine heathrow_machine; | @@ -1024,6 +1024,10 @@ extern QEMUMachine heathrow_machine; | ||
| 1024 | /* mips_r4k.c */ | 1024 | /* mips_r4k.c */ |
| 1025 | extern QEMUMachine mips_machine; | 1025 | extern QEMUMachine mips_machine; |
| 1026 | 1026 | ||
| 1027 | +/* mips_timer.c */ | ||
| 1028 | +extern void cpu_mips_clock_init(CPUState *); | ||
| 1029 | +extern void cpu_mips_irqctrl_init (void); | ||
| 1030 | + | ||
| 1027 | /* shix.c */ | 1031 | /* shix.c */ |
| 1028 | extern QEMUMachine shix_machine; | 1032 | extern QEMUMachine shix_machine; |
| 1029 | 1033 |