mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
[FREELDR]
- implement the amd64 real mode entry point and callback mechanism - implement PnpBiosSupported, PnpBiosGetDeviceNodeCount, PnpBiosGetDeviceNode for amd64 - delete outdated amd64 files svn path=/trunk/; revision=53453
This commit is contained in:
parent
82454038b9
commit
41523bb55f
15 changed files with 260 additions and 2763 deletions
|
@ -124,7 +124,9 @@ if(ARCH MATCHES i386)
|
||||||
elseif(ARCH MATCHES amd64)
|
elseif(ARCH MATCHES amd64)
|
||||||
list(APPEND FREELDR_COMMON_SOURCE
|
list(APPEND FREELDR_COMMON_SOURCE
|
||||||
arch/amd64/entry.S
|
arch/amd64/entry.S
|
||||||
|
arch/amd64/int386.S
|
||||||
arch/amd64/loader.c
|
arch/amd64/loader.c
|
||||||
|
arch/amd64/pnpbios.S
|
||||||
arch/i386/hardware.c
|
arch/i386/hardware.c
|
||||||
arch/i386/hwacpi.c
|
arch/i386/hwacpi.c
|
||||||
arch/i386/hwapm.c
|
arch/i386/hwapm.c
|
||||||
|
|
|
@ -1,454 +0,0 @@
|
||||||
|
|
||||||
#define ASM
|
|
||||||
|
|
||||||
#include <asm.inc>
|
|
||||||
|
|
||||||
.text
|
|
||||||
.code16
|
|
||||||
|
|
||||||
//.org 0x8000
|
|
||||||
|
|
||||||
.global RealEntryPoint
|
|
||||||
RealEntryPoint:
|
|
||||||
|
|
||||||
cli
|
|
||||||
|
|
||||||
/* Setup real mode segment registers */
|
|
||||||
xor ax, ax
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
mov ss, ax
|
|
||||||
|
|
||||||
/* checkPoint Charlie - where it all began... */
|
|
||||||
mov si, offset CheckPoint0
|
|
||||||
call writestr
|
|
||||||
|
|
||||||
/* Setup a real mode stack */
|
|
||||||
mov sp, stack16
|
|
||||||
|
|
||||||
/* Zero BootPartition */
|
|
||||||
xor eax, eax
|
|
||||||
mov FrldrBootPartition, eax
|
|
||||||
|
|
||||||
/* Store the boot drive */
|
|
||||||
mov FrldrBootDrive, dl
|
|
||||||
|
|
||||||
/* Store the boot partition */
|
|
||||||
mov FrldrBootPartition, dh
|
|
||||||
|
|
||||||
/* Load the GDT */
|
|
||||||
lgdt gdtptr
|
|
||||||
/* Load the IDT */
|
|
||||||
// lidt idtptr
|
|
||||||
|
|
||||||
call x86_16_EnableA20
|
|
||||||
|
|
||||||
/* checkPoint Charlie - where it all began... */
|
|
||||||
mov si, offset CheckPoint1
|
|
||||||
call writestr
|
|
||||||
|
|
||||||
call x86_16_BuildPageTables
|
|
||||||
|
|
||||||
/* checkPoint Charlie - where it all began... */
|
|
||||||
mov si, offset CheckPoint2
|
|
||||||
call writestr
|
|
||||||
|
|
||||||
/* Check if CPU supports CPUID */
|
|
||||||
|
|
||||||
pushfd
|
|
||||||
pop eax
|
|
||||||
mov ebx, eax
|
|
||||||
xor eax, 0x00200000
|
|
||||||
push eax
|
|
||||||
popfd
|
|
||||||
pushfd
|
|
||||||
pop eax
|
|
||||||
cmp eax,ebx
|
|
||||||
jz NO_CPUID_SUPPORT_DETECTED
|
|
||||||
|
|
||||||
/* CPUID support detected - getting the PAE/PGE */
|
|
||||||
|
|
||||||
mov eax,1 // Fn0000_0001 - PAE in EDX[6]
|
|
||||||
cpuid
|
|
||||||
xor eax,eax
|
|
||||||
and edx,0x00a0
|
|
||||||
test edx,edx // are PAE and PGE bits set?
|
|
||||||
jz NO_X64_SUPPORT_DETECTED
|
|
||||||
|
|
||||||
/* PAE and PGE are here */
|
|
||||||
|
|
||||||
xor edx, edx
|
|
||||||
mov eax, 0x80000001
|
|
||||||
cpuid
|
|
||||||
and edx, 0x20000000
|
|
||||||
test edx,edx
|
|
||||||
jz NO_X64_SUPPORT_DETECTED
|
|
||||||
|
|
||||||
/* X64 Processor */
|
|
||||||
|
|
||||||
/* checkPoint Charlie - where it all began... */
|
|
||||||
mov si, offset CheckPoint3
|
|
||||||
call writestr
|
|
||||||
|
|
||||||
jmp switch64
|
|
||||||
|
|
||||||
NO_X64_SUPPORT_DETECTED:
|
|
||||||
mov si, offset NotAnX64Processor // Loading message
|
|
||||||
call writestr
|
|
||||||
jmp fail
|
|
||||||
|
|
||||||
NO_CPUID_SUPPORT_DETECTED:
|
|
||||||
mov si, offset NoCPUIDSupport // Loading message
|
|
||||||
call writestr
|
|
||||||
|
|
||||||
fail:
|
|
||||||
jmp fail
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
|
|
||||||
switch64:
|
|
||||||
call x86_16_SwitchToLong
|
|
||||||
|
|
||||||
.code64
|
|
||||||
|
|
||||||
// mov ax, LMODE_DS
|
|
||||||
// mov ds, ax
|
|
||||||
// mov word ptr ds:[0xb8000], 0x0e00 + '1'
|
|
||||||
|
|
||||||
/* GO! */
|
|
||||||
xor rcx, rcx
|
|
||||||
call BootMain
|
|
||||||
|
|
||||||
/* Checkpoint */
|
|
||||||
// mov ax, LMODE_DS
|
|
||||||
// mov ds, ax
|
|
||||||
// mov word ptr ds:[0xb8002], 0x0e02 + '2'
|
|
||||||
|
|
||||||
|
|
||||||
/* Return into real mode */
|
|
||||||
call x86_64_SwitchToReal
|
|
||||||
.code16
|
|
||||||
|
|
||||||
// int 0x19
|
|
||||||
|
|
||||||
/* We should never get here */
|
|
||||||
stop:
|
|
||||||
jmp stop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
|
|
||||||
|
|
||||||
/** 16 Bit helper functions ***************************************************/
|
|
||||||
.code16
|
|
||||||
|
|
||||||
x86_16_Empty8042:
|
|
||||||
.word 0x00eb,0x00eb // jmp $+2, jmp $+2
|
|
||||||
in al, 0x64
|
|
||||||
cmp al, 0xff // legacy-free machine without keyboard
|
|
||||||
jz empty_8042_ret // controllers on Intel Macs read back 0xFF
|
|
||||||
test al, 0x02
|
|
||||||
jnz x86_16_Empty8042
|
|
||||||
empty_8042_ret:
|
|
||||||
ret
|
|
||||||
|
|
||||||
x86_16_EnableA20:
|
|
||||||
pusha
|
|
||||||
call x86_16_Empty8042
|
|
||||||
mov al, 0xD1 // command write
|
|
||||||
out 0x64, al
|
|
||||||
call x86_16_Empty8042
|
|
||||||
mov al, 0xDF // A20 on
|
|
||||||
out 0x60, al
|
|
||||||
call x86_16_Empty8042
|
|
||||||
popa
|
|
||||||
ret
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We define 512 2MB pages at the start of memory, so we can access the first
|
|
||||||
* 1 GB as if paging was disabled
|
|
||||||
*/
|
|
||||||
x86_16_BuildPageTables:
|
|
||||||
pusha
|
|
||||||
push es
|
|
||||||
|
|
||||||
/* Get segment of pml4 */
|
|
||||||
mov eax, offset pml4_startup
|
|
||||||
shr eax, 4
|
|
||||||
mov es, ax
|
|
||||||
cld
|
|
||||||
xor di, di
|
|
||||||
|
|
||||||
/* One entry in the PML4 pointing to PDP */
|
|
||||||
mov eax, offset pdp_startup
|
|
||||||
or eax, 0x00f
|
|
||||||
stosd
|
|
||||||
/* clear rest */
|
|
||||||
xor eax, eax
|
|
||||||
mov cx, 0x03ff
|
|
||||||
rep stosd
|
|
||||||
|
|
||||||
/* One entry in the PDP pointing to PD */
|
|
||||||
mov eax, offset pd_startup
|
|
||||||
or eax, 0x00f
|
|
||||||
stosd
|
|
||||||
/* clear rest */
|
|
||||||
xor eax, eax
|
|
||||||
mov ecx, 0x03ff
|
|
||||||
rep stosd
|
|
||||||
|
|
||||||
/* 512 entries in the PD defining a 2MB page each */
|
|
||||||
mov ecx, 512
|
|
||||||
mov eax, 0x008f
|
|
||||||
|
|
||||||
Bpt2:
|
|
||||||
mov es: [di], eax
|
|
||||||
mov dword ptr es: [di + 4], 0
|
|
||||||
add eax, 512 << 12 // add 512 4k pages
|
|
||||||
add di, 8
|
|
||||||
|
|
||||||
/* Loop it */
|
|
||||||
dec cx
|
|
||||||
jnz Bpt2
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
pop es
|
|
||||||
popa
|
|
||||||
ret
|
|
||||||
|
|
||||||
/*
|
|
||||||
* writechr,writestr
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
writestr:
|
|
||||||
pushfd
|
|
||||||
pushad
|
|
||||||
.top:
|
|
||||||
lodsb
|
|
||||||
and al, al
|
|
||||||
jz .end
|
|
||||||
call writechr
|
|
||||||
jmp short .top
|
|
||||||
.end:
|
|
||||||
popad
|
|
||||||
popfd
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
writechr:
|
|
||||||
pushf
|
|
||||||
pusha
|
|
||||||
mov ah, 0x0E
|
|
||||||
xor bx, bx
|
|
||||||
int 0x10
|
|
||||||
popa
|
|
||||||
popf
|
|
||||||
ret
|
|
||||||
|
|
||||||
//.global x86_16_SwitchToLong
|
|
||||||
x86_16_SwitchToLong:
|
|
||||||
|
|
||||||
cli
|
|
||||||
|
|
||||||
xor ax,ax
|
|
||||||
mov ds,ax
|
|
||||||
mov es,ax
|
|
||||||
mov fs,ax
|
|
||||||
mov gs,ax
|
|
||||||
mov ss,ax
|
|
||||||
|
|
||||||
/* Get the return address off the stack */
|
|
||||||
pop word ptr code64ret
|
|
||||||
|
|
||||||
/* Save 16-bit stack pointer */
|
|
||||||
mov stack16, sp
|
|
||||||
|
|
||||||
mov eax, 0x00a0 // Set PAE and PGE: 10100000b
|
|
||||||
mov cr4, eax
|
|
||||||
|
|
||||||
mov edx, offset pml4_startup // Point cr3 at PML4
|
|
||||||
mov cr3, edx
|
|
||||||
|
|
||||||
mov ecx, 0xC0000080 // Specify EFER MSR
|
|
||||||
|
|
||||||
rdmsr // Enable long mode
|
|
||||||
or eax, 0x00000100
|
|
||||||
wrmsr
|
|
||||||
|
|
||||||
mov ebx, cr0 // Activate long mode
|
|
||||||
or ebx, 0x80000001 // by enabling paging and protection simultaneously
|
|
||||||
mov cr0, ebx // skipping protected mode entirely
|
|
||||||
|
|
||||||
jmp LMODE_CS:offset LongCat //Load CS with 64 bit segment and flush the instruction cache
|
|
||||||
|
|
||||||
.code64
|
|
||||||
LongCat:
|
|
||||||
/* Set up 64 bit stack */
|
|
||||||
mov rsp, stack64
|
|
||||||
|
|
||||||
/* Put the return address back onto the stack */
|
|
||||||
push qword ptr code64ret
|
|
||||||
|
|
||||||
/* Now return in long mode! */
|
|
||||||
ret
|
|
||||||
|
|
||||||
/** 64 Bit functions **********************************************************/
|
|
||||||
.code64
|
|
||||||
|
|
||||||
.global x86_64_SwitchToReal
|
|
||||||
x86_64_SwitchToReal:
|
|
||||||
|
|
||||||
/* Get the return address off the stack */
|
|
||||||
pop qword ptr code64ret
|
|
||||||
|
|
||||||
/* Save 64-bit stack pointer */
|
|
||||||
mov stack64, rsp
|
|
||||||
|
|
||||||
// mov ax, LMODE_DS
|
|
||||||
// mov ds, ax
|
|
||||||
// mov word ptr ds:[0xb8004], 0x0e00 + '3'
|
|
||||||
|
|
||||||
/* Step 1 - jump to compatibility segment */
|
|
||||||
ljmp jumpvector
|
|
||||||
|
|
||||||
jumpvector:
|
|
||||||
.long SwitchToReal1
|
|
||||||
.word CMODE_CS
|
|
||||||
|
|
||||||
SwitchToReal1:
|
|
||||||
.code32
|
|
||||||
|
|
||||||
// mov word ptr ds:[0xb8006], 0x0e00 + '4'
|
|
||||||
|
|
||||||
/* Step 2 - deactivate long mode, by disabling paging */
|
|
||||||
mov eax, cr0
|
|
||||||
and eax, 0x000000007fffffff //~0x80000000
|
|
||||||
mov cr0, eax
|
|
||||||
|
|
||||||
/* Step 2 - disable long mode in EFER MSR */
|
|
||||||
// mov ecx, 0xC0000080 // Specify EFER MSR
|
|
||||||
// rdmsr
|
|
||||||
// and eax, ~0x00000100 // Disable EFER.LME
|
|
||||||
// wrmsr
|
|
||||||
|
|
||||||
/* Step 3 - jump to 16-bit segment to set the limit correctly */
|
|
||||||
jmp RMODE_CS: offset SwitchToReal2
|
|
||||||
|
|
||||||
SwitchToReal2:
|
|
||||||
.code16
|
|
||||||
|
|
||||||
/* Step 4 - Disable Protected Mode */
|
|
||||||
mov eax, cr0
|
|
||||||
and eax, ~0x00000001
|
|
||||||
mov cr0, eax
|
|
||||||
|
|
||||||
/* Clear prefetch queue & correct CS */
|
|
||||||
jmp 0:offset BeReal
|
|
||||||
|
|
||||||
BeReal:
|
|
||||||
/* Checkpoint */
|
|
||||||
// mov ax, 0xb800
|
|
||||||
// mov fs, ax
|
|
||||||
// mov word ptr fs:[0x0C], 0x0e00 + '7'
|
|
||||||
|
|
||||||
/* Restore segment registers */
|
|
||||||
mov ax, 0
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
mov ss, ax
|
|
||||||
|
|
||||||
/* Restore 16 bit stack */
|
|
||||||
mov sp, stack16
|
|
||||||
|
|
||||||
// lidt rmode_idtptr /* Load IDTR with real mode value */
|
|
||||||
|
|
||||||
// sti /* These are ok now */
|
|
||||||
|
|
||||||
/* Put the return address back onto the stack */
|
|
||||||
push word ptr code64ret
|
|
||||||
|
|
||||||
/* Now return in real mode! */
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Some data *****************************************************************/
|
|
||||||
|
|
||||||
.code64
|
|
||||||
|
|
||||||
stack16:
|
|
||||||
.quad STACK16ADDR
|
|
||||||
|
|
||||||
stack64:
|
|
||||||
.quad STACK64ADDR
|
|
||||||
|
|
||||||
code64ret:
|
|
||||||
.quad 0
|
|
||||||
|
|
||||||
.p2align 2
|
|
||||||
gdt:
|
|
||||||
.quad 0x0000000000000000 /* 00: NULL descriptor */
|
|
||||||
.quad 0x0000000000000000 /* 08: */
|
|
||||||
.quad 0x0020980000000000 /* 10: long mode cs */
|
|
||||||
.quad 0x00cff3000000ffff /* 18: long mode ds */
|
|
||||||
.word 0xFFFF, 0x0000, 0x9E00, 0x0000 /* 16-bit real mode CS */
|
|
||||||
.word 0xFFFF, 0x0000, 0x9200, 0x0000 /* 16-bit real mode DS */
|
|
||||||
.quad 0x00CF9B000000FFFF /* 30: compat mode cs */
|
|
||||||
|
|
||||||
/* GDT table pointer */
|
|
||||||
gdtptr:
|
|
||||||
.word 0x37 /* Limit */
|
|
||||||
.long gdt /* Base Address */
|
|
||||||
|
|
||||||
|
|
||||||
.global FrldrBootDrive
|
|
||||||
FrldrBootDrive:
|
|
||||||
.byte 0
|
|
||||||
|
|
||||||
.global FrldrBootPartition
|
|
||||||
FrldrBootPartition:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
.global NotAnX64Processor
|
|
||||||
NotAnX64Processor:
|
|
||||||
.ascii "FreeLoader: No x64-compatible CPU detected! Exiting..."
|
|
||||||
.byte 0x0d, 0x0a, 0
|
|
||||||
|
|
||||||
.global NoCPUIDSupport
|
|
||||||
NoCPUIDSupport:
|
|
||||||
.ascii "FreeLoader: No CPUID instruction support detected! Exiting..."
|
|
||||||
.byte 0x0d, 0x0a, 0
|
|
||||||
|
|
||||||
/////////////////////////// Checkpoint messages ///////////////////////////////
|
|
||||||
.global CheckPoint0
|
|
||||||
CheckPoint0:
|
|
||||||
.ascii "Starting FreeLoader..."
|
|
||||||
.byte 0x0d, 0x0a, 0
|
|
||||||
|
|
||||||
.global CheckPoint1
|
|
||||||
CheckPoint1:
|
|
||||||
.ascii "FreeLoader[16-bit]: building page tables..."
|
|
||||||
.byte 0x0d, 0x0a, 0
|
|
||||||
|
|
||||||
.global CheckPoint2
|
|
||||||
CheckPoint2:
|
|
||||||
.ascii "FreeLoader[16-bit]: checking CPU for x64 long mode..."
|
|
||||||
.byte 0x0d, 0x0a, 0
|
|
||||||
|
|
||||||
.global CheckPoint3
|
|
||||||
CheckPoint3:
|
|
||||||
.ascii "FreeLoader: Switching to x64 long mode..."
|
|
||||||
.byte 0x0d, 0x0a, 0
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/* Need to include them here, because of linking issues between 64 / 16 bit */
|
|
||||||
//#include "debug16.S"
|
|
||||||
#include "int386.S"
|
|
||||||
#include "boot.S"
|
|
||||||
#include "i386pnp.S"
|
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
* FreeLoader
|
|
||||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <asm.inc>
|
|
||||||
|
|
||||||
|
|
||||||
.text
|
|
||||||
.code16
|
|
||||||
|
|
||||||
PUBLIC ChainLoadBiosBootSectorCode
|
|
||||||
ChainLoadBiosBootSectorCode:
|
|
||||||
.code64
|
|
||||||
|
|
||||||
call x86_64_SwitchToReal
|
|
||||||
.code16
|
|
||||||
|
|
||||||
/* Set the boot drive */
|
|
||||||
mov dl, BootDrive
|
|
||||||
|
|
||||||
/* Load segment registers */
|
|
||||||
cli
|
|
||||||
mov bx, 0x0000
|
|
||||||
mov ds, bx
|
|
||||||
mov es, bx
|
|
||||||
mov fs, bx
|
|
||||||
mov gs, bx
|
|
||||||
mov ss, bx
|
|
||||||
mov sp, 0x7C00
|
|
||||||
|
|
||||||
// ljmpl $0x0000,$0x7C00
|
|
||||||
jmp 0x7c00:0x0000
|
|
||||||
|
|
||||||
PUBLIC SoftReboot
|
|
||||||
SoftReboot:
|
|
||||||
.code64
|
|
||||||
|
|
||||||
call x86_64_SwitchToReal
|
|
||||||
.code16
|
|
||||||
|
|
||||||
mov ax, 0x40
|
|
||||||
mov ds, ax
|
|
||||||
mov si, 0x72
|
|
||||||
|
|
||||||
// Set the word at location 40:72 to 1234h
|
|
||||||
mov word ptr [si], 0x1234
|
|
||||||
|
|
||||||
// and jump to location FFFF:0 in ROM
|
|
||||||
// ljmpl $0xFFFF,$0x0000
|
|
||||||
jmp 0xffff: 0x0000
|
|
|
@ -1,130 +0,0 @@
|
||||||
/*
|
|
||||||
* FreeLoader
|
|
||||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.text
|
|
||||||
.code16
|
|
||||||
|
|
||||||
#include <arch/pc/x86common.h>
|
|
||||||
|
|
||||||
EXTERN(DriveMapInt13HandlerStart)
|
|
||||||
Int13Handler:
|
|
||||||
|
|
||||||
pushw %bp
|
|
||||||
movw %sp,%bp
|
|
||||||
pushw %ax
|
|
||||||
pushw %cx
|
|
||||||
pushw %si
|
|
||||||
|
|
||||||
cld
|
|
||||||
|
|
||||||
/* Get callers flags from stack */
|
|
||||||
movw 0x06(%bp),%ax
|
|
||||||
movw %ax,%cs:(CallersFlags - Int13Handler)
|
|
||||||
|
|
||||||
/* Save the drive number they passed in */
|
|
||||||
movb %dl,%cs:(PassedInDriveNumber - Int13Handler)
|
|
||||||
|
|
||||||
/* Now we need to perform the mapping */
|
|
||||||
xorw %cx,%cx
|
|
||||||
movw $(Int13HandlerMapCount - Int13Handler),%si
|
|
||||||
/* Get the count of drives in the map list */
|
|
||||||
movb %cs:(%si),%cl
|
|
||||||
incw %si
|
|
||||||
|
|
||||||
/* If the map list is empty then just call the old int 13h handler */
|
|
||||||
cmpb $0,%cl
|
|
||||||
jz CallOldInt13Handler
|
|
||||||
|
|
||||||
GetMappedDriveNumberLoop:
|
|
||||||
|
|
||||||
/* Get the next drive number in the list */
|
|
||||||
lodsw %cs:(%si),%ax
|
|
||||||
/* Check to see if it's the one they are calling int 13h for */
|
|
||||||
cmpb %al,%dl
|
|
||||||
/* If not get the next one */
|
|
||||||
jne GetMappedDriveNumberLoopNext
|
|
||||||
|
|
||||||
/* If we get here then we have found a mapped drive */
|
|
||||||
/* Send new drive number on to the old int 13h handler */
|
|
||||||
movb %ah,%dl
|
|
||||||
/* Call BIOS Int 13 Handler */
|
|
||||||
jmp CallOldInt13Handler
|
|
||||||
|
|
||||||
GetMappedDriveNumberLoopNext:
|
|
||||||
loop GetMappedDriveNumberLoop
|
|
||||||
|
|
||||||
CallOldInt13Handler:
|
|
||||||
/* Restore the registers we changed off the stack */
|
|
||||||
popw %si
|
|
||||||
popw %cx
|
|
||||||
popw %ax
|
|
||||||
|
|
||||||
/* Put flags onto stack */
|
|
||||||
pushw %cs:(CallersFlags - Int13Handler)
|
|
||||||
|
|
||||||
/* Call old int 13h handler with new drive number */
|
|
||||||
.byte 0x9a /* lcall */
|
|
||||||
EXTERN(DriveMapOldInt13HandlerAddress)
|
|
||||||
.word 0
|
|
||||||
.word 0
|
|
||||||
|
|
||||||
/* Update the callers flags with the values the BIOS returned */
|
|
||||||
pushw %ax
|
|
||||||
pushf
|
|
||||||
popw %ax
|
|
||||||
movw %ax,0x06(%bp)
|
|
||||||
popw %ax
|
|
||||||
/* Restore the callers drive number */
|
|
||||||
movb %cs:(PassedInDriveNumber - Int13Handler),%dl
|
|
||||||
|
|
||||||
popw %bp
|
|
||||||
|
|
||||||
iret
|
|
||||||
|
|
||||||
CallersFlags:
|
|
||||||
.word 0
|
|
||||||
|
|
||||||
PassedInDriveNumber:
|
|
||||||
.byte 0
|
|
||||||
|
|
||||||
EXTERN(DriveMapInt13HandlerMapList)
|
|
||||||
Int13HandlerMapCount:
|
|
||||||
.byte 0
|
|
||||||
|
|
||||||
Int13HandlerDrive1:
|
|
||||||
.byte 0
|
|
||||||
Int13HandlerDriveNew1:
|
|
||||||
.byte 0
|
|
||||||
|
|
||||||
Int13HandlerDrive2:
|
|
||||||
.byte 0
|
|
||||||
Int13HandlerDriveNew2:
|
|
||||||
.byte 0
|
|
||||||
|
|
||||||
Int13HandlerDrive3:
|
|
||||||
.byte 0
|
|
||||||
Int13HandlerDriveNew3:
|
|
||||||
.byte 0
|
|
||||||
|
|
||||||
Int13HandlerDrive4:
|
|
||||||
.byte 0
|
|
||||||
Int13HandlerDriveNew4:
|
|
||||||
.byte 0
|
|
||||||
|
|
||||||
EXTERN(DriveMapInt13HandlerEnd)
|
|
|
@ -28,7 +28,6 @@ RealEntryPoint:
|
||||||
ContinueAddress:
|
ContinueAddress:
|
||||||
.double offset FrldrStartup
|
.double offset FrldrStartup
|
||||||
|
|
||||||
|
|
||||||
FrldrStartup:
|
FrldrStartup:
|
||||||
|
|
||||||
/* Store BootDrive and BootPartition */
|
/* Store BootDrive and BootPartition */
|
||||||
|
@ -72,7 +71,7 @@ SwitchToReal:
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
//mov ss, ax
|
//mov ss, ax
|
||||||
|
|
||||||
mov word ptr [HEX(0b8008)], HEX(0e00) + '4'
|
//mov word ptr [HEX(0b8008)], HEX(0e00) + '4'
|
||||||
|
|
||||||
/* Save 64-bit stack pointer */
|
/* Save 64-bit stack pointer */
|
||||||
mov qword ptr [stack64], rsp
|
mov qword ptr [stack64], rsp
|
||||||
|
@ -122,75 +121,22 @@ PUBLIC FrldrBootPartition
|
||||||
FrldrBootPartition:
|
FrldrBootPartition:
|
||||||
.long 0
|
.long 0
|
||||||
|
|
||||||
PUBLIC PageDirectoryEnd
|
PUBLIC PxeCallApi
|
||||||
PageDirectoryEnd:
|
PxeCallApi:
|
||||||
PUBLIC PageDirectoryStart
|
xor eax, eax
|
||||||
PageDirectoryStart:
|
ret
|
||||||
PUBLIC PnpBiosGetDeviceNode
|
|
||||||
PnpBiosGetDeviceNode:
|
|
||||||
PUBLIC PnpBiosGetDeviceNodeCount
|
|
||||||
PnpBiosGetDeviceNodeCount:
|
|
||||||
PUBLIC PnpBiosSupported
|
|
||||||
PnpBiosSupported:
|
|
||||||
|
|
||||||
/* int Int386(int ivec<ecx>, REGS* in<rdx>, REGS* out<r8>); */
|
//void __lgdt(void *Source);
|
||||||
PUBLIC Int386
|
PUBLIC __lgdt
|
||||||
Int386:
|
__lgdt:
|
||||||
|
lgdt fword ptr [rcx]
|
||||||
|
ret
|
||||||
|
|
||||||
/* Save home registers */
|
//void __ltr(unsigned short Source);
|
||||||
mov r11, rsp
|
PUBLIC __ltr
|
||||||
mov qword ptr [r11 + 8], rcx
|
__ltr:
|
||||||
mov qword ptr [r11 + 16], rdx
|
ltr cx
|
||||||
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
|
ret
|
||||||
|
|
||||||
|
|
||||||
PUBLIC PxeCallApi
|
|
||||||
PxeCallApi:
|
|
||||||
PUBLIC __lgdt
|
|
||||||
__lgdt:
|
|
||||||
PUBLIC __ltr
|
|
||||||
__ltr:
|
|
||||||
|
|
||||||
nop
|
|
||||||
|
|
||||||
|
|
||||||
END
|
END
|
||||||
|
|
|
@ -1,235 +0,0 @@
|
||||||
// fathelp.S
|
|
||||||
// FAT12/16 Boot Sector Helper Code
|
|
||||||
// Copyright (c) 1998, 2001, 2002, 2003 Brian Palmer
|
|
||||||
|
|
||||||
.intel_syntax noprefix
|
|
||||||
|
|
||||||
//org 8000h
|
|
||||||
|
|
||||||
.text
|
|
||||||
|
|
||||||
.code16
|
|
||||||
|
|
||||||
|
|
||||||
#define BootSectorStackTop 0x7bf2
|
|
||||||
#define DataAreaStartHigh 0x2
|
|
||||||
#define DataAreaStartLow 0x4
|
|
||||||
#define BiosCHSDriveSizeHigh 0x6
|
|
||||||
#define BiosCHSDriveSizeLow 0x8
|
|
||||||
#define BiosCHSDriveSize 0x8
|
|
||||||
#define ReadSectorsOffset 0xa
|
|
||||||
#define ReadClusterOffset 0xc
|
|
||||||
#define PutCharsOffset 0xe
|
|
||||||
|
|
||||||
#define OEMName 3
|
|
||||||
#define BytesPerSector 11
|
|
||||||
#define SectsPerCluster 13
|
|
||||||
#define ReservedSectors 14
|
|
||||||
#define NumberOfFats 16
|
|
||||||
#define MaxRootEntries 17
|
|
||||||
#define TotalSectors 19
|
|
||||||
#define MediaDescriptor 21
|
|
||||||
#define SectorsPerFat 22
|
|
||||||
#define SectorsPerTrack 24
|
|
||||||
#define NumberOfHeads 26
|
|
||||||
#define HiddenSectors 28
|
|
||||||
#define TotalSectorsBig 32
|
|
||||||
#define BootDrive 36
|
|
||||||
#define Reserved 37
|
|
||||||
#define ExtendSig 38
|
|
||||||
#define SerialNumber 39
|
|
||||||
#define VolumeLabel 43
|
|
||||||
#define FileSystem 54
|
|
||||||
|
|
||||||
#define BootPartition 0x7dfd
|
|
||||||
|
|
||||||
|
|
||||||
// This code will be stored in the first 512 bytes
|
|
||||||
// of freeldr.sys. The first 3 bytes will be a jmp
|
|
||||||
// instruction to skip past the FAT helper code
|
|
||||||
// that is stored in the rest of the 512 bytes.
|
|
||||||
//
|
|
||||||
// This code is loaded at 0000:8000 so we have to
|
|
||||||
// encode a jmp instruction to jump to 0000:8200
|
|
||||||
|
|
||||||
.global _mainCRTStartup // For Mingw32 builds where the linker looks for this symbol
|
|
||||||
_mainCRTStartup:
|
|
||||||
.global start
|
|
||||||
start:
|
|
||||||
.byte 0xe9
|
|
||||||
.byte 0xfd
|
|
||||||
.byte 0x01
|
|
||||||
|
|
||||||
// Now starts the extra boot code that we will store
|
|
||||||
// in the first 512 bytes of freeldr.sys. This code
|
|
||||||
// allows the FAT12/16 bootsector to navigate the
|
|
||||||
// FAT table so that we can still load freeldr.sys
|
|
||||||
// even if it is fragmented.
|
|
||||||
|
|
||||||
|
|
||||||
FatHelperEntryPoint:
|
|
||||||
|
|
||||||
push ax // First save AX - the start cluster of freeldr.sys
|
|
||||||
|
|
||||||
|
|
||||||
// Display "Loading FreeLoader..." message
|
|
||||||
mov esi, offset msgLoading // Loading message
|
|
||||||
call [bp-PutCharsOffset] // Display it
|
|
||||||
|
|
||||||
|
|
||||||
call ReadFatIntoMemory
|
|
||||||
|
|
||||||
pop ax // Restore AX (start cluster)
|
|
||||||
// AX has start cluster of freeldr.sys
|
|
||||||
|
|
||||||
mov bx,0x800
|
|
||||||
mov es,bx
|
|
||||||
|
|
||||||
LoadFile:
|
|
||||||
push ax
|
|
||||||
call IsFat12
|
|
||||||
pop ax
|
|
||||||
jnc LoadFile2
|
|
||||||
cmp ax,0x0ff8 // Check to see if this is the last cluster in the chain
|
|
||||||
jmp LoadFile3
|
|
||||||
LoadFile2:
|
|
||||||
cmp ax,0x0fff8
|
|
||||||
LoadFile3:
|
|
||||||
jae LoadFile_Done // If so continue, if not then read then next one
|
|
||||||
push ax
|
|
||||||
xor bx,bx // Load ROSLDR starting at 0000:8000h
|
|
||||||
push es
|
|
||||||
call [bp-ReadClusterOffset]
|
|
||||||
pop es
|
|
||||||
|
|
||||||
xor bx,bx
|
|
||||||
mov bl, [bp+SectsPerCluster]
|
|
||||||
shl bx,5 // BX = BX * 512 / 16
|
|
||||||
mov ax,es // Increment the load address by
|
|
||||||
add ax,bx // The size of a cluster
|
|
||||||
mov es,ax
|
|
||||||
|
|
||||||
call IsFat12
|
|
||||||
pop ax
|
|
||||||
push es
|
|
||||||
jnc LoadFile4
|
|
||||||
call GetFatEntry12 // Get the next entry
|
|
||||||
jmp LoadFile5
|
|
||||||
LoadFile4:
|
|
||||||
call GetFatEntry16
|
|
||||||
LoadFile5:
|
|
||||||
pop es
|
|
||||||
|
|
||||||
jmp LoadFile // Load the next cluster (if any)
|
|
||||||
|
|
||||||
LoadFile_Done:
|
|
||||||
mov dl,BYTE PTR [bp+BootDrive] // Load the boot drive into DL
|
|
||||||
mov dh,[BootPartition] // Load the boot partition into DH
|
|
||||||
|
|
||||||
push 0 // push segment (0x0000)
|
|
||||||
mov bx, [0x8000 + 0xA8] // load the RVA of the EntryPoint into eax
|
|
||||||
add bx, 0x8000 // RVA -> VA and skip 3 bytes (jump to fathelper code)
|
|
||||||
push bx // push offset
|
|
||||||
retf // Transfer control to FreeLoader
|
|
||||||
|
|
||||||
// Reads the entire FAT into memory at 7000:0000
|
|
||||||
ReadFatIntoMemory:
|
|
||||||
mov ax, [bp+HiddenSectors]
|
|
||||||
mov dx, [bp+HiddenSectors+2]
|
|
||||||
add ax, [bp+ReservedSectors]
|
|
||||||
adc dx, 0
|
|
||||||
mov cx, [bp+SectorsPerFat]
|
|
||||||
mov bx,0x7000
|
|
||||||
mov es,bx
|
|
||||||
xor bx,bx
|
|
||||||
call [bp-ReadSectorsOffset]
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
// Returns the FAT entry for a given cluster number for 16-bit FAT
|
|
||||||
// On entry AX has cluster number
|
|
||||||
// On return AX has FAT entry for that cluster
|
|
||||||
GetFatEntry16:
|
|
||||||
|
|
||||||
mov cx,2 // AX = AX * 2 (since FAT16 entries are 2 bytes)
|
|
||||||
mul cx
|
|
||||||
shl dx,12
|
|
||||||
|
|
||||||
mov bx,0x7000
|
|
||||||
add bx,dx
|
|
||||||
mov es,bx
|
|
||||||
mov bx,ax // Restore FAT entry offset
|
|
||||||
mov ax, es:[bx] // Get FAT entry
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
// Returns the FAT entry for a given cluster number for 12-bit FAT
|
|
||||||
// On entry AX has cluster number
|
|
||||||
// On return AX has FAT entry for that cluster
|
|
||||||
GetFatEntry12:
|
|
||||||
|
|
||||||
push ax
|
|
||||||
mov cx,ax
|
|
||||||
shr ax,1
|
|
||||||
add ax,cx // AX = AX * 1.5 (AX = AX + (AX / 2)) (since FAT12 entries are 12 bits)
|
|
||||||
|
|
||||||
mov bx,0x7000
|
|
||||||
mov es,bx
|
|
||||||
mov bx,ax // Put FAT entry offset into BX
|
|
||||||
mov ax, es:[bx] // Get FAT entry
|
|
||||||
pop cx // Get cluster number from stack
|
|
||||||
and cx,1
|
|
||||||
jz UseLow12Bits
|
|
||||||
and ax,0x0fff0
|
|
||||||
shr ax,4
|
|
||||||
jmp GetFatEntry12_Done
|
|
||||||
|
|
||||||
UseLow12Bits:
|
|
||||||
and ax,0x0fff
|
|
||||||
|
|
||||||
GetFatEntry12_Done:
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
// Returns CF = 1 if this is a FAT12 file system
|
|
||||||
// Otherwise CF = 0 for FAT16
|
|
||||||
IsFat12:
|
|
||||||
|
|
||||||
mov ebx, [bp-DataAreaStartLow]
|
|
||||||
// EBX now has the number of the starting sector of the data area
|
|
||||||
// starting from the beginning of the disk, so subtrace hidden sectors
|
|
||||||
sub ebx, [bp+HiddenSectors]
|
|
||||||
|
|
||||||
|
|
||||||
xor eax,eax
|
|
||||||
mov ax, [bp+TotalSectors]
|
|
||||||
cmp ax, 0
|
|
||||||
jnz IsFat12_2
|
|
||||||
mov eax, [bp+TotalSectorsBig]
|
|
||||||
|
|
||||||
// EAX now contains the number of sectors on the volume
|
|
||||||
|
|
||||||
IsFat12_2:
|
|
||||||
sub eax,ebx // Subtract data area start sector
|
|
||||||
xor edx,edx // from total sectors of volume
|
|
||||||
|
|
||||||
// EDX:EAX now contains the number of data sectors on the volume
|
|
||||||
movzx ebx, byte ptr [bp+SectsPerCluster]
|
|
||||||
div ebx
|
|
||||||
// EAX now has the number of clusters on the volume
|
|
||||||
stc
|
|
||||||
cmp eax,4085
|
|
||||||
jb IsFat12_Done
|
|
||||||
clc
|
|
||||||
|
|
||||||
IsFat12_Done:
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
msgLoading: .asciz "Loading FreeLoader...\r\n"
|
|
||||||
|
|
||||||
.org 0x1fe // Pad to 510 bytes
|
|
||||||
.word 0x0aa55 // BootSector signature
|
|
|
@ -1,129 +0,0 @@
|
||||||
/*
|
|
||||||
* FreeLoader
|
|
||||||
* Copyright (C) 2003 Eric Kohl
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.text
|
|
||||||
.code16
|
|
||||||
|
|
||||||
#include <arch/pc/x86common.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* U32 CpuidSupported(VOID);
|
|
||||||
*
|
|
||||||
* RETURNS:
|
|
||||||
* 0x00000001: CPU supports the CPUID instruction
|
|
||||||
* 0x00000300: Found 80386 CPU
|
|
||||||
* 0x00000400: Found 80486 CPU without CPUID support
|
|
||||||
*/
|
|
||||||
|
|
||||||
EXTERN(CpuidSupported)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
pushl %ecx /* save ECX */
|
|
||||||
|
|
||||||
pushfl /* push original EFLAGS */
|
|
||||||
popl %eax /* get original EFLAGS */
|
|
||||||
movl %eax,%ecx /* save original EFLAGS */
|
|
||||||
xorl $0x40000,%eax /* flip AC bit in EFLAGS */
|
|
||||||
pushl %eax /* save new EFLAGS value on stack */
|
|
||||||
popfl /* replace current EFLAGS value */
|
|
||||||
|
|
||||||
pushfl /* get new EFLAGS */
|
|
||||||
popl %eax /* store new EFLAGS in EAX */
|
|
||||||
xorl %ecx, %eax /* can't toggle AC bit, processor=80386 */
|
|
||||||
|
|
||||||
movl $0x300,%eax /* return processor id */
|
|
||||||
jz NoCpuid /* jump if 80386 processor */
|
|
||||||
|
|
||||||
pushl %ecx
|
|
||||||
popfl /* restore AC bit in EFLAGS first */
|
|
||||||
|
|
||||||
movl %ecx,%eax /* get original EFLAGS */
|
|
||||||
xorl $0x200000,%eax /* flip ID bit in EFLAGS */
|
|
||||||
pushl %eax /* save new EFLAGS value on stack */
|
|
||||||
popfl /* replace current EFLAGS value */
|
|
||||||
pushfl /* get new EFLAGS */
|
|
||||||
popl %eax /* store new EFLAGS in EAX */
|
|
||||||
xorl %ecx,%eax /* can't toggle ID bit, */
|
|
||||||
|
|
||||||
movl $0x400,%eax /* return processor id */
|
|
||||||
je NoCpuid /* processor=80486 */
|
|
||||||
|
|
||||||
movl $1,%eax /* CPUID supported */
|
|
||||||
|
|
||||||
NoCpuid:
|
|
||||||
pushl %ecx
|
|
||||||
popfl /* restore EFLAGS */
|
|
||||||
popl %ecx /* retore ECX */
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* VOID GetCpuid(U32 Level, U32 *eax, U32 *ebx, U32 *ecx, U32 *edx);
|
|
||||||
*/
|
|
||||||
|
|
||||||
EXTERN(GetCpuid)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
pushl %ebp
|
|
||||||
movl %esp,%ebp
|
|
||||||
|
|
||||||
pushl %eax
|
|
||||||
pushl %ebx
|
|
||||||
pushl %ecx
|
|
||||||
pushl %edx
|
|
||||||
pushl %esi
|
|
||||||
|
|
||||||
movl 0x08(%ebp),%eax
|
|
||||||
|
|
||||||
cpuid
|
|
||||||
|
|
||||||
movl 0x0C(%ebp),%esi
|
|
||||||
movl %eax,(%esi)
|
|
||||||
|
|
||||||
movl 0x10(%ebp),%esi
|
|
||||||
movl %ebx,(%esi)
|
|
||||||
|
|
||||||
movl 0x14(%ebp),%esi
|
|
||||||
movl %ecx,(%esi)
|
|
||||||
|
|
||||||
movl 0x18(%ebp),%esi
|
|
||||||
movl %edx,(%esi)
|
|
||||||
|
|
||||||
popl %esi
|
|
||||||
popl %edx
|
|
||||||
popl %ecx
|
|
||||||
popl %ebx
|
|
||||||
popl %eax
|
|
||||||
|
|
||||||
movl %ebp,%esp
|
|
||||||
popl %ebp
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* U64 RDTSC(VOID);
|
|
||||||
*/
|
|
||||||
|
|
||||||
EXTERN(RDTSC)
|
|
||||||
.code32
|
|
||||||
rdtsc
|
|
||||||
ret
|
|
||||||
|
|
||||||
/* EOF */
|
|
|
@ -1,220 +0,0 @@
|
||||||
/*
|
|
||||||
* FreeLoader
|
|
||||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.text
|
|
||||||
.code16
|
|
||||||
|
|
||||||
.p2align 2 /* force 4-byte alignment */
|
|
||||||
EXTERN(i386idt)
|
|
||||||
/* Exception 0 - Divide By Zero */
|
|
||||||
.word i386DivideByZero /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Flags, Zero Byte */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 1 - Debug Exception */
|
|
||||||
.word i386DebugException /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 2 - NMI */
|
|
||||||
.word i386NMIException /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 3 - Breakpoint (INT 3) */
|
|
||||||
.word i386Breakpoint /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 4 - Overflow (INTO with EFLAGS[OF] set) */
|
|
||||||
.word i386Overflow /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 5 - Bound Exception */
|
|
||||||
.word i386BoundException /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 6 - Invalid Opcode */
|
|
||||||
.word i386InvalidOpcode /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 7 - FPU Not Available */
|
|
||||||
.word i386FPUNotAvailable /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 8 - Double Fault */
|
|
||||||
.word i386DoubleFault /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 9 - Coprocessor Segment Overrun */
|
|
||||||
.word i386CoprocessorSegment /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 10 (0x0A) - Invalid TSS */
|
|
||||||
.word i386InvalidTSS /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 11 (0x0B) - Segment Not Present */
|
|
||||||
.word i386SegmentNotPresent /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 12 (0x0C) - Stack Exception */
|
|
||||||
.word i386StackException /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 13 (0x0D) - General Protection Fault */
|
|
||||||
.word i386GeneralProtectionFault /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 14 (0x0E) - Page Fault */
|
|
||||||
.word i386PageFault /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 15 (0x0F) - Reserved */
|
|
||||||
.word 0x0000 /* Offset 0 - 15 */
|
|
||||||
.word 0x0000 /* Selector */
|
|
||||||
.word 0x0000 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 16 (0x10) - Coprocessor Error */
|
|
||||||
.word i386CoprocessorError /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 17 (0x11) - Alignment Check */
|
|
||||||
.word i386AlignmentCheck /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 18 (0x12) - Machine Check */
|
|
||||||
.word i386MachineCheck /* Offset 0 - 15 */
|
|
||||||
.word 0x0008 /* Selector */
|
|
||||||
.word 0x8e00 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 19 (0x13) - Reserved */
|
|
||||||
.word 0x0000 /* Offset 0 - 15 */
|
|
||||||
.word 0x0000 /* Selector */
|
|
||||||
.word 0x0000 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 20 (0x14) - Reserved */
|
|
||||||
.word 0x0000 /* Offset 0 - 15 */
|
|
||||||
.word 0x0000 /* Selector */
|
|
||||||
.word 0x0000 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 21 (0x15) - Reserved */
|
|
||||||
.word 0x0000 /* Offset 0 - 15 */
|
|
||||||
.word 0x0000 /* Selector */
|
|
||||||
.word 0x0000 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 22 (0x16) - Reserved */
|
|
||||||
.word 0x0000 /* Offset 0 - 15 */
|
|
||||||
.word 0x0000 /* Selector */
|
|
||||||
.word 0x0000 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 23 (0x17) - Reserved */
|
|
||||||
.word 0x0000 /* Offset 0 - 15 */
|
|
||||||
.word 0x0000 /* Selector */
|
|
||||||
.word 0x0000 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 24 (0x18) - Reserved */
|
|
||||||
.word 0x0000 /* Offset 0 - 15 */
|
|
||||||
.word 0x0000 /* Selector */
|
|
||||||
.word 0x0000 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 25 (0x19) - Reserved */
|
|
||||||
.word 0x0000 /* Offset 0 - 15 */
|
|
||||||
.word 0x0000 /* Selector */
|
|
||||||
.word 0x0000 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 26 (0x1A) - Reserved */
|
|
||||||
.word 0x0000 /* Offset 0 - 15 */
|
|
||||||
.word 0x0000 /* Selector */
|
|
||||||
.word 0x0000 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 27 (0x1B) - Reserved */
|
|
||||||
.word 0x0000 /* Offset 0 - 15 */
|
|
||||||
.word 0x0000 /* Selector */
|
|
||||||
.word 0x0000 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 28 (0x1C) - Reserved */
|
|
||||||
.word 0x0000 /* Offset 0 - 15 */
|
|
||||||
.word 0x0000 /* Selector */
|
|
||||||
.word 0x0000 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 29 (0x1D) - Reserved */
|
|
||||||
.word 0x0000 /* Offset 0 - 15 */
|
|
||||||
.word 0x0000 /* Selector */
|
|
||||||
.word 0x0000 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 30 (0x1E) - Reserved */
|
|
||||||
.word 0x0000 /* Offset 0 - 15 */
|
|
||||||
.word 0x0000 /* Selector */
|
|
||||||
.word 0x0000 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* Exception 31 (0x1F) - Reserved */
|
|
||||||
.word 0x0000 /* Offset 0 - 15 */
|
|
||||||
.word 0x0000 /* Selector */
|
|
||||||
.word 0x0000 /* Zero byte, flags */
|
|
||||||
.word 0x0000 /* Offset 16 - 31 */
|
|
||||||
|
|
||||||
/* IDT table pointer */
|
|
||||||
EXTERN(i386idtptr)
|
|
||||||
.word (i386idtptr-i386idt) /* Limit */
|
|
||||||
.long i386idt /* Base Address */
|
|
|
@ -1,260 +0,0 @@
|
||||||
/*
|
|
||||||
* FreeLoader
|
|
||||||
* Copyright (C) 2003 Eric Kohl
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <asm.inc>
|
|
||||||
|
|
||||||
|
|
||||||
.text
|
|
||||||
.code16
|
|
||||||
|
|
||||||
#include <arch/pc/x86common.h>
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* U32 PnpBiosSupported(VOID);
|
|
||||||
*
|
|
||||||
* RETURNS:
|
|
||||||
*/
|
|
||||||
_pnp_bios_entry_point:
|
|
||||||
.long 0
|
|
||||||
_pnp_bios_data_segment:
|
|
||||||
.word 0
|
|
||||||
|
|
||||||
EXTERN(PnpBiosSupported)
|
|
||||||
.code64
|
|
||||||
|
|
||||||
push rdi
|
|
||||||
push rsi
|
|
||||||
push rcx
|
|
||||||
push rdx
|
|
||||||
|
|
||||||
xor edi, edi
|
|
||||||
|
|
||||||
/* init esi */
|
|
||||||
mov esi, 0xF0000
|
|
||||||
|
|
||||||
pnp_again:
|
|
||||||
mov eax, [%esi]
|
|
||||||
cmp eax, 0x506E5024 /* "$PnP" */
|
|
||||||
je pnp_found
|
|
||||||
|
|
||||||
cmp esi, 0xFFFF0
|
|
||||||
je pnp_not_found
|
|
||||||
|
|
||||||
pnp_add:
|
|
||||||
add esi, 0x10
|
|
||||||
jmp pnp_again
|
|
||||||
|
|
||||||
pnp_found:
|
|
||||||
/* first calculate the checksum */
|
|
||||||
push rsi
|
|
||||||
|
|
||||||
push 0x21
|
|
||||||
pop rcx
|
|
||||||
xor edx, edx
|
|
||||||
|
|
||||||
pnp_loop:
|
|
||||||
lodsb
|
|
||||||
add dl, al
|
|
||||||
loop pnp_loop
|
|
||||||
|
|
||||||
test dl, dl
|
|
||||||
pop rsi
|
|
||||||
jnz pnp_add
|
|
||||||
|
|
||||||
mov edi, esi
|
|
||||||
|
|
||||||
/* Calculate the bios entry point (far pointer) */
|
|
||||||
xor eax, eax
|
|
||||||
mov ax, [esi + 0x0F]
|
|
||||||
shl eax, 16
|
|
||||||
mov ax, [esi + 0x0D]
|
|
||||||
mov _pnp_bios_entry_point, eax
|
|
||||||
|
|
||||||
/* Store bios data segment */
|
|
||||||
mov ax, [esi + 0x1B]
|
|
||||||
mov _pnp_bios_data_segment, ax
|
|
||||||
|
|
||||||
pnp_not_found:
|
|
||||||
mov eax, edi
|
|
||||||
|
|
||||||
pop rdx
|
|
||||||
pop rcx
|
|
||||||
pop rsi
|
|
||||||
pop rdi
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* U32 PnpBiosGetDeviceNodeCount(U32 *NodeSize, U32 *NodeCount);
|
|
||||||
*
|
|
||||||
* RETURNS:
|
|
||||||
*/
|
|
||||||
_pnp_result:
|
|
||||||
.long 0
|
|
||||||
_pnp_node_size:
|
|
||||||
.word 0
|
|
||||||
_pnp_node_count:
|
|
||||||
.word 0
|
|
||||||
|
|
||||||
EXTERN(PnpBiosGetDeviceNodeCount)
|
|
||||||
.code64
|
|
||||||
|
|
||||||
push rbp
|
|
||||||
mov rbp, rsp
|
|
||||||
|
|
||||||
// pushal FIXME
|
|
||||||
// push es
|
|
||||||
|
|
||||||
call x86_64_SwitchToReal
|
|
||||||
.code16
|
|
||||||
|
|
||||||
mov ax, _pnp_bios_data_segment
|
|
||||||
push ax
|
|
||||||
|
|
||||||
push cs
|
|
||||||
mov ax, _pnp_node_size
|
|
||||||
push ax
|
|
||||||
|
|
||||||
push cs
|
|
||||||
mov ax, _pnp_node_count
|
|
||||||
push ax
|
|
||||||
|
|
||||||
push 0
|
|
||||||
|
|
||||||
call [_pnp_bios_entry_point]
|
|
||||||
add sp, 12
|
|
||||||
|
|
||||||
movzx ecx, ax
|
|
||||||
mov _pnp_result, ecx
|
|
||||||
|
|
||||||
call x86_16_SwitchToLong
|
|
||||||
.code64
|
|
||||||
|
|
||||||
mov esi, [rbp + 0x08]
|
|
||||||
mov ax, _pnp_node_size
|
|
||||||
movzx ecx, ax
|
|
||||||
mov [rsi], ecx
|
|
||||||
|
|
||||||
mov rsi, [ebp + 0x0C]
|
|
||||||
mov ax, _pnp_node_count
|
|
||||||
movzx ecx, ax
|
|
||||||
mov [rsi], eax
|
|
||||||
|
|
||||||
// pop es
|
|
||||||
// popal
|
|
||||||
|
|
||||||
mov rsp, rbp
|
|
||||||
pop rbp
|
|
||||||
|
|
||||||
xor rax, rax
|
|
||||||
mov eax, _pnp_result
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* U32 PnpBiosGetDeviceNode(U8 *NodeId, U8 *NodeBuffer);
|
|
||||||
*
|
|
||||||
* RETURNS:
|
|
||||||
*/
|
|
||||||
_pnp_buffer_segment:
|
|
||||||
.word 0
|
|
||||||
_pnp_buffer_offset:
|
|
||||||
.word 0
|
|
||||||
|
|
||||||
_pnp_node_number:
|
|
||||||
.byte 0
|
|
||||||
|
|
||||||
EXTERN(PnpBiosGetDeviceNode)
|
|
||||||
.code64
|
|
||||||
|
|
||||||
push rbp
|
|
||||||
mov rbp, rsp
|
|
||||||
|
|
||||||
// pushal
|
|
||||||
// push es
|
|
||||||
|
|
||||||
/* get current node number */
|
|
||||||
mov rsi, [rbp + 0x08]
|
|
||||||
mov al, [rsi]
|
|
||||||
mov _pnp_node_number, al
|
|
||||||
|
|
||||||
/* convert pointer to node buffer to segment/offset */
|
|
||||||
mov eax, [rbp + 0x0C]
|
|
||||||
shr eax, 4
|
|
||||||
and eax, 0xf000
|
|
||||||
mov _pnp_buffer_segment , ax
|
|
||||||
mov eax, [rbp + 0x0C]
|
|
||||||
and eax, 0xffff
|
|
||||||
mov _pnp_buffer_offset, ax
|
|
||||||
|
|
||||||
call x86_64_SwitchToReal
|
|
||||||
.code16
|
|
||||||
|
|
||||||
/* push bios segment */
|
|
||||||
mov ax, _pnp_bios_data_segment
|
|
||||||
push ax
|
|
||||||
|
|
||||||
/* push control flag */
|
|
||||||
push 0x0001
|
|
||||||
|
|
||||||
/* push pointer to node buffer (segment/offset) */
|
|
||||||
mov ax, _pnp_buffer_segment
|
|
||||||
push ax
|
|
||||||
mov ax, _pnp_buffer_offset
|
|
||||||
push ax
|
|
||||||
|
|
||||||
/* push pointer to node number (segment/offset) */
|
|
||||||
push cs
|
|
||||||
mov ax, _pnp_node_number
|
|
||||||
push ax
|
|
||||||
|
|
||||||
/* push function number */
|
|
||||||
push 1
|
|
||||||
|
|
||||||
/* call entry point */
|
|
||||||
call [_pnp_bios_entry_point]
|
|
||||||
add sp, 14
|
|
||||||
|
|
||||||
movzx ecx, ax
|
|
||||||
mov _pnp_result, ecx
|
|
||||||
|
|
||||||
call x86_16_SwitchToLong
|
|
||||||
.code64
|
|
||||||
|
|
||||||
/* update node number */
|
|
||||||
mov rsi, [rbp + 0x08]
|
|
||||||
mov al, _pnp_node_number
|
|
||||||
mov [rsi], al
|
|
||||||
|
|
||||||
// pop es
|
|
||||||
// popal
|
|
||||||
|
|
||||||
mov rsp, rbp
|
|
||||||
pop rbp
|
|
||||||
|
|
||||||
xor rax, rax
|
|
||||||
mov eax, _pnp_result
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
END
|
|
||||||
/* EOF */
|
|
|
@ -1,941 +0,0 @@
|
||||||
/*
|
|
||||||
* FreeLoader
|
|
||||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.text
|
|
||||||
.code16
|
|
||||||
|
|
||||||
#include <arch/pc/x86common.h>
|
|
||||||
#include <ver.h>
|
|
||||||
|
|
||||||
#define SCREEN_ATTR 0x1f /* Bright white on blue background */
|
|
||||||
|
|
||||||
.macro SAVE_CPU_REGS
|
|
||||||
movl %eax,i386_EAX
|
|
||||||
movl %ebx,i386_EBX
|
|
||||||
movl %ecx,i386_ECX
|
|
||||||
movl %edx,i386_EDX
|
|
||||||
movl %esp,i386_ESP
|
|
||||||
movl %ebp,i386_EBP
|
|
||||||
movl %esi,i386_ESI
|
|
||||||
movl %edi,i386_EDI
|
|
||||||
movw %ds,%ax
|
|
||||||
movw %ax,i386_DS
|
|
||||||
movw %es,%ax
|
|
||||||
movw %ax,i386_ES
|
|
||||||
movw %fs,%ax
|
|
||||||
movw %ax,i386_FS
|
|
||||||
movw %gs,%ax
|
|
||||||
movw %ax,i386_GS
|
|
||||||
movw %ss,%ax
|
|
||||||
movw %ax,i386_SS
|
|
||||||
popl %eax
|
|
||||||
movl %eax,i386_EIP
|
|
||||||
popl %eax
|
|
||||||
movw %ax,i386_CS
|
|
||||||
popl %eax
|
|
||||||
movl %eax,i386_EFLAGS
|
|
||||||
movl %cr0,%eax
|
|
||||||
movl %eax,i386_CR0
|
|
||||||
//movl %cr1,%eax
|
|
||||||
//movl %eax,i386_CR1
|
|
||||||
movl %cr2,%eax
|
|
||||||
movl %eax,i386_CR2
|
|
||||||
movl %cr3,%eax
|
|
||||||
movl %eax,i386_CR3
|
|
||||||
movl %dr0,%eax
|
|
||||||
movl %eax,i386_DR0
|
|
||||||
movl %dr1,%eax
|
|
||||||
movl %eax,i386_DR1
|
|
||||||
movl %dr2,%eax
|
|
||||||
movl %eax,i386_DR2
|
|
||||||
movl %dr3,%eax
|
|
||||||
movl %eax,i386_DR3
|
|
||||||
movl %dr6,%eax
|
|
||||||
movl %eax,i386_DR6
|
|
||||||
movl %dr7,%eax
|
|
||||||
movl %eax,i386_DR7
|
|
||||||
sgdt i386_GDTR
|
|
||||||
sidt i386_IDTR
|
|
||||||
sldt i386_LDTR
|
|
||||||
str i386_TR
|
|
||||||
.endm
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
i386ExceptionHandlerText:
|
|
||||||
.ascii "An error occured in FreeLoader\n"
|
|
||||||
.ascii VERSION
|
|
||||||
.ascii "\n"
|
|
||||||
.asciz "Report this error to the ReactOS Development mailing list <ros-dev@reactos.org>\n\n"
|
|
||||||
|
|
||||||
i386DivideByZeroText:
|
|
||||||
.asciz "Exception 00: DIVIDE BY ZERO\n\n"
|
|
||||||
i386DebugExceptionText:
|
|
||||||
.asciz "Exception 01: DEBUG EXCEPTION\n\n"
|
|
||||||
i386NMIExceptionText:
|
|
||||||
.asciz "Exception 02: NON-MASKABLE INTERRUPT EXCEPTION\n\n"
|
|
||||||
i386BreakpointText:
|
|
||||||
.asciz "Exception 03: BREAKPOINT (INT 3)\n\n"
|
|
||||||
i386OverflowText:
|
|
||||||
.asciz "Exception 04: OVERFLOW\n\n"
|
|
||||||
i386BoundExceptionText:
|
|
||||||
.asciz "Exception 05: BOUND EXCEPTION\n\n"
|
|
||||||
i386InvalidOpcodeText:
|
|
||||||
.asciz "Exception 06: INVALID OPCODE\n\n"
|
|
||||||
i386FPUNotAvailableText:
|
|
||||||
.asciz "Exception 07: FPU NOT AVAILABLE\n\n"
|
|
||||||
i386DoubleFaultText:
|
|
||||||
.asciz "Exception 08: DOUBLE FAULT\n\n"
|
|
||||||
i386CoprocessorSegmentText:
|
|
||||||
.asciz "Exception 09: COPROCESSOR SEGMENT OVERRUN\n\n"
|
|
||||||
i386InvalidTSSText:
|
|
||||||
.asciz "Exception 0A: INVALID TSS\n\n"
|
|
||||||
i386SegmentNotPresentText:
|
|
||||||
.asciz "Exception 0B: SEGMENT NOT PRESENT\n\n"
|
|
||||||
i386StackExceptionText:
|
|
||||||
.asciz "Exception 0C: STACK EXCEPTION\n\n"
|
|
||||||
i386GeneralProtectionFaultText:
|
|
||||||
.asciz "Exception 0D: GENERAL PROTECTION FAULT\n\n"
|
|
||||||
i386PageFaultText:
|
|
||||||
.asciz "Exception 0E: PAGE FAULT\n\n"
|
|
||||||
i386CoprocessorErrorText:
|
|
||||||
.asciz "Exception 10: COPROCESSOR ERROR\n\n"
|
|
||||||
i386AlignmentCheckText:
|
|
||||||
.asciz "Exception 11: ALIGNMENT CHECK\n\n"
|
|
||||||
i386MachineCheckText:
|
|
||||||
.asciz "Exception 12: MACHINE CHECK\n\n"
|
|
||||||
|
|
||||||
i386_EAX_Text:
|
|
||||||
.asciz "EAX: "
|
|
||||||
i386_EBX_Text:
|
|
||||||
.asciz "EBX: "
|
|
||||||
i386_ECX_Text:
|
|
||||||
.asciz "ECX: "
|
|
||||||
i386_EDX_Text:
|
|
||||||
.asciz "EDX: "
|
|
||||||
i386_ESP_Text:
|
|
||||||
.asciz " ESP: "
|
|
||||||
i386_EBP_Text:
|
|
||||||
.asciz " EBP: "
|
|
||||||
i386_ESI_Text:
|
|
||||||
.asciz " ESI: "
|
|
||||||
i386_EDI_Text:
|
|
||||||
.asciz " EDI: "
|
|
||||||
i386_CS_Text:
|
|
||||||
.asciz "CS: "
|
|
||||||
i386_DS_Text:
|
|
||||||
.asciz "DS: "
|
|
||||||
i386_ES_Text:
|
|
||||||
.asciz "ES: "
|
|
||||||
i386_FS_Text:
|
|
||||||
.asciz "FS: "
|
|
||||||
i386_GS_Text:
|
|
||||||
.asciz "GS: "
|
|
||||||
i386_SS_Text:
|
|
||||||
.asciz "SS: "
|
|
||||||
i386_EFLAGS_Text:
|
|
||||||
.asciz " EFLAGS: "
|
|
||||||
i386_EIP_Text:
|
|
||||||
.asciz " EIP: "
|
|
||||||
i386_ERROR_CODE_Text:
|
|
||||||
.asciz " ERROR CODE: "
|
|
||||||
i386_CR0_Text:
|
|
||||||
.asciz " CR0: "
|
|
||||||
i386_CR1_Text:
|
|
||||||
.asciz " CR1: "
|
|
||||||
i386_CR2_Text:
|
|
||||||
.asciz " CR2: "
|
|
||||||
i386_CR3_Text:
|
|
||||||
.asciz " CR3: "
|
|
||||||
i386_DR0_Text:
|
|
||||||
.asciz " DR0: "
|
|
||||||
i386_DR1_Text:
|
|
||||||
.asciz " DR1: "
|
|
||||||
i386_DR2_Text:
|
|
||||||
.asciz " DR2: "
|
|
||||||
i386_DR3_Text:
|
|
||||||
.asciz " DR3: "
|
|
||||||
i386_DR6_Text:
|
|
||||||
.asciz " DR6: "
|
|
||||||
i386_DR7_Text:
|
|
||||||
.asciz " DR7: "
|
|
||||||
i386_GDTR_Text:
|
|
||||||
.asciz " GDTR Base: "
|
|
||||||
i386_IDTR_Text:
|
|
||||||
.asciz " IDTR Base: "
|
|
||||||
i386_Limit_Text:
|
|
||||||
.asciz " Limit: "
|
|
||||||
i386_LDTR_Text:
|
|
||||||
.asciz " LDTR: "
|
|
||||||
i386_TR_Text:
|
|
||||||
.asciz " TR: "
|
|
||||||
|
|
||||||
i386FramesText:
|
|
||||||
.asciz "Frames:\n"
|
|
||||||
|
|
||||||
/* Set by each exception handler to the address of the description text */
|
|
||||||
i386ExceptionDescriptionText:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
/* Used to store the contents of all the registers when an exception occurs */
|
|
||||||
i386_EAX:
|
|
||||||
.long 0
|
|
||||||
i386_EBX:
|
|
||||||
.long 0
|
|
||||||
i386_ECX:
|
|
||||||
.long 0
|
|
||||||
i386_EDX:
|
|
||||||
.long 0
|
|
||||||
i386_ESP:
|
|
||||||
.long 0
|
|
||||||
i386_EBP:
|
|
||||||
.long 0
|
|
||||||
i386_ESI:
|
|
||||||
.long 0
|
|
||||||
i386_EDI:
|
|
||||||
.long 0
|
|
||||||
i386_CS:
|
|
||||||
.word 0
|
|
||||||
i386_DS:
|
|
||||||
.word 0
|
|
||||||
i386_ES:
|
|
||||||
.word 0
|
|
||||||
i386_FS:
|
|
||||||
.word 0
|
|
||||||
i386_GS:
|
|
||||||
.word 0
|
|
||||||
i386_SS:
|
|
||||||
.word 0
|
|
||||||
i386_EFLAGS:
|
|
||||||
.long 0
|
|
||||||
i386_EIP:
|
|
||||||
.long 0
|
|
||||||
i386_ERROR_CODE:
|
|
||||||
.long 0
|
|
||||||
i386_CR0:
|
|
||||||
.long 0
|
|
||||||
i386_CR1:
|
|
||||||
.long 0
|
|
||||||
i386_CR2:
|
|
||||||
.long 0
|
|
||||||
i386_CR3:
|
|
||||||
.long 0
|
|
||||||
i386_DR0:
|
|
||||||
.long 0
|
|
||||||
i386_DR1:
|
|
||||||
.long 0
|
|
||||||
i386_DR2:
|
|
||||||
.long 0
|
|
||||||
i386_DR3:
|
|
||||||
.long 0
|
|
||||||
i386_DR6:
|
|
||||||
.long 0
|
|
||||||
i386_DR7:
|
|
||||||
.long 0
|
|
||||||
i386_GDTR:
|
|
||||||
.word 0
|
|
||||||
.long 0
|
|
||||||
i386_IDTR:
|
|
||||||
.word 0
|
|
||||||
.long 0
|
|
||||||
i386_LDTR:
|
|
||||||
.word 0
|
|
||||||
i386_TR:
|
|
||||||
.word 0
|
|
||||||
|
|
||||||
/* Used to store the current X and Y position on the screen */
|
|
||||||
i386_ScreenPosX:
|
|
||||||
.long 0
|
|
||||||
i386_ScreenPosY:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
i386CommonExceptionHandler:
|
|
||||||
.code32
|
|
||||||
|
|
||||||
SAVE_CPU_REGS
|
|
||||||
|
|
||||||
pushl $SCREEN_ATTR
|
|
||||||
call MachVideoClearScreen
|
|
||||||
add $4,%esp
|
|
||||||
|
|
||||||
movl $i386ExceptionHandlerText,%esi
|
|
||||||
call i386PrintText
|
|
||||||
|
|
||||||
movl i386ExceptionDescriptionText,%esi
|
|
||||||
call i386PrintText
|
|
||||||
|
|
||||||
movl $i386_EAX_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_EAX,%eax
|
|
||||||
call i386PrintHexDword // Display EAX
|
|
||||||
movl $i386_ESP_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_ESP,%eax
|
|
||||||
call i386PrintHexDword // Display ESP
|
|
||||||
movl $i386_CR0_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_CR0,%eax
|
|
||||||
call i386PrintHexDword // Display CR0
|
|
||||||
movl $i386_DR0_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_DR0,%eax
|
|
||||||
call i386PrintHexDword // Display DR0
|
|
||||||
movl $0,i386_ScreenPosX
|
|
||||||
incl i386_ScreenPosY
|
|
||||||
movl $i386_EBX_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_EBX,%eax
|
|
||||||
call i386PrintHexDword // Display EBX
|
|
||||||
movl $i386_EBP_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_EBP,%eax
|
|
||||||
call i386PrintHexDword // Display EBP
|
|
||||||
movl $i386_CR1_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_CR1,%eax
|
|
||||||
call i386PrintHexDword // Display CR1
|
|
||||||
movl $i386_DR1_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_DR1,%eax
|
|
||||||
call i386PrintHexDword // Display DR1
|
|
||||||
movl $0,i386_ScreenPosX
|
|
||||||
incl i386_ScreenPosY
|
|
||||||
movl $i386_ECX_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_ECX,%eax
|
|
||||||
call i386PrintHexDword // Display ECX
|
|
||||||
movl $i386_ESI_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_ESI,%eax
|
|
||||||
call i386PrintHexDword // Display ESI
|
|
||||||
movl $i386_CR2_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_CR2,%eax
|
|
||||||
call i386PrintHexDword // Display CR2
|
|
||||||
movl $i386_DR2_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_DR2,%eax
|
|
||||||
call i386PrintHexDword // Display DR2
|
|
||||||
movl $0,i386_ScreenPosX
|
|
||||||
incl i386_ScreenPosY
|
|
||||||
movl $i386_EDX_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_EDX,%eax
|
|
||||||
call i386PrintHexDword // Display EDX
|
|
||||||
movl $i386_EDI_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_EDI,%eax
|
|
||||||
call i386PrintHexDword // Display EDI
|
|
||||||
movl $i386_CR3_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_CR3,%eax
|
|
||||||
call i386PrintHexDword // Display CR3
|
|
||||||
movl $i386_DR3_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_DR3,%eax
|
|
||||||
call i386PrintHexDword // Display DR3
|
|
||||||
incl i386_ScreenPosY
|
|
||||||
movl $55,i386_ScreenPosX
|
|
||||||
movl $i386_DR6_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_DR6,%eax
|
|
||||||
call i386PrintHexDword // Display DR6
|
|
||||||
incl i386_ScreenPosY
|
|
||||||
movl $55,i386_ScreenPosX
|
|
||||||
movl $i386_DR7_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_DR7,%eax
|
|
||||||
call i386PrintHexDword // Display DR7
|
|
||||||
movl $0,i386_ScreenPosX
|
|
||||||
incl i386_ScreenPosY
|
|
||||||
incl i386_ScreenPosY
|
|
||||||
movl $i386_CS_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movw i386_CS,%ax
|
|
||||||
call i386PrintHexWord // Display CS
|
|
||||||
movl $i386_EIP_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_EIP,%eax
|
|
||||||
call i386PrintHexDword // Display EIP
|
|
||||||
movl $0,i386_ScreenPosX
|
|
||||||
incl i386_ScreenPosY
|
|
||||||
movl $i386_DS_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movw i386_DS,%ax
|
|
||||||
call i386PrintHexWord // Display DS
|
|
||||||
movl $i386_ERROR_CODE_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_ERROR_CODE,%eax
|
|
||||||
call i386PrintHexDword // Display ERROR CODE
|
|
||||||
movl $0,i386_ScreenPosX
|
|
||||||
incl i386_ScreenPosY
|
|
||||||
movl $i386_ES_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movw i386_ES,%ax
|
|
||||||
call i386PrintHexWord // Display ES
|
|
||||||
movl $i386_EFLAGS_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_EFLAGS,%eax
|
|
||||||
call i386PrintHexDword // Display EFLAGS
|
|
||||||
movl $0,i386_ScreenPosX
|
|
||||||
incl i386_ScreenPosY
|
|
||||||
movl $i386_FS_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movw i386_FS,%ax
|
|
||||||
call i386PrintHexWord // Display FS
|
|
||||||
movl $i386_GDTR_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_GDTR+2,%eax
|
|
||||||
call i386PrintHexDword // Display GDTR Base
|
|
||||||
movl $i386_Limit_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movw i386_GDTR,%ax
|
|
||||||
call i386PrintHexWord // Display GDTR Limit
|
|
||||||
movl $0,i386_ScreenPosX
|
|
||||||
incl i386_ScreenPosY
|
|
||||||
movl $i386_GS_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movw i386_GS,%ax
|
|
||||||
call i386PrintHexWord // Display GS
|
|
||||||
movl $i386_IDTR_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movl i386_IDTR+2,%eax
|
|
||||||
call i386PrintHexDword // Display IDTR Base
|
|
||||||
movl $i386_Limit_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movw i386_IDTR,%ax
|
|
||||||
call i386PrintHexWord // Display IDTR Limit
|
|
||||||
movl $0,i386_ScreenPosX
|
|
||||||
incl i386_ScreenPosY
|
|
||||||
movl $i386_SS_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movw i386_SS,%ax
|
|
||||||
call i386PrintHexWord // Display SS
|
|
||||||
movl $i386_LDTR_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movw i386_LDTR,%ax
|
|
||||||
call i386PrintHexWord // Display LDTR
|
|
||||||
movl $i386_TR_Text,%esi
|
|
||||||
call i386PrintText
|
|
||||||
movw i386_TR,%ax
|
|
||||||
call i386PrintHexWord // Display TR
|
|
||||||
movl $0,i386_ScreenPosX
|
|
||||||
incl i386_ScreenPosY
|
|
||||||
incl i386_ScreenPosY
|
|
||||||
call i386PrintFrames // Display frames
|
|
||||||
incl i386_ScreenPosY
|
|
||||||
incl i386_ScreenPosY
|
|
||||||
|
|
||||||
cli
|
|
||||||
i386ExceptionHandlerHang:
|
|
||||||
hlt
|
|
||||||
jmp i386ExceptionHandlerHang
|
|
||||||
|
|
||||||
iret
|
|
||||||
|
|
||||||
i386PrintFrames:
|
|
||||||
movl $0,i386_ScreenPosX
|
|
||||||
movl $i386FramesText,%esi
|
|
||||||
call i386PrintText
|
|
||||||
|
|
||||||
movl i386_EBP,%edi
|
|
||||||
printnextframe:
|
|
||||||
test %edi,%edi
|
|
||||||
je nomoreframes
|
|
||||||
movl $STACK32ADDR,%eax
|
|
||||||
cmpl %edi,%eax
|
|
||||||
jbe nomoreframes
|
|
||||||
movl 4(%edi),%eax
|
|
||||||
pushl %edi
|
|
||||||
call i386PrintHexDword // Display frame
|
|
||||||
popl %edi
|
|
||||||
incl i386_ScreenPosX
|
|
||||||
incl i386_ScreenPosX
|
|
||||||
movl 0(%edi),%edi
|
|
||||||
jmp printnextframe
|
|
||||||
nomoreframes:
|
|
||||||
ret
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* AL = Char to display */
|
|
||||||
/************************************************************************/
|
|
||||||
i386PrintChar:
|
|
||||||
.code32
|
|
||||||
|
|
||||||
pushl i386_ScreenPosY
|
|
||||||
pushl i386_ScreenPosX
|
|
||||||
pushl $SCREEN_ATTR
|
|
||||||
andl $0xff,%eax
|
|
||||||
pushl %eax
|
|
||||||
call MachVideoPutChar
|
|
||||||
addl $16,%esp
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* ESI = Address of text to display */
|
|
||||||
/************************************************************************/
|
|
||||||
i386PrintText:
|
|
||||||
.code32
|
|
||||||
|
|
||||||
i386PrintTextLoop:
|
|
||||||
lodsb
|
|
||||||
|
|
||||||
// Check for end of string char
|
|
||||||
cmp $0,%al
|
|
||||||
je i386PrintTextDone
|
|
||||||
|
|
||||||
// Check for newline char
|
|
||||||
cmp $0x0a,%al
|
|
||||||
jne i386PrintTextLoop2
|
|
||||||
incl i386_ScreenPosY
|
|
||||||
movl $0,i386_ScreenPosX
|
|
||||||
jmp i386PrintTextLoop
|
|
||||||
|
|
||||||
i386PrintTextLoop2:
|
|
||||||
call i386PrintChar
|
|
||||||
incl i386_ScreenPosX
|
|
||||||
|
|
||||||
jmp i386PrintTextLoop
|
|
||||||
|
|
||||||
i386PrintTextDone:
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* Prints the value in EAX on the screen in hex */
|
|
||||||
/************************************************************************/
|
|
||||||
i386PrintHexDword:
|
|
||||||
.code32
|
|
||||||
|
|
||||||
call i386PrintHex1
|
|
||||||
|
|
||||||
i386PrintHex1:
|
|
||||||
call i386PrintHex2
|
|
||||||
i386PrintHex2:
|
|
||||||
call i386PrintHex3
|
|
||||||
i386PrintHex3:
|
|
||||||
movb $4,%cl
|
|
||||||
rol %cl,%eax
|
|
||||||
push %eax
|
|
||||||
andb $0x0f,%al
|
|
||||||
movl $i386PrintHexTable,%ebx
|
|
||||||
xlat /*$i386PrintHexTable*/
|
|
||||||
call i386PrintChar
|
|
||||||
incl i386_ScreenPosX
|
|
||||||
pop %eax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
i386PrintHexTable:
|
|
||||||
.ascii "0123456789ABCDEF"
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* Prints the value in AX on the screen in hex */
|
|
||||||
/************************************************************************/
|
|
||||||
i386PrintHexWord:
|
|
||||||
.code32
|
|
||||||
|
|
||||||
call i386PrintHexWord1
|
|
||||||
i386PrintHexWord1:
|
|
||||||
call i386PrintHexWord2
|
|
||||||
i386PrintHexWord2:
|
|
||||||
movb $4,%cl
|
|
||||||
rol %cl,%ax
|
|
||||||
push %eax
|
|
||||||
andb $0x0f,%al
|
|
||||||
movl $i386PrintHexTable,%ebx
|
|
||||||
xlat /*$i386PrintHexTable*/
|
|
||||||
call i386PrintChar
|
|
||||||
incl i386_ScreenPosX
|
|
||||||
pop %eax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* Prints the value in AL on the screen in hex */
|
|
||||||
/************************************************************************/
|
|
||||||
i386PrintHexByte:
|
|
||||||
.code32
|
|
||||||
|
|
||||||
call i386PrintHexByte1
|
|
||||||
i386PrintHexByte1:
|
|
||||||
movb $4,%cl
|
|
||||||
rol %cl,%al
|
|
||||||
push %eax
|
|
||||||
andb $0x0f,%al
|
|
||||||
movl $i386PrintHexTable,%ebx
|
|
||||||
xlat /*$i386PrintHexTable*/
|
|
||||||
call i386PrintChar
|
|
||||||
incl i386_ScreenPosX
|
|
||||||
pop %eax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386DivideByZero)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
movl $i386DivideByZeroText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386DebugException)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
movl $i386DebugExceptionText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386NMIException)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
movl $i386NMIExceptionText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386Breakpoint)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
movl $i386BreakpointText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386Overflow)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
movl $i386OverflowText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386BoundException)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
movl $i386BoundExceptionText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386InvalidOpcode)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
movl $i386InvalidOpcodeText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386FPUNotAvailable)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
movl $i386FPUNotAvailableText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386DoubleFault)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
movl %eax,i386_ERROR_CODE
|
|
||||||
|
|
||||||
movl $i386DoubleFaultText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386CoprocessorSegment)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
movl $i386CoprocessorSegmentText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386InvalidTSS)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
movl %eax,i386_ERROR_CODE
|
|
||||||
|
|
||||||
movl $i386InvalidTSSText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386SegmentNotPresent)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
movl %eax,i386_ERROR_CODE
|
|
||||||
|
|
||||||
movl $i386SegmentNotPresentText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386StackException)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
movl %eax,i386_ERROR_CODE
|
|
||||||
|
|
||||||
movl $i386StackExceptionText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386GeneralProtectionFault)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
movl %eax,i386_ERROR_CODE
|
|
||||||
|
|
||||||
movl $i386GeneralProtectionFaultText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386PageFault)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
movl %eax,i386_ERROR_CODE
|
|
||||||
|
|
||||||
movl $i386PageFaultText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386CoprocessorError)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
movl $i386CoprocessorErrorText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386AlignmentCheck)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
movl $i386AlignmentCheckText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
EXTERN(i386MachineCheck)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
movl $i386MachineCheckText,i386ExceptionDescriptionText
|
|
||||||
jmp i386CommonExceptionHandler
|
|
||||||
|
|
||||||
/************************************************************************
|
|
||||||
* DEBUGGING SUPPORT FUNCTIONS
|
|
||||||
************************************************************************/
|
|
||||||
EXTERN(_INSTRUCTION_BREAKPOINT1)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
pushl %eax
|
|
||||||
|
|
||||||
movl 8(%esp),%eax
|
|
||||||
|
|
||||||
movl %eax,%dr0
|
|
||||||
movl %dr7,%eax
|
|
||||||
andl $0xfff0ffff,%eax
|
|
||||||
orl $0x00000303,%eax
|
|
||||||
movl %eax,%dr7
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
EXTERN(_MEMORY_READWRITE_BREAKPOINT1)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
pushl %eax
|
|
||||||
|
|
||||||
movl 8(%esp),%eax
|
|
||||||
|
|
||||||
movl %eax,%dr0
|
|
||||||
movl %dr7,%eax
|
|
||||||
andl $0xfff0ffff,%eax
|
|
||||||
orl $0x00030303,%eax
|
|
||||||
movl %eax,%dr7
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
EXTERN(_MEMORY_WRITE_BREAKPOINT1)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
pushl %eax
|
|
||||||
|
|
||||||
movl 8(%esp),%eax
|
|
||||||
|
|
||||||
movl %eax,%dr0
|
|
||||||
movl %dr7,%eax
|
|
||||||
andl $0xfff0ffff,%eax
|
|
||||||
orl $0x00010303,%eax
|
|
||||||
movl %eax,%dr7
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
EXTERN(_INSTRUCTION_BREAKPOINT2)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
pushl %eax
|
|
||||||
|
|
||||||
movl 8(%esp),%eax
|
|
||||||
|
|
||||||
movl %eax,%dr1
|
|
||||||
movl %dr7,%eax
|
|
||||||
andl $0xff0fffff,%eax
|
|
||||||
orl $0x0000030c,%eax
|
|
||||||
movl %eax,%dr7
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
EXTERN(_MEMORY_READWRITE_BREAKPOINT2)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
pushl %eax
|
|
||||||
|
|
||||||
movl 8(%esp),%eax
|
|
||||||
|
|
||||||
movl %eax,%dr1
|
|
||||||
movl %dr7,%eax
|
|
||||||
andl $0xff0fffff,%eax
|
|
||||||
orl $0x0030030c,%eax
|
|
||||||
movl %eax,%dr7
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
EXTERN(_MEMORY_WRITE_BREAKPOINT2)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
pushl %eax
|
|
||||||
|
|
||||||
movl 8(%esp),%eax
|
|
||||||
|
|
||||||
movl %eax,%dr1
|
|
||||||
movl %dr7,%eax
|
|
||||||
andl $0xff0fffff,%eax
|
|
||||||
orl $0x0010030c,%eax
|
|
||||||
movl %eax,%dr7
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
EXTERN(_INSTRUCTION_BREAKPOINT3)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
pushl %eax
|
|
||||||
|
|
||||||
movl 8(%esp),%eax
|
|
||||||
|
|
||||||
movl %eax,%dr2
|
|
||||||
movl %dr7,%eax
|
|
||||||
andl $0xf0ffffff,%eax
|
|
||||||
orl $0x00000330,%eax
|
|
||||||
movl %eax,%dr7
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
EXTERN(_MEMORY_READWRITE_BREAKPOINT3)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
pushl %eax
|
|
||||||
|
|
||||||
movl 8(%esp),%eax
|
|
||||||
|
|
||||||
movl %eax,%dr2
|
|
||||||
movl %dr7,%eax
|
|
||||||
andl $0xf0ffffff,%eax
|
|
||||||
orl $0x03000330,%eax
|
|
||||||
movl %eax,%dr7
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
EXTERN(_MEMORY_WRITE_BREAKPOINT3)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
pushl %eax
|
|
||||||
|
|
||||||
movl 8(%esp),%eax
|
|
||||||
|
|
||||||
movl %eax,%dr2
|
|
||||||
movl %dr7,%eax
|
|
||||||
andl $0xf0ffffff,%eax
|
|
||||||
orl $0x01000330,%eax
|
|
||||||
movl %eax,%dr7
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
EXTERN(_INSTRUCTION_BREAKPOINT4)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
pushl %eax
|
|
||||||
|
|
||||||
movl 8(%esp),%eax
|
|
||||||
|
|
||||||
movl %eax,%dr3
|
|
||||||
movl %dr7,%eax
|
|
||||||
andl $0x0fffffff,%eax
|
|
||||||
orl $0x000003c0,%eax
|
|
||||||
movl %eax,%dr7
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
EXTERN(_MEMORY_READWRITE_BREAKPOINT4)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
pushl %eax
|
|
||||||
|
|
||||||
movl 8(%esp),%eax
|
|
||||||
|
|
||||||
movl %eax,%dr3
|
|
||||||
movl %dr7,%eax
|
|
||||||
andl $0x0fffffff,%eax
|
|
||||||
orl $0x300003c0,%eax
|
|
||||||
movl %eax,%dr7
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
EXTERN(_MEMORY_WRITE_BREAKPOINT4)
|
|
||||||
.code32
|
|
||||||
|
|
||||||
pushl %eax
|
|
||||||
|
|
||||||
movl 8(%esp),%eax
|
|
||||||
|
|
||||||
movl %eax,%dr3
|
|
||||||
movl %dr7,%eax
|
|
||||||
andl $0x0fffffff,%eax
|
|
||||||
orl $0x100003c0,%eax
|
|
||||||
movl %eax,%dr7
|
|
||||||
|
|
||||||
popl %eax
|
|
||||||
|
|
||||||
ret
|
|
|
@ -18,157 +18,66 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <asm.inc>
|
#include <asm.inc>
|
||||||
|
|
||||||
|
|
||||||
.intel_syntax noprefix
|
|
||||||
.text
|
|
||||||
.code16
|
|
||||||
|
|
||||||
#include <arch/pc/x86common.h>
|
#include <arch/pc/x86common.h>
|
||||||
|
|
||||||
|
|
||||||
Int386_REGS:
|
|
||||||
|
|
||||||
Int386_eax:
|
|
||||||
.long 0
|
|
||||||
Int386_ebx:
|
|
||||||
.long 0
|
|
||||||
Int386_ecx:
|
|
||||||
.long 0
|
|
||||||
Int386_edx:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
Int386_esi:
|
|
||||||
.long 0
|
|
||||||
Int386_edi:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
Int386_ds:
|
|
||||||
.word 0
|
|
||||||
Int386_es:
|
|
||||||
.word 0
|
|
||||||
Int386_fs:
|
|
||||||
.word 0
|
|
||||||
Int386_gs:
|
|
||||||
.word 0
|
|
||||||
|
|
||||||
Int386_eflags:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
Int386_vector:
|
|
||||||
.quad 0
|
|
||||||
Int386_regsin:
|
|
||||||
.quad 0
|
|
||||||
Int386_regsout:
|
|
||||||
.quad 0
|
|
||||||
|
|
||||||
/*
|
|
||||||
* int Int386(int ivec, REGS* in, REGS* out);
|
|
||||||
*/
|
|
||||||
EXTERN(Int386)
|
|
||||||
.code64
|
.code64
|
||||||
|
|
||||||
/* Get the function parameters */
|
EXTERN CallRealMode:PROC
|
||||||
mov Int386_vector, rcx
|
|
||||||
mov Int386_vector_opcode, cl
|
|
||||||
mov Int386_regsin, rdx
|
|
||||||
mov Int386_regsout, r8
|
|
||||||
|
|
||||||
/* Save all registers + segment registers */
|
/* int Int386(int ivec<ecx>, REGS* in<rdx>, REGS* out<r8>); */
|
||||||
// push ds
|
PUBLIC Int386
|
||||||
// push es
|
Int386:
|
||||||
push fs
|
|
||||||
push gs
|
/* 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 rbx
|
||||||
push rcx
|
push rbp
|
||||||
push rdx
|
|
||||||
push rsi
|
push rsi
|
||||||
push rdi
|
push rdi
|
||||||
|
|
||||||
/* Copy the input regs to our variables */
|
/* Alloc stack space for home registers */
|
||||||
lea rdi, Int386_REGS
|
sub rsp, 40
|
||||||
mov esi, Int386_regsin
|
//.ENDPROLOG
|
||||||
mov ecx, 0x24
|
|
||||||
rep movsb
|
|
||||||
|
|
||||||
call x86_64_SwitchToReal
|
int386_2:
|
||||||
.code16
|
/* Copy the int vector to shared memory */
|
||||||
|
mov dword ptr [BSS_IntVector], ecx
|
||||||
|
|
||||||
/* Setup the registers */
|
/* Copy input registers */
|
||||||
mov ax, cs:Int386_ds
|
mov rsi, rdx
|
||||||
mov ds, ax /* DS register */
|
mov rdi, BSS_RegisterSet
|
||||||
mov ax, cs:Int386_es
|
mov rcx, REGS_SIZE / 4
|
||||||
mov es, ax /* ES register */
|
rep movsd
|
||||||
mov ax, cs:Int386_fs
|
|
||||||
mov fs, ax /* FS register */
|
|
||||||
mov ax, cs:Int386_gs
|
|
||||||
mov gs, ax /* GS register */
|
|
||||||
|
|
||||||
mov eax, cs:Int386_eax /* EAX register */
|
xor rax, rax
|
||||||
mov ebx, cs:Int386_ebx /* EBX register */
|
xor rbx, rbx
|
||||||
mov ecx, cs:Int386_ecx /* ECX register */
|
xor rcx, rcx
|
||||||
mov edx, cs:Int386_edx /* EDX register */
|
xor rdx, rdx
|
||||||
|
xor rbp, rbp
|
||||||
|
xor rsi, rsi
|
||||||
|
xor rdi, rdi
|
||||||
|
|
||||||
mov esi, cs:Int386_esi /* ESI register */
|
/* Set the function ID and call real mode */
|
||||||
mov edi, cs:Int386_edi /* EDI register */
|
mov bx, FNID_Int386
|
||||||
|
call CallRealMode
|
||||||
|
|
||||||
/* Do not set the flags register */
|
/* Copy output registers */
|
||||||
/* only return its value in regsout */
|
mov rsi, BSS_RegisterSet
|
||||||
//pushl Int386_eflags
|
mov rdi, [r11 + 24]
|
||||||
//popfl /* EFLAGS register */
|
mov rcx, REGS_SIZE / 4
|
||||||
|
rep movsd
|
||||||
|
|
||||||
/* Call the interrupt vector */
|
/* cleanup and return */
|
||||||
/*int Int386_vector*/
|
add rsp, 40
|
||||||
Int386_int_opcode:
|
|
||||||
.byte 0xcd
|
|
||||||
Int386_vector_opcode:
|
|
||||||
.byte 0x00
|
|
||||||
|
|
||||||
/* Save the registers */
|
|
||||||
mov cs:Int386_eax, eax /* EAX register */
|
|
||||||
mov cs:Int386_ebx, ebx /* EBX register */
|
|
||||||
mov cs:Int386_ecx, ecx /* ECX register */
|
|
||||||
mov cs:Int386_edx, edx /* EDX register */
|
|
||||||
|
|
||||||
mov cs:Int386_esi, esi /* ESI register */
|
|
||||||
mov cs:Int386_edi, edi /* EDI register */
|
|
||||||
|
|
||||||
mov ax, ds /* DS register */
|
|
||||||
mov cs:Int386_ds, ax
|
|
||||||
mov ax, es /* ES register */
|
|
||||||
mov cs:Int386_es, ax
|
|
||||||
mov ax, fs /* FS register */
|
|
||||||
mov cs:Int386_fs, ax
|
|
||||||
mov ax, gs /* GS register */
|
|
||||||
mov cs:Int386_gs, ax
|
|
||||||
|
|
||||||
pushf
|
|
||||||
pop cs:Int386_eflags /* EFLAGS register */
|
|
||||||
|
|
||||||
call x86_16_SwitchToLong
|
|
||||||
.code64
|
|
||||||
|
|
||||||
/* Copy the variables to the output regs */
|
|
||||||
lea rsi, Int386_REGS
|
|
||||||
mov rdi, Int386_regsout
|
|
||||||
mov rcx, 0x24
|
|
||||||
rep movsb
|
|
||||||
|
|
||||||
/* Restore segment and all other registers */
|
|
||||||
pop rdi
|
pop rdi
|
||||||
pop rsi
|
pop rsi
|
||||||
pop rdx
|
pop rbp
|
||||||
pop rcx
|
|
||||||
pop rbx
|
pop rbx
|
||||||
pop gs
|
|
||||||
pop fs
|
|
||||||
// pop es
|
|
||||||
// pop ds
|
|
||||||
|
|
||||||
/* Get return value */
|
|
||||||
xor rax, rax
|
|
||||||
mov eax, Int386_eax
|
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
END
|
END
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
/*
|
|
||||||
* FreeLoader
|
|
||||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <asm.inc>
|
|
||||||
|
|
||||||
|
|
||||||
.text
|
|
||||||
.code16
|
|
||||||
|
|
||||||
#include <arch/pc/x86common.h>
|
|
||||||
#include <multiboot.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Here we assume the kernel is loaded at 1mb
|
|
||||||
* This boots the kernel
|
|
||||||
*/
|
|
||||||
.code64
|
|
||||||
.globl PageDirectoryStart
|
|
||||||
|
|
||||||
.globl pml4_startup
|
|
||||||
.globl pdp_startup
|
|
||||||
.globl pd_startup
|
|
||||||
|
|
||||||
.globl PageDirectoryEnd
|
|
||||||
|
|
||||||
//
|
|
||||||
// Boot information structure
|
|
||||||
//
|
|
||||||
|
|
||||||
EXTERN(reactos_memory_map_descriptor_size)
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
EXTERN(reactos_memory_map)
|
|
||||||
.rept (32 * /*sizeof(memory_map_t)*/24)
|
|
||||||
.byte 0
|
|
||||||
.endr
|
|
||||||
|
|
||||||
.bss
|
|
||||||
PageDirectoryStart:
|
|
||||||
pml4_startup:
|
|
||||||
.fill 4096, 1, 0
|
|
||||||
|
|
||||||
pdp_startup:
|
|
||||||
.fill 4096, 1, 0
|
|
||||||
|
|
||||||
pd_startup:
|
|
||||||
.fill 4096, 1, 0
|
|
||||||
|
|
||||||
PageDirectoryEnd:
|
|
||||||
|
|
||||||
END
|
|
156
reactos/boot/freeldr/freeldr/arch/amd64/pnpbios.S
Normal file
156
reactos/boot/freeldr/freeldr/arch/amd64/pnpbios.S
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
/*
|
||||||
|
* FreeLoader
|
||||||
|
* Copyright (C) 2003 Eric Kohl
|
||||||
|
* Copyright (C) 2011 Timo Kreuzer
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <asm.inc>
|
||||||
|
#include <arch/pc/x86common.h>
|
||||||
|
|
||||||
|
EXTERN CallRealMode:PROC
|
||||||
|
|
||||||
|
.code64
|
||||||
|
|
||||||
|
/*
|
||||||
|
* U32 PnpBiosSupported(VOID);
|
||||||
|
*
|
||||||
|
* RETURNS:
|
||||||
|
*/
|
||||||
|
PUBLIC PnpBiosSupported
|
||||||
|
PnpBiosSupported:
|
||||||
|
|
||||||
|
push rdi
|
||||||
|
push rsi
|
||||||
|
push rcx
|
||||||
|
push rdx
|
||||||
|
|
||||||
|
xor rdi, rdi
|
||||||
|
|
||||||
|
/* init rsi */
|
||||||
|
mov rsi, HEX(0F0000)
|
||||||
|
|
||||||
|
pnp_again:
|
||||||
|
mov eax, [rsi]
|
||||||
|
cmp eax, HEX(506E5024) /* "$PnP" */
|
||||||
|
je pnp_found
|
||||||
|
|
||||||
|
cmp rsi, HEX(0FFFF0)
|
||||||
|
je pnp_not_found
|
||||||
|
|
||||||
|
pnp_add:
|
||||||
|
add rsi, 16
|
||||||
|
jmp pnp_again
|
||||||
|
|
||||||
|
pnp_found:
|
||||||
|
/* first calculate the checksum */
|
||||||
|
push rsi
|
||||||
|
|
||||||
|
push HEX(21)
|
||||||
|
pop rcx
|
||||||
|
xor edx, edx
|
||||||
|
|
||||||
|
pnp_loop:
|
||||||
|
lodsb
|
||||||
|
add dl, al
|
||||||
|
loop pnp_loop
|
||||||
|
|
||||||
|
test dl, dl
|
||||||
|
pop rsi
|
||||||
|
jnz pnp_add
|
||||||
|
|
||||||
|
mov rdi, rsi
|
||||||
|
|
||||||
|
/* Calculate the bios entry point (far pointer) */
|
||||||
|
xor eax, eax
|
||||||
|
mov ax, [rsi + HEX(0F)]
|
||||||
|
shl eax, 16
|
||||||
|
mov ax, [rsi + HEX(0D)]
|
||||||
|
mov dword ptr [BSS_PnpBiosEntryPoint], eax
|
||||||
|
|
||||||
|
/* Store bios data segment */
|
||||||
|
mov ax, [rsi + HEX(1B)]
|
||||||
|
mov word ptr [BSS_PnpBiosDataSegment], ax
|
||||||
|
|
||||||
|
pnp_not_found:
|
||||||
|
mov rax, rdi
|
||||||
|
|
||||||
|
pop rdx
|
||||||
|
pop rcx
|
||||||
|
pop rsi
|
||||||
|
pop rdi
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* U32 PnpBiosGetDeviceNodeCount(U32 *NodeSize<rcx>, U32 *NodeCount<rdx>);
|
||||||
|
*
|
||||||
|
* RETURNS:
|
||||||
|
*/
|
||||||
|
PUBLIC PnpBiosGetDeviceNodeCount
|
||||||
|
PnpBiosGetDeviceNodeCount:
|
||||||
|
|
||||||
|
/* Call the real mode function */
|
||||||
|
mov bx, FNID_PnpBiosGetDeviceNodeCount
|
||||||
|
call CallRealMode
|
||||||
|
|
||||||
|
xor eax, eax
|
||||||
|
mov ax, [BSS_PnpNodeSize]
|
||||||
|
mov [rcx], eax
|
||||||
|
mov ax, [BSS_PnpNodeCount]
|
||||||
|
mov [rdx], eax
|
||||||
|
|
||||||
|
mov eax, dword ptr [BSS_PnpResult]
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* U32 PnpBiosGetDeviceNode(U8 *NodeId<rcx>, U8 *NodeBuffer<rdx>);
|
||||||
|
*
|
||||||
|
* RETURNS:
|
||||||
|
*/
|
||||||
|
PUBLIC PnpBiosGetDeviceNode
|
||||||
|
PnpBiosGetDeviceNode:
|
||||||
|
|
||||||
|
/* get current node number */
|
||||||
|
mov al, [rcx]
|
||||||
|
mov byte ptr [BSS_PnpNodeNumber], al
|
||||||
|
|
||||||
|
/* convert pointer to node buffer to segment/offset */
|
||||||
|
mov rax, rdx
|
||||||
|
shr eax, 4
|
||||||
|
mov word ptr [BSS_PnpBiosBufferSegment], ax
|
||||||
|
mov rax, rdx
|
||||||
|
and eax, HEX(0f)
|
||||||
|
mov word ptr [BSS_PnpBiosBufferOffset], ax
|
||||||
|
|
||||||
|
/* Call the real mode function */
|
||||||
|
mov bx, FNID_PnpBiosGetDeviceNode
|
||||||
|
call CallRealMode
|
||||||
|
|
||||||
|
/* update node number */
|
||||||
|
mov al, byte ptr [BSS_PnpNodeNumber]
|
||||||
|
mov [rcx], al
|
||||||
|
|
||||||
|
mov eax, [BSS_PnpResult]
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
END
|
||||||
|
/* EOF */
|
|
@ -1,48 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
#include <asm.inc>
|
|
||||||
|
|
||||||
EXTERN BootMain:PROC
|
|
||||||
|
|
||||||
.code64
|
|
||||||
|
|
||||||
/* 64 bit entry point */
|
|
||||||
PUBLIC mainCRTStartup
|
|
||||||
mainCRTStartup:
|
|
||||||
jmp BootMain
|
|
||||||
|
|
||||||
PUBLIC Int386
|
|
||||||
Int386:
|
|
||||||
ret
|
|
||||||
|
|
||||||
PUBLIC __lgdt
|
|
||||||
__lgdt:
|
|
||||||
|
|
||||||
PUBLIC __ltr
|
|
||||||
__ltr:
|
|
||||||
|
|
||||||
PUBLIC PxeCallApi
|
|
||||||
PxeCallApi:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
PUBLIC PageDirectoryStart
|
|
||||||
PageDirectoryStart:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
PUBLIC PageDirectoryEnd
|
|
||||||
PageDirectoryEnd:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
PUBLIC PnpBiosGetDeviceNode
|
|
||||||
PnpBiosGetDeviceNode:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
PUBLIC PnpBiosGetDeviceNodeCount
|
|
||||||
PnpBiosGetDeviceNodeCount:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
PUBLIC PnpBiosSupported
|
|
||||||
PnpBiosSupported:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
END
|
|
|
@ -69,7 +69,7 @@ Msg_LongModeSupported:
|
||||||
/* Build the startup page tables */
|
/* Build the startup page tables */
|
||||||
call BuildPageTables
|
call BuildPageTables
|
||||||
|
|
||||||
/* Safe real mode entry point in shared memory */
|
/* Store real mode entry point in shared memory */
|
||||||
mov dword ptr ds:[BSS_RealModeEntry], offset RealModeEntryPoint
|
mov dword ptr ds:[BSS_RealModeEntry], offset RealModeEntryPoint
|
||||||
|
|
||||||
/* Address the image with es segment */
|
/* Address the image with es segment */
|
||||||
|
@ -242,11 +242,34 @@ RealModeEntryPoint:
|
||||||
|
|
||||||
InRealMode:
|
InRealMode:
|
||||||
|
|
||||||
mov ax, HEX(0b800)
|
// mov ax, HEX(0b800)
|
||||||
mov es, ax
|
// mov es, ax
|
||||||
mov word ptr es:[12], HEX(0e00) + '6'
|
// mov word ptr es:[12], HEX(0e00) + '6'
|
||||||
jmp $
|
|
||||||
|
|
||||||
|
/* Set real mode segments */
|
||||||
|
xor ax, ax
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
mov ss, ax
|
||||||
|
|
||||||
|
/* Clear out the high 16-bits of ESP */
|
||||||
|
/* This is needed because I have one */
|
||||||
|
/* machine that hangs when booted to dos if */
|
||||||
|
/* anything other than 0x0000 is in the high */
|
||||||
|
/* 16-bits of ESP. Even though real-mode */
|
||||||
|
/* code should only use SP and not ESP. */
|
||||||
|
xor esp, esp
|
||||||
|
|
||||||
|
/* Restore real mode stack */
|
||||||
|
mov sp, word ptr ds:[stack16]
|
||||||
|
|
||||||
|
// sti /* These are ok now */
|
||||||
|
|
||||||
|
/* Do the callback, specified by bx */
|
||||||
|
shl bx, 1
|
||||||
|
call word ptr ds:CallbackTable[bx]
|
||||||
|
|
||||||
ExitToLongMode:
|
ExitToLongMode:
|
||||||
/* Disable interrupts */
|
/* Disable interrupts */
|
||||||
|
@ -271,7 +294,6 @@ ExitToLongMode:
|
||||||
mov edx, PML4_ADDRESS
|
mov edx, PML4_ADDRESS
|
||||||
mov cr3, edx
|
mov cr3, edx
|
||||||
|
|
||||||
|
|
||||||
/* Enable long mode */
|
/* Enable long mode */
|
||||||
mov ecx, MSR_EFER
|
mov ecx, MSR_EFER
|
||||||
rdmsr
|
rdmsr
|
||||||
|
@ -287,12 +309,12 @@ ExitToLongMode:
|
||||||
/* Clear prefetch queue & correct CS */
|
/* Clear prefetch queue & correct CS */
|
||||||
ljmp16 LMODE_CS, InLongMode
|
ljmp16 LMODE_CS, InLongMode
|
||||||
InLongMode:
|
InLongMode:
|
||||||
DB 66h, 0B8h, 18h, 00h // mov ax, LMODE_DS
|
//DB 66h, 0B8h, 18h, 00h // mov ax, LMODE_DS
|
||||||
DB 66h, 8Eh, 0D8h // mov ds, ax
|
//DB 66h, 8Eh, 0D8h // mov ds, ax
|
||||||
DB 66h, 66h, 0C7h, 04h, 25h, 00h, 80h, 0Bh, 00h, 31h, 0Eh
|
//DB 66h, 66h, 0C7h, 04h, 25h, 00h, 80h, 0Bh, 00h, 31h, 0Eh
|
||||||
//mov word ptr [HEX(b8000)], HEX(0e00) + '1'
|
//mov word ptr [HEX(b8000)], HEX(0e00) + '1'
|
||||||
|
|
||||||
.byte HEX(0ff), HEX(25) // opcode of indirect jump
|
.byte HEX(0ff), HEX(25) // opcode of 64bit indirect jump
|
||||||
.long 1 // relative address of LongModeEntryPoint
|
.long 1 // relative address of LongModeEntryPoint
|
||||||
nop
|
nop
|
||||||
LongModeEntryPoint:
|
LongModeEntryPoint:
|
||||||
|
@ -301,12 +323,23 @@ LongModeEntryPoint:
|
||||||
int HEX(16)
|
int HEX(16)
|
||||||
jmp SoftReboot
|
jmp SoftReboot
|
||||||
|
|
||||||
|
CallbackTable:
|
||||||
|
.word Int386
|
||||||
|
.word SoftReboot
|
||||||
|
.word ChainLoadBiosBootSectorCode
|
||||||
|
.word PxeCallApi
|
||||||
|
.word PnpBiosGetDeviceNodeCount
|
||||||
|
.word PnpBiosGetDeviceNode
|
||||||
|
.word 0 // BootLinuxKernel
|
||||||
|
|
||||||
/* 16-bit stack pointer */
|
/* 16-bit stack pointer */
|
||||||
stack16:
|
stack16:
|
||||||
.word STACK16ADDR
|
.word STACK16ADDR
|
||||||
|
|
||||||
|
|
||||||
|
#include "int386.inc"
|
||||||
|
#include "pxe.inc"
|
||||||
|
#include "pnp.inc"
|
||||||
#include "helpers.inc"
|
#include "helpers.inc"
|
||||||
|
|
||||||
.org (FREELDR_PE_BASE - FREELDR_BASE - 1)
|
.org (FREELDR_PE_BASE - FREELDR_BASE - 1)
|
||||||
|
|
Loading…
Reference in a new issue