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 /* PRIVATE FUNCTIONS **********************************************************/
26 #if defined(_M_IX86) || defined(_M_AMD64)
29 IntInitializeVideoAddressSpace(VOID
)
31 OBJECT_ATTRIBUTES ObjectAttributes
;
32 UNICODE_STRING PhysMemName
= RTL_CONSTANT_STRING(L
"\\Device\\PhysicalMemory");
38 CHAR IVTAndBda
[1024+256];
40 /* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */
42 ViewSize
= 1024 * 1024;
43 Status
= ZwFreeVirtualMemory(NtCurrentProcess(),
47 if (!NT_SUCCESS(Status
))
49 DPRINT1("Couldn't unmap reserved memory (%x)\n", Status
);
53 /* Open the physical memory section */
54 InitializeObjectAttributes(&ObjectAttributes
,
59 Status
= ZwOpenSection(&PhysMemHandle
,
62 if (!NT_SUCCESS(Status
))
64 DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
68 /* Map the BIOS and device registers into the address space */
69 Offset
.QuadPart
= 0xa0000;
70 ViewSize
= 0x100000 - 0xa0000;
71 BaseAddress
= (PVOID
)0xa0000;
72 Status
= ZwMapViewOfSection(PhysMemHandle
,
81 PAGE_EXECUTE_READWRITE
);
82 if (!NT_SUCCESS(Status
))
84 DPRINT1("Couldn't map physical memory (%x)\n", Status
);
85 ZwClose(PhysMemHandle
);
89 /* Close physical memory section handle */
90 ZwClose(PhysMemHandle
);
92 if (BaseAddress
!= (PVOID
)0xa0000)
94 DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
96 return STATUS_UNSUCCESSFUL
;
99 /* Allocate some low memory to use for the non-BIOS
100 * parts of the v86 mode address space
102 BaseAddress
= (PVOID
)0x1;
103 ViewSize
= 0xa0000 - 0x1000;
104 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(),
108 MEM_RESERVE
| MEM_COMMIT
,
109 PAGE_EXECUTE_READWRITE
);
110 if (!NT_SUCCESS(Status
))
112 DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status
);
115 if (BaseAddress
!= (PVOID
)0x0)
117 DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
122 /* Get the real mode IVT and BDA from the kernel */
123 Status
= NtVdmControl(VdmInitialize
, IVTAndBda
);
124 if (!NT_SUCCESS(Status
))
126 DPRINT1("NtVdmControl failed (status %x)\n", Status
);
131 return STATUS_SUCCESS
;
137 IntInt10AllocateBuffer(
141 IN OUT PULONG Length
)
145 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
148 TRACE_(VIDEOPRT
, "IntInt10AllocateBuffer\n");
150 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
152 MemoryAddress
= (PVOID
)0x20000;
153 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(), &MemoryAddress
, 0,
154 Length
, MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
156 if (!NT_SUCCESS(Status
))
158 WARN_(VIDEOPRT
, "- ZwAllocateVirtualMemory failed\n");
159 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
160 return ERROR_NOT_ENOUGH_MEMORY
;
163 if (MemoryAddress
> (PVOID
)(0x100000 - *Length
))
165 ZwFreeVirtualMemory(NtCurrentProcess(), &MemoryAddress
, Length
,
167 WARN_(VIDEOPRT
, "- Unacceptable memory allocated\n");
168 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
169 return ERROR_NOT_ENOUGH_MEMORY
;
172 *Seg
= (USHORT
)((ULONG
)MemoryAddress
>> 4);
173 *Off
= (USHORT
)((ULONG
)MemoryAddress
& 0xF);
175 INFO_(VIDEOPRT
, "- Segment: %x\n", (ULONG
)MemoryAddress
>> 4);
176 INFO_(VIDEOPRT
, "- Offset: %x\n", (ULONG
)MemoryAddress
& 0xF);
177 INFO_(VIDEOPRT
, "- Length: %x\n", *Length
);
179 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
190 PVOID MemoryAddress
= (PVOID
)((Seg
<< 4) | Off
);
192 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
196 TRACE_(VIDEOPRT
, "IntInt10FreeBuffer\n");
197 INFO_(VIDEOPRT
, "- Segment: %x\n", Seg
);
198 INFO_(VIDEOPRT
, "- Offset: %x\n", Off
);
200 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
201 Status
= ZwFreeVirtualMemory(NtCurrentProcess(), &MemoryAddress
, &Size
,
203 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
216 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
219 TRACE_(VIDEOPRT
, "IntInt10ReadMemory\n");
220 INFO_(VIDEOPRT
, "- Segment: %x\n", Seg
);
221 INFO_(VIDEOPRT
, "- Offset: %x\n", Off
);
222 INFO_(VIDEOPRT
, "- Buffer: %x\n", Buffer
);
223 INFO_(VIDEOPRT
, "- Length: %x\n", Length
);
225 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
226 RtlCopyMemory(Buffer
, (PVOID
)((Seg
<< 4) | Off
), Length
);
227 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
240 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
243 TRACE_(VIDEOPRT
, "IntInt10WriteMemory\n");
244 INFO_(VIDEOPRT
, "- Segment: %x\n", Seg
);
245 INFO_(VIDEOPRT
, "- Offset: %x\n", Off
);
246 INFO_(VIDEOPRT
, "- Buffer: %x\n", Buffer
);
247 INFO_(VIDEOPRT
, "- Length: %x\n", Length
);
249 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
250 RtlCopyMemory((PVOID
)((Seg
<< 4) | Off
), Buffer
, Length
);
251 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
260 IN OUT PINT10_BIOS_ARGUMENTS BiosArguments
)
264 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
267 /* Attach to CSRSS */
268 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
270 /* Clear the context */
271 RtlZeroMemory(&BiosContext
, sizeof(CONTEXT
));
273 /* Fill out the bios arguments */
274 BiosContext
.Eax
= BiosArguments
->Eax
;
275 BiosContext
.Ebx
= BiosArguments
->Ebx
;
276 BiosContext
.Ecx
= BiosArguments
->Ecx
;
277 BiosContext
.Edx
= BiosArguments
->Edx
;
278 BiosContext
.Esi
= BiosArguments
->Esi
;
279 BiosContext
.Edi
= BiosArguments
->Edi
;
280 BiosContext
.Ebp
= BiosArguments
->Ebp
;
281 BiosContext
.SegDs
= BiosArguments
->SegDs
;
282 BiosContext
.SegEs
= BiosArguments
->SegEs
;
284 /* Do the ROM BIOS call */
285 Status
= Ke386CallBios(0x10, &BiosContext
);
287 /* Return the arguments */
288 BiosArguments
->Eax
= BiosContext
.Eax
;
289 BiosArguments
->Ebx
= BiosContext
.Ebx
;
290 BiosArguments
->Ecx
= BiosContext
.Ecx
;
291 BiosArguments
->Edx
= BiosContext
.Edx
;
292 BiosArguments
->Esi
= BiosContext
.Esi
;
293 BiosArguments
->Edi
= BiosContext
.Edi
;
294 BiosArguments
->Ebp
= BiosContext
.Ebp
;
295 BiosArguments
->SegDs
= (USHORT
)BiosContext
.SegDs
;
296 BiosArguments
->SegEs
= (USHORT
)BiosContext
.SegEs
;
298 /* Detach and return status */
299 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
300 if (NT_SUCCESS(Status
)) return NO_ERROR
;
301 return ERROR_INVALID_PARAMETER
;
305 /* PUBLIC FUNCTIONS ***********************************************************/
313 IN PVOID HwDeviceExtension
,
314 IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments
)
319 PKPROCESS CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
322 if (!CsrssInitialized
)
324 return ERROR_INVALID_PARAMETER
;
327 /* Attach to CSRSS */
328 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
330 /* Clear the context */
331 RtlZeroMemory(&BiosContext
, sizeof(CONTEXT
));
333 /* Fill out the bios arguments */
334 BiosContext
.Eax
= BiosArguments
->Eax
;
335 BiosContext
.Ebx
= BiosArguments
->Ebx
;
336 BiosContext
.Ecx
= BiosArguments
->Ecx
;
337 BiosContext
.Edx
= BiosArguments
->Edx
;
338 BiosContext
.Esi
= BiosArguments
->Esi
;
339 BiosContext
.Edi
= BiosArguments
->Edi
;
340 BiosContext
.Ebp
= BiosArguments
->Ebp
;
342 /* Do the ROM BIOS call */
343 Status
= Ke386CallBios(0x10, &BiosContext
);
345 /* Return the arguments */
346 BiosArguments
->Eax
= BiosContext
.Eax
;
347 BiosArguments
->Ebx
= BiosContext
.Ebx
;
348 BiosArguments
->Ecx
= BiosContext
.Ecx
;
349 BiosArguments
->Edx
= BiosContext
.Edx
;
350 BiosArguments
->Esi
= BiosContext
.Esi
;
351 BiosArguments
->Edi
= BiosContext
.Edi
;
352 BiosArguments
->Ebp
= BiosContext
.Ebp
;
354 /* Detach from CSRSS */
355 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
356 if (NT_SUCCESS(Status
)) return NO_ERROR
;
357 return ERROR_INVALID_PARAMETER
;
359 /* Not implemented for anything else than X86*/
360 DPRINT1("Int10 not available on non-x86!\n");
361 return ERROR_INVALID_FUNCTION
;