From 7a8e9bed17d7924a9c5c4699b1f6a3a0359524ed Mon Sep 17 00:00:00 2001 From: wdenk Date: Sat, 31 May 2003 18:35:21 +0000 Subject: * Patch by Marc Singer, 29 May 2003: Fixed rarp boot method for IA32 and other little-endian CPUs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Patch by Marc Singer, 28 May 2003: Added port I/O commands. * Patch by Matthew McClintock, 28 May 2003 - cpu/mpc824x/start.S: fix relocation code when booting from RAM - minor patches for utx8245 * Patch by Daniel Engström, 28 May 2003: x86 update * Patch by Dave Ellis, 9 May 2003 + 27 May 2003: add nand flash support to SXNI855T configuration fix/extend nand flash support: - fix 'nand erase' command so does not erase bad blocks - fix 'nand write' command so does not write to bad blocks - fix nand_probe() so handles no flash detected properly - add doc/README.nand - add .jffs2 and .oob options to nand read/write - add 'nand bad' command to list bad blocks - add 'clean' option to 'nand erase' to write JFFS2 clean markers - make NAND read/write faster * Patch by Rune Torgersen, 23 May 2003: Update for MPC8266ADS board --- lib_i386/realmode.c | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) (limited to 'lib_i386/realmode.c') diff --git a/lib_i386/realmode.c b/lib_i386/realmode.c index 27d469382..d7bb81c57 100644 --- a/lib_i386/realmode.c +++ b/lib_i386/realmode.c @@ -33,25 +33,33 @@ extern char realmode_enter; - -int enter_realmode(u16 seg, u16 off, struct pt_regs *in, struct pt_regs *out) +int realmode_setup(void) { - - /* setup out thin bios emulation */ - if (bios_setup()) { - return -1; - } - /* copy the realmode switch code */ if (i386boot_realmode_size > (REALMODE_MAILBOX-REALMODE_BASE)) { printf("realmode switch too large (%ld bytes, max is %d)\n", - i386boot_realmode_size, (int)(REALMODE_MAILBOX-REALMODE_BASE)); + i386boot_realmode_size, (REALMODE_MAILBOX-REALMODE_BASE)); return -1; } memcpy(REALMODE_BASE, (void*)i386boot_realmode, i386boot_realmode_size); + asm("wbinvd\n"); + + return 0; +} +int enter_realmode(u16 seg, u16 off, struct pt_regs *in, struct pt_regs *out) +{ + /* setup out thin bios emulation */ + if (bios_setup()) { + return -1; + } + + if (realmode_setup()) { + return -1; + } + in->eip = off; in->xcs = seg; if (3>(in->esp & 0xffff)) { @@ -59,12 +67,30 @@ int enter_realmode(u16 seg, u16 off, struct pt_regs *in, struct pt_regs *out) } memcpy(REALMODE_MAILBOX, in, sizeof(struct pt_regs)); + asm("wbinvd\n"); __asm__ volatile ( "lcall $0x20,%0\n" : : "i" (&realmode_enter) ); + asm("wbinvd\n"); memcpy(out, REALMODE_MAILBOX, sizeof(struct pt_regs)); return out->eax; } + +/* This code is supposed to access a realmode interrupt + * it does currently not work for me */ +int enter_realmode_int(u8 lvl, struct pt_regs *in, struct pt_regs *out) +{ + /* place two instructions at 0x700 */ + writeb(0xcd, 0x700); /* int $lvl */ + writeb(lvl, 0x701); + writeb(0xcb, 0x702); /* lret */ + asm("wbinvd\n"); + + enter_realmode(0x00, 0x700, in, out); + + return out->eflags&1; +} + -- cgit v1.2.3