Author: tkreuzer
Date: Fri Aug 26 09:15:38 2011
New Revision: 53451
URL:
http://svn.reactos.org/svn/reactos?rev=53451&view=rev
Log:
[FREELDR]
- Implement switching back to real mode
- use a symbolic name for the size of the REGGS structure
Modified:
trunk/reactos/boot/freeldr/freeldr/arch/amd64/entry.S
trunk/reactos/boot/freeldr/freeldr/arch/i386/entry.S
trunk/reactos/boot/freeldr/freeldr/arch/realmode/amd64.S
trunk/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h
trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h
Modified: trunk/reactos/boot/freeldr/freeldr/arch/amd64/entry.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/amd64/entry.S [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/amd64/entry.S [iso-8859-1] Fri Aug 26 09:15:38
2011
@@ -9,20 +9,118 @@
PUBLIC RealEntryPoint
RealEntryPoint:
- //mov ax, LMODE_DS
- //mov ds, ax
+ /* Setup segment selectors */
+ mov ax, LMODE_DS
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+// mov ss, ax
+
//mov word ptr [HEX(b8000)], HEX(0e00) + '1'
+
+ /* Setup long mode stack */
+ mov rsp, qword ptr [stack64]
+
+ /* Continue execution */
+ jmp qword ptr [ContinueAddress]
+
+ContinueAddress:
+ .double offset FrldrStartup
+
+
+FrldrStartup:
+
+ /* Store BootDrive and BootPartition */
+ mov byte ptr [FrldrBootDrive], dl
+ xor eax, eax
+ mov al, dh
+ mov dword ptr [FrldrBootPartition], eax
+
+ /* Patch long jump with real mode entry point */
+ mov eax, dword ptr [BSS_RealModeEntry]
+ mov dword ptr [AddressOfRealModeEntryPoint], eax
/* GO! */
xor rcx, rcx
call BootMain
+ /* We should never get here */
+stop:
+ jmp stop
+ nop
+ nop
+
+
+/* Internal function for realmode calls
+ * bx must be set to the ID of the realmode function to call. */
+PUBLIC CallRealMode
+CallRealMode:
+ /* Save current stack pointer */
+ mov qword ptr [stack64], rsp
+
+ /* Set continue address and switch to real mode */
+ lea rax, [CallRealMode_return]
+ mov qword ptr [ContinueAddress], rax
+
+SwitchToReal:
+ /* Set sane segments */
+ mov ax, LMODE_DS
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ //mov ss, ax
+
+ mov word ptr [HEX(0b8008)], HEX(0e00) + '4'
+
+ /* Save 64-bit stack pointer */
+ mov qword ptr [stack64], rsp
+
+ /* Step 1 - jump to compatibility segment */
+ jmp fword ptr [jumpvector]
+
+jumpvector:
+ .long offset SwitchToRealCompSegment
+ .word CMODE_CS
+
+SwitchToRealCompSegment:
+ /* Note: In fact the CPU is in 32 bit mode here. But it will interprete
+ the generated instructions accordingly. rax will become eax */
+
+ /* Step 2 - deactivate long mode, by disabling paging */
+ mov rax, cr0
+ and eax, HEX(7fffffff) //~0x80000000, upper bits cleared
+ mov cr0, rax
+
+// mov word ptr [HEX(0b800a)], HEX(0e00) + '5'
+
+ /* Step 3 - jump to 16-bit segment to set the limit correctly */
+ .byte HEX(0EA) // 32bit long jmp
+AddressOfRealModeEntryPoint:
+ .long 0 // receives address of RealModeEntryPoint
+ .word HEX(20)//RMODE_CS
+ nop
+
+CallRealMode_return:
+ /* restore stack pointer */
+ mov rsp, qword ptr [stack64]
+ ret
+
+/////////////////////////////////////////
+
+
+ /* 64-bit stack pointer */
+stack64:
+ .double STACK64ADDR
PUBLIC FrldrBootDrive
FrldrBootDrive:
+ .byte 0
PUBLIC FrldrBootPartition
FrldrBootPartition:
+ .long 0
PUBLIC PageDirectoryEnd
PageDirectoryEnd:
@@ -34,8 +132,57 @@
PnpBiosGetDeviceNodeCount:
PUBLIC PnpBiosSupported
PnpBiosSupported:
+
+/* int Int386(int ivec<ecx>, REGS* in<rdx>, REGS* out<r8>); */
PUBLIC Int386
Int386:
+
+ /* Save home registers */
+ mov r11, rsp
+ mov qword ptr [r11 + 8], rcx
+ mov qword ptr [r11 + 16], rdx
+ mov qword ptr [r11 + 24], r8
+
+ /* Save non-volatile registers */
+ push rbx
+ push rbp
+ push rsi
+ push rdi
+
+ /* Alloc stack space for home registers */
+ sub rsp, 40
+ //.ENDPROLOG
+
+ mov word ptr [HEX(0b8006)], HEX(0e00) + '3'
+
+ /* Copy the int vector to shared memory */
+ mov dword ptr [BSS_IntVector], ecx
+
+ /* Copy input registers */
+ mov rsi, rdx
+ mov rdi, BSS_RegisterSet
+ mov rcx, REGS_SIZE / 4
+ rep movsd
+
+ /* Set the function ID and call real mode */
+ mov bx, FNID_Int386
+ call CallRealMode
+
+ /* Copy output registers */
+ mov rsi, BSS_RegisterSet
+ mov rdi, [r11 + 16]
+ mov rcx, REGS_SIZE / 4
+ rep movsd
+
+ /* cleanup and return */
+ add rsp, 40
+ pop rdi
+ pop rsi
+ pop rbp
+ pop rbx
+ ret
+
+
PUBLIC PxeCallApi
PxeCallApi:
PUBLIC __lgdt
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/entry.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/i386/entry.S [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/i386/entry.S [iso-8859-1] Fri Aug 26 09:15:38
2011
@@ -110,7 +110,7 @@
/* Copy input registers */
mov esi, dword ptr [Int386_regsin]
mov edi, BSS_RegisterSet
- mov ecx, 9
+ mov ecx, REGS_SIZE / 4
rep movsd
/* Set the function ID */
@@ -125,7 +125,7 @@
/* Copy output registers */
mov esi, BSS_RegisterSet
mov edi, dword ptr [Int386_regsout]
- mov ecx, 9
+ mov ecx, REGS_SIZE / 4
rep movsd
popa
Modified: trunk/reactos/boot/freeldr/freeldr/arch/realmode/amd64.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/realmode/amd64.S [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/realmode/amd64.S [iso-8859-1] Fri Aug 26
09:15:38 2011
@@ -100,14 +100,14 @@
Msg_SwitchToLongMode:
.ascii "Switching to long mode....", CR, LF, NUL
-.align 4
+.align 8
gdt:
.word HEX(0000), HEX(0000), HEX(0000), HEX(0000) /* 00: NULL descriptor */
.word HEX(0000), HEX(0000), HEX(0000), HEX(0000) /* 08: */
.word HEX(0000), HEX(0000), HEX(9800), HEX(0020) /* 10: long mode cs */
.word HEX(ffff), HEX(0000), HEX(f300), HEX(00cf) /* 18: long mode ds */
- .word HEX(FFFF), HEX(0000), HEX(9E00), HEX(0000) /* 16-bit real mode CS */
- .word HEX(FFFF), HEX(0000), HEX(9200), HEX(0000) /* 16-bit real mode DS */
+ .word HEX(FFFF), HEX(0000), HEX(9E00), HEX(0000) /* 20: 16-bit real mode CS */
+ .word HEX(FFFF), HEX(0000), HEX(9200), HEX(0000) /* 28: 16-bit real mode DS */
.word HEX(FFFF), HEX(0000), HEX(9B00), HEX(00CF) /* 30: compat mode cs */
/* GDT table pointer */
@@ -232,7 +232,20 @@
/* This is the entry point from long mode */
RealModeEntryPoint:
-
+ /* Disable Protected Mode */
+ mov eax, cr0
+ and eax, HEX(0fffffffe) // ~0x00000001
+ mov cr0, eax
+
+ /* Clear prefetch queue & correct CS */
+ ljmp16 0, offset InRealMode
+
+InRealMode:
+
+ mov ax, HEX(0b800)
+ mov es, ax
+ mov word ptr es:[12], HEX(0e00) + '6'
+ jmp $
ExitToLongMode:
Modified: trunk/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/inclu…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h [iso-8859-1] Fri Aug 26
09:15:38 2011
@@ -26,12 +26,6 @@
#undef KIP0PCRADDRESS
#define KIP0PCRADDRESS 0xFFFFF78000001000ULL /* FIXME!!! */
-#define STACK64ADDR 0x74000 /* The 64-bit stack top will be at 0x74000 */
-
-/* Long mode selectors */
-#define LMODE_CS 0x10
-#define LMODE_DS 0x18
-
#define VA_MASK 0x0000FFFFFFFFFFFFUL
#define PtrToPfn(p) \
Modified: trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/inclu…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h [iso-8859-1]
(original)
+++ trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h [iso-8859-1] Fri Aug 26
09:15:38 2011
@@ -14,6 +14,7 @@
#define FREELDR_BASE HEX(F800)
#define FREELDR_PE_BASE HEX(10000)
#define STACK32ADDR HEX(98000) /* The 32-bit stack top will be at 9000:8000, or
0xA8000 */
+#define STACK64ADDR HEX(98000) /* The 64-bit stack top will be at 98000 */
#define BIOSCALLBUFFER HEX(98000) /* Buffer to store temporary data for any Int386()
call */
#define FILESYSBUFFER HEX(80000) /* Buffer to store file system data (e.g. cluster
buffer for FAT) */
#define DISKREADBUFFER HEX(90000) /* Buffer to store data read in from the disk via
the BIOS */
@@ -21,6 +22,20 @@
#define BIOSCALLBUFSEGMENT (BIOSCALLBUFFER/16) /* Buffer to store temporary data for any
Int386() call */
#define BIOSCALLBUFOFFSET HEX(0000) /* Buffer to store temporary data for any Int386()
call */
+
+/* Layout of the REGS structure */
+#define REGS_EAX 0
+#define REGS_EBX 4
+#define REGS_ECX 8
+#define REGS_EDX 12
+#define REGS_ESI 16
+#define REGS_EDI 20
+#define REGS_DS 24
+#define REGS_ES 26
+#define REGS_FS 28
+#define REGS_GS 30
+#define REGS_EFLAGS 32
+#define REGS_SIZE 36
/* These addresses specify the realmode "BSS section" layout */
#define BSS_RealModeEntry (BSS_START + 0)
@@ -52,19 +67,6 @@
#define FNID_PnpBiosGetDeviceNode 5
#define FNID_BootLinuxKernel 6
-/* Layout of the REGS structure */
-#define REGS_EAX 0
-#define REGS_EBX 4
-#define REGS_ECX 8
-#define REGS_EDX 12
-#define REGS_ESI 16
-#define REGS_EDI 20
-#define REGS_DS 24
-#define REGS_ES 26
-#define REGS_FS 28
-#define REGS_GS 30
-#define REGS_EFLAGS 32
-
/* Flag Masks */
#define CR0_PE_SET HEX(00000001) /* OR this value with CR0 to enable pmode */
#define CR0_PE_CLR HEX(FFFFFFFE) /* AND this value with CR0 to disable pmode */
@@ -80,6 +82,7 @@
/* Long mode selectors */
#define LMODE_CS HEX(10)
#define LMODE_DS HEX(18)
+#define CMODE_CS HEX(30)
//#endif
/* Makes "x" a global variable or label */