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 | 357 | DEFINES += -DHAS_AUDIO |
| 358 | 358 | endif |
| 359 | 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 | 361 | #VL_OBJS+= #pckbd.o fdc.o m48t59.o |
| 362 | 362 | endif |
| 363 | 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 | 10 | #include "vl.h" |
| 2 | 11 | |
| 3 | 12 | #define BIOS_FILENAME "mips_bios.bin" |
| ... | ... | @@ -13,8 +22,10 @@ static const int ide_irq[2] = { 14, 15 }; |
| 13 | 22 | |
| 14 | 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 | 29 | static void pic_irq_request(void *opaque, int level) |
| 19 | 30 | { |
| 20 | 31 | CPUState *env = first_cpu; |
| ... | ... | @@ -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 | 41 | static void mips_qemu_writel (void *opaque, target_phys_addr_t addr, |
| 114 | 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 | 175 | env->initrd_filename = initrd_filename; |
| 248 | 176 | } |
| 249 | 177 | |
| 250 | - /* Init internal devices */ | |
| 178 | + /* Init CPU internal devices */ | |
| 251 | 179 | cpu_mips_clock_init(env); |
| 252 | 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 | 1024 | /* mips_r4k.c */ |
| 1025 | 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 | 1031 | /* shix.c */ |
| 1028 | 1032 | extern QEMUMachine shix_machine; |
| 1029 | 1033 | ... | ... |