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
,
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
;
142 IntInt10AllocateBuffer(
146 IN OUT PULONG Length
)
150 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
153 TRACE_(VIDEOPRT
, "IntInt10AllocateBuffer\n");
155 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
157 MemoryAddress
= (PVOID
)0x20000;
158 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(), &MemoryAddress
, 0,
159 Length
, MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
161 if (!NT_SUCCESS(Status
))
163 WARN_(VIDEOPRT
, "- ZwAllocateVirtualMemory failed\n");
164 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
165 return ERROR_NOT_ENOUGH_MEMORY
;
168 if (MemoryAddress
> (PVOID
)(0x100000 - *Length
))
170 ZwFreeVirtualMemory(NtCurrentProcess(), &MemoryAddress
, Length
,
172 WARN_(VIDEOPRT
, "- Unacceptable memory allocated\n");
173 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
174 return ERROR_NOT_ENOUGH_MEMORY
;
177 *Seg
= (USHORT
)((ULONG
)MemoryAddress
>> 4);
178 *Off
= (USHORT
)((ULONG
)MemoryAddress
& 0xF);
180 INFO_(VIDEOPRT
, "- Segment: %x\n", (ULONG
)MemoryAddress
>> 4);
181 INFO_(VIDEOPRT
, "- Offset: %x\n", (ULONG
)MemoryAddress
& 0xF);
182 INFO_(VIDEOPRT
, "- Length: %x\n", *Length
);
184 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
195 PVOID MemoryAddress
= (PVOID
)((Seg
<< 4) | Off
);
197 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
201 TRACE_(VIDEOPRT
, "IntInt10FreeBuffer\n");
202 INFO_(VIDEOPRT
, "- Segment: %x\n", Seg
);
203 INFO_(VIDEOPRT
, "- Offset: %x\n", Off
);
205 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
206 Status
= ZwFreeVirtualMemory(NtCurrentProcess(), &MemoryAddress
, &Size
,
208 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
221 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
224 TRACE_(VIDEOPRT
, "IntInt10ReadMemory\n");
225 INFO_(VIDEOPRT
, "- Segment: %x\n", Seg
);
226 INFO_(VIDEOPRT
, "- Offset: %x\n", Off
);
227 INFO_(VIDEOPRT
, "- Buffer: %x\n", Buffer
);
228 INFO_(VIDEOPRT
, "- Length: %x\n", Length
);
230 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
231 RtlCopyMemory(Buffer
, (PVOID
)((Seg
<< 4) | Off
), Length
);
232 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
245 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
248 TRACE_(VIDEOPRT
, "IntInt10WriteMemory\n");
249 INFO_(VIDEOPRT
, "- Segment: %x\n", Seg
);
250 INFO_(VIDEOPRT
, "- Offset: %x\n", Off
);
251 INFO_(VIDEOPRT
, "- Buffer: %x\n", Buffer
);
252 INFO_(VIDEOPRT
, "- Length: %x\n", Length
);
254 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
255 RtlCopyMemory((PVOID
)((Seg
<< 4) | Off
), Buffer
, Length
);
256 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
265 IN OUT PINT10_BIOS_ARGUMENTS BiosArguments
)
269 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
272 /* Attach to CSRSS */
273 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
275 /* Clear the context */
276 RtlZeroMemory(&BiosContext
, sizeof(CONTEXT
));
278 /* Fill out the bios arguments */
279 BiosContext
.Eax
= BiosArguments
->Eax
;
280 BiosContext
.Ebx
= BiosArguments
->Ebx
;
281 BiosContext
.Ecx
= BiosArguments
->Ecx
;
282 BiosContext
.Edx
= BiosArguments
->Edx
;
283 BiosContext
.Esi
= BiosArguments
->Esi
;
284 BiosContext
.Edi
= BiosArguments
->Edi
;
285 BiosContext
.Ebp
= BiosArguments
->Ebp
;
286 BiosContext
.SegDs
= BiosArguments
->SegDs
;
287 BiosContext
.SegEs
= BiosArguments
->SegEs
;
289 /* Do the ROM BIOS call */
290 Status
= Ke386CallBios(0x10, &BiosContext
);
292 /* Return the arguments */
293 BiosArguments
->Eax
= BiosContext
.Eax
;
294 BiosArguments
->Ebx
= BiosContext
.Ebx
;
295 BiosArguments
->Ecx
= BiosContext
.Ecx
;
296 BiosArguments
->Edx
= BiosContext
.Edx
;
297 BiosArguments
->Esi
= BiosContext
.Esi
;
298 BiosArguments
->Edi
= BiosContext
.Edi
;
299 BiosArguments
->Ebp
= BiosContext
.Ebp
;
300 BiosArguments
->SegDs
= (USHORT
)BiosContext
.SegDs
;
301 BiosArguments
->SegEs
= (USHORT
)BiosContext
.SegEs
;
303 /* Detach and return status */
304 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
305 if (NT_SUCCESS(Status
)) return NO_ERROR
;
306 return ERROR_INVALID_PARAMETER
;
310 /* PUBLIC FUNCTIONS ***********************************************************/
318 IN PVOID HwDeviceExtension
,
319 IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments
)
324 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
327 if (!CsrssInitialized
)
329 return ERROR_INVALID_PARAMETER
;
332 /* Attach to CSRSS */
333 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
335 /* Clear the context */
336 RtlZeroMemory(&BiosContext
, sizeof(CONTEXT
));
338 /* Fill out the bios arguments */
339 BiosContext
.Eax
= BiosArguments
->Eax
;
340 BiosContext
.Ebx
= BiosArguments
->Ebx
;
341 BiosContext
.Ecx
= BiosArguments
->Ecx
;
342 BiosContext
.Edx
= BiosArguments
->Edx
;
343 BiosContext
.Esi
= BiosArguments
->Esi
;
344 BiosContext
.Edi
= BiosArguments
->Edi
;
345 BiosContext
.Ebp
= BiosArguments
->Ebp
;
347 /* Do the ROM BIOS call */
348 Status
= Ke386CallBios(0x10, &BiosContext
);
350 /* Return the arguments */
351 BiosArguments
->Eax
= BiosContext
.Eax
;
352 BiosArguments
->Ebx
= BiosContext
.Ebx
;
353 BiosArguments
->Ecx
= BiosContext
.Ecx
;
354 BiosArguments
->Edx
= BiosContext
.Edx
;
355 BiosArguments
->Esi
= BiosContext
.Esi
;
356 BiosArguments
->Edi
= BiosContext
.Edi
;
357 BiosArguments
->Ebp
= BiosContext
.Ebp
;
359 /* Detach from CSRSS */
360 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
361 if (NT_SUCCESS(Status
)) return NO_ERROR
;
362 return ERROR_INVALID_PARAMETER
;
364 /* Not implemented for anything else than X86*/
365 DPRINT1("Int10 not available on non-x86!\n");
366 return ERROR_INVALID_FUNCTION
;