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
;
155 IntInt10AllocateBuffer(
159 IN OUT PULONG Length
)
163 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
167 TRACE_(VIDEOPRT
, "IntInt10AllocateBuffer\n");
169 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
172 MemoryAddress
= (PVOID
)0x20000;
173 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
178 PAGE_EXECUTE_READWRITE
);
179 if (!NT_SUCCESS(Status
))
181 WARN_(VIDEOPRT
, "- ZwAllocateVirtualMemory failed\n");
182 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
183 return ERROR_NOT_ENOUGH_MEMORY
;
186 if (MemoryAddress
> (PVOID
)(0x100000 - Size
))
188 ZwFreeVirtualMemory(NtCurrentProcess(),
192 WARN_(VIDEOPRT
, "- Unacceptable memory allocated\n");
193 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
194 return ERROR_NOT_ENOUGH_MEMORY
;
197 *Length
= (ULONG
)Size
;
198 *Seg
= (USHORT
)((ULONG_PTR
)MemoryAddress
>> 4);
199 *Off
= (USHORT
)((ULONG_PTR
)MemoryAddress
& 0xF);
201 INFO_(VIDEOPRT
, "- Segment: %x\n", (ULONG_PTR
)MemoryAddress
>> 4);
202 INFO_(VIDEOPRT
, "- Offset: %x\n", (ULONG_PTR
)MemoryAddress
& 0xF);
203 INFO_(VIDEOPRT
, "- Length: %x\n", *Length
);
205 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
217 PVOID MemoryAddress
= (PVOID
)((ULONG_PTR
)(Seg
<< 4) | Off
);
219 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
223 TRACE_(VIDEOPRT
, "IntInt10FreeBuffer\n");
224 INFO_(VIDEOPRT
, "- Segment: %x\n", Seg
);
225 INFO_(VIDEOPRT
, "- Offset: %x\n", Off
);
227 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
228 Status
= ZwFreeVirtualMemory(NtCurrentProcess(),
233 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
247 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
250 TRACE_(VIDEOPRT
, "IntInt10ReadMemory\n");
251 INFO_(VIDEOPRT
, "- Segment: %x\n", Seg
);
252 INFO_(VIDEOPRT
, "- Offset: %x\n", Off
);
253 INFO_(VIDEOPRT
, "- Buffer: %x\n", Buffer
);
254 INFO_(VIDEOPRT
, "- Length: %x\n", Length
);
256 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
257 RtlCopyMemory(Buffer
, (PVOID
)((ULONG_PTR
)(Seg
<< 4) | Off
), Length
);
258 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
272 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
275 TRACE_(VIDEOPRT
, "IntInt10WriteMemory\n");
276 INFO_(VIDEOPRT
, "- Segment: %x\n", Seg
);
277 INFO_(VIDEOPRT
, "- Offset: %x\n", Off
);
278 INFO_(VIDEOPRT
, "- Buffer: %x\n", Buffer
);
279 INFO_(VIDEOPRT
, "- Length: %x\n", Length
);
281 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
282 RtlCopyMemory((PVOID
)((ULONG_PTR
)(Seg
<< 4) | Off
), Buffer
, Length
);
283 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
293 IN OUT PINT10_BIOS_ARGUMENTS BiosArguments
)
297 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
300 /* Attach to CSRSS */
301 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
303 /* Clear the context */
304 RtlZeroMemory(&BiosContext
, sizeof(BiosContext
));
306 /* Fill out the bios arguments */
307 BiosContext
.Eax
= BiosArguments
->Eax
;
308 BiosContext
.Ebx
= BiosArguments
->Ebx
;
309 BiosContext
.Ecx
= BiosArguments
->Ecx
;
310 BiosContext
.Edx
= BiosArguments
->Edx
;
311 BiosContext
.Esi
= BiosArguments
->Esi
;
312 BiosContext
.Edi
= BiosArguments
->Edi
;
313 BiosContext
.Ebp
= BiosArguments
->Ebp
;
314 BiosContext
.SegDs
= BiosArguments
->SegDs
;
315 BiosContext
.SegEs
= BiosArguments
->SegEs
;
317 /* Do the ROM BIOS call */
318 (void)KeWaitForMutexObject(&VideoPortInt10Mutex
,
324 Status
= Ke386CallBios(0x10, &BiosContext
);
326 KeReleaseMutex(&VideoPortInt10Mutex
, FALSE
);
328 /* Return the arguments */
329 BiosArguments
->Eax
= BiosContext
.Eax
;
330 BiosArguments
->Ebx
= BiosContext
.Ebx
;
331 BiosArguments
->Ecx
= BiosContext
.Ecx
;
332 BiosArguments
->Edx
= BiosContext
.Edx
;
333 BiosArguments
->Esi
= BiosContext
.Esi
;
334 BiosArguments
->Edi
= BiosContext
.Edi
;
335 BiosArguments
->Ebp
= BiosContext
.Ebp
;
336 BiosArguments
->SegDs
= (USHORT
)BiosContext
.SegDs
;
337 BiosArguments
->SegEs
= (USHORT
)BiosContext
.SegEs
;
339 /* Detach and return status */
340 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
342 if (NT_SUCCESS(Status
))
347 return ERROR_INVALID_PARAMETER
;
354 IN OUT PINT10_BIOS_ARGUMENTS BiosArguments
)
356 DPRINT1("Int10 not available on non-x86!\n");
357 return ERROR_INVALID_FUNCTION
;
361 /* PUBLIC FUNCTIONS ***********************************************************/
369 IN PVOID HwDeviceExtension
,
370 IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments
)
372 INT10_BIOS_ARGUMENTS Int10BiosArguments
;
375 if (!CsrssInitialized
)
377 return ERROR_INVALID_PARAMETER
;
380 /* Copy arguments to other format */
381 RtlCopyMemory(&Int10BiosArguments
, BiosArguments
, sizeof(BiosArguments
));
382 Int10BiosArguments
.SegDs
= 0;
383 Int10BiosArguments
.SegEs
= 0;
385 /* Do the BIOS call */
386 Status
= IntInt10CallBios(NULL
, &Int10BiosArguments
);
388 /* Copy results back */
389 RtlCopyMemory(BiosArguments
, &Int10BiosArguments
, sizeof(BiosArguments
));