Added support for calling BIOS functions

Partially implemented VideoPortInt10

svn path=/trunk/; revision=1477
This commit is contained in:
David Welch 2000-12-26 05:32:44 +00:00
parent 3b50cd9ca9
commit 390fd4f1fb
14 changed files with 371 additions and 44 deletions

View file

@ -1,4 +1,4 @@
/* $Id: vidport.c,v 1.15 2000/09/12 10:12:13 jean Exp $
/* $Id: vidport.c,v 1.16 2000/12/26 05:32:44 dwelch Exp $
*
* VideoPort driver
* Written by Rex Jolliff
@ -7,6 +7,8 @@
#include <ddk/ntddk.h>
#include <ddk/ntddvid.h>
#include "../../../ntoskrnl/include/internal/v86m.h"
#include "vidport.h"
#define UNIMPLEMENTED do {DbgPrint("%s:%d: Function not implemented", __FILE__, __LINE__); for(;;);} while (0)
@ -317,12 +319,26 @@ VideoPortInitialize(IN PVOID Context1,
return STATUS_SUCCESS;
}
VP_STATUS
STDCALL
VP_STATUS STDCALL
VideoPortInt10(IN PVOID HwDeviceExtension,
IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments)
{
UNIMPLEMENTED;
KV86M_REGISTERS Regs;
NTSTATUS Status;
/* FIXME: Attach to csrss */
/* FIXME: Check address space is set up */
memset(&Regs, 0, sizeof(Regs));
Regs.Eax = BiosArguments->Eax;
Regs.Ebx = BiosArguments->Ebx;
Regs.Ecx = BiosArguments->Ecx;
Regs.Edx = BiosArguments->Edx;
Regs.Esi = BiosArguments->Esi;
Regs.Edi = BiosArguments->Edi;
Regs.Ebp = BiosArguments->Ebp;
Status = Ke386CallBios(0x10, &Regs);
return(Status);
}
VOID

View file

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.5 2000/12/23 02:37:38 dwelch Exp $
# $Id: Makefile,v 1.6 2000/12/26 05:32:43 dwelch Exp $
#
# ReactOS Operating System
#
@ -34,7 +34,8 @@ OBJECTS_NT = \
nt/nttimer.o \
nt/plugplay.o \
nt/profile.o \
nt/zw.o
nt/zw.o \
nt/vdm.o
# Run-Time Library (Rtl)
OBJECTS_RTL = \
@ -97,7 +98,8 @@ OBJECTS_KE_I386 = \
ke/i386/syscall.o \
ke/i386/tskswitch.o \
ke/i386/v86m.o \
ke/i386/v86m_sup.o
ke/i386/v86m_sup.o \
ke/i386/bios.o
# Memory Manager (Mm)
OBJECTS_MM = \

View file

@ -102,5 +102,7 @@ VOID KeInit1(VOID);
VOID KeInit2(VOID);
BOOLEAN KiDeliverUserApc(PKTRAP_FRAME TrapFrame);
VOID
NtEarlyInitVdm(VOID);
#endif

View file

@ -69,7 +69,10 @@ typedef struct _KV86M_REGISTERS
ULONG Vif;
ULONG Flags;
PNTSTATUS PStatus;
} KV86M_REGISTERS;
} KV86M_REGISTERS, *PKV86M_REGISTERS;
NTSTATUS STDCALL
Ke386CallBios(UCHAR Int, PKV86M_REGISTERS Regs);
#else /* ASSEMBLER */

View file

@ -35,13 +35,16 @@
#define TRAMPOLINE_BASE (0x10000)
extern VOID Ki386RetToV86Mode(PKV86M_REGISTERS InRegs,
PKV86M_REGISTERS OutRegs);
/* FUNCTIONS *****************************************************************/
VOID
NTSTATUS STDCALL
Ke386CallBios(UCHAR Int, PKV86M_REGISTERS Regs)
{
PUCHAR Ip;
KVM86_REGISTERS ORegs;
KV86M_REGISTERS ORegs;
NTSTATUS Status;
/*
@ -80,8 +83,8 @@ Ke386CallBios(UCHAR Int, PKV86M_REGISTERS Regs)
/*
* Copy the return values back to the caller
*/
memcpy(Regs, &ORegs, sizeof(Regs));
memcpy(Regs, &ORegs, sizeof(KV86M_REGISTERS));
return(Status);
}

