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 | ... | ... |