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");
43 CHAR IVTAndBda
[1024+256];
45 /* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */
47 ViewSize
= 1024 * 1024;
48 Status
= ZwFreeVirtualMemory(NtCurrentProcess(),
52 if (!NT_SUCCESS(Status
))
54 DPRINT1("Couldn't unmap reserved memory (%x)\n", Status
);
58 /* Open the physical memory section */
59 InitializeObjectAttributes(&ObjectAttributes
,
61 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
64 Status
= ZwOpenSection(&PhysMemHandle
,
67 if (!NT_SUCCESS(Status
))
69 DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
73 /* Map the BIOS and device registers into the address space */
74 Offset
.QuadPart
= 0xa0000;
75 ViewSize
= 0x100000 - 0xa0000;
76 BaseAddress
= (PVOID
)0xa0000;
77 Status
= ZwMapViewOfSection(PhysMemHandle
,
86 PAGE_EXECUTE_READWRITE
);
87 if (!NT_SUCCESS(Status
))
89 DPRINT1("Couldn't map physical memory (%x)\n", Status
);
90 ZwClose(PhysMemHandle
);
94 /* Close physical memory section handle */
95 ZwClose(PhysMemHandle
);
97 if (BaseAddress
!= (PVOID
)0xa0000)
99 DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
101 return STATUS_UNSUCCESSFUL
;
104 /* Allocate some low memory to use for the non-BIOS
105 * parts of the v86 mode address space
107 BaseAddress
= (PVOID
)0x1;
108 ViewSize
= 0xa0000 - 0x1000;
109 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
113 MEM_RESERVE
| MEM_COMMIT
,
114 PAGE_EXECUTE_READWRITE
);
115 if (!NT_SUCCESS(Status
))
117 DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status
);
120 if (BaseAddress
!= (PVOID
)0x0)
122 DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
127 /* Get the real mode IVT and BDA from the kernel */
128 Status
= NtVdmControl(VdmInitialize
, IVTAndBda
);
129 if (!NT_SUCCESS(Status
))
131 DPRINT1("NtVdmControl failed (status %x)\n", Status
);
136 return STATUS_SUCCESS
;
141 IntInitializeVideoAddressSpace(VOID
)
145 return STATUS_NOT_IMPLEMENTED
;
151 IntInt10AllocateBuffer(
155 IN OUT PULONG Length
)
159 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
162 TRACE_(VIDEOPRT
, "IntInt10AllocateBuffer\n");
164 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
166 MemoryAddress
= (PVOID
)0x20000;
167 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(), &MemoryAddress
, 0,
168 Length
, MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
170 if (!NT_SUCCESS(Status
))
172 WARN_(VIDEOPRT
, "- ZwAllocateVirtualMemory failed\n");
173 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
174 return ERROR_NOT_ENOUGH_MEMORY
;
177 if (MemoryAddress
> (PVOID
)(0x100000 - *Length
))
179 ZwFreeVirtualMemory(NtCurrentProcess(), &MemoryAddress
, Length
,
181 WARN_(VIDEOPRT
, "- Unacceptable memory allocated\n");
182 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
183 return ERROR_NOT_ENOUGH_MEMORY
;
186 *Seg
= (USHORT
)((ULONG
)MemoryAddress
>> 4);
187 *Off
= (USHORT
)((ULONG
)MemoryAddress
& 0xF);
189 INFO_(VIDEOPRT
, "- Segment: %x\n", (ULONG
)MemoryAddress
>> 4);
190 INFO_(VIDEOPRT
, "- Offset: %x\n", (ULONG
)MemoryAddress
& 0xF);
191 INFO_(VIDEOPRT
, "- Length: %x\n", *Length
);
193 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
204 PVOID MemoryAddress
= (PVOID
)((Seg
<< 4) | Off
);
206 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
210 TRACE_(VIDEOPRT
, "IntInt10FreeBuffer\n");
211 INFO_(VIDEOPRT
, "- Segment: %x\n", Seg
);
212 INFO_(VIDEOPRT
, "- Offset: %x\n", Off
);
214 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
215 Status
= ZwFreeVirtualMemory(NtCurrentProcess(), &MemoryAddress
, &Size
,
217 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
230 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
233 TRACE_(VIDEOPRT
, "IntInt10ReadMemory\n");
234 INFO_(VIDEOPRT
, "- Segment: %x\n", Seg
);
235 INFO_(VIDEOPRT
, "- Offset: %x\n", Off
);
236 INFO_(VIDEOPRT
, "- Buffer: %x\n", Buffer
);
237 INFO_(VIDEOPRT
, "- Length: %x\n", Length
);
239 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
240 RtlCopyMemory(Buffer
, (PVOID
)((Seg
<< 4) | Off
), Length
);
241 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
254 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
257 TRACE_(VIDEOPRT
, "IntInt10WriteMemory\n");
258 INFO_(VIDEOPRT
, "- Segment: %x\n", Seg
);
259 INFO_(VIDEOPRT
, "- Offset: %x\n", Off
);
260 INFO_(VIDEOPRT
, "- Buffer: %x\n", Buffer
);
261 INFO_(VIDEOPRT
, "- Length: %x\n", Length
);
263 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
264 RtlCopyMemory((PVOID
)((Seg
<< 4) | Off
), Buffer
, Length
);
265 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
274 IN OUT PINT10_BIOS_ARGUMENTS BiosArguments
)
278 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
281 /* Attach to CSRSS */
282 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
284 /* Clear the context */
285 RtlZeroMemory(&BiosContext
, sizeof(CONTEXT
));
287 /* Fill out the bios arguments */
288 BiosContext
.Eax
= BiosArguments
->Eax
;
289 BiosContext
.Ebx
= BiosArguments
->Ebx
;
290 BiosContext
.Ecx
= BiosArguments
->Ecx
;
291 BiosContext
.Edx
= BiosArguments
->Edx
;
292 BiosContext
.Esi
= BiosArguments
->Esi
;
293 BiosContext
.Edi
= BiosArguments
->Edi
;
294 BiosContext
.Ebp
= BiosArguments
->Ebp
;
295 BiosContext
.SegDs
= BiosArguments
->SegDs
;
296 BiosContext
.SegEs
= BiosArguments
->SegEs
;
298 /* Do the ROM BIOS call */
299 (void)KeWaitForMutexObject(&VideoPortInt10Mutex
, Executive
, KernelMode
, FALSE
, NULL
);
300 Status
= Ke386CallBios(0x10, &BiosContext
);
301 KeReleaseMutex(&VideoPortInt10Mutex
, FALSE
);
303 /* Return the arguments */
304 BiosArguments
->Eax
= BiosContext
.Eax
;
305 BiosArguments
->Ebx
= BiosContext
.Ebx
;
306 BiosArguments
->Ecx
= BiosContext
.Ecx
;
307 BiosArguments
->Edx
= BiosContext
.Edx
;
308 BiosArguments
->Esi
= BiosContext
.Esi
;
309 BiosArguments
->Edi
= BiosContext
.Edi
;
310 BiosArguments
->Ebp
= BiosContext
.Ebp
;
311 BiosArguments
->SegDs
= (USHORT
)BiosContext
.SegDs
;
312 BiosArguments
->SegEs
= (USHORT
)BiosContext
.SegEs
;
314 /* Detach and return status */
315 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
316 if (NT_SUCCESS(Status
)) return NO_ERROR
;
317 return ERROR_INVALID_PARAMETER
;
321 /* PUBLIC FUNCTIONS ***********************************************************/
329 IN PVOID HwDeviceExtension
,
330 IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments
)
335 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
338 if (!CsrssInitialized
)
340 return ERROR_INVALID_PARAMETER
;
343 /* Attach to CSRSS */
344 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
346 /* Clear the context */
347 RtlZeroMemory(&BiosContext
, sizeof(CONTEXT
));
349 /* Fill out the bios arguments */
350 BiosContext
.Eax
= BiosArguments
->Eax
;
351 BiosContext
.Ebx
= BiosArguments
->Ebx
;
352 BiosContext
.Ecx
= BiosArguments
->Ecx
;
353 BiosContext
.Edx
= BiosArguments
->Edx
;
354 BiosContext
.Esi
= BiosArguments
->Esi
;
355 BiosContext
.Edi
= BiosArguments
->Edi
;
356 BiosContext
.Ebp
= BiosArguments
->Ebp
;
358 /* Do the ROM BIOS call */
359 (void)KeWaitForMutexObject(&VideoPortInt10Mutex
, Executive
, KernelMode
, FALSE
, NULL
);
360 Status
= Ke386CallBios(0x10, &BiosContext
);
361 KeReleaseMutex(&VideoPortInt10Mutex
, FALSE
);
363 /* Return the arguments */
364 BiosArguments
->Eax
= BiosContext
.Eax
;
365 BiosArguments
->Ebx
= BiosContext
.Ebx
;
366 BiosArguments
->Ecx
= BiosContext
.Ecx
;
367 BiosArguments
->Edx
= BiosContext
.Edx
;
368 BiosArguments
->Esi
= BiosContext
.Esi
;
369 BiosArguments
->Edi
= BiosContext
.Edi
;
370 BiosArguments
->Ebp
= BiosContext
.Ebp
;
372 /* Detach from CSRSS */
373 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
374 if (NT_SUCCESS(Status
)) return NO_ERROR
;
375 return ERROR_INVALID_PARAMETER
;
377 /* Not implemented for anything else than X86*/
378 DPRINT1("Int10 not available on non-x86!\n");
379 return ERROR_INVALID_FUNCTION
;