View file

@ -31,7 +31,7 @@
#include <internal/mm.h>
#include <internal/i386/segment.h>
#define NDEBUG
//#define NDEBUG
#include <internal/debug.h>
/* GLOBALS *******************************************************************/
@ -48,10 +48,189 @@ KeV86GPF(struct trap_frame* tf)
PUSHORT sp;
ip = (PUCHAR)((tf->cs & 0xFFFF) * 16 + (tf->eip & 0xFFFF));
sp = (PUSHORT)((tf->ss0 & 0xFFFF) * 16 + (tf->esp & 0xFFFF));
sp = (PUSHORT)((tf->ss0 & 0xFFFF) * 16 + (tf->esp0 & 0xFFFF));
DPRINT("KeV86GPF handling %x at %x:%x ss:sp %x:%x\n",
ip[0], tf->cs, tf->eip, tf->ss0, tf->esp0);
switch (ip[0])
{
/* sti */
case 0xFB:
if (tf->regs->Flags & KV86M_EMULATE_CLI_STI)
{
tf->eip++;
tf->regs->Vif = 1;
return(0);
}
break;
/* cli */
case 0xFA:
if (tf->regs->Flags & KV86M_EMULATE_CLI_STI)
{
tf->eip++;
tf->regs->Vif = 0;
return(0);
}
break;
/* pushf */
case 0x9C:
if (tf->regs->Flags & KV86M_EMULATE_CLI_STI)
{
tf->eip++;
tf->esp0 = tf->esp0 - 2;
sp = sp - 1;
sp[0] = tf->eflags & 0xFFFF;
if (tf->regs->Vif)
{
sp[0] = sp[0] | INTERRUPT_FLAG;
}
return(0);
}
break;
/* popf */
case 0x9D:
if (tf->regs->Flags & KV86M_EMULATE_CLI_STI)
{
tf->eip++;
tf->eflags = tf->eflags & (~0xFFFF);
tf->eflags = tf->eflags | sp[0];
if (tf->eflags & INTERRUPT_FLAG)
{
tf->regs->Vif = 1;
}
else
{
tf->regs->Vif = 0;
}
tf->eflags = tf->eflags & (~INTERRUPT_FLAG);
tf->esp0 = tf->esp0 + 2;
return(0);
}
break;
/* iret */
case 0xCF:
if (tf->regs->Flags & KV86M_EMULATE_CLI_STI)
{
tf->eip = sp[0];
tf->cs = sp[1];
tf->eflags = tf->eflags & (~0xFFFF);
tf->eflags = tf->eflags | sp[2];
if (tf->eflags & INTERRUPT_FLAG)
{
tf->regs->Vif = 1;
}
else
{
tf->regs->Vif = 0;
}
tf->eflags = tf->eflags & (~INTERRUPT_FLAG);
tf->esp0 = tf->esp0 + 6;
return(0);
}
break;
/* out imm8, al */
case 0xE6:
if (tf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
WRITE_PORT_UCHAR((PUCHAR)(ULONG)ip[1],
tf->eax & 0xFF);
tf->eip = tf->eip + 2;
return(0);
}
break;
/* out imm8, ax */
case 0xE7:
if (tf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
WRITE_PORT_USHORT((PUSHORT)(ULONG)ip[1], tf->eax & 0xFFFF);
tf->eip = tf->eip + 2;
return(0);
}
break;
/* out dx, al */
case 0xEE:
if (tf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
WRITE_PORT_UCHAR((PUCHAR)(tf->edx & 0xFFFF), tf->eax & 0xFF);
tf->eip = tf->eip + 1;
return(0);
}
break;
/* out dx, ax */
case 0xEF:
if (tf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
WRITE_PORT_USHORT((PUSHORT)(tf->edx & 0xFFFF), tf->eax & 0xFFFF);
tf->eip = tf->eip + 1;
return(0);
}
break;
/* in al, imm8 */
case 0xE4:
if (tf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
UCHAR v;
v = READ_PORT_UCHAR((PUCHAR)(ULONG)ip[1]);
tf->eax = tf->eax & (~0xFF);
tf->eax = tf->eax | v;
tf->eip = tf->eip + 2;
return(0);
}
break;
/* in ax, imm8 */
case 0xE5:
if (tf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
USHORT v;
v = READ_PORT_USHORT((PUSHORT)(ULONG)ip[1]);
tf->eax = tf->eax & (~0xFFFF);
tf->eax = tf->eax | v;
tf->eip = tf->eip + 2;
return(0);
}
break;
/* in al, dx */
case 0xEC:
if (tf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
UCHAR v;
v = READ_PORT_UCHAR((PUCHAR)(tf->edx & 0xFFFF));
tf->eax = tf->eax & (~0xFF);
tf->eax = tf->eax | v;
tf->eip = tf->eip + 1;
return(0);
}
break;
/* in ax, dx */
case 0xED:
if (tf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
USHORT v;
v = READ_PORT_USHORT((PUSHORT)(tf->edx & 0xFFFF));
tf->eax = tf->eax & (~0xFFFF);
tf->eax = tf->eax | v;
tf->eip = tf->eip + 1;
return(0);
}
break;
/* Int nn */
case 0xCD:
{
@ -62,7 +241,7 @@ KeV86GPF(struct trap_frame* tf)
entry = ((unsigned int *)0)[inum];
tf->esp0 = tf->esp0 - 6;
sp = sp - 6;
sp = sp - 3;
sp[0] = (tf->eip & 0xFFFF) + 2;
sp[1] = tf->cs & 0xFFFF;
@ -71,14 +250,20 @@ KeV86GPF(struct trap_frame* tf)
{
sp[2] = sp[2] | INTERRUPT_FLAG;
}
DPRINT("sp[0] %x sp[1] %x sp[2] %x\n", sp[0], sp[1], sp[2]);
tf->eip = entry & 0xFFFF;
tf->cs = entry >> 16;
tf->eflags = tf->eflags & (~TRAP_FLAG);
return(0);
}
}
/* FIXME: Also emulate ins and outs */
/* FIXME: Handle opcode prefixes */
/* FIXME: Don't allow the BIOS to write to sensitive I/O ports */
}
DPRINT("V86GPF unhandled\n");
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}
@ -86,12 +271,15 @@ KeV86GPF(struct trap_frame* tf)
ULONG
KeV86Exception(struct trap_frame* tf, ULONG address)
{
PVOID Ip;
PUCHAR Ip;
/*
* Check if we have reached the recovery instruction
*/
Ip = (PVOID)((tf->cs & 0xFFFF) * 16 + (tf->eip & 0xFFFF));
Ip = (PUCHAR)((tf->cs & 0xFFFF) * 16 + (tf->eip & 0xFFFF));
DbgPrint("tf->type %d Ip[0] %x Ip[1] %x Ip[2] %x Ip[3] %x tf->cs %x "
"tf->eip %x\n", tf->type, Ip[0], Ip[1], Ip[2], Ip[3], tf->cs,
tf->eip);
if (tf->type == 6 &&
memcmp(Ip, tf->regs->RecoveryInstruction, 4) == 0 &&
(tf->cs * 16 + tf->eip) == tf->regs->RecoveryAddress)
@ -186,6 +374,7 @@ KeV86Exception(struct trap_frame* tf, ULONG address)
tf->error_code);
if (!NT_SUCCESS(Status))
{
DPRINT("V86Exception, halting due to page fault\n");
*tf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}

