4 * Copyright (C) 2002, 2003, 2004 ReactOS Team
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.
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.
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
24 #include <ndk/kefuncs.h>
25 #include <ndk/halfuncs.h>
30 /* PRIVATE FUNCTIONS **********************************************************/
32 #if defined(_M_IX86) || defined(_M_AMD64)
35 IntInitializeVideoAddressSpace(VOID
)
37 OBJECT_ATTRIBUTES ObjectAttributes
;
38 UNICODE_STRING PhysMemName
= RTL_CONSTANT_STRING(L
"\\Device\\PhysicalMemory");
45 CHAR IVTAndBda
[1024 + 256];
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. */
50 ViewSize
= 1024 * 1024;
51 Status
= ZwFreeVirtualMemory(NtCurrentProcess(),
55 if (!NT_SUCCESS(Status
))
57 DPRINT1("Couldn't unmap reserved memory (%x)\n", Status
);
61 /* Open the physical memory section */
62 InitializeObjectAttributes(&ObjectAttributes
,
64 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
67 Status
= ZwOpenSection(&PhysMemHandle
,
70 if (!NT_SUCCESS(Status
))
72 DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
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
,
89 PAGE_EXECUTE_READWRITE
);
90 if (!NT_SUCCESS(Status
))
92 DPRINT1("Couldn't map physical memory (%x)\n", Status
);
93 ZwClose(PhysMemHandle
);
97 /* Close physical memory section handle */
98 ZwClose(PhysMemHandle
);
100 if (BaseAddress
!= (PVOID
)0xa0000)
102 DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
104 return STATUS_UNSUCCESSFUL
;
107 /* Allocate some low memory to use for the non-BIOS
108 * parts of the v86 mode address space
110 BaseAddress
= (PVOID
)0x1;
111 ViewSize
= 0xa0000 - 0x1000;
112 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
116 MEM_RESERVE
| MEM_COMMIT
,
117 PAGE_EXECUTE_READWRITE
);
118 if (!NT_SUCCESS(Status
))
120 DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status
);
123 if (BaseAddress
!= (PVOID
)0x0)
125 DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
131 /* Get the real mode IVT and BDA from the kernel */
132 Status
= NtVdmControl(VdmInitialize
, IVTAndBda
);
133 if (!NT_SUCCESS(Status
))
135 DPRINT1("NtVdmControl failed (status %x)\n", Status
);
141 return STATUS_SUCCESS
;
146 IntInitializeVideoAddressSpace(VOID
)
150 return STATUS_NOT_IMPLEMENTED
;
156 IntInt10AllocateBuffer(
160 IN OUT PULONG Length
)
165 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
169 TRACE_(VIDEOPRT
, "IntInt10AllocateBuffer\n");
171 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
174 MemoryAddress
= (PVOID
)0x20000;
175 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
180 PAGE_EXECUTE_READWRITE
);
181 if (!NT_SUCCESS(Status
))
183 WARN_(VIDEOPRT
, "- ZwAllocateVirtualMemory failed\n");
184 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
185 return ERROR_NOT_ENOUGH_MEMORY
;
188 if (MemoryAddress
> (PVOID
)(0x100000 - Size
))
190 ZwFreeVirtualMemory(NtCurrentProcess(),
194 WARN_(VIDEOPRT
, "- Unacceptable memory allocated\n");
195 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
196 return ERROR_NOT_ENOUGH_MEMORY
;
199 *Length
= (ULONG
)Size
;
200 *Seg
= (USHORT
)((ULONG_PTR
)MemoryAddress
>> 4);
201 *Off
= (USHORT
)((ULONG_PTR
)MemoryAddress
& 0xF);
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
);
207 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
211 Status
= x86BiosAllocateBuffer(Length
, Seg
, Off
);
212 return NT_SUCCESS(Status
) ? NO_ERROR
: ERROR_NOT_ENOUGH_MEMORY
;
225 PVOID MemoryAddress
= (PVOID
)((ULONG_PTR
)(Seg
<< 4) | Off
);
226 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
230 TRACE_(VIDEOPRT
, "IntInt10FreeBuffer\n");
231 INFO_(VIDEOPRT
, "- Segment: %x\n", Seg
);
232 INFO_(VIDEOPRT
, "- Offset: %x\n", Off
);
234 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
235 Status
= ZwFreeVirtualMemory(NtCurrentProcess(),
240 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
244 Status
= x86BiosFreeBuffer(Seg
, Off
);
245 return NT_SUCCESS(Status
) ? NO_ERROR
: ERROR_INVALID_PARAMETER
;
259 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
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
);
268 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
269 RtlCopyMemory(Buffer
, (PVOID
)((ULONG_PTR
)(Seg
<< 4) | Off
), Length
);
270 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
276 Status
= x86BiosReadMemory(Seg
, Off
, Buffer
, Length
);
277 return NT_SUCCESS(Status
) ? NO_ERROR
: ERROR_INVALID_PARAMETER
;
291 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
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
);
300 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
301 RtlCopyMemory((PVOID
)((ULONG_PTR
)(Seg
<< 4) | Off
), Buffer
, Length
);
302 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
308 Status
= x86BiosWriteMemory(Seg
, Off
, Buffer
, Length
);
309 return NT_SUCCESS(Status
) ? NO_ERROR
: ERROR_INVALID_PARAMETER
;
317 IN OUT PINT10_BIOS_ARGUMENTS BiosArguments
)
320 X86_BIOS_REGISTERS BiosContext
;
325 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
328 /* Attach to CSRSS */
329 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
331 /* Clear the context */
332 RtlZeroMemory(&BiosContext
, sizeof(BiosContext
));
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
;
345 /* Do the ROM BIOS call */
346 (void)KeWaitForMutexObject(&VideoPortInt10Mutex
,
353 Status
= x86BiosCall(0x10, &BiosContext
) ? STATUS_SUCCESS
: STATUS_UNSUCCESSFUL
;
355 Status
= Ke386CallBios(0x10, &BiosContext
);
358 KeReleaseMutex(&VideoPortInt10Mutex
, FALSE
);
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
;
371 /* Detach and return status */
372 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
374 if (NT_SUCCESS(Status
))
379 return ERROR_INVALID_PARAMETER
;
382 /* PUBLIC FUNCTIONS ***********************************************************/
390 IN PVOID HwDeviceExtension
,
391 IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments
)
393 INT10_BIOS_ARGUMENTS Int10BiosArguments
;
396 if (!CsrssInitialized
)
398 return ERROR_INVALID_PARAMETER
;
401 /* Copy arguments to other format */
402 RtlCopyMemory(&Int10BiosArguments
, BiosArguments
, sizeof(BiosArguments
));
403 Int10BiosArguments
.SegDs
= 0;
404 Int10BiosArguments
.SegEs
= 0;
406 /* Do the BIOS call */
407 Status
= IntInt10CallBios(NULL
, &Int10BiosArguments
);
409 /* Copy results back */
410 RtlCopyMemory(BiosArguments
, &Int10BiosArguments
, sizeof(BiosArguments
));