ReactOS  0.4.14-dev-358-gbef841c
int10.c
Go to the documentation of this file.
1 /*
2  * VideoPort driver
3  *
4  * Copyright (C) 2002, 2003, 2004 ReactOS Team
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  *
20  */
21 
22 #include "videoprt.h"
23 
24 #include <ndk/kefuncs.h>
25 #include <ndk/halfuncs.h>
26 
27 #define NDEBUG
28 #include <debug.h>
29 
30 /* PRIVATE FUNCTIONS **********************************************************/
31 
32 #if defined(_M_IX86) || defined(_M_AMD64)
34 NTAPI
36 {
38  UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
40  HANDLE PhysMemHandle;
44 #ifdef _M_IX86
45  CHAR IVTAndBda[1024 + 256];
46 #endif // _M_IX86
47 
48  /* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */
49  BaseAddress = 0;
50  ViewSize = 1024 * 1024;
51  Status = ZwFreeVirtualMemory(NtCurrentProcess(),
52  &BaseAddress,
53  &ViewSize,
54  MEM_RELEASE);
55  if (!NT_SUCCESS(Status))
56  {
57  DPRINT1("Couldn't unmap reserved memory (%x)\n", Status);
58  return 0;
59  }
60 
61  /* Open the physical memory section */
63  &PhysMemName,
65  NULL,
66  NULL);
67  Status = ZwOpenSection(&PhysMemHandle,
70  if (!NT_SUCCESS(Status))
71  {
72  DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
73  return Status;
74  }
75 
76  /* Map the BIOS and device registers into the address space */
77  Offset.QuadPart = 0xa0000;
78  ViewSize = 0x100000 - 0xa0000;
79  BaseAddress = (PVOID)0xa0000;
80  Status = ZwMapViewOfSection(PhysMemHandle,
82  &BaseAddress,
83  0,
84  ViewSize,
85  &Offset,
86  &ViewSize,
87  ViewUnmap,
88  0,
90  if (!NT_SUCCESS(Status))
91  {
92  DPRINT1("Couldn't map physical memory (%x)\n", Status);
93  ZwClose(PhysMemHandle);
94  return Status;
95  }
96 
97  /* Close physical memory section handle */
98  ZwClose(PhysMemHandle);
99 
100  if (BaseAddress != (PVOID)0xa0000)
101  {
102  DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
103  BaseAddress);
104  return STATUS_UNSUCCESSFUL;
105  }
106 
107  /* Allocate some low memory to use for the non-BIOS
108  * parts of the v86 mode address space
109  */
110  BaseAddress = (PVOID)0x1;
111  ViewSize = 0xa0000 - 0x1000;
112  Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
113  &BaseAddress,
114  0,
115  &ViewSize,
118  if (!NT_SUCCESS(Status))
119  {
120  DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status);
121  return Status;
122  }
123  if (BaseAddress != (PVOID)0x0)
124  {
125  DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
126  BaseAddress);
127  return 0;
128  }
129 
130 #ifdef _M_IX86
131  /* Get the real mode IVT and BDA from the kernel */
132  Status = NtVdmControl(VdmInitialize, IVTAndBda);
133  if (!NT_SUCCESS(Status))
134  {
135  DPRINT1("NtVdmControl failed (status %x)\n", Status);
136  return Status;
137  }
138 #endif // _M_IX86
139 
140  /* Return success */
141  return STATUS_SUCCESS;
142 }
143 #else
144 NTSTATUS
145 NTAPI
147 {
149  NT_ASSERT(FALSE);
150  return STATUS_NOT_IMPLEMENTED;
151 }
152 #endif
153 
154 VP_STATUS
155 NTAPI
157  IN PVOID Context,
158  OUT PUSHORT Seg,
159  OUT PUSHORT Off,
161 {
163 #ifdef _M_IX86
164  PVOID MemoryAddress;
165  PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
167  SIZE_T Size;
168 
169  TRACE_(VIDEOPRT, "IntInt10AllocateBuffer\n");
170 
171  IntAttachToCSRSS(&CallingProcess, &ApcState);
172 
173  Size = *Length;
174  MemoryAddress = (PVOID)0x20000;
175  Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
176  &MemoryAddress,
177  0,
178  &Size,
179  MEM_COMMIT,
181  if (!NT_SUCCESS(Status))
182  {
183  WARN_(VIDEOPRT, "- ZwAllocateVirtualMemory failed\n");
184  IntDetachFromCSRSS(&CallingProcess, &ApcState);
186  }
187 
188  if (MemoryAddress > (PVOID)(0x100000 - Size))
189  {
190  ZwFreeVirtualMemory(NtCurrentProcess(),
191  &MemoryAddress,
192  &Size,
193  MEM_RELEASE);
194  WARN_(VIDEOPRT, "- Unacceptable memory allocated\n");
195  IntDetachFromCSRSS(&CallingProcess, &ApcState);
197  }
198 
199  *Length = (ULONG)Size;
200  *Seg = (USHORT)((ULONG_PTR)MemoryAddress >> 4);
201  *Off = (USHORT)((ULONG_PTR)MemoryAddress & 0xF);
202 
203  INFO_(VIDEOPRT, "- Segment: %x\n", (ULONG_PTR)MemoryAddress >> 4);
204  INFO_(VIDEOPRT, "- Offset: %x\n", (ULONG_PTR)MemoryAddress & 0xF);
205  INFO_(VIDEOPRT, "- Length: %x\n", *Length);
206 
207  IntDetachFromCSRSS(&CallingProcess, &ApcState);
208 
209  return NO_ERROR;
210 #else
211  Status = x86BiosAllocateBuffer(Length, Seg, Off);
213 #endif
214 }
215 
216 VP_STATUS
217 NTAPI
219  IN PVOID Context,
220  IN USHORT Seg,
221  IN USHORT Off)
222 {
224 #ifdef _M_IX86
225  PVOID MemoryAddress = (PVOID)((ULONG_PTR)(Seg << 4) | Off);
226  PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
228  SIZE_T Size = 0;
229 
230  TRACE_(VIDEOPRT, "IntInt10FreeBuffer\n");
231  INFO_(VIDEOPRT, "- Segment: %x\n", Seg);
232  INFO_(VIDEOPRT, "- Offset: %x\n", Off);
233 
234  IntAttachToCSRSS(&CallingProcess, &ApcState);
235  Status = ZwFreeVirtualMemory(NtCurrentProcess(),
236  &MemoryAddress,
237  &Size,
238  MEM_RELEASE);
239 
240  IntDetachFromCSRSS(&CallingProcess, &ApcState);
241 
242  return Status;
243 #else
244  Status = x86BiosFreeBuffer(Seg, Off);
246 #endif
247 }
248 
249 VP_STATUS
250 NTAPI
252  IN PVOID Context,
253  IN USHORT Seg,
254  IN USHORT Off,
255  OUT PVOID Buffer,
256  IN ULONG Length)
257 {
258 #ifdef _M_IX86
259  PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
261 
262  TRACE_(VIDEOPRT, "IntInt10ReadMemory\n");
263  INFO_(VIDEOPRT, "- Segment: %x\n", Seg);
264  INFO_(VIDEOPRT, "- Offset: %x\n", Off);
265  INFO_(VIDEOPRT, "- Buffer: %x\n", Buffer);
266  INFO_(VIDEOPRT, "- Length: %x\n", Length);
267 
268  IntAttachToCSRSS(&CallingProcess, &ApcState);
269  RtlCopyMemory(Buffer, (PVOID)((ULONG_PTR)(Seg << 4) | Off), Length);
270  IntDetachFromCSRSS(&CallingProcess, &ApcState);
271 
272  return NO_ERROR;
273 #else
275 
276  Status = x86BiosReadMemory(Seg, Off, Buffer, Length);
278 #endif
279 }
280 
281 VP_STATUS
282 NTAPI
284  IN PVOID Context,
285  IN USHORT Seg,
286  IN USHORT Off,
287  IN PVOID Buffer,
288  IN ULONG Length)
289 {
290 #ifdef _M_IX86
291  PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
293 
294  TRACE_(VIDEOPRT, "IntInt10WriteMemory\n");
295  INFO_(VIDEOPRT, "- Segment: %x\n", Seg);
296  INFO_(VIDEOPRT, "- Offset: %x\n", Off);
297  INFO_(VIDEOPRT, "- Buffer: %x\n", Buffer);
298  INFO_(VIDEOPRT, "- Length: %x\n", Length);
299 
300  IntAttachToCSRSS(&CallingProcess, &ApcState);
301  RtlCopyMemory((PVOID)((ULONG_PTR)(Seg << 4) | Off), Buffer, Length);
302  IntDetachFromCSRSS(&CallingProcess, &ApcState);
303 
304  return NO_ERROR;
305 #else
307 
308  Status = x86BiosWriteMemory(Seg, Off, Buffer, Length);
310 #endif
311 }
312 
313 VP_STATUS
314 NTAPI
316  IN PVOID Context,
317  IN OUT PINT10_BIOS_ARGUMENTS BiosArguments)
318 {
319 #ifdef _M_AMD64
320  X86_BIOS_REGISTERS BiosContext;
321 #else
323 #endif
325  PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
327 
328  /* Attach to CSRSS */
329  IntAttachToCSRSS(&CallingProcess, &ApcState);
330 
331  /* Clear the context */
333 
334  /* Fill out the bios arguments */
335  BiosContext.Eax = BiosArguments->Eax;
336  BiosContext.Ebx = BiosArguments->Ebx;
337  BiosContext.Ecx = BiosArguments->Ecx;
338  BiosContext.Edx = BiosArguments->Edx;
339  BiosContext.Esi = BiosArguments->Esi;
340  BiosContext.Edi = BiosArguments->Edi;
341  BiosContext.Ebp = BiosArguments->Ebp;
342  BiosContext.SegDs = BiosArguments->SegDs;
343  BiosContext.SegEs = BiosArguments->SegEs;
344 
345  /* Do the ROM BIOS call */
347  Executive,
348  KernelMode,
349  FALSE,
350  NULL);
351 
352 #ifdef _M_AMD64
354 #else
355  Status = Ke386CallBios(0x10, &BiosContext);
356 #endif
357 
359 
360  /* Return the arguments */
361  BiosArguments->Eax = BiosContext.Eax;
362  BiosArguments->Ebx = BiosContext.Ebx;
363  BiosArguments->Ecx = BiosContext.Ecx;
364  BiosArguments->Edx = BiosContext.Edx;
365  BiosArguments->Esi = BiosContext.Esi;
366  BiosArguments->Edi = BiosContext.Edi;
367  BiosArguments->Ebp = BiosContext.Ebp;
368  BiosArguments->SegDs = (USHORT)BiosContext.SegDs;
369  BiosArguments->SegEs = (USHORT)BiosContext.SegEs;
370 
371  /* Detach and return status */
372  IntDetachFromCSRSS(&CallingProcess, &ApcState);
373 
374  if (NT_SUCCESS(Status))
375  {
376  return NO_ERROR;
377  }
378 
380 }
381 
382 /* PUBLIC FUNCTIONS ***********************************************************/
383 
384 /*
385  * @implemented
386  */
387 VP_STATUS
388 NTAPI
390  IN PVOID HwDeviceExtension,
391  IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments)
392 {
393  INT10_BIOS_ARGUMENTS Int10BiosArguments;
395 
396  if (!CsrssInitialized)
397  {
399  }
400 
401  /* Copy arguments to other format */
402  RtlCopyMemory(&Int10BiosArguments, BiosArguments, sizeof(*BiosArguments));
403  Int10BiosArguments.SegDs = 0;
404  Int10BiosArguments.SegEs = 0;
405 
406  /* Do the BIOS call */
407  Status = IntInt10CallBios(NULL, &Int10BiosArguments);
408 
409  /* Copy results back */
410  RtlCopyMemory(BiosArguments, &Int10BiosArguments, sizeof(*BiosArguments));
411 
412  return Status;
413 }
NTSTATUS NTAPI NtVdmControl(IN ULONG ControlCode, IN PVOID ControlData)
Definition: stubs.c:430
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define IN
Definition: typedefs.h:38
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
KAPC_STATE
Definition: ketypes.h:1273
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
VP_STATUS NTAPI IntInt10AllocateBuffer(IN PVOID Context, OUT PUSHORT Seg, OUT PUSHORT Off, IN OUT PULONG Length)
Definition: int10.c:156
#define INFO_(ch,...)
Definition: debug.h:159
GLint x0
Definition: linetemp.h:95
#define KeWaitForMutexObject
Definition: kefuncs.h:568
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
char CHAR
Definition: xmlstorage.h:175
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
LONG NTSTATUS
Definition: precomp.h:26
KMUTEX VideoPortInt10Mutex
Definition: videoprt.c:36
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
LONG NTAPI KeReleaseMutex(IN PKMUTEX Mutex, IN BOOLEAN Wait)
Definition: mutex.c:189
#define NO_ERROR
Definition: dderror.h:5
#define MEM_COMMIT
Definition: nt_native.h:1313
uint32_t ULONG_PTR
Definition: typedefs.h:63
VP_STATUS NTAPI IntInt10ReadMemory(IN PVOID Context, IN USHORT Seg, IN USHORT Off, OUT PVOID Buffer, IN ULONG Length)
Definition: int10.c:251
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
NTSTATUS NTAPI x86BiosFreeBuffer(_In_ USHORT Segment, _In_ USHORT Offset)
Definition: x86bios.c:145
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define MEM_RESERVE
Definition: nt_native.h:1314
NTSTATUS NTAPI x86BiosAllocateBuffer(_In_ ULONG *Size, _In_ USHORT *Segment, _In_ USHORT *Offset)
Definition: x86bios.c:116
#define PsGetCurrentProcess
Definition: psfuncs.h:17
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
NTSTATUS NTAPI IntInitializeVideoAddressSpace(VOID)
Definition: int10.c:146
void * PVOID
Definition: retypes.h:9
NTSTATUS NTAPI x86BiosReadMemory(_In_ USHORT Segment, _In_ USHORT Offset, _Out_writes_bytes_(Size) PVOID Buffer, _In_ ULONG Size)
Definition: x86bios.c:169
VP_STATUS NTAPI IntInt10WriteMemory(IN PVOID Context, IN USHORT Seg, IN USHORT Off, IN PVOID Buffer, IN ULONG Length)
Definition: int10.c:283
VP_STATUS NTAPI IntInt10CallBios(IN PVOID Context, IN OUT PINT10_BIOS_ARGUMENTS BiosArguments)
Definition: int10.c:315
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define TRACE_(x)
Definition: compat.h:66
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
CALLBACK16 BiosContext
Definition: bios32.c:45
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static const WCHAR L[]
Definition: oid.c:1250
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
VP_STATUS NTAPI VideoPortInt10(IN PVOID HwDeviceExtension, IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments)
Definition: int10.c:389
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
VP_STATUS NTAPI IntInt10FreeBuffer(IN PVOID Context, IN USHORT Seg, IN USHORT Off)
Definition: int10.c:218
NTSTATUS NTAPI Ke386CallBios(IN ULONG Int, OUT PCONTEXT Context)
Definition: v86vdm.c:613
VOID FASTCALL IntAttachToCSRSS(PKPROCESS *CallingProcess, PKAPC_STATE ApcState)
Definition: videoprt.c:425
unsigned short USHORT
Definition: pedump.c:61
struct _KPROCESS * PKPROCESS
Definition: wdm.template.h:199
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1492
unsigned int * PULONG
Definition: retypes.h:1
#define DPRINT1
Definition: precomp.h:8
#define MEM_RELEASE
Definition: nt_native.h:1316
#define OUT
Definition: typedefs.h:39
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
ULONG CsrssInitialized
Definition: videoprt.c:33
VOID FASTCALL IntDetachFromCSRSS(PKPROCESS *CallingProcess, PKAPC_STATE ApcState)
Definition: videoprt.c:438
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:114
BOOLEAN NTAPI x86BiosCall(_In_ ULONG InterruptNumber, _Inout_ PX86_BIOS_REGISTERS Registers)
Definition: x86bios.c:367
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
LONG VP_STATUS
Definition: video.h:153
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
NTSYSAPI NTSTATUS NTAPI ZwOpenSection(_Out_ PHANDLE SectionHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define WARN_(ch,...)
Definition: debug.h:157
unsigned short * PUSHORT
Definition: retypes.h:2
NTSTATUS NTAPI x86BiosWriteMemory(_In_ USHORT Segment, _In_ USHORT Offset, _In_reads_bytes_(Size) PVOID Buffer, _In_ ULONG Size)
Definition: x86bios.c:196
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define NT_ASSERT
Definition: rtlfuncs.h:3312