View file

@ -71,6 +71,7 @@ _Ki386RetToV86Mode:
* will be the current stack adjusted so we don't overwrite the
* existing stack frames
*/
movl $_KiTss, %esi
movl %esp, KTSS_ESP0(%esi)
/*
@ -120,10 +121,12 @@ _KiV86Complete:
popl KV86M_REGISTERS_EDI(%ebx)
popl KV86M_REGISTERS_ESI(%ebx)
popl KV86M_REGISTERS_EBP(%ebx)
addl $4, %esp /* Ignore ring0 esp */
popl KV86M_REGISTERS_EBX(%ebx)
popl KV86M_REGISTERS_EDX(%ebx)
popl KV86M_REGISTERS_ECX(%ebx)
popl KV86M_REGISTERS_EAX(%ebx)
addl $4, %esp /* Ignore trap code */
addl $16, %esp /* Ignore 32-bit segment registers */
addl $4, %esp /* Ignore error code */

View file

@ -1,4 +1,4 @@
/* $Id: main.c,v 1.68 2000/12/23 02:37:40 dwelch Exp $
/* $Id: main.c,v 1.69 2000/12/26 05:32:44 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -25,7 +25,7 @@
#include <internal/mmhal.h>
#include <internal/i386/segment.h>
#include <napi/shared_data.h>
#include <internal/v86m.h>
#define NDEBUG
#include <internal/debug.h>
@ -361,7 +361,66 @@ InitSystemSharedUserPage (PCSZ ParameterLine)
}
}
void
extern NTSTATUS STDCALL
Ke386CallBios(UCHAR Int, KV86M_REGISTERS* Regs);
struct __attribute__((packed)) vesa_info
{
UCHAR Signature[4];
USHORT Version;
ULONG OEMName;
ULONG Capabilities;
ULONG SupportedModes;
USHORT TotalVideoMemory;
USHORT OEMVersion;
ULONG VendorName;
ULONG ProductName;
ULONG ProductRevisionString;
UCHAR Reserved[478];
};
VOID
TestV86Mode(VOID)
{
ULONG i;
extern UCHAR OrigIVT[1024];
KV86M_REGISTERS regs;
NTSTATUS Status;
struct vesa_info* vi;
for (i = 0; i < (640 / 4); i++)
{
MmCreateVirtualMapping(NULL,
(PVOID)(i * 4096),
PAGE_EXECUTE_READWRITE,
(ULONG)MmAllocPage(0));
}
for (; i < (1024 / 4); i++)
{
MmCreateVirtualMapping(NULL,
(PVOID)(i * 4096),
PAGE_EXECUTE_READ,
i * 4096);
}
vi = (struct vesa_info*)0x20000;
vi->Signature[0] = 'V';
vi->Signature[1] = 'B';
vi->Signature[2] = 'E';
vi->Signature[3] = '2';
memset(&regs, 0, sizeof(regs));
regs.Eax = 0x4F00;
regs.Es = 0x2000;
regs.Edi = 0x0;
memcpy((PVOID)0x0, OrigIVT, 1024);
Status = Ke386CallBios(0x10, &regs);
DbgPrint("Finished (Status %x, CS:EIP %x:%x)\n", Status, regs.Cs,
regs.Eip);
DbgPrint("Eax %x\n", regs.Eax);
DbgPrint("Signature %.4s\n", vi->Signature);
DbgPrint("TotalVideoMemory %dKB\n", vi->TotalVideoMemory * 64);
}
VOID
_main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
/*
* FUNCTION: Called by the boot loader to start the kernel
@ -412,23 +471,28 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
KeLowerIrql(DISPATCH_LEVEL);
{
char tmpbuf[80];
sprintf(tmpbuf,"system with %d MB extended memory\n"
,(unsigned int)(KeLoaderBlock.MemLower)/1024);
char tmpbuf[80];
sprintf(tmpbuf,"system with %d MB extended memory\n",
(unsigned int)(KeLoaderBlock.MemLower)/1024);
HalDisplayString(tmpbuf);
}
/*
* Display version number and copyright/warranty message
*/
HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build "KERNEL_VERSION_BUILD_STR")\n");
HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build "
KERNEL_VERSION_BUILD_STR")\n");
HalDisplayString("Copyright 2000 (So who owns the copyright?).\n");
HalDisplayString("ReactOS is free software, covered by the GNU General Public License, and you\n");
HalDisplayString("are welcome to change it and/or distribute copies of it under certain\n");
HalDisplayString("ReactOS is free software, covered by the GNU General "
"Public License, and you\n");
HalDisplayString("are welcome to change it and/or distribute copies of it "
"under certain\n");
HalDisplayString("conditions.\n");
HalDisplayString("There is absolutely no warranty for ReactOS.\n");
last_kernel_address = KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd;
NtEarlyInitVdm();
MmInit1(KeLoaderModules[0].ModStart - 0xc0000000 + 0x200000,
last_kernel_address - 0xc0000000 + 0x200000,
last_kernel_address);
@ -521,8 +585,12 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
/*
* Launch initial process
*/
#if 0
LdrLoadInitialProcess();
#endif
TestV86Mode();
DbgPrint("Finished main()\n");
PsTerminateSystemThread(STATUS_SUCCESS);
}

