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/a... ============================================================================== --- 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/i... ============================================================================== --- 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/r... ============================================================================== --- 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/includ... ============================================================================== --- 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/includ... ============================================================================== --- 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 */