[REACTOS] Cleanup INIT and some PAGE section allocations
[reactos.git] / win32ss / drivers / miniport / pc98vid / pc98vid.c
1 /*
2 * PROJECT: ReactOS framebuffer driver for NEC PC-98 series
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Miniport driver entrypoint
5 * COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com)
6 */
7
8 /* INCLUDES *******************************************************************/
9
10 #include "pc98vid.h"
11
12 /* GLOBALS ********************************************************************/
13
14 const VIDEOMODE VideoModes[] =
15 {
16 {640, 480, GRAPH_HF_31KHZ, GDC2_CLOCK1_5MHZ, GDC2_CLOCK2_5MHZ,
17 GDC2_MODE_LINES_800, 60,
18 {0, 80, 12, 2, 4, 4, 6, 480, 37}, {0, 80, 12, 2, 4, 132, 6, 480, 37}}
19 };
20
21 static VIDEO_ACCESS_RANGE LegacyRangeList[] =
22 {
23 { {{0x60, 0}}, 0x00000001, 1, 1, 1, 0 },
24 { {{0x62, 0}}, 0x00000001, 1, 1, 1, 0 },
25 { {{0x68, 0}}, 0x00000001, 1, 1, 1, 0 },
26 { {{0x6A, 0}}, 0x00000001, 1, 1, 1, 0 },
27 { {{0x7C, 0}}, 0x00000001, 1, 1, 1, 0 },
28 { {{0xA0, 0}}, 0x00000001, 1, 1, 1, 0 },
29 { {{0xA2, 0}}, 0x00000001, 1, 1, 1, 0 },
30 { {{0xA4, 0}}, 0x00000001, 1, 1, 1, 0 },
31 { {{0xA6, 0}}, 0x00000001, 1, 1, 1, 0 },
32 { {{0xA8, 0}}, 0x00000001, 1, 1, 1, 0 },
33 { {{0xAA, 0}}, 0x00000001, 1, 1, 1, 0 },
34 { {{0xAC, 0}}, 0x00000001, 1, 1, 1, 0 },
35 { {{0xAE, 0}}, 0x00000001, 1, 1, 1, 0 },
36 { {{0x9A0, 0}}, 0x00000001, 1, 1, 1, 0 },
37 { {{0x9A2, 0}}, 0x00000001, 1, 1, 1, 0 },
38 { {{0x9A8, 0}}, 0x00000001, 1, 1, 1, 0 },
39 { {{0xFAC, 0}}, 0x00000001, 1, 1, 1, 0 },
40 { {{VRAM_NORMAL_PLANE_I, 0}}, PEGC_CONTROL_SIZE, 0, 0, 1, 0 },
41 { {{PEGC_FRAMEBUFFER_PACKED, 0}}, PEGC_FRAMEBUFFER_SIZE, 0, 0, 1, 0 }
42 };
43 #define CONTROL_RANGE_INDEX 17
44 #define FRAMEBUFFER_RANGE_INDEX 18
45
46 /* FUNCTIONS ******************************************************************/
47
48 CODE_SEG("PAGE")
49 VP_STATUS
50 NTAPI
51 Pc98VidFindAdapter(
52 _In_ PVOID HwDeviceExtension,
53 _In_opt_ PVOID HwContext,
54 _In_opt_ PWSTR ArgumentString,
55 _Inout_ PVIDEO_PORT_CONFIG_INFO ConfigInfo,
56 _Out_ PUCHAR Again)
57 {
58 VP_STATUS Status;
59 PHW_DEVICE_EXTENSION DeviceExtension = HwDeviceExtension;
60 ULONG inIoSpace = VIDEO_MEMORY_SPACE_MEMORY;
61 static WCHAR AdapterChipType[] = L"Onboard";
62 static WCHAR AdapterDacType[] = L"8 bit";
63 static WCHAR AdapterString[] = L"PEGC";
64
65 PAGED_CODE();
66
67 VideoDebugPrint((Trace, "%s()\n", __FUNCTION__));
68
69 if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO))
70 return ERROR_INVALID_PARAMETER;
71
72 Status = VideoPortVerifyAccessRanges(DeviceExtension,
73 RTL_NUMBER_OF(LegacyRangeList),
74 LegacyRangeList);
75 if (Status != NO_ERROR)
76 {
77 VideoDebugPrint((Error, "%s() Resource conflict was found\n", __FUNCTION__));
78
79 return ERROR_INVALID_PARAMETER;
80 }
81
82 DeviceExtension->PegcControl = LegacyRangeList[CONTROL_RANGE_INDEX].RangeStart;
83 DeviceExtension->PegcControlLength = LegacyRangeList[CONTROL_RANGE_INDEX].RangeLength;
84 DeviceExtension->FrameBuffer = LegacyRangeList[FRAMEBUFFER_RANGE_INDEX].RangeStart;
85 DeviceExtension->FrameBufferLength = LegacyRangeList[FRAMEBUFFER_RANGE_INDEX].RangeLength;
86
87 Status = VideoPortMapMemory(DeviceExtension,
88 DeviceExtension->PegcControl,
89 &DeviceExtension->PegcControlLength,
90 &inIoSpace,
91 (PVOID)&DeviceExtension->PegcControlVa);
92 if (Status != NO_ERROR)
93 {
94 VideoDebugPrint((Error, "%s() Failed to map control memory\n", __FUNCTION__));
95
96 VideoPortVerifyAccessRanges(DeviceExtension, 0, NULL);
97
98 return ERROR_DEV_NOT_EXIST;
99 }
100
101 if (!HasPegcController(DeviceExtension))
102 {
103 VideoDebugPrint((Error, "%s() Unsupported hardware\n", __FUNCTION__));
104
105 VideoPortVerifyAccessRanges(DeviceExtension, 0, NULL);
106 VideoPortUnmapMemory(DeviceExtension,
107 (PVOID)DeviceExtension->PegcControlVa,
108 NULL);
109
110 return ERROR_DEV_NOT_EXIST;
111 }
112
113 /* Not VGA-compatible */
114 ConfigInfo->NumEmulatorAccessEntries = 0;
115 ConfigInfo->EmulatorAccessEntries = NULL;
116 ConfigInfo->EmulatorAccessEntriesContext = 0;
117 ConfigInfo->HardwareStateSize = 0;
118 ConfigInfo->VdmPhysicalVideoMemoryAddress.QuadPart = 0;
119 ConfigInfo->VdmPhysicalVideoMemoryLength = 0;
120
121 VideoPortSetRegistryParameters(DeviceExtension,
122 L"HardwareInformation.ChipType",
123 AdapterChipType,
124 sizeof(AdapterChipType));
125 VideoPortSetRegistryParameters(DeviceExtension,
126 L"HardwareInformation.DacType",
127 AdapterDacType,
128 sizeof(AdapterDacType));
129 VideoPortSetRegistryParameters(DeviceExtension,
130 L"HardwareInformation.MemorySize",
131 &DeviceExtension->FrameBufferLength,
132 sizeof(ULONG));
133 VideoPortSetRegistryParameters(DeviceExtension,
134 L"HardwareInformation.AdapterString",
135 AdapterString,
136 sizeof(AdapterString));
137
138 return NO_ERROR;
139 }
140
141 CODE_SEG("PAGE")
142 BOOLEAN
143 NTAPI
144 Pc98VidInitialize(
145 _In_ PVOID HwDeviceExtension)
146 {
147 PHW_DEVICE_EXTENSION DeviceExtension = HwDeviceExtension;
148
149 PAGED_CODE();
150
151 VideoDebugPrint((Trace, "%s()\n", __FUNCTION__));
152
153 DeviceExtension->ModeCount = RTL_NUMBER_OF(VideoModes);
154 DeviceExtension->MonitorCount = 1;
155
156 return TRUE;
157 }
158
159 CODE_SEG("PAGE")
160 VP_STATUS
161 NTAPI
162 Pc98VidGetVideoChildDescriptor(
163 _In_ PVOID HwDeviceExtension,
164 _In_ PVIDEO_CHILD_ENUM_INFO ChildEnumInfo,
165 _Out_ PVIDEO_CHILD_TYPE VideoChildType,
166 _Out_ PUCHAR pChildDescriptor,
167 _Out_ PULONG UId,
168 _Out_ PULONG pUnused)
169 {
170 PHW_DEVICE_EXTENSION DeviceExtension = HwDeviceExtension;
171
172 UNREFERENCED_PARAMETER(pChildDescriptor);
173
174 PAGED_CODE();
175
176 VideoDebugPrint((Trace, "%s() Index %d\n",
177 __FUNCTION__, ChildEnumInfo->ChildIndex));
178
179 *pUnused = 0;
180
181 if (ChildEnumInfo->ChildIndex > 0 &&
182 ChildEnumInfo->ChildIndex <= DeviceExtension->MonitorCount)
183 {
184 *VideoChildType = Monitor;
185 *UId = MONITOR_HW_ID;
186
187 return VIDEO_ENUM_MORE_DEVICES;
188 }
189
190 return ERROR_NO_MORE_DEVICES;
191 }
192
193 CODE_SEG("INIT")
194 ULONG
195 NTAPI
196 DriverEntry(
197 _In_ PVOID Context1,
198 _In_ PVOID Context2)
199 {
200 VIDEO_HW_INITIALIZATION_DATA InitData;
201 ULONG Status;
202 BOOLEAN IsLiveCd;
203
204 VideoDebugPrint((Trace, "(%s:%d) %s()\n",
205 __FILE__, __LINE__, __FUNCTION__));
206
207 // FIXME: Detect IsLiveCd
208 IsLiveCd = TRUE;
209
210 VideoPortZeroMemory(&InitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));
211 InitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
212 InitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
213 InitData.HwFindAdapter = Pc98VidFindAdapter;
214 InitData.HwInitialize = Pc98VidInitialize;
215 InitData.HwStartIO = Pc98VidStartIO;
216 /*
217 * On LiveCD, we expect to see the initialized video
218 * before starting the device enumeration,
219 * so we should mark the driver as non-PnP miniport.
220 */
221 if (!IsLiveCd)
222 {
223 InitData.HwGetPowerState = Pc98VidGetPowerState;
224 InitData.HwSetPowerState = Pc98VidSetPowerState;
225 InitData.HwGetVideoChildDescriptor = Pc98VidGetVideoChildDescriptor;
226 }
227
228 InitData.HwLegacyResourceList = LegacyRangeList;
229 InitData.HwLegacyResourceCount = RTL_NUMBER_OF(LegacyRangeList);
230
231 InitData.AdapterInterfaceType = Isa;
232
233 Status = VideoPortInitialize(Context1, Context2, &InitData, NULL);
234 if (!NT_SUCCESS(Status))
235 {
236 VideoDebugPrint((Error, "(%s:%d) %s() Initialization failed 0x%lX\n",
237 __FILE__, __LINE__, __FUNCTION__, Status));
238 }
239
240 return Status;
241 }