View file

@ -1,4 +1,4 @@
/* $Id: spinlock.c,v 1.5 2000/10/07 13:41:52 dwelch Exp $
/* $Id: spinlock.c,v 1.6 2000/12/26 05:32:44 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -73,6 +73,12 @@ KeAcquireSpinLockAtDpcLevel (PKSPIN_LOCK SpinLock)
{
ULONG i;
if (!(SpinLock->Lock == 0 || SpinLock->Lock == 1))
{
DbgPrint("Lock %x has bad value %x\n", SpinLock, i);
KeBugCheck(0);
}
while ((i = InterlockedExchange(&SpinLock->Lock, 1)) == 1)
{
DbgPrint("Spinning on spinlock %x current value %x\n", SpinLock, i);

View file

@ -31,10 +31,4 @@ NtDisplayString(IN PUNICODE_STRING DisplayString)
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL NtVdmControl(VOID)
{
UNIMPLEMENTED;
}
/* EOF */

40
reactos/ntoskrnl/nt/vdm.c Normal file
View file

@ -0,0 +1,40 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/nt/vdm.c
* PURPOSE: Virtual DOS machine support
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
* Created 22/05/98
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/debug.h>
/* GLOBALS *******************************************************************/
/* static */ UCHAR OrigIVT[1024];
/* static UCHAR OrigBDA[]; */
/* static UCHAR OrigEBDA[]; */
/* FUNCTIONS *****************************************************************/
VOID
NtEarlyInitVdm(VOID)
{
/*
* Save various BIOS data tables. At this point the lower 4MB memory
* map is still active so we can just copy the data from low memory.
*/
memcpy(OrigIVT, (PVOID)0x0, 1024);
}
NTSTATUS STDCALL NtVdmControl(VOID)
{
UNIMPLEMENTED;
}
/* EOF */

