[PATCH] mips: add support for Qemu system architecture
Add support for the virtual MIPS system that is emulated by Qemu. See
http://www.linux-mips.org/wiki/Qemu for a detailed current status.
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/arch/mips/qemu/Makefile b/arch/mips/qemu/Makefile
new file mode 100644
index 0000000..934944a
--- /dev/null
+++ b/arch/mips/qemu/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for Qemu specific kernel interface routines under Linux.
+#
+
+obj-y = q-firmware.o q-int.o q-irq.o q-mem.o q-setup.o
diff --git a/arch/mips/qemu/q-firmware.c b/arch/mips/qemu/q-firmware.c
new file mode 100644
index 0000000..5980f02
--- /dev/null
+++ b/arch/mips/qemu/q-firmware.c
@@ -0,0 +1,7 @@
+#include <linux/init.h>
+#include <asm/bootinfo.h>
+
+void __init prom_init(void)
+{
+ add_memory_region(0x0<<20, 0x10<<20, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/qemu/q-int.S b/arch/mips/qemu/q-int.S
new file mode 100644
index 0000000..6e3dfe5
--- /dev/null
+++ b/arch/mips/qemu/q-int.S
@@ -0,0 +1,17 @@
+/*
+ * Qemu interrupt handler code.
+ *
+ * Copyright (C) 2005 by Ralf Baechle
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+ .align 5
+ NESTED(qemu_handle_int, PT_SIZE, sp)
+ SAVE_ALL
+ CLI
+ move a0, sp
+ PTR_LA ra, ret_from_irq
+ j do_qemu_int
+ END(qemu_handle_int)
diff --git a/arch/mips/qemu/q-irq.c b/arch/mips/qemu/q-irq.c
new file mode 100644
index 0000000..2c4e070
--- /dev/null
+++ b/arch/mips/qemu/q-irq.c
@@ -0,0 +1,37 @@
+#include <linux/init.h>
+#include <linux/linkage.h>
+
+#include <asm/i8259.h>
+#include <asm/mipsregs.h>
+#include <asm/qemu.h>
+#include <asm/system.h>
+#include <asm/time.h>
+
+extern asmlinkage void qemu_handle_int(void);
+
+asmlinkage void do_qemu_int(struct pt_regs *regs)
+{
+ unsigned int pending = read_c0_status() & read_c0_cause();
+
+ if (pending & 0x8000) {
+ ll_timer_interrupt(Q_COUNT_COMPARE_IRQ, regs);
+ return;
+ }
+ if (pending & 0x0400) {
+ int irq = i8259_irq();
+
+ if (likely(irq >= 0))
+ do_IRQ(irq, regs);
+
+ return;
+ }
+}
+
+void __init arch_init_irq(void)
+{
+ set_except_vector(0, qemu_handle_int);
+ mips_hpt_frequency = QEMU_C0_COUNTER_CLOCK; /* 100MHz */
+
+ init_i8259_irqs();
+ set_c0_status(0x8400);
+}
diff --git a/arch/mips/qemu/q-mem.c b/arch/mips/qemu/q-mem.c
new file mode 100644
index 0000000..d174fac
--- /dev/null
+++ b/arch/mips/qemu/q-mem.c
@@ -0,0 +1,6 @@
+#include <linux/init.h>
+
+unsigned long __init prom_free_prom_memory(void)
+{
+ return 0UL;
+}
diff --git a/arch/mips/qemu/q-setup.c b/arch/mips/qemu/q-setup.c
new file mode 100644
index 0000000..1a80eee
--- /dev/null
+++ b/arch/mips/qemu/q-setup.c
@@ -0,0 +1,20 @@
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/time.h>
+
+#define QEMU_PORT_BASE 0xb4000000
+
+static void __init qemu_timer_setup(struct irqaction *irq)
+{
+ /* set the clock to 100 Hz */
+ outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
+ outb_p(LATCH & 0xff , 0x40); /* LSB */
+ outb(LATCH >> 8 , 0x40); /* MSB */
+ setup_irq(0, irq);
+}
+
+void __init plat_setup(void)
+{
+ set_io_port_base(QEMU_PORT_BASE);
+ board_timer_setup = qemu_timer_setup;
+}