summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.target2
-rw-r--r--hw/mips_r4k.c98
-rw-r--r--hw/mips_timer.c85
-rw-r--r--vl.h4
4 files changed, 103 insertions, 86 deletions
diff --git a/Makefile.target b/Makefile.target
index bdc365908c..aa9a013069 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -357,7 +357,7 @@ VL_OBJS+= grackle_pci.o prep_pci.o unin_pci.o
DEFINES += -DHAS_AUDIO
endif
ifeq ($(TARGET_ARCH), mips)
-VL_OBJS+= mips_r4k.o dma.o vga.o serial.o i8254.o i8259.o ide.o
+VL_OBJS+= mips_r4k.o mips_timer.o dma.o vga.o serial.o i8254.o i8259.o ide.o
#VL_OBJS+= #pckbd.o fdc.o m48t59.o
endif
ifeq ($(TARGET_BASE_ARCH), sparc)
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 60eb191bdf..0ddd916278 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -1,3 +1,12 @@
+/*
+ * QEMU/MIPS pseudo-board
+ *
+ * emulates a simple machine with ISA-like bus.
+ * ISA IO space mapped to the 0x14000000 (PHYS) and
+ * ISA memory at the 0x10000000 (PHYS, 16Mb in size).
+ * All peripherial devices are attached to this "bus" with
+ * the standard PC ISA addresses.
+*/
#include "vl.h"
#define BIOS_FILENAME "mips_bios.bin"
@@ -13,8 +22,10 @@ static const int ide_irq[2] = { 14, 15 };
extern FILE *logfile;
-static PITState *pit;
+static PITState *pit; /* PIT i8254 */
+/*i8254 PIT is attached to the IRQ0 at PIC i8259 */
+/*The PIC is attached to the MIPS CPU INT0 pin */
static void pic_irq_request(void *opaque, int level)
{
CPUState *env = first_cpu;
@@ -27,89 +38,6 @@ static void pic_irq_request(void *opaque, int level)
}
}
-void cpu_mips_irqctrl_init (void)
-{
-}
-
-/* XXX: do not use a global */
-uint32_t cpu_mips_get_random (CPUState *env)
-{
- static uint32_t seed = 0;
- uint32_t idx;
- seed = seed * 314159 + 1;
- idx = (seed >> 16) % (MIPS_TLB_NB - env->CP0_Wired) + env->CP0_Wired;
- return idx;
-}
-
-/* MIPS R4K timer */
-uint32_t cpu_mips_get_count (CPUState *env)
-{
- return env->CP0_Count +
- (uint32_t)muldiv64(qemu_get_clock(vm_clock),
- 100 * 1000 * 1000, ticks_per_sec);
-}
-
-static void cpu_mips_update_count (CPUState *env, uint32_t count,
- uint32_t compare)
-{
- uint64_t now, next;
- uint32_t tmp;
-
- tmp = count;
- if (count == compare)
- tmp++;
- now = qemu_get_clock(vm_clock);
- next = now + muldiv64(compare - tmp, ticks_per_sec, 100 * 1000 * 1000);
- if (next == now)
- next++;
-#if 0
- if (logfile) {
- fprintf(logfile, "%s: 0x%08" PRIx64 " %08x %08x => 0x%08" PRIx64 "\n",
- __func__, now, count, compare, next - now);
- }
-#endif
- /* Store new count and compare registers */
- env->CP0_Compare = compare;
- env->CP0_Count =
- count - (uint32_t)muldiv64(now, 100 * 1000 * 1000, ticks_per_sec);
- /* Adjust timer */
- qemu_mod_timer(env->timer, next);
-}
-
-void cpu_mips_store_count (CPUState *env, uint32_t value)
-{
- cpu_mips_update_count(env, value, env->CP0_Compare);
-}
-
-void cpu_mips_store_compare (CPUState *env, uint32_t value)
-{
- cpu_mips_update_count(env, cpu_mips_get_count(env), value);
- env->CP0_Cause &= ~0x00008000;
- cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
-}
-
-static void mips_timer_cb (void *opaque)
-{
- CPUState *env;
-
- env = opaque;
-#if 0
- if (logfile) {
- fprintf(logfile, "%s\n", __func__);
- }
-#endif
- cpu_mips_update_count(env, cpu_mips_get_count(env), env->CP0_Compare);
- env->CP0_Cause |= 0x00008000;
- cpu_interrupt(env, CPU_INTERRUPT_HARD);
-}
-
-void cpu_mips_clock_init (CPUState *env)
-{
- env->timer = qemu_new_timer(vm_clock, &mips_timer_cb, env);
- env->CP0_Compare = 0;
- cpu_mips_update_count(env, 1, 0);
-}
-
static void mips_qemu_writel (void *opaque, target_phys_addr_t addr,
uint32_t val)
{
@@ -247,7 +175,7 @@ void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device,
env->initrd_filename = initrd_filename;
}
- /* Init internal devices */
+ /* Init CPU internal devices */
cpu_mips_clock_init(env);
cpu_mips_irqctrl_init();
diff --git a/hw/mips_timer.c b/hw/mips_timer.c
new file mode 100644
index 0000000000..251324d7b8
--- /dev/null
+++ b/hw/mips_timer.c
@@ -0,0 +1,85 @@
+#include "vl.h"
+
+void cpu_mips_irqctrl_init (void)
+{
+}
+
+/* XXX: do not use a global */
+uint32_t cpu_mips_get_random (CPUState *env)
+{
+ static uint32_t seed = 0;
+ uint32_t idx;
+ seed = seed * 314159 + 1;
+ idx = (seed >> 16) % (MIPS_TLB_NB - env->CP0_Wired) + env->CP0_Wired;
+ return idx;
+}
+
+/* MIPS R4K timer */
+uint32_t cpu_mips_get_count (CPUState *env)
+{
+ return env->CP0_Count +
+ (uint32_t)muldiv64(qemu_get_clock(vm_clock),
+ 100 * 1000 * 1000, ticks_per_sec);
+}
+
+static void cpu_mips_update_count (CPUState *env, uint32_t count,
+ uint32_t compare)
+{
+ uint64_t now, next;
+ uint32_t tmp;
+
+ tmp = count;
+ if (count == compare)
+ tmp++;
+ now = qemu_get_clock(vm_clock);
+ next = now + muldiv64(compare - tmp, ticks_per_sec, 100 * 1000 * 1000);
+ if (next == now)
+ next++;
+#if 0
+ if (logfile) {
+ fprintf(logfile, "%s: 0x%08" PRIx64 " %08x %08x => 0x%08" PRIx64 "\n",
+ __func__, now, count, compare, next - now);
+ }
+#endif
+ /* Store new count and compare registers */
+ env->CP0_Compare = compare;
+ env->CP0_Count =
+ count - (uint32_t)muldiv64(now, 100 * 1000 * 1000, ticks_per_sec);
+ /* Adjust timer */
+ qemu_mod_timer(env->timer, next);
+}
+
+void cpu_mips_store_count (CPUState *env, uint32_t value)
+{
+ cpu_mips_update_count(env, value, env->CP0_Compare);
+}
+
+void cpu_mips_store_compare (CPUState *env, uint32_t value)
+{
+ cpu_mips_update_count(env, cpu_mips_get_count(env), value);
+ env->CP0_Cause &= ~0x00008000;
+ cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+}
+
+static void mips_timer_cb (void *opaque)
+{
+ CPUState *env;
+
+ env = opaque;
+#if 0
+ if (logfile) {
+ fprintf(logfile, "%s\n", __func__);
+ }
+#endif
+ cpu_mips_update_count(env, cpu_mips_get_count(env), env->CP0_Compare);
+ env->CP0_Cause |= 0x00008000;
+ cpu_interrupt(env, CPU_INTERRUPT_HARD);
+}
+
+void cpu_mips_clock_init (CPUState *env)
+{
+ env->timer = qemu_new_timer(vm_clock, &mips_timer_cb, env);
+ env->CP0_Compare = 0;
+ cpu_mips_update_count(env, 1, 0);
+}
+
diff --git a/vl.h b/vl.h
index eedef51bd5..89b24cf918 100644
--- a/vl.h
+++ b/vl.h
@@ -1024,6 +1024,10 @@ extern QEMUMachine heathrow_machine;
/* mips_r4k.c */
extern QEMUMachine mips_machine;
+/* mips_timer.c */
+extern void cpu_mips_clock_init(CPUState *);
+extern void cpu_mips_irqctrl_init (void);
+
/* shix.c */
extern QEMUMachine shix_machine;