1 /*
2 * PROJECT: ReactOS VGA Miniport Driver
3 * LICENSE: Microsoft NT4 DDK Sample Code License
4 * FILE: win32ss/drivers/miniport/vga_new/vga.c
5 * PURPOSE: Main Standard VGA-compatible Minport Handling Code
6 * PROGRAMMERS: Copyright (c) 1992 Microsoft Corporation
7 * ReactOS Portable Systems Group
8 */
9
10 //---------------------------------------------------------------------------
11
12 #include "vga.h"
13
14 #include <devioctl.h>
15
16 //---------------------------------------------------------------------------
17 //
18 // Function declarations
19 //
20 // Functions that start with 'VGA' are entry points for the OS port driver.
21 //
22
23 VP_STATUS
24 NTAPI
25 VgaFindAdapter(
26 PVOID HwDeviceExtension,
27 PVOID HwContext,
28 PWSTR ArgumentString,
29 PVIDEO_PORT_CONFIG_INFO ConfigInfo,
30 PUCHAR Again
31 );
32
33 BOOLEAN
34 NTAPI
35 VgaInitialize(
36 PVOID HwDeviceExtension
37 );
38
39 BOOLEAN
40 NTAPI
41 VgaStartIO(
42 PVOID HwDeviceExtension,
43 PVIDEO_REQUEST_PACKET RequestPacket
44 );
45
46 //
47 // Private function prototypes.
48 //
49
50 VP_STATUS
51 NTAPI
52 VgaQueryAvailableModes(
53 PHW_DEVICE_EXTENSION HwDeviceExtension,
54 PVIDEO_MODE_INFORMATION ModeInformation,
55 ULONG ModeInformationSize,
56 PULONG_PTR OutputSize
57 );
58
59 VP_STATUS
60 NTAPI
61 VgaQueryNumberOfAvailableModes(
62 PHW_DEVICE_EXTENSION HwDeviceExtension,
63 PVIDEO_NUM_MODES NumModes,
64 ULONG NumModesSize,
65 PULONG_PTR OutputSize
66 );
67
68 VP_STATUS
69 NTAPI
70 VgaQueryCurrentMode(
71 PHW_DEVICE_EXTENSION HwDeviceExtension,
72 PVIDEO_MODE_INFORMATION ModeInformation,
73 ULONG ModeInformationSize,
74 PULONG_PTR OutputSize
75 );
76
77 VP_STATUS
78 NTAPI
79 VgaSetMode(
80 PHW_DEVICE_EXTENSION HwDeviceExtension,
81 PVIDEO_MODE Mode,
82 ULONG ModeSize,
83 // eVb: 1.1 [SET MODE] - Add new output parameter for framebuffer update functionality
84 PULONG PhysPtrChange
85 // eVb: 1.1 [END]
86 );
87
88 BOOLEAN
89 NTAPI
90 VgaIsPresent(
91 PHW_DEVICE_EXTENSION HwDeviceExtension
92 );
93
94 VP_STATUS
95 NTAPI
96 VgaInterpretCmdStream(
97 PHW_DEVICE_EXTENSION HwDeviceExtension,
98 PUSHORT pusCmdStream
99 );
100
101 VP_STATUS
102 NTAPI
103 VgaSetPaletteReg(
104 PHW_DEVICE_EXTENSION HwDeviceExtension,
105 PVIDEO_PALETTE_DATA PaletteBuffer,
106 ULONG PaletteBufferSize
107 );
108
109 VP_STATUS
110 NTAPI
111 VgaSetColorLookup(
112 PHW_DEVICE_EXTENSION HwDeviceExtension,
113 PVIDEO_CLUT ClutBuffer,
114 ULONG ClutBufferSize
115 );
116
117 VP_STATUS
118 NTAPI
119 GetDeviceDataCallback(
120 PVOID HwDeviceExtension,
121 PVOID Context,
122 VIDEO_DEVICE_DATA_TYPE DeviceDataType,
123 PVOID Identifier,
124 ULONG IdentifierLength,
125 PVOID ConfigurationData,
126 ULONG ConfigurationDataLength,
127 PVOID ComponentInformation,
128 ULONG ComponentInformationLength
129 );
130
131 // eVb: 1.2 [RESOURCE] - Add new function for acquiring VGA resources (I/O, memory)
132 VP_STATUS
133 NTAPI
134 VgaAcquireResources(
135 PHW_DEVICE_EXTENSION DeviceExtension
136 );
137 // eVb: 1.2 [END]
138
139 #if defined(ALLOC_PRAGMA)
140 #pragma alloc_text(PAGE,DriverEntry)
141 #pragma alloc_text(PAGE,VgaFindAdapter)
142 #pragma alloc_text(PAGE,VgaInitialize)
143 #pragma alloc_text(PAGE,VgaStartIO)
144 #pragma alloc_text(PAGE,VgaIsPresent)
145 #pragma alloc_text(PAGE,VgaSetColorLookup)
146 #endif
147
148 //---------------------------------------------------------------------------
149 ULONG
150 // eVb: 1.3 [GCC] - Add NTAPI for GCC support
151 NTAPI
152 // eVb: 1.3 [END]
DriverEntry(PVOID Context1,PVOID Context2)153 DriverEntry(
154 PVOID Context1,
155 PVOID Context2
156 )
157
158 /*++
159
160 Routine Description:
161
162 Installable driver initialization entry point.
163 This entry point is called directly by the I/O system.
164
165 Arguments:
166
167 Context1 - First context value passed by the operating system. This is
168 the value with which the miniport driver calls VideoPortInitialize().
169
170 Context2 - Second context value passed by the operating system. This is
171 the value with which the miniport driver calls 3VideoPortInitialize().
172
173 Return Value:
174
175 Status from VideoPortInitialize()
176
177 --*/
178
179 {
180
181 VIDEO_HW_INITIALIZATION_DATA hwInitData;
182 ULONG status;
183 ULONG initializationStatus = (ULONG) -1;
184
185 //
186 // Zero out structure.
187 //
188
189 VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));
190
191 //
192 // Specify sizes of structure and extension.
193 //
194
195 hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
196
197 //
198 // Set entry points.
199 //
200
201 hwInitData.HwFindAdapter = VgaFindAdapter;
202 hwInitData.HwInitialize = VgaInitialize;
203 hwInitData.HwInterrupt = NULL;
204 hwInitData.HwStartIO = VgaStartIO;
205
206 //
207 // Determine the size we require for the device extension.
208 //
209
210 hwInitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
211
212 //
213 // Always start with parameters for device0 in this case.
214 // We can leave it like this since we know we will only ever find one
215 // VGA type adapter in a machine.
216 //
217
218 // hwInitData.StartingDeviceNumber = 0;
219
220 //
221 // Once all the relevant information has been stored, call the video
222 // port driver to do the initialization.
223 // For this device we will repeat this call three times, for ISA, EISA
224 // and PCI.
225 // We will return the minimum of all return values.
226 //
227
228 //
229 // We will try the PCI bus first so that our ISA detection does'nt claim
230 // PCI cards (since it is impossible to differentiate between the two
231 // by looking at the registers).
232 //
233
234 //
235 // NOTE: since this driver only supports one adapter, we will return
236 // as soon as we find a device, without going on to the following buses.
237 // Normally one would call for each bus type and return the smallest
238 // value.
239 //
240
241 #if !defined(_ALPHA_)
242
243 //
244 // Before we can enable this on ALPHA we need to find a way to map a
245 // sparse view of a 4MB region successfully.
246 //
247
248 hwInitData.AdapterInterfaceType = PCIBus;
249
250 initializationStatus = VideoPortInitialize(Context1,
251 Context2,
252 &hwInitData,
253 NULL);
254
255 if (initializationStatus == NO_ERROR)
256 {
257 return initializationStatus;
258 }
259
260 #endif
261
262 hwInitData.AdapterInterfaceType = MicroChannel;
263
264 initializationStatus = VideoPortInitialize(Context1,
265 Context2,
266 &hwInitData,
267 NULL);
268
269 //
270 // Return immediately instead of checkin for smallest return code.
271 //
272
273 if (initializationStatus == NO_ERROR)
274 {
275 return initializationStatus;
276 }
277
278
279 hwInitData.AdapterInterfaceType = Internal;
280
281 initializationStatus = VideoPortInitialize(Context1,
282 Context2,
283 &hwInitData,
284 NULL);
285
286 if (initializationStatus == NO_ERROR)
287 {
288 return initializationStatus;
289 }
290
291
292 hwInitData.AdapterInterfaceType = Isa;
293
294 initializationStatus = VideoPortInitialize(Context1,
295 Context2,
296 &hwInitData,
297 NULL);
298
299 if (initializationStatus == NO_ERROR)
300 {
301 return initializationStatus;
302 }
303
304
305
306 hwInitData.AdapterInterfaceType = Eisa;
307
308 status = VideoPortInitialize(Context1,
309 Context2,
310 &hwInitData,
311 NULL);
312
313 if (initializationStatus > status) {
314 initializationStatus = status;
315 }
316
317 return initializationStatus;
318
319 } // end DriverEntry()
320
321 //---------------------------------------------------------------------------
322 VP_STATUS
323 NTAPI
VgaFindAdapter(PVOID HwDeviceExtension,PVOID HwContext,PWSTR ArgumentString,PVIDEO_PORT_CONFIG_INFO ConfigInfo,PUCHAR Again)324 VgaFindAdapter(
325 PVOID HwDeviceExtension,
326 PVOID HwContext,
327 PWSTR ArgumentString,
328 PVIDEO_PORT_CONFIG_INFO ConfigInfo,
329 PUCHAR Again
330 )
331
332 /*++
333
334 Routine Description:
335
336 This routine is called to determine if the adapter for this driver
337 is present in the system.
338 If it is present, the function fills out some information describing
339 the adapter.
340
341 Arguments:
342
343 HwDeviceExtension - Supplies the miniport driver's adapter storage. This
344 storage is initialized to zero before this call.
345
346 HwContext - Supplies the context value which was passed to
347 VideoPortInitialize().
348
349 ArgumentString - Supplies a NULL terminated ASCII string. This string
350 originates from the user.
351
352 ConfigInfo - Returns the configuration information structure which is
353 filled by the miniport driver. This structure is initialized with
354 any known configuration information (such as SystemIoBusNumber) by
355 the port driver. Where possible, drivers should have one set of
356 defaults which do not require any supplied configuration information.
357
358 Again - Indicates if the miniport driver wants the port driver to call
359 its VIDEO_HW_FIND_ADAPTER function again with a new device extension
360 and the same config info. This is used by the miniport drivers which
361 can search for several adapters on a bus.
362
363 Return Value:
364
365 This routine must return:
366
367 NO_ERROR - Indicates a host adapter was found and the
368 configuration information was successfully determined.
369
370 ERROR_INVALID_PARAMETER - Indicates an adapter was found but there was an
371 error obtaining the configuration information. If possible an error
372 should be logged.
373
374 ERROR_DEV_NOT_EXIST - Indicates no host adapter was found for the
375 supplied configuration information.
376
377 --*/
378
379 {
380
381 PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
382
383 //
384 // Make sure the size of the structure is at least as large as what we
385 // are expecting (check version of the config info structure).
386 //
387
388 if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO)) {
389
390 return ERROR_INVALID_PARAMETER;
391
392 }
393 // eVb: 1.4 [CIRRUS] - Remove CIRRUS-specific support
394 //
395 // Check internal VGA (MIPS and ARM systems)
396 //
397
398 if ((ConfigInfo->AdapterInterfaceType == Internal) &&
399 (VideoPortGetDeviceData(HwDeviceExtension,
400 VpControllerData,
401 &GetDeviceDataCallback,
402 VgaAccessRange) != NO_ERROR))
403 {
404 return ERROR_INVALID_PARAMETER;
405 }
406 // eVb: 1.4 [END]
407 //
408 // No interrupt information is necessary.
409 //
410
411 //
412 // Check to see if there is a hardware resource conflict.
413 //
414 // eVb: 1.5 [RESOURCE] - Use new function for acquiring VGA resources (I/O, memory)
415 if (VgaAcquireResources(hwDeviceExtension) != NO_ERROR) return ERROR_INVALID_PARAMETER;
416 // eVb: 1.5 [END]
417 //
418 // Get logical IO port addresses.
419 //
420
421 if ((hwDeviceExtension->IOAddress =
422 VideoPortGetDeviceBase(hwDeviceExtension,
423 VgaAccessRange->RangeStart,
424 VGA_MAX_IO_PORT - VGA_BASE_IO_PORT + 1,
425 VgaAccessRange->RangeInIoSpace)) == NULL)
426 {
427 VideoDebugPrint((0, "VgaFindAdapter - Fail to get io address\n"));
428
429 return ERROR_INVALID_PARAMETER;
430 }
431
432 //
433 // Determine whether a VGA is present.
434 //
435
436 if (!VgaIsPresent(hwDeviceExtension)) {
437
438 VideoDebugPrint((0, "VgaFindAdapter - VGA Failed\n"));
439 return ERROR_DEV_NOT_EXIST;
440 }
441
442 //
443 // Minimum size of the buffer required to store the hardware state
444 // information returned by IOCTL_VIDEO_SAVE_HARDWARE_STATE.
445 //
446
447 ConfigInfo->HardwareStateSize = VGA_TOTAL_STATE_SIZE;
448
449 //
450 // Pass a pointer to the emulator range we are using.
451 //
452 // eVb: 1.6 [VDM] - Disable VDM for now
453 ConfigInfo->NumEmulatorAccessEntries = 0;
454 ConfigInfo->EmulatorAccessEntries = NULL;
455 ConfigInfo->EmulatorAccessEntriesContext = 0;
456 // eVb: 1.6 [END]
457 //
458 // BUGBUG
459 //
460 // There is really no reason to have the frame buffer mapped. On an
461 // x86 we use if for save/restore (supposedly) but even then we
462 // would only need to map a 64K window, not all 16 Meg!
463 //
464
465 #ifdef _X86_
466
467 //
468 // Map the video memory into the system virtual address space so we can
469 // clear it out and use it for save and restore.
470 //
471
472 if ( (hwDeviceExtension->VideoMemoryAddress =
473 VideoPortGetDeviceBase(hwDeviceExtension,
474 VgaAccessRange[2].RangeStart,
475 VgaAccessRange[2].RangeLength,
476 FALSE)) == NULL)
477 {
478 VideoDebugPrint((0, "VgaFindAdapter - Fail to get memory address\n"));
479
480 return ERROR_INVALID_PARAMETER;
481 }
482
483 VideoDebugPrint((0, "vga mapped at %x\n", hwDeviceExtension->VideoMemoryAddress));
484 #endif
485 // eVb: 1.7 [VDM] - Disable VDM for now
486 ConfigInfo->VdmPhysicalVideoMemoryAddress.QuadPart = 0;
487 ConfigInfo->VdmPhysicalVideoMemoryLength = 0;
488 // eVb: 1.7 [END]
489 //
490 // Indicate we do not wish to be called again for another initialization.
491 //
492
493 *Again = 0;
494
495 //
496 // Indicate a successful completion status.
497 //
498
499 return NO_ERROR;
500
501
502 } // VgaFindAdapter()
503
504 //---------------------------------------------------------------------------
505 BOOLEAN
506 NTAPI
VgaInitialize(PVOID HwDeviceExtension)507 VgaInitialize(
508 PVOID HwDeviceExtension
509 )
510
511 /*++
512
513 Routine Description:
514
515 This routine does one time initialization of the device.
516
517 Arguments:
518
519 HwDeviceExtension - Pointer to the miniport driver's adapter information.
520
521 Return Value:
522
523 None.
524
525 --*/
526
527 {
528 PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
529
530 //
531 // set up the default cursor position and type.
532 //
533
534 hwDeviceExtension->CursorPosition.Column = 0;
535 hwDeviceExtension->CursorPosition.Row = 0;
536 hwDeviceExtension->CursorTopScanLine = 0;
537 hwDeviceExtension->CursorBottomScanLine = 31;
538 hwDeviceExtension->CursorEnable = TRUE;
539
540 // eVb: 1.8 [VBE] - Initialize VBE modes
541 InitializeModeTable(hwDeviceExtension);
542 // eVb: 1.8 [END]
543 return TRUE;
544
545 } // VgaInitialize()
546
547 //---------------------------------------------------------------------------
548 BOOLEAN
549 NTAPI
VgaStartIO(PVOID HwDeviceExtension,PVIDEO_REQUEST_PACKET RequestPacket)550 VgaStartIO(
551 PVOID HwDeviceExtension,
552 PVIDEO_REQUEST_PACKET RequestPacket
553 )
554
555 /*++
556
557 Routine Description:
558
559 This routine is the main execution routine for the miniport driver. It
560 accepts a Video Request Packet, performs the request, and then returns
561 with the appropriate status.
562
563 Arguments:
564
565 HwDeviceExtension - Pointer to the miniport driver's adapter information.
566
567 RequestPacket - Pointer to the video request packet. This structure
568 contains all the parameters passed to the VideoIoControl function.
569
570 Return Value:
571
572 This routine will return error codes from the various support routines
573 and will also return ERROR_INSUFFICIENT_BUFFER for incorrectly sized
574 buffers and ERROR_INVALID_FUNCTION for unsupported functions.
575
576 --*/
577
578 {
579 PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
580 VP_STATUS status;
581 VIDEO_MODE videoMode;
582 PVIDEO_MEMORY_INFORMATION memoryInformation;
583 ULONG inIoSpace;
584 ULONG Result;
585
586 //
587 // Switch on the IoContolCode in the RequestPacket. It indicates which
588 // function must be performed by the driver.
589 //
590 // eVb: 1.9 [IOCTL] - Remove IOCTLs not needed yet
591 switch (RequestPacket->IoControlCode)
592 {
593 case IOCTL_VIDEO_SHARE_VIDEO_MEMORY:
594
595 VideoDebugPrint((2, "VgaStartIO - ShareVideoMemory\n"));
596
597 status = ERROR_INVALID_FUNCTION;
598
599 break;
600
601 case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY:
602
603 VideoDebugPrint((2, "VgaStartIO - UnshareVideoMemory\n"));
604
605 status = ERROR_INVALID_FUNCTION;
606
607 break;
608
609
610 case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
611
612 VideoDebugPrint((2, "VgaStartIO - MapVideoMemory\n"));
613
614 if ( (RequestPacket->OutputBufferLength <
615 (RequestPacket->StatusBlock->Information =
616 sizeof(VIDEO_MEMORY_INFORMATION))) ||
617 (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) )
618 {
619 status = ERROR_INSUFFICIENT_BUFFER;
620 }
621
622 memoryInformation = RequestPacket->OutputBuffer;
623
624 memoryInformation->VideoRamBase = ((PVIDEO_MEMORY)
625 (RequestPacket->InputBuffer))->RequestedVirtualAddress;
626
627 //
628 // We reserved 16 meg for the frame buffer, however, it makes
629 // no sense to map more memory than there is on the card. So
630 // only map the amount of memory we have on the card.
631 //
632 // eVb: 1.10 [CIRRUS] - On VGA, we have VRAM size since boot, use it
633 memoryInformation->VideoRamLength =
634 hwDeviceExtension->PhysicalVideoMemoryLength;
635 // eVb: 1.10 [END]
636 //
637 // If you change to using a dense space frame buffer, make this
638 // value a 4 for the ALPHA.
639 //
640
641 inIoSpace = 0;
642
643 status = VideoPortMapMemory(hwDeviceExtension,
644 hwDeviceExtension->PhysicalVideoMemoryBase,
645 // eVb: 1.11 [CIRRUS] - On VGA, we have VRAM size since boot, use it
646 &memoryInformation->VideoRamLength,
647 // eVb: 1.11 [END]
648 &inIoSpace,
649 &(memoryInformation->VideoRamBase));
650
651 if (status != NO_ERROR) {
652 VideoDebugPrint((0, "VgaStartIO - IOCTL_VIDEO_MAP_VIDEO_MEMORY failed VideoPortMapMemory (%x)\n", status));
653 }
654
655 memoryInformation->FrameBufferBase =
656 ((PUCHAR) (memoryInformation->VideoRamBase)) +
657 hwDeviceExtension->PhysicalFrameOffset.LowPart;
658
659 memoryInformation->FrameBufferLength =
660 hwDeviceExtension->PhysicalFrameLength ?
661 hwDeviceExtension->PhysicalFrameLength :
662 memoryInformation->VideoRamLength;
663
664
665 VideoDebugPrint((2, "physical VideoMemoryBase %08lx\n", hwDeviceExtension->PhysicalVideoMemoryBase));
666 VideoDebugPrint((2, "physical VideoMemoryLength %08lx\n", hwDeviceExtension->PhysicalVideoMemoryLength));
667 VideoDebugPrint((2, "VideoMemoryBase %08lx\n", memoryInformation->VideoRamBase));
668 VideoDebugPrint((2, "VideoMemoryLength %08lx\n", memoryInformation->VideoRamLength));
669
670 VideoDebugPrint((2, "physical framebuf offset %08lx\n", hwDeviceExtension->PhysicalFrameOffset.LowPart));
671 VideoDebugPrint((2, "framebuf base %08lx\n", memoryInformation->FrameBufferBase));
672 VideoDebugPrint((2, "physical framebuf len %08lx\n", hwDeviceExtension->PhysicalFrameLength));
673 VideoDebugPrint((2, "framebuf length %08lx\n", memoryInformation->FrameBufferLength));
674
675 break;
676
677 case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
678
679 VideoDebugPrint((2, "VgaStartIO - UnMapVideoMemory\n"));
680
681 status = ERROR_INVALID_FUNCTION;
682
683 break;
684
685
686 case IOCTL_VIDEO_QUERY_AVAIL_MODES:
687
688 VideoDebugPrint((2, "VgaStartIO - QueryAvailableModes\n"));
689
690 status = VgaQueryAvailableModes(HwDeviceExtension,
691 (PVIDEO_MODE_INFORMATION)
692 RequestPacket->OutputBuffer,
693 RequestPacket->OutputBufferLength,
694 &RequestPacket->StatusBlock->Information);
695
696 break;
697
698
699 case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
700
701 VideoDebugPrint((2, "VgaStartIO - QueryNumAvailableModes\n"));
702
703 status = VgaQueryNumberOfAvailableModes(HwDeviceExtension,
704 (PVIDEO_NUM_MODES)
705 RequestPacket->OutputBuffer,
706 RequestPacket->OutputBufferLength,
707 &RequestPacket->StatusBlock->Information);
708
709 break;
710
711
712 case IOCTL_VIDEO_QUERY_CURRENT_MODE:
713
714 VideoDebugPrint((2, "VgaStartIO - QueryCurrentMode\n"));
715
716 status = VgaQueryCurrentMode(HwDeviceExtension,
717 (PVIDEO_MODE_INFORMATION) RequestPacket->OutputBuffer,
718 RequestPacket->OutputBufferLength,
719 &RequestPacket->StatusBlock->Information);
720
721 break;
722
723
724 case IOCTL_VIDEO_SET_CURRENT_MODE:
725
726 VideoDebugPrint((2, "VgaStartIO - SetCurrentModes\n"));
727
728 status = VgaSetMode(HwDeviceExtension,
729 (PVIDEO_MODE) RequestPacket->InputBuffer,
730 RequestPacket->InputBufferLength,
731 // eVb: 1.12 [SET MODE] - Use new output parameter for framebuffer update functionality
732 &Result);
733 // eVb: 1.12 [END]
734
735 break;
736
737
738 case IOCTL_VIDEO_RESET_DEVICE:
739
740 VideoDebugPrint((2, "VgaStartIO - Reset Device\n"));
741
742 videoMode.RequestedMode = 0;
743
744 VgaSetMode(HwDeviceExtension,
745 (PVIDEO_MODE) &videoMode,
746 sizeof(videoMode),
747 // eVb: 1.13 [SET MODE] - Use new output parameter for framebuffer update functionality
748 &Result);
749 // eVb: 1.13 [END]
750
751 //
752 // Always return success since settings the text mode will fail on
753 // non-x86.
754 //
755 // Also, failure to set the text mode is not fatal in any way, since
756 // this operation must be followed by another set mode operation.
757 //
758
759 status = NO_ERROR;
760
761 break;
762
763
764 case IOCTL_VIDEO_LOAD_AND_SET_FONT:
765
766 VideoDebugPrint((2, "VgaStartIO - LoadAndSetFont\n"));
767
768 status = ERROR_INVALID_FUNCTION;
769
770 break;
771
772
773 case IOCTL_VIDEO_QUERY_CURSOR_POSITION:
774
775 VideoDebugPrint((2, "VgaStartIO - QueryCursorPosition\n"));
776
777 status = ERROR_INVALID_FUNCTION;
778
779 break;
780
781
782 case IOCTL_VIDEO_SET_CURSOR_POSITION:
783
784 VideoDebugPrint((2, "VgaStartIO - SetCursorPosition\n"));
785
786 status = ERROR_INVALID_FUNCTION;
787
788 break;
789
790
791 case IOCTL_VIDEO_QUERY_CURSOR_ATTR:
792
793 VideoDebugPrint((2, "VgaStartIO - QueryCursorAttributes\n"));
794
795 status = ERROR_INVALID_FUNCTION;
796
797 break;
798
799
800 case IOCTL_VIDEO_SET_CURSOR_ATTR:
801
802 VideoDebugPrint((2, "VgaStartIO - SetCursorAttributes\n"));
803
804 status = ERROR_INVALID_FUNCTION;
805
806 break;
807
808
809 case IOCTL_VIDEO_SET_PALETTE_REGISTERS:
810
811 VideoDebugPrint((2, "VgaStartIO - SetPaletteRegs\n"));
812
813 status = VgaSetPaletteReg(HwDeviceExtension,
814 (PVIDEO_PALETTE_DATA) RequestPacket->InputBuffer,
815 RequestPacket->InputBufferLength);
816
817 break;
818
819
820 case IOCTL_VIDEO_SET_COLOR_REGISTERS:
821
822 VideoDebugPrint((2, "VgaStartIO - SetColorRegs\n"));
823
824 status = VgaSetColorLookup(HwDeviceExtension,
825 (PVIDEO_CLUT) RequestPacket->InputBuffer,
826 RequestPacket->InputBufferLength);
827
828 break;
829
830
831 case IOCTL_VIDEO_ENABLE_VDM:
832
833 VideoDebugPrint((2, "VgaStartIO - EnableVDM\n"));
834
835 status = ERROR_INVALID_FUNCTION;
836
837 break;
838
839
840 case IOCTL_VIDEO_RESTORE_HARDWARE_STATE:
841
842 VideoDebugPrint((2, "VgaStartIO - RestoreHardwareState\n"));
843
844 status = ERROR_INVALID_FUNCTION;
845
846 break;
847
848
849 case IOCTL_VIDEO_SAVE_HARDWARE_STATE:
850
851 VideoDebugPrint((2, "VgaStartIO - SaveHardwareState\n"));
852
853 status = ERROR_INVALID_FUNCTION;
854
855 break;
856
857 case IOCTL_VIDEO_GET_BANK_SELECT_CODE:
858
859 VideoDebugPrint((2, "VgaStartIO - GetBankSelectCode\n"));
860
861 status = ERROR_INVALID_FUNCTION;
862 break;
863
864 case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES:
865 {
866 PVIDEO_PUBLIC_ACCESS_RANGES portAccess;
867 ULONG physicalPortLength;
868
869 VideoDebugPrint((2, "VgaStartIO - Query Public Address Ranges\n"));
870
871 if (RequestPacket->OutputBufferLength <
872 sizeof(VIDEO_PUBLIC_ACCESS_RANGES))
873 {
874 status = ERROR_INSUFFICIENT_BUFFER;
875 break;
876 }
877
878 RequestPacket->StatusBlock->Information =
879 sizeof(VIDEO_PUBLIC_ACCESS_RANGES);
880
881 portAccess = RequestPacket->OutputBuffer;
882
883 //
884 // The first public access range is the IO ports.
885 //
886
887 portAccess->VirtualAddress = (PVOID) NULL;
888 portAccess->InIoSpace = TRUE;
889 portAccess->MappedInIoSpace = portAccess->InIoSpace;
890 physicalPortLength = VGA_MAX_IO_PORT - VGA_BASE_IO_PORT + 1;
891
892 status = VideoPortMapMemory(hwDeviceExtension,
893 VgaAccessRange->RangeStart,
894 &physicalPortLength,
895 &(portAccess->MappedInIoSpace),
896 &(portAccess->VirtualAddress));
897 // eVb: 1.17 [GCG] - Fix lvalue error
898 portAccess->VirtualAddress = (PVOID)((ULONG_PTR)portAccess->VirtualAddress - VGA_BASE_IO_PORT);
899 // eVb: 1.17 [END]
900 VideoDebugPrint((2, "VgaStartIO - mapping ports to (%x)\n", portAccess->VirtualAddress));
901 }
902
903 break;
904
905 case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES:
906
907 VideoDebugPrint((2, "VgaStartIO - Free Public Access Ranges\n"));
908
909 status = ERROR_INVALID_FUNCTION;
910 break;
911
912 //
913 // if we get here, an invalid IoControlCode was specified.
914 //
915
916 default:
917
918 VideoDebugPrint((0, "Fell through vga startIO routine - invalid command\n"));
919
920 status = ERROR_INVALID_FUNCTION;
921
922 break;
923
924 }
925 // eVb: 1.9 [END]
926 RequestPacket->StatusBlock->Status = status;
927
928 return TRUE;
929
930 } // VgaStartIO()
931
932 //---------------------------------------------------------------------------
933 //
934 // private routines
935 //
936
937 //---------------------------------------------------------------------------
938 BOOLEAN
939 NTAPI
VgaIsPresent(PHW_DEVICE_EXTENSION HwDeviceExtension)940 VgaIsPresent(
941 PHW_DEVICE_EXTENSION HwDeviceExtension
942 )
943
944 /*++
945
946 Routine Description:
947
948 This routine returns TRUE if a VGA is present. Determining whether a VGA
949 is present is a two-step process. First, this routine walks bits through
950 the Bit Mask register, to establish that there are readable indexed
951 registers (EGAs normally don't have readable registers, and other adapters
952 are unlikely to have indexed registers). This test is done first because
953 it's a non-destructive EGA rejection test (correctly rejects EGAs, but
954 doesn't potentially mess up the screen or the accessibility of display
955 memory). Normally, this would be an adequate test, but some EGAs have
956 readable registers, so next, we check for the existence of the Chain4 bit
957 in the Memory Mode register; this bit doesn't exist in EGAs. It's
958 conceivable that there are EGAs with readable registers and a register bit
959 where Chain4 is stored, although I don't know of any; if a better test yet
960 is needed, memory could be written to in Chain4 mode, and then examined
961 plane by plane in non-Chain4 mode to make sure the Chain4 bit did what it's
962 supposed to do. However, the current test should be adequate to eliminate
963 just about all EGAs, and 100% of everything else.
964
965 If this function fails to find a VGA, it attempts to undo any damage it
966 may have inadvertently done while testing. The underlying assumption for
967 the damage control is that if there's any non-VGA adapter at the tested
968 ports, it's an EGA or an enhanced EGA, because: a) I don't know of any
969 other adapters that use 3C4/5 or 3CE/F, and b), if there are other
970 adapters, I certainly don't know how to restore their original states. So
971 all error recovery is oriented toward putting an EGA back in a writable
972 state, so that error messages are visible. The EGA's state on entry is
973 assumed to be text mode, so the Memory Mode register is restored to the
974 default state for text mode.
975
976 If a VGA is found, the VGA is returned to its original state after
977 testing is finished.
978
979 Arguments:
980
981 None.
982
983 Return Value:
984
985 TRUE if a VGA is present, FALSE if not.
986
987 --*/
988
989 {
990 UCHAR originalGCAddr;
991 UCHAR originalSCAddr;
992 UCHAR originalBitMask;
993 UCHAR originalReadMap;
994 UCHAR originalMemoryMode;
995 UCHAR testMask;
996 BOOLEAN returnStatus;
997
998 //
999 // Remember the original state of the Graphics Controller Address register.
1000 //
1001
1002 originalGCAddr = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1003 GRAPH_ADDRESS_PORT);
1004
1005 //
1006 // Write the Read Map register with a known state so we can verify
1007 // that it isn't changed after we fool with the Bit Mask. This ensures
1008 // that we're dealing with indexed registers, since both the Read Map and
1009 // the Bit Mask are addressed at GRAPH_DATA_PORT.
1010 //
1011
1012 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1013 GRAPH_ADDRESS_PORT, IND_READ_MAP);
1014
1015 //
1016 // If we can't read back the Graphics Address register setting we just
1017 // performed, it's not readable and this isn't a VGA.
1018 //
1019
1020 if ((VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1021 GRAPH_ADDRESS_PORT) & GRAPH_ADDR_MASK) != IND_READ_MAP) {
1022
1023 return FALSE;
1024 }
1025
1026 //
1027 // Set the Read Map register to a known state.
1028 //
1029
1030 originalReadMap = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1031 GRAPH_DATA_PORT);
1032 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1033 GRAPH_DATA_PORT, READ_MAP_TEST_SETTING);
1034
1035 if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1036 GRAPH_DATA_PORT) != READ_MAP_TEST_SETTING) {
1037
1038 //
1039 // The Read Map setting we just performed can't be read back; not a
1040 // VGA. Restore the default Read Map state.
1041 //
1042
1043 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1044 GRAPH_DATA_PORT, READ_MAP_DEFAULT);
1045
1046 return FALSE;
1047 }
1048
1049 //
1050 // Remember the original setting of the Bit Mask register.
1051 //
1052
1053 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1054 GRAPH_ADDRESS_PORT, IND_BIT_MASK);
1055 if ((VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1056 GRAPH_ADDRESS_PORT) & GRAPH_ADDR_MASK) != IND_BIT_MASK) {
1057
1058 //
1059 // The Graphics Address register setting we just made can't be read
1060 // back; not a VGA. Restore the default Read Map state.
1061 //
1062
1063 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1064 GRAPH_ADDRESS_PORT, IND_READ_MAP);
1065 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1066 GRAPH_DATA_PORT, READ_MAP_DEFAULT);
1067
1068 return FALSE;
1069 }
1070
1071 originalBitMask = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1072 GRAPH_DATA_PORT);
1073
1074 //
1075 // Set up the initial test mask we'll write to and read from the Bit Mask.
1076 //
1077
1078 testMask = 0xBB;
1079
1080 do {
1081
1082 //
1083 // Write the test mask to the Bit Mask.
1084 //
1085
1086 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1087 GRAPH_DATA_PORT, testMask);
1088
1089 //
1090 // Make sure the Bit Mask remembered the value.
1091 //
1092
1093 if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1094 GRAPH_DATA_PORT) != testMask) {
1095
1096 //
1097 // The Bit Mask is not properly writable and readable; not a VGA.
1098 // Restore the Bit Mask and Read Map to their default states.
1099 //
1100
1101 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1102 GRAPH_DATA_PORT, BIT_MASK_DEFAULT);
1103 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1104 GRAPH_ADDRESS_PORT, IND_READ_MAP);
1105 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1106 GRAPH_DATA_PORT, READ_MAP_DEFAULT);
1107
1108 return FALSE;
1109 }
1110
1111 //
1112 // Cycle the mask for next time.
1113 //
1114
1115 testMask >>= 1;
1116
1117 } while (testMask != 0);
1118
1119 //
1120 // There's something readable at GRAPH_DATA_PORT; now switch back and
1121 // make sure that the Read Map register hasn't changed, to verify that
1122 // we're dealing with indexed registers.
1123 //
1124
1125 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1126 GRAPH_ADDRESS_PORT, IND_READ_MAP);
1127 if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1128 GRAPH_DATA_PORT) != READ_MAP_TEST_SETTING) {
1129
1130 //
1131 // The Read Map is not properly writable and readable; not a VGA.
1132 // Restore the Bit Mask and Read Map to their default states, in case
1133 // this is an EGA, so subsequent writes to the screen aren't garbled.
1134 //
1135
1136 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1137 GRAPH_DATA_PORT, READ_MAP_DEFAULT);
1138 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1139 GRAPH_ADDRESS_PORT, IND_BIT_MASK);
1140 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1141 GRAPH_DATA_PORT, BIT_MASK_DEFAULT);
1142
1143 return FALSE;
1144 }
1145
1146 //
1147 // We've pretty surely verified the existence of the Bit Mask register.
1148 // Put the Graphics Controller back to the original state.
1149 //
1150
1151 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1152 GRAPH_DATA_PORT, originalReadMap);
1153 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1154 GRAPH_ADDRESS_PORT, IND_BIT_MASK);
1155 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1156 GRAPH_DATA_PORT, originalBitMask);
1157 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1158 GRAPH_ADDRESS_PORT, originalGCAddr);
1159
1160 //
1161 // Now, check for the existence of the Chain4 bit.
1162 //
1163
1164 //
1165 // Remember the original states of the Sequencer Address and Memory Mode
1166 // registers.
1167 //
1168
1169 originalSCAddr = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1170 SEQ_ADDRESS_PORT);
1171 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1172 SEQ_ADDRESS_PORT, IND_MEMORY_MODE);
1173 if ((VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1174 SEQ_ADDRESS_PORT) & SEQ_ADDR_MASK) != IND_MEMORY_MODE) {
1175
1176 //
1177 // Couldn't read back the Sequencer Address register setting we just
1178 // performed.
1179 //
1180
1181 return FALSE;
1182 }
1183 originalMemoryMode = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1184 SEQ_DATA_PORT);
1185
1186 //
1187 // Toggle the Chain4 bit and read back the result. This must be done during
1188 // sync reset, since we're changing the chaining state.
1189 //
1190
1191 //
1192 // Begin sync reset.
1193 //
1194
1195 VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress +
1196 SEQ_ADDRESS_PORT),
1197 (IND_SYNC_RESET + (START_SYNC_RESET_VALUE << 8)));
1198
1199 //
1200 // Toggle the Chain4 bit.
1201 //
1202
1203 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1204 SEQ_ADDRESS_PORT, IND_MEMORY_MODE);
1205 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1206 SEQ_DATA_PORT, (UCHAR)(originalMemoryMode ^ CHAIN4_MASK));
1207
1208 if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1209 SEQ_DATA_PORT) != (UCHAR) (originalMemoryMode ^ CHAIN4_MASK)) {
1210
1211 //
1212 // Chain4 bit not there; not a VGA.
1213 // Set text mode default for Memory Mode register.
1214 //
1215
1216 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1217 SEQ_DATA_PORT, MEMORY_MODE_TEXT_DEFAULT);
1218 //
1219 // End sync reset.
1220 //
1221
1222 VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress +
1223 SEQ_ADDRESS_PORT),
1224 (IND_SYNC_RESET + (END_SYNC_RESET_VALUE << 8)));
1225
1226 returnStatus = FALSE;
1227
1228 } else {
1229
1230 //
1231 // It's a VGA.
1232 //
1233
1234 //
1235 // Restore the original Memory Mode setting.
1236 //
1237
1238 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1239 SEQ_DATA_PORT, originalMemoryMode);
1240
1241 //
1242 // End sync reset.
1243 //
1244
1245 VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress +
1246 SEQ_ADDRESS_PORT),
1247 (USHORT)(IND_SYNC_RESET + (END_SYNC_RESET_VALUE << 8)));
1248
1249 //
1250 // Restore the original Sequencer Address setting.
1251 //
1252
1253 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1254 SEQ_ADDRESS_PORT, originalSCAddr);
1255
1256 returnStatus = TRUE;
1257 }
1258
1259 return returnStatus;
1260
1261 } // VgaIsPresent()
1262
1263 //---------------------------------------------------------------------------
1264 VP_STATUS
1265 NTAPI
VgaSetPaletteReg(PHW_DEVICE_EXTENSION HwDeviceExtension,PVIDEO_PALETTE_DATA PaletteBuffer,ULONG PaletteBufferSize)1266 VgaSetPaletteReg(
1267 PHW_DEVICE_EXTENSION HwDeviceExtension,
1268 PVIDEO_PALETTE_DATA PaletteBuffer,
1269 ULONG PaletteBufferSize
1270 )
1271
1272 /*++
1273
1274 Routine Description:
1275
1276 This routine sets a specified portion of the EGA (not DAC) palette
1277 registers.
1278
1279 Arguments:
1280
1281 HwDeviceExtension - Pointer to the miniport driver's device extension.
1282
1283 PaletteBuffer - Pointer to the structure containing the palette data.
1284
1285 PaletteBufferSize - Length of the input buffer supplied by the user.
1286
1287 Return Value:
1288
1289 NO_ERROR - information returned successfully
1290
1291 ERROR_INSUFFICIENT_BUFFER - input buffer not large enough for input data.
1292
1293 ERROR_INVALID_PARAMETER - invalid palette size.
1294
1295 --*/
1296
1297 {
1298 USHORT i;
1299
1300 //
1301 // Check if the size of the data in the input buffer is large enough.
1302 //
1303
1304 if ((PaletteBufferSize) < (sizeof(VIDEO_PALETTE_DATA)) ||
1305 (PaletteBufferSize < (sizeof(VIDEO_PALETTE_DATA) +
1306 (sizeof(USHORT) * (PaletteBuffer->NumEntries -1)) ))) {
1307
1308 return ERROR_INSUFFICIENT_BUFFER;
1309
1310 }
1311
1312 //
1313 // Check to see if the parameters are valid.
1314 //
1315
1316 if ( (PaletteBuffer->FirstEntry > VIDEO_MAX_COLOR_REGISTER ) ||
1317 (PaletteBuffer->NumEntries == 0) ||
1318 (PaletteBuffer->FirstEntry + PaletteBuffer->NumEntries >
1319 VIDEO_MAX_PALETTE_REGISTER + 1 ) ) {
1320
1321 return ERROR_INVALID_PARAMETER;
1322
1323 }
1324
1325 //
1326 // Reset ATC to index mode
1327 //
1328
1329 VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1330 ATT_INITIALIZE_PORT_COLOR);
1331
1332 //
1333 // Blast out our palette values.
1334 //
1335
1336 for (i = 0; i < PaletteBuffer->NumEntries; i++) {
1337
1338 VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ATT_ADDRESS_PORT,
1339 (UCHAR)(i+PaletteBuffer->FirstEntry));
1340
1341 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1342 ATT_DATA_WRITE_PORT,
1343 (UCHAR)PaletteBuffer->Colors[i]);
1344 }
1345
1346 VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ATT_ADDRESS_PORT,
1347 VIDEO_ENABLE);
1348
1349 return NO_ERROR;
1350
1351 } // end VgaSetPaletteReg()
1352
1353 //---------------------------------------------------------------------------
1354 VP_STATUS
1355 NTAPI
VgaSetColorLookup(PHW_DEVICE_EXTENSION HwDeviceExtension,PVIDEO_CLUT ClutBuffer,ULONG ClutBufferSize)1356 VgaSetColorLookup(
1357 PHW_DEVICE_EXTENSION HwDeviceExtension,
1358 PVIDEO_CLUT ClutBuffer,
1359 ULONG ClutBufferSize
1360 )
1361
1362 /*++
1363
1364 Routine Description:
1365
1366 This routine sets a specified portion of the DAC color lookup table
1367 settings.
1368
1369 Arguments:
1370
1371 HwDeviceExtension - Pointer to the miniport driver's device extension.
1372
1373 ClutBufferSize - Length of the input buffer supplied by the user.
1374
1375 ClutBuffer - Pointer to the structure containing the color lookup table.
1376
1377 Return Value:
1378
1379 NO_ERROR - information returned successfully
1380
1381 ERROR_INSUFFICIENT_BUFFER - input buffer not large enough for input data.
1382
1383 ERROR_INVALID_PARAMETER - invalid clut size.
1384
1385 --*/
1386
1387 {
1388 PVIDEOMODE CurrentMode = HwDeviceExtension->CurrentMode;
1389 USHORT i;
1390
1391 //
1392 // Check if the size of the data in the input buffer is large enough.
1393 //
1394
1395 if ( (ClutBufferSize < sizeof(VIDEO_CLUT) - sizeof(ULONG)) ||
1396 (ClutBufferSize < sizeof(VIDEO_CLUT) +
1397 (sizeof(ULONG) * (ClutBuffer->NumEntries - 1)) ) ) {
1398
1399 return ERROR_INSUFFICIENT_BUFFER;
1400
1401 }
1402
1403 //
1404 // Check to see if the parameters are valid.
1405 //
1406
1407 if ( (ClutBuffer->NumEntries == 0) ||
1408 (ClutBuffer->FirstEntry > VIDEO_MAX_COLOR_REGISTER) ||
1409 (ClutBuffer->FirstEntry + ClutBuffer->NumEntries >
1410 VIDEO_MAX_COLOR_REGISTER + 1) ) {
1411
1412 return ERROR_INVALID_PARAMETER;
1413
1414 }
1415 // eVb: 1.14 [VBE] - Add VBE color support
1416 //
1417 // Check SVGA mode
1418 //
1419
1420 if (CurrentMode->bitsPerPlane >= 8) return VbeSetColorLookup(HwDeviceExtension, ClutBuffer);
1421 // eVb: 1.14 [END]
1422 //
1423 // Path for VGA mode
1424 //
1425 // eVb: 1.15 [VBE] - Add VBE support for non-VGA-compatible detected modes
1426 if (!CurrentMode->NonVgaMode)
1427 {
1428 // eVb: 1.15 [END]
1429 //
1430 // Set CLUT registers directly on the hardware
1431 //
1432
1433 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1434 DAC_ADDRESS_WRITE_PORT, (UCHAR) ClutBuffer->FirstEntry);
1435
1436 for (i = 0; i < ClutBuffer->NumEntries; i++) {
1437 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1438 DAC_ADDRESS_WRITE_PORT,
1439 (UCHAR)(i + ClutBuffer->FirstEntry));
1440
1441 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1442 DAC_DATA_REG_PORT,
1443 ClutBuffer->LookupTable[i].RgbArray.Red);
1444
1445 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1446 DAC_DATA_REG_PORT,
1447 ClutBuffer->LookupTable[i].RgbArray.Green);
1448
1449 VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1450 DAC_DATA_REG_PORT,
1451 ClutBuffer->LookupTable[i].RgbArray.Blue);
1452 }
1453 return NO_ERROR;
1454 }
1455
1456 return ERROR_INVALID_PARAMETER;
1457
1458 } // end VgaSetColorLookup()
1459
1460 VP_STATUS
1461 NTAPI
GetDeviceDataCallback(PVOID HwDeviceExtension,PVOID Context,VIDEO_DEVICE_DATA_TYPE DeviceDataType,PVOID Identifier,ULONG IdentifierLength,PVOID ConfigurationData,ULONG ConfigurationDataLength,PVOID ComponentInformation,ULONG ComponentInformationLength)1462 GetDeviceDataCallback(
1463 PVOID HwDeviceExtension,
1464 PVOID Context,
1465 VIDEO_DEVICE_DATA_TYPE DeviceDataType,
1466 PVOID Identifier,
1467 ULONG IdentifierLength,
1468 PVOID ConfigurationData,
1469 ULONG ConfigurationDataLength,
1470 PVOID ComponentInformation,
1471 ULONG ComponentInformationLength
1472 )
1473
1474 /*++
1475
1476 Routine Description:
1477
1478 Callback routine for the VideoPortGetDeviceData function.
1479
1480 Arguments:
1481
1482 HwDeviceExtension - Pointer to the miniport drivers device extension.
1483
1484 Context - Context value passed to the VideoPortGetDeviceData function.
1485
1486 DeviceDataType - The type of data that was requested in
1487 VideoPortGetDeviceData.
1488
1489 Identifier - Pointer to a string that contains the name of the device,
1490 as setup by the ROM or ntdetect.
1491
1492 IdentifierLength - Length of the Identifier string.
1493
1494 ConfigurationData - Pointer to the configuration data for the device or
1495 BUS.
1496
1497 ConfigurationDataLength - Length of the data in the configurationData
1498 field.
1499
1500 ComponentInformation - Undefined.
1501
1502 ComponentInformationLength - Undefined.
1503
1504 Return Value:
1505
1506 Returns NO_ERROR if the function completed properly.
1507 Returns ERROR_DEV_NOT_EXIST if we did not find the device.
1508 Returns ERROR_INVALID_PARAMETER otherwise.
1509
1510 --*/
1511
1512 {
1513 VideoDebugPrint((Error, "Detected internal VGA chip on embedded board, todo\n"));
1514 while (TRUE);
1515 return NO_ERROR;
1516
1517 } //end GetDeviceDataCallback()
1518
1519 // eVb: 1.16 [RESOURCE] - Add new function for acquiring VGA resources (I/O, memory)
1520 VP_STATUS
1521 NTAPI
VgaAcquireResources(PHW_DEVICE_EXTENSION DeviceExtension)1522 VgaAcquireResources(
1523 PHW_DEVICE_EXTENSION DeviceExtension
1524 )
1525 {
1526 VP_STATUS Status = NO_ERROR;
1527 ULONG Ranges, i;
1528
1529 //
1530 // Try exclusive ranges (vga + ati)
1531 //
1532
1533 Ranges = NUM_VGA_ACCESS_RANGES;
1534 for (i = 0; i < Ranges; i++) VgaAccessRange[i].RangeShareable = FALSE;
1535 if (VideoPortVerifyAccessRanges(DeviceExtension, Ranges, VgaAccessRange) != NO_ERROR)
1536 {
1537 //
1538 // Not worked, try vga only
1539 //
1540
1541 Ranges = 3;
1542 if (VideoPortVerifyAccessRanges(DeviceExtension, Ranges, VgaAccessRange) != NO_ERROR)
1543 {
1544 //
1545 // Still not, try shared ranges
1546 //
1547
1548 for (i = 0; i < Ranges; i++) VgaAccessRange[i].RangeShareable = TRUE;
1549 Status = VideoPortVerifyAccessRanges(DeviceExtension, Ranges, VgaAccessRange);
1550 if (Status == NO_ERROR)
1551 {
1552 //
1553 // It did work
1554 //
1555
1556 VideoPortVerifyAccessRanges(DeviceExtension, 0, 0);
1557 Status = NO_ERROR;
1558 }
1559 }
1560 }
1561
1562 if (Status == NO_ERROR)
1563 {
1564 //
1565 // Worked with exclusive, also try shared
1566 //
1567
1568 for (i = 0; i < Ranges; i++) VgaAccessRange[i].RangeShareable = TRUE;
1569 Status = VideoPortVerifyAccessRanges(DeviceExtension, Ranges, VgaAccessRange);
1570 }
1571
1572 return Status;
1573 }
1574 // eVb: 1.16 [END]
1575