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>
29 /* PRIVATE FUNCTIONS **********************************************************/
31 #if defined(_M_IX86) || defined(_M_AMD64)
34 IntInitializeVideoAddressSpace(VOID
)
36 OBJECT_ATTRIBUTES ObjectAttributes
;
37 UNICODE_STRING PhysMemName
= RTL_CONSTANT_STRING(L
"\\Device\\PhysicalMemory");
44 CHAR IVTAndBda
[1024 + 256];
47 /* 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 ViewSize
= 1024 * 1024;
50 Status
= ZwFreeVirtualMemory(NtCurrentProcess(),
54 if (!NT_SUCCESS(Status
))
56 DPRINT1("Couldn't unmap reserved memory (%x)\n", Status
);
60 /* Open the physical memory section */
61 InitializeObjectAttributes(&ObjectAttributes
,
63 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
66 Status
= ZwOpenSection(&PhysMemHandle
,
69 if (!NT_SUCCESS(Status
))
71 DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
75 /* Map the BIOS and device registers into the address space */
76 Offset
.QuadPart
= 0xa0000;
77 ViewSize
= 0x100000 - 0xa0000;
78 BaseAddress
= (PVOID
)0xa0000;
79 Status
= ZwMapViewOfSection(PhysMemHandle
,
88 PAGE_EXECUTE_READWRITE
);
89 if (!NT_SUCCESS(Status
))
91 DPRINT1("Couldn't map physical memory (%x)\n", Status
);
92 ZwClose(PhysMemHandle
);
96 /* Close physical memory section handle */
97 ZwClose(PhysMemHandle
);
99 if (BaseAddress
!= (PVOID
)0xa0000)
101 DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
103 return STATUS_UNSUCCESSFUL
;
106 /* Allocate some low memory to use for the non-BIOS
107 * parts of the v86 mode address space
109 BaseAddress
= (PVOID
)0x1;
110 ViewSize
= 0xa0000 - 0x1000;
111 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
115 MEM_RESERVE
| MEM_COMMIT
,
116 PAGE_EXECUTE_READWRITE
);
117 if (!NT_SUCCESS(Status
))
119 DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status
);
122 if (BaseAddress
!= (PVOID
)0x0)
124 DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
130 /* Get the real mode IVT and BDA from the kernel */
131 Status
= NtVdmControl(VdmInitialize
, IVTAndBda
);
132 if (!NT_SUCCESS(Status
))
134 DPRINT1("NtVdmControl failed (status %x)\n", Status
);
140 return STATUS_SUCCESS
;
145 IntInitializeVideoAddressSpace(VOID
)
149 return STATUS_NOT_IMPLEMENTED
;
156 IntInt10AllocateBuffer(
160 IN OUT PULONG Length
)
164 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
167 TRACE_(VIDEOPRT
, "IntInt10AllocateBuffer\n");
169 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
171 MemoryAddress
= (PVOID
)0x20000;
172 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
177 PAGE_EXECUTE_READWRITE
);
178 if (!NT_SUCCESS(Status
))
180 WARN_(VIDEOPRT
, "- ZwAllocateVirtualMemory failed\n");
181 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
182 return ERROR_NOT_ENOUGH_MEMORY
;
185 if (MemoryAddress
> (PVOID
)(0x100000 - *Length
))
187 ZwFreeVirtualMemory(NtCurrentProcess(), &MemoryAddress
, Length
,
189 WARN_(VIDEOPRT
, "- Unacceptable memory allocated\n");
190 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
191 return ERROR_NOT_ENOUGH_MEMORY
;
194 *Seg
= (USHORT
)((ULONG
)MemoryAddress
>> 4);
195 *Off
= (USHORT
)((ULONG
)MemoryAddress
& 0xF);
197 INFO_(VIDEOPRT
, "- Segment: %x\n", (ULONG
)MemoryAddress
>> 4);
198 INFO_(VIDEOPRT
, "- Offset: %x\n", (ULONG
)MemoryAddress
& 0xF);
199 INFO_(VIDEOPRT
, "- Length: %x\n", *Length
);
201 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
213 PVOID MemoryAddress
= (PVOID
)((Seg
<< 4) | Off
);
215 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
219 TRACE_(VIDEOPRT
, "IntInt10FreeBuffer\n");
220 INFO_(VIDEOPRT
, "- Segment: %x\n", Seg
);
221 INFO_(VIDEOPRT
, "- Offset: %x\n", Off
);
223 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
224 Status
= ZwFreeVirtualMemory(NtCurrentProcess(),
229 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
243 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
246 TRACE_(VIDEOPRT
, "IntInt10ReadMemory\n");
247 INFO_(VIDEOPRT
, "- Segment: %x\n", Seg
);
248 INFO_(VIDEOPRT
, "- Offset: %x\n", Off
);
249 INFO_(VIDEOPRT
, "- Buffer: %x\n", Buffer
);
250 INFO_(VIDEOPRT
, "- Length: %x\n", Length
);
252 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
253 RtlCopyMemory(Buffer
, (PVOID
)((Seg
<< 4) | Off
), Length
);
254 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
268 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
271 TRACE_(VIDEOPRT
, "IntInt10WriteMemory\n");
272 INFO_(VIDEOPRT
, "- Segment: %x\n", Seg
);
273 INFO_(VIDEOPRT
, "- Offset: %x\n", Off
);
274 INFO_(VIDEOPRT
, "- Buffer: %x\n", Buffer
);
275 INFO_(VIDEOPRT
, "- Length: %x\n", Length
);
277 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
278 RtlCopyMemory((PVOID
)((Seg
<< 4) | Off
), Buffer
, Length
);
279 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
288 IN OUT PINT10_BIOS_ARGUMENTS BiosArguments
)
292 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
295 /* Attach to CSRSS */
296 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
298 /* Clear the context */
299 RtlZeroMemory(&BiosContext
, sizeof(BiosContext
));
301 /* Fill out the bios arguments */
302 BiosContext
.Eax
= BiosArguments
->Eax
;
303 BiosContext
.Ebx
= BiosArguments
->Ebx
;
304 BiosContext
.Ecx
= BiosArguments
->Ecx
;
305 BiosContext
.Edx
= BiosArguments
->Edx
;
306 BiosContext
.Esi
= BiosArguments
->Esi
;
307 BiosContext
.Edi
= BiosArguments
->Edi
;
308 BiosContext
.Ebp
= BiosArguments
->Ebp
;
309 BiosContext
.SegDs
= BiosArguments
->SegDs
;
310 BiosContext
.SegEs
= BiosArguments
->SegEs
;
312 /* Do the ROM BIOS call */
313 (void)KeWaitForMutexObject(&VideoPortInt10Mutex
,
319 Status
= Ke386CallBios(0x10, &BiosContext
);
321 KeReleaseMutex(&VideoPortInt10Mutex
, FALSE
);
323 /* Return the arguments */
324 BiosArguments
->Eax
= BiosContext
.Eax
;
325 BiosArguments
->Ebx
= BiosContext
.Ebx
;
326 BiosArguments
->Ecx
= BiosContext
.Ecx
;
327 BiosArguments
->Edx
= BiosContext
.Edx
;
328 BiosArguments
->Esi
= BiosContext
.Esi
;
329 BiosArguments
->Edi
= BiosContext
.Edi
;
330 BiosArguments
->Ebp
= BiosContext
.Ebp
;
331 BiosArguments
->SegDs
= (USHORT
)BiosContext
.SegDs
;
332 BiosArguments
->SegEs
= (USHORT
)BiosContext
.SegEs
;
334 /* Detach and return status */
335 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
337 if (NT_SUCCESS(Status
))
342 return ERROR_INVALID_PARAMETER
;
346 /* PUBLIC FUNCTIONS ***********************************************************/
355 IN PVOID HwDeviceExtension
,
356 IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments
)
361 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
364 if (!CsrssInitialized
)
366 return ERROR_INVALID_PARAMETER
;
369 /* Attach to CSRSS */
370 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
372 /* Clear the context */
373 RtlZeroMemory(&BiosContext
, sizeof(CONTEXT
));
375 /* Fill out the bios arguments */
376 BiosContext
.Eax
= BiosArguments
->Eax
;
377 BiosContext
.Ebx
= BiosArguments
->Ebx
;
378 BiosContext
.Ecx
= BiosArguments
->Ecx
;
379 BiosContext
.Edx
= BiosArguments
->Edx
;
380 BiosContext
.Esi
= BiosArguments
->Esi
;
381 BiosContext
.Edi
= BiosArguments
->Edi
;
382 BiosContext
.Ebp
= BiosArguments
->Ebp
;
384 /* Do the ROM BIOS call */
385 (void)KeWaitForMutexObject(&VideoPortInt10Mutex
,
390 Status
= Ke386CallBios(0x10, &BiosContext
);
391 KeReleaseMutex(&VideoPortInt10Mutex
, FALSE
);
393 /* Return the arguments */
394 BiosArguments
->Eax
= BiosContext
.Eax
;
395 BiosArguments
->Ebx
= BiosContext
.Ebx
;
396 BiosArguments
->Ecx
= BiosContext
.Ecx
;
397 BiosArguments
->Edx
= BiosContext
.Edx
;
398 BiosArguments
->Esi
= BiosContext
.Esi
;
399 BiosArguments
->Edi
= BiosContext
.Edi
;
400 BiosArguments
->Ebp
= BiosContext
.Ebp
;
402 /* Detach from CSRSS */
403 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
405 if (NT_SUCCESS(Status
))
410 return ERROR_INVALID_PARAMETER
;
412 /* Not implemented for anything else than X86*/
413 DPRINT1("Int10 not available on non-x86!\n");
414 return ERROR_INVALID_FUNCTION
;