Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

504 lines
14 KiB

  1. /*++
  2. Copyright (c) 1991 - 2001 Microsoft Corporation
  3. Module Name:
  4. ### ## # ## ##### #### ### ##### #### ##### #####
  5. ## # ## ### ## ## ## ## ## # ## ## ## # ## ## ## ##
  6. ### ## ### ## ## ## ## ### ## ## ## ## ## ## ##
  7. ### ## # # ## ## ## ## ### ## ## ## ## ## ## ##
  8. ### ### ### ## ## ## ### ##### ## ##### #####
  9. # ## ### ### ## ## ## # ## ## ## ## # ## ##
  10. ### ## ## ##### #### ### ## ## #### ## ##
  11. Abstract:
  12. This module contains the entire implementation of
  13. the local display miniport for the ServerWorks
  14. CSB5 server chip set.
  15. Author:
  16. Wesley Witt (wesw) 1-Oct-2001
  17. Environment:
  18. Kernel mode only.
  19. Notes:
  20. --*/
  21. #include "swdisp.h"
  22. #ifdef ALLOC_PRAGMA
  23. #pragma alloc_text(INIT,DriverEntry)
  24. #endif
  25. NTSTATUS
  26. SaDispHwInitialize(
  27. IN PDEVICE_OBJECT DeviceObject,
  28. IN PIRP Irp,
  29. IN PVOID DeviceExtensionIn,
  30. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResources,
  31. IN ULONG PartialResourceCount
  32. )
  33. /*++
  34. Routine Description:
  35. This routine is the driver's entry point, called by the I/O system
  36. to load the driver. The driver's entry points are initialized and
  37. a mutex to control paging is initialized.
  38. In DBG mode, this routine also examines the registry for special
  39. debug parameters.
  40. Arguments:
  41. DeviceObject - Miniport's device object
  42. Irp - Current IRP in progress
  43. DeviceExtensionIn - Miniport's device extension
  44. PartialResources - List of resources that are assigned to the miniport
  45. PartialResourceCount - Number of assigned resources
  46. Return Value:
  47. NT status code
  48. --*/
  49. {
  50. ULONG i;
  51. PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION) DeviceExtensionIn;
  52. PCM_PARTIAL_RESOURCE_DESCRIPTOR Resource = NULL;
  53. for (i=0; i<PartialResourceCount; i++) {
  54. if (PartialResources[i].Type == CmResourceTypeMemory) {
  55. Resource = &PartialResources[i];
  56. break;
  57. }
  58. }
  59. if (Resource == NULL) {
  60. REPORT_ERROR( SA_DEVICE_DISPLAY, "Missing memory resource", STATUS_UNSUCCESSFUL );
  61. return STATUS_UNSUCCESSFUL;
  62. }
  63. DeviceExtension->VideoMemBase = (PUCHAR) SaPortGetVirtualAddress(
  64. DeviceExtension,
  65. Resource->u.Memory.Start,
  66. Resource->u.Memory.Length
  67. );
  68. if (DeviceExtension->VideoMemBase == NULL) {
  69. REPORT_ERROR( SA_DEVICE_DISPLAY, "SaPortGetVirtualAddress failed", STATUS_NO_MEMORY );
  70. return STATUS_NO_MEMORY;
  71. }
  72. return STATUS_SUCCESS;
  73. }
  74. NTSTATUS
  75. SaDispDeviceIoctl(
  76. IN PVOID DeviceExtension,
  77. IN PIRP Irp,
  78. IN PVOID FsContext,
  79. IN ULONG FunctionCode,
  80. IN PVOID InputBuffer,
  81. IN ULONG InputBufferLength,
  82. IN PVOID OutputBuffer,
  83. IN ULONG OutputBufferLength
  84. )
  85. /*++
  86. Routine Description:
  87. This routine processes the device control requests for the
  88. local display miniport.
  89. Arguments:
  90. DeviceExtension - Miniport's device extension
  91. FunctionCode - Device control function code
  92. InputBuffer - Pointer to the user's input buffer
  93. InputBufferLength - Length in bytes of the input buffer
  94. OutputBuffer - Pointer to the user's output buffer
  95. OutputBufferLength - Length in bytes of the output buffer
  96. Return Value:
  97. NT status code.
  98. --*/
  99. {
  100. NTSTATUS Status = STATUS_SUCCESS;
  101. PSA_DISPLAY_CAPS DeviceCaps;
  102. switch (FunctionCode) {
  103. case FUNC_SA_GET_VERSION:
  104. *((PULONG)OutputBuffer) = SA_INTERFACE_VERSION;
  105. break;
  106. case FUNC_SA_GET_CAPABILITIES:
  107. DeviceCaps = (PSA_DISPLAY_CAPS)OutputBuffer;
  108. DeviceCaps->SizeOfStruct = sizeof(SA_DISPLAY_CAPS);
  109. DeviceCaps->DisplayType = SA_DISPLAY_TYPE_BIT_MAPPED_LCD;
  110. DeviceCaps->CharacterSet = SA_DISPLAY_CHAR_ASCII;
  111. DeviceCaps->DisplayHeight = DISPLAY_HEIGHT;
  112. DeviceCaps->DisplayWidth = DISPLAY_WIDTH;
  113. break;
  114. default:
  115. Status = STATUS_NOT_SUPPORTED;
  116. REPORT_ERROR( SA_DEVICE_DISPLAY, "Unsupported device control", Status );
  117. break;
  118. }
  119. return Status;
  120. }
  121. UCHAR TestMask[128] =
  122. {
  123. 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
  124. 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
  125. 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
  126. 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
  127. 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
  128. 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
  129. 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
  130. 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01
  131. };
  132. ULONG
  133. TransformBitmap(
  134. PUCHAR Bits,
  135. ULONG Width,
  136. ULONG Height,
  137. PUCHAR NewBits
  138. )
  139. /*++
  140. Routine Description:
  141. The TransformBitmap() function morphs the input bitmap from a
  142. normal bitmap that has it's pixel bits organized as sequential
  143. bits starting from coord (0,0) through (n,n). The bits are
  144. in a stream that proceed from column to column and row to row.
  145. The transformation accomplished by this function changes the bitmap
  146. into one that has it's bits organized in pages, lines, and columns.
  147. Each page is a unit of 8 lines and is organized as follows:
  148. ---------------------------------------------------------
  149. |Columns
  150. ---------------------------------------------------------
  151. | 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14|15|16| ...128
  152. ---------------------------------------------------------
  153. Line #1 | | | | | | | | | | | | | | | | | ...
  154. |--------------------------------------------------------
  155. Line #2 | | | | | | | | | | | | | | | | | ...
  156. |--------------------------------------------------------
  157. Line #3 | | | | | | | | | | | | | | | | | ...
  158. |--------------------------------------------------------
  159. Line #4 | | | | | | | | | | | | | | | | | ...
  160. |--------------------------------------------------------
  161. Line #5 | | | | | | | | | | | | | | | | | ...
  162. |--------------------------------------------------------
  163. Line #6 | | | | | | | | | | | | | | | | | ...
  164. |--------------------------------------------------------
  165. Line #7 | | | | | | | | | | | | | | | | | ...
  166. |--------------------------------------------------------
  167. Line #8 | | | | | | | | | | | | | | | | | ...
  168. |--------------------------------------------------------
  169. The bytes that comprise the bitmap correspond to the columns in the
  170. page, so there are 128 bytes per page. If the first byte of the
  171. transformed bitmap is 0x46 then the pixels in column 1 of lines 2,6,&7
  172. are illuminated by the display.
  173. Arguments:
  174. Bits - Input bits that are to be transformed
  175. Width - Width of the bitmap in pixels
  176. Height - Height of the bitmap in pixels
  177. NewBits - Buffer to hold the newly transformed bitmap
  178. Return Value:
  179. NT status code.
  180. --*/
  181. {
  182. ULONG i,j,k,line,idx,mask,coli;
  183. UCHAR byte;
  184. ULONG padBytes;
  185. ULONG byteWidth;
  186. ULONG NewSize = 0;
  187. //
  188. // Compute the pad bytes. It is assumed
  189. // that the data width of the input bitmap
  190. // is dword aliged long.
  191. //
  192. if (((Width % 32) == 0) || ((Width % 32) > 24)) {
  193. padBytes = 0;
  194. } else if ((Width % 32) <= 8) {
  195. padBytes = 3;
  196. } else if ((Width % 32) <= 16) {
  197. padBytes = 2;
  198. } else {
  199. padBytes = 1;
  200. }
  201. //
  202. // Compute the realy byte width
  203. // based on the pad bytes.
  204. //
  205. byteWidth = (Width / 8) + padBytes;
  206. if (Width % 8) {
  207. byteWidth += 1;
  208. }
  209. //
  210. // Loop through the input bitmap and
  211. // create a new, morphed bitmap.
  212. //
  213. for (i=0; i<DISPLAY_PAGES; i++) {
  214. //
  215. // starting line number for this page
  216. //
  217. line = i * DISPLAY_LINES_PER_PAGE;
  218. //
  219. // This handles the case where the
  220. // input bitmap is not as tall as the display.
  221. //
  222. if (line >= Height) {
  223. break;
  224. }
  225. //
  226. // loop over the bits for this column
  227. //
  228. for (j=0; j<Width; j++) {
  229. //
  230. // Reset the new byte value to a zero state
  231. //
  232. byte = 0;
  233. //
  234. // Compute the column index as the
  235. // current column number divided by 8 (width of a byte)
  236. //
  237. coli = j >> 3;
  238. //
  239. // Compute the mask that is used to test the
  240. // bit in the input bitmap.
  241. //
  242. mask = TestMask[j];
  243. //
  244. // Process the bits in all this pages's lines
  245. // for the current column.
  246. //
  247. for (k=0; k<DISPLAY_LINES_PER_PAGE; k++) {
  248. if ((k + line) >= Height) {
  249. break;
  250. }
  251. //
  252. // index the byte that contains this pixel
  253. //
  254. idx = (((k + line) * byteWidth)) + coli;
  255. //
  256. // set the bit
  257. //
  258. if (Bits[idx] & mask) {
  259. byte = byte | (1 << k);
  260. }
  261. }
  262. //
  263. // Save the new byte in the bitmap
  264. //
  265. *NewBits = byte;
  266. NewBits += 1;
  267. NewSize += 1;
  268. }
  269. }
  270. return NewSize;
  271. }
  272. NTSTATUS
  273. SaDispWrite(
  274. IN PVOID DeviceExtensionIn,
  275. IN PIRP Irp,
  276. IN PVOID FsContext,
  277. IN LONGLONG StartingOffset,
  278. IN PVOID DataBuffer,
  279. IN ULONG DataBufferLength
  280. )
  281. /*++
  282. Routine Description:
  283. This routine processes the write request for the local display miniport.
  284. Arguments:
  285. DeviceExtensionIn - Miniport's device extension
  286. StartingOffset - Starting offset for the I/O
  287. DataBuffer - Pointer to the data buffer
  288. DataBufferLength - Length of the data buffer in bytes
  289. Return Value:
  290. NT status code.
  291. --*/
  292. {
  293. NTSTATUS Status;
  294. PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION) DeviceExtensionIn;
  295. PSA_DISPLAY_SHOW_MESSAGE SaDisplay = (PSA_DISPLAY_SHOW_MESSAGE)DataBuffer;
  296. UCHAR i,j;
  297. PUCHAR NewBits = NULL;
  298. PUCHAR byte;
  299. ULONG Pages;
  300. ULONG NewSize;
  301. UNREFERENCED_PARAMETER(StartingOffset);
  302. if (SaDisplay->Width > DISPLAY_WIDTH || SaDisplay->Height > DISPLAY_HEIGHT) {
  303. REPORT_ERROR( SA_DEVICE_DISPLAY, "Bitmap size is too large\n", STATUS_INVALID_PARAMETER );
  304. return STATUS_INVALID_PARAMETER;
  305. }
  306. NewBits = (PUCHAR) SaPortAllocatePool( DeviceExtension, MAX_BITMAP_SIZE );
  307. if (NewBits == NULL) {
  308. REPORT_ERROR( SA_DEVICE_DISPLAY, "Failed to allocate pool\n", MAX_BITMAP_SIZE );
  309. return STATUS_INSUFFICIENT_RESOURCES;
  310. }
  311. RtlZeroMemory( NewBits, MAX_BITMAP_SIZE );
  312. NewSize = TransformBitmap(
  313. SaDisplay->Bits,
  314. SaDisplay->Width,
  315. SaDisplay->Height,
  316. NewBits
  317. );
  318. if (NewSize == 0) {
  319. SaPortFreePool( DeviceExtension, NewBits );
  320. REPORT_ERROR( SA_DEVICE_DISPLAY, "Failed to transform the bitmap\n", STATUS_UNSUCCESSFUL );
  321. return STATUS_UNSUCCESSFUL;
  322. }
  323. Pages = SaDisplay->Height / DISPLAY_LINES_PER_PAGE;
  324. if (SaDisplay->Height % DISPLAY_LINES_PER_PAGE) {
  325. Pages += 1;
  326. }
  327. for (i=0,byte=NewBits; i<Pages; i++) {
  328. SetDisplayPage( DeviceExtension->VideoMemBase, i );
  329. for (j=0; j<SaDisplay->Width; j++) {
  330. SetDisplayColumnAddress( DeviceExtension->VideoMemBase, j );
  331. SetDisplayData( DeviceExtension->VideoMemBase, *byte );
  332. byte += 1;
  333. }
  334. }
  335. SaPortFreePool( DeviceExtension, NewBits );
  336. return STATUS_SUCCESS;
  337. }
  338. NTSTATUS
  339. DriverEntry(
  340. IN PDRIVER_OBJECT DriverObject,
  341. IN PUNICODE_STRING RegistryPath
  342. )
  343. /*++
  344. Routine Description:
  345. This routine is the driver's entry point, called by the I/O system
  346. to load the driver. The driver's entry points are initialized and
  347. a mutex to control paging is initialized.
  348. In DBG mode, this routine also examines the registry for special
  349. debug parameters.
  350. Arguments:
  351. DriverObject - a pointer to the object that represents this device
  352. driver.
  353. RegistryPath - a pointer to this driver's key in the Services tree.
  354. Return Value:
  355. STATUS_SUCCESS
  356. --*/
  357. {
  358. NTSTATUS Status;
  359. SAPORT_INITIALIZATION_DATA SaPortInitData;
  360. RtlZeroMemory( &SaPortInitData, sizeof(SAPORT_INITIALIZATION_DATA) );
  361. SaPortInitData.StructSize = sizeof(SAPORT_INITIALIZATION_DATA);
  362. SaPortInitData.DeviceType = SA_DEVICE_DISPLAY;
  363. SaPortInitData.HwInitialize = SaDispHwInitialize;
  364. SaPortInitData.Write = SaDispWrite;
  365. SaPortInitData.DeviceIoctl = SaDispDeviceIoctl;
  366. SaPortInitData.DeviceExtensionSize = sizeof(DEVICE_EXTENSION);
  367. Status = SaPortInitialize( DriverObject, RegistryPath, &SaPortInitData );
  368. if (!NT_SUCCESS(Status)) {
  369. REPORT_ERROR( SA_DEVICE_DISPLAY, "SaPortInitialize failed\n", Status );
  370. return Status;
  371. }
  372. return STATUS_SUCCESS;
  373. }