aboutsummaryrefslogtreecommitdiff
path: root/util/extensions/legacybios/kernel/x86glue.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/extensions/legacybios/kernel/x86glue.c')
-rw-r--r--util/extensions/legacybios/kernel/x86glue.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/util/extensions/legacybios/kernel/x86glue.c b/util/extensions/legacybios/kernel/x86glue.c
new file mode 100644
index 0000000000..4abbd98113
--- /dev/null
+++ b/util/extensions/legacybios/kernel/x86glue.c
@@ -0,0 +1,137 @@
+#include <types.h>
+#include <io.h>
+#include <x86emu.h>
+#include <x86glue.h>
+
+void printk(const char *fmt, ...);
+void x86emu_dump_xregs(void);
+void pci_init(void);
+
+int int10_handler(void);
+int int1a_handler(void);
+
+void pushw(u16 val);
+unsigned char biosmem[1024 * 1024];
+int verbose = 0;
+
+u8 x_inb(u16 port)
+{
+ return inb(port);
+}
+
+u16 x_inw(u16 port)
+{
+ return inw(port);
+}
+
+u32 x_inl(u16 port)
+{
+ return inb(port);
+}
+
+void x_outb(u16 port, u8 val)
+{
+ outb(port, val);
+}
+
+void x_outw(u16 port, u16 val)
+{
+ outb(port, val);
+}
+
+void x_outl(u16 port, u32 val)
+{
+ outb(port, val);
+}
+
+X86EMU_pioFuncs myfuncs = {
+ x_inb, x_inw, x_inl,
+ x_outb, x_outw, x_outl
+};
+
+void irq_multiplexer(int num)
+{
+ int ret = 0;
+ switch (num) {
+ case 0x10:
+ case 0x42:
+ case 0x6d:
+ ret = int10_handler();
+ break;
+ case 0x1a:
+ ret = int1a_handler();
+ break;
+ default:
+ break;
+ }
+
+ if (!ret) {
+ printk("int%x not implemented\n", num);
+ x86emu_dump_xregs();
+ }
+}
+
+ptr current = 0;
+int startrom(unsigned char *addr)
+{
+ X86EMU_intrFuncs intFuncs[256];
+ void X86EMU_setMemBase(void *base, size_t size);
+ int trace = 1;
+ int i;
+
+ int devfn=0x18; // FIXME
+ int size=64*1024; // FIXME
+ int initialcs=0xc000;
+ int initialip=0x0003;
+ int base=0xc0000;
+
+ X86EMU_setMemBase(biosmem, sizeof(biosmem));
+ X86EMU_setupPioFuncs(&myfuncs);
+ pci_init();
+ for (i = 0; i < 256; i++)
+ intFuncs[i] = irq_multiplexer;
+ X86EMU_setupIntrFuncs(intFuncs);
+
+
+ current->ax = devfn ? devfn : 0xff; // FIXME
+ /* above we need to search the device on the bus */
+
+ current->dx = 0x80;
+ // current->ip = 0;
+
+ for (i = 0; i < size; i++)
+ wrb(base + i, addr[i]);
+
+ /* cpu setup */
+ X86_AX = devfn ? devfn : 0xff;
+ X86_DX = 0x80;
+ X86_EIP = initialip;
+ X86_CS = initialcs;
+
+ /* Initialize stack and data segment */
+ X86_SS = 0x0030;
+ X86_DS = 0x0040;
+ X86_SP = 0xfffe;
+
+ /* We need a sane way to return from bios
+ * execution. A hlt instruction and a pointer
+ * to it, both kept on the stack, will do.
+ */
+
+ pushw(0xf4f4); /* hlt; hlt */
+ pushw(X86_SS);
+ pushw(X86_SP + 2);
+
+ X86_ES = 0x0000;
+
+ if (trace) {
+ printk("Switching to single step mode.\n");
+ X86EMU_trace_on();
+ }
+
+ X86EMU_exec();
+
+
+
+ return 0;
+}