summaryrefslogtreecommitdiff
path: root/lib_i386/realmode.c
diff options
context:
space:
mode:
authorwdenk <wdenk>2003-05-31 18:35:21 +0000
committerwdenk <wdenk>2003-05-31 18:35:21 +0000
commit7a8e9bed17d7924a9c5c4699b1f6a3a0359524ed (patch)
tree5c273df9c5efa7b1b6a4ca88904e48039ef591e8 /lib_i386/realmode.c
parent3b57fe0a70b903f4db66c558bb9828bc58acf06b (diff)
* Patch by Marc Singer, 29 May 2003:
Fixed rarp boot method for IA32 and other little-endian CPUs. * 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
Diffstat (limited to 'lib_i386/realmode.c')
-rw-r--r--lib_i386/realmode.c44
1 files changed, 35 insertions, 9 deletions
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;
+}
+