Sync with trunk (r49303)
[reactos.git] / drivers / video / videoprt / int10.c
1 /*
2 * VideoPort driver
3 *
4 * Copyright (C) 2002, 2003, 2004 ReactOS Team
5 *
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.
10 *
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.
15 *
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
19 *
20 */
21
22 #include "videoprt.h"
23
24 /* PRIVATE FUNCTIONS **********************************************************/
25
26 #if defined(_M_IX86)
27 VP_STATUS NTAPI
28 IntInt10AllocateBuffer(
29 IN PVOID Context,
30 OUT PUSHORT Seg,
31 OUT PUSHORT Off,
32 IN OUT PULONG Length)
33 {
34 PVOID MemoryAddress;
35 NTSTATUS Status;
36 PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
37 KAPC_STATE ApcState;
38
39 TRACE_(VIDEOPRT, "IntInt10AllocateBuffer\n");
40
41 IntAttachToCSRSS(&CallingProcess, &ApcState);
42
43 MemoryAddress = (PVOID)0x20000;
44 Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &MemoryAddress, 0,
45 Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
46
47 if (!NT_SUCCESS(Status))
48 {
49 WARN_(VIDEOPRT, "- ZwAllocateVirtualMemory failed\n");
50 IntDetachFromCSRSS(&CallingProcess, &ApcState);
51 return ERROR_NOT_ENOUGH_MEMORY;
52 }
53
54 if (MemoryAddress > (PVOID)(0x100000 - *Length))
55 {
56 ZwFreeVirtualMemory(NtCurrentProcess(), &MemoryAddress, Length,
57 MEM_RELEASE);
58 WARN_(VIDEOPRT, "- Unacceptable memory allocated\n");
59 IntDetachFromCSRSS(&CallingProcess, &ApcState);
60 return ERROR_NOT_ENOUGH_MEMORY;
61 }
62
63 *Seg = (ULONG)MemoryAddress >> 4;
64 *Off = (ULONG)MemoryAddress & 0xF;
65
66 INFO_(VIDEOPRT, "- Segment: %x\n", (ULONG)MemoryAddress >> 4);
67 INFO_(VIDEOPRT, "- Offset: %x\n", (ULONG)MemoryAddress & 0xF);
68 INFO_(VIDEOPRT, "- Length: %x\n", *Length);
69
70 IntDetachFromCSRSS(&CallingProcess, &ApcState);
71
72 return NO_ERROR;
73 }
74
75 VP_STATUS NTAPI
76 IntInt10FreeBuffer(
77 IN PVOID Context,
78 IN USHORT Seg,
79 IN USHORT Off)
80 {
81 PVOID MemoryAddress = (PVOID)((Seg << 4) | Off);
82 NTSTATUS Status;
83 PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
84 KAPC_STATE ApcState;
85
86 TRACE_(VIDEOPRT, "IntInt10FreeBuffer\n");
87 INFO_(VIDEOPRT, "- Segment: %x\n", Seg);
88 INFO_(VIDEOPRT, "- Offset: %x\n", Off);
89
90 IntAttachToCSRSS(&CallingProcess, &ApcState);
91 Status = ZwFreeVirtualMemory(NtCurrentProcess(), &MemoryAddress, 0,
92 MEM_RELEASE);
93 IntDetachFromCSRSS(&CallingProcess, &ApcState);
94
95 return Status;
96 }
97
98 VP_STATUS NTAPI
99 IntInt10ReadMemory(
100 IN PVOID Context,
101 IN USHORT Seg,
102 IN USHORT Off,
103 OUT PVOID Buffer,
104 IN ULONG Length)
105 {
106 PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
107 KAPC_STATE ApcState;
108
109 TRACE_(VIDEOPRT, "IntInt10ReadMemory\n");
110 INFO_(VIDEOPRT, "- Segment: %x\n", Seg);
111 INFO_(VIDEOPRT, "- Offset: %x\n", Off);
112 INFO_(VIDEOPRT, "- Buffer: %x\n", Buffer);
113 INFO_(VIDEOPRT, "- Length: %x\n", Length);
114
115 IntAttachToCSRSS(&CallingProcess, &ApcState);
116 RtlCopyMemory(Buffer, (PVOID)((Seg << 4) | Off), Length);
117 IntDetachFromCSRSS(&CallingProcess, &ApcState);
118
119 return NO_ERROR;
120 }
121
122 VP_STATUS NTAPI
123 IntInt10WriteMemory(
124 IN PVOID Context,
125 IN USHORT Seg,
126 IN USHORT Off,
127 IN PVOID Buffer,
128 IN ULONG Length)
129 {
130 PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
131 KAPC_STATE ApcState;
132
133 TRACE_(VIDEOPRT, "IntInt10WriteMemory\n");
134 INFO_(VIDEOPRT, "- Segment: %x\n", Seg);
135 INFO_(VIDEOPRT, "- Offset: %x\n", Off);
136 INFO_(VIDEOPRT, "- Buffer: %x\n", Buffer);
137 INFO_(VIDEOPRT, "- Length: %x\n", Length);
138
139 IntAttachToCSRSS(&CallingProcess, &ApcState);
140 RtlCopyMemory((PVOID)((Seg << 4) | Off), Buffer, Length);
141 IntDetachFromCSRSS(&CallingProcess, &ApcState);
142
143 return NO_ERROR;
144 }
145
146 VP_STATUS
147 NTAPI
148 IntInt10CallBios(
149 IN PVOID Context,
150 IN OUT PINT10_BIOS_ARGUMENTS BiosArguments)
151 {
152 CONTEXT BiosContext;
153 NTSTATUS Status;
154 PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
155 KAPC_STATE ApcState;
156
157 /* Attach to CSRSS */
158 IntAttachToCSRSS(&CallingProcess, &ApcState);
159
160 /* Clear the context */
161 RtlZeroMemory(&BiosContext, sizeof(CONTEXT));
162
163 /* Fill out the bios arguments */
164 BiosContext.Eax = BiosArguments->Eax;
165 BiosContext.Ebx = BiosArguments->Ebx;
166 BiosContext.Ecx = BiosArguments->Ecx;
167 BiosContext.Edx = BiosArguments->Edx;
168 BiosContext.Esi = BiosArguments->Esi;
169 BiosContext.Edi = BiosArguments->Edi;
170 BiosContext.Ebp = BiosArguments->Ebp;
171 BiosContext.SegDs = BiosArguments->SegDs;
172 BiosContext.SegEs = BiosArguments->SegEs;
173
174 /* Do the ROM BIOS call */
175 Status = Ke386CallBios(0x10, &BiosContext);
176
177 /* Return the arguments */
178 BiosArguments->Eax = BiosContext.Eax;
179 BiosArguments->Ebx = BiosContext.Ebx;
180 BiosArguments->Ecx = BiosContext.Ecx;
181 BiosArguments->Edx = BiosContext.Edx;
182 BiosArguments->Esi = BiosContext.Esi;
183 BiosArguments->Edi = BiosContext.Edi;
184 BiosArguments->Ebp = BiosContext.Ebp;
185 BiosArguments->SegDs = BiosContext.SegDs;
186 BiosArguments->SegEs = BiosContext.SegEs;
187
188 /* Detach and return status */
189 IntDetachFromCSRSS(&CallingProcess, &ApcState);
190 if (NT_SUCCESS(Status)) return NO_ERROR;
191 return ERROR_INVALID_PARAMETER;
192 }
193 #endif
194
195 /* PUBLIC FUNCTIONS ***********************************************************/
196
197 /*
198 * @implemented
199 */
200
201 VP_STATUS NTAPI
202 VideoPortInt10(
203 IN PVOID HwDeviceExtension,
204 IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments)
205 {
206 #if defined(_M_IX86)
207 CONTEXT BiosContext;
208 NTSTATUS Status;
209 PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
210 KAPC_STATE ApcState;
211
212 if (!CsrssInitialized)
213 {
214 return ERROR_INVALID_PARAMETER;
215 }
216
217 /* Attach to CSRSS */
218 IntAttachToCSRSS(&CallingProcess, &ApcState);
219
220 /* Clear the context */
221 RtlZeroMemory(&BiosContext, sizeof(CONTEXT));
222
223 /* Fill out the bios arguments */
224 BiosContext.Eax = BiosArguments->Eax;
225 BiosContext.Ebx = BiosArguments->Ebx;
226 BiosContext.Ecx = BiosArguments->Ecx;
227 BiosContext.Edx = BiosArguments->Edx;
228 BiosContext.Esi = BiosArguments->Esi;
229 BiosContext.Edi = BiosArguments->Edi;
230 BiosContext.Ebp = BiosArguments->Ebp;
231
232 /* Do the ROM BIOS call */
233 Status = Ke386CallBios(0x10, &BiosContext);
234
235 /* Return the arguments */
236 BiosArguments->Eax = BiosContext.Eax;
237 BiosArguments->Ebx = BiosContext.Ebx;
238 BiosArguments->Ecx = BiosContext.Ecx;
239 BiosArguments->Edx = BiosContext.Edx;
240 BiosArguments->Esi = BiosContext.Esi;
241 BiosArguments->Edi = BiosContext.Edi;
242 BiosArguments->Ebp = BiosContext.Ebp;
243
244 /* Detach from CSRSS */
245 IntDetachFromCSRSS(&CallingProcess, &ApcState);
246 if (NT_SUCCESS(Status)) return NO_ERROR;
247 return ERROR_INVALID_PARAMETER;
248 #else
249 /* Not implemented for anything else than X86*/
250 DPRINT1("Int10 not available on non-x86!\n");
251 return ERROR_INVALID_FUNCTION;
252 #endif
253 }