View file

@ -1,4 +1,4 @@
; $Id: ntoskrnl.def,v 1.89 2000/10/08 12:43:56 ekohl Exp $
; $Id: ntoskrnl.def,v 1.90 2000/12/26 05:32:43 dwelch Exp $
;
; reactos/ntoskrnl/ntoskrnl.def
;
@ -308,7 +308,7 @@ IofCompleteRequest@8
KdDebuggerEnabled DATA
KdDebuggerNotPresent DATA
KdPollBreakIn@0
;Ke386CallBios
Ke386CallBios@8
;Ke386IoSetAccessProcess
;Ke386QueryIoAccessMap
;Ke386SetIoAccessMap

View file

@ -1,4 +1,4 @@
; $Id: ntoskrnl.edf,v 1.76 2000/10/08 12:43:56 ekohl Exp $
; $Id: ntoskrnl.edf,v 1.77 2000/12/26 05:32:43 dwelch Exp $
;
; reactos/ntoskrnl/ntoskrnl.def
;
@ -308,7 +308,7 @@ IofCompleteRequest=IofCompleteRequest@8
KdDebuggerEnabled DATA
KdDebuggerNotPresent DATA
KdPollBreakIn=KdPollBreakIn@0
;Ke386CallBios
Ke386CallBios=Ke386CallBios@8
;Ke386IoSetAccessProcess
;Ke386QueryIoAccessMap
;Ke386SetIoAccessMap

View file

@ -1,4 +1,4 @@
/* $Id: thread.c,v 1.63 2000/12/24 03:35:54 dwelch Exp $
/* $Id: thread.c,v 1.64 2000/12/26 05:32:44 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -627,9 +627,10 @@ NtCallbackReturn (PVOID Result,
ULONG ResultLength,
NTSTATUS Status)
{
UNIMPLEMENTED;
UNIMPLEMENTED;
}
NTSTATUS STDCALL
NtW32Call (IN ULONG RoutineIndex,
IN PVOID Argument,
@ -637,7 +638,7 @@ NtW32Call (IN ULONG RoutineIndex,
OUT PVOID* Result OPTIONAL,
OUT PULONG ResultLength OPTIONAL)
{
UNIMPLEMENTED;
UNIMPLEMENTED;
}
NTSTATUS STDCALL