Source code of Windows XP (NT5)
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.

337 lines
8.2 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. abiosc.c
  5. Abstract:
  6. This module implements keybaord detection C routines.
  7. Author:
  8. Shie-Lin Tzong (shielint) 18-Dec-1991
  9. Environment:
  10. Real Mode.
  11. Revision History:
  12. --*/
  13. #include "hwdetect.h"
  14. #include "string.h"
  15. extern
  16. UCHAR
  17. GetKeyboardFlags (
  18. VOID
  19. );
  20. extern
  21. USHORT
  22. HwGetKey (
  23. VOID
  24. );
  25. extern UCHAR NoLegacy;
  26. //
  27. // SavedKey is used to save the key left in the keyboard type-ahead buffer
  28. // before we start our keyboard/mouse tests. The key will be push back
  29. // to the type-ahead buffer once the mouse detection is done.
  30. //
  31. USHORT SavedKey = 0;
  32. BOOLEAN NoBiosKbdCheck=FALSE;
  33. //
  34. // String table to map keyboard id to an ascii string.
  35. //
  36. PUCHAR KeyboardIdentifier[] = {
  37. "UNKNOWN_KEYBOARD",
  38. "OLI_83KEY",
  39. "OLI_102KEY",
  40. "OLI_86KEY",
  41. "OLI_A101_102KEY",
  42. "XT_83KEY",
  43. "ATT_302",
  44. "PCAT_ENHANCED",
  45. "PCAT_86KEY",
  46. "PCXT_84KEY"
  47. };
  48. UCHAR KeyboardType[] = {
  49. 255,
  50. 1,
  51. 2,
  52. 3,
  53. 4,
  54. 1,
  55. 1,
  56. 4,
  57. 3,
  58. 1
  59. };
  60. UCHAR KeyboardSubtype[] = {
  61. 255,
  62. 0,
  63. 1,
  64. 10,
  65. 4,
  66. 42,
  67. 4,
  68. 0,
  69. 0,
  70. 0
  71. };
  72. USHORT
  73. GetKeyboardId(
  74. VOID
  75. )
  76. /*++
  77. Routine Description:
  78. This routine determines the Id of the keyboard. It calls GetKeyboardIdBytes
  79. to complete the task.
  80. Arguments:
  81. None.
  82. Return Value:
  83. Keyboard ID.
  84. --*/
  85. {
  86. char KeybID_Bytes[5];
  87. int Num_ID_Bytes;
  88. int keytype = UNKNOWN_KEYBOARD;
  89. SavedKey = HwGetKey();
  90. keytype = UNKNOWN_KEYBOARD;
  91. if (!NoBiosKbdCheck) {
  92. if (IsEnhancedKeyboard()) {
  93. keytype = PCAT_ENHANCED;
  94. }
  95. }
  96. if (keytype == UNKNOWN_KEYBOARD) {
  97. Num_ID_Bytes = GetKeyboardIdBytes(KeybID_Bytes, 0xf2);
  98. if (Num_ID_Bytes > 0) {
  99. if ((KeybID_Bytes[0] & 0x00ff) == 0xfa) {
  100. keytype = PCAT_86KEY;
  101. } else if ((KeybID_Bytes[0] & 0x00ff) == 0xfe) {
  102. keytype = PCAT_86KEY;
  103. } else if (Num_ID_Bytes >= 3 &&
  104. ((KeybID_Bytes[1] & 0x00ff) == 0xAB) &&
  105. ((KeybID_Bytes[2] & 0x00ff) == 0x41)) {
  106. keytype = PCAT_ENHANCED;
  107. } else {
  108. keytype = UNKNOWN_KEYBOARD;
  109. }
  110. } else {
  111. keytype = UNKNOWN_KEYBOARD;
  112. }
  113. }
  114. return keytype;
  115. }
  116. FPFWCONFIGURATION_COMPONENT_DATA
  117. SetKeyboardConfigurationData (
  118. USHORT KeyboardId
  119. )
  120. /*++
  121. Routine Description:
  122. This routine maps Keyboard Id information to an ASCII string and
  123. stores the string in configuration data heap.
  124. Arguments:
  125. KeyboardId - Supplies a USHORT which describes the keyboard id information.
  126. Buffer - Supplies a pointer to a buffer where to put the ascii.
  127. Returns:
  128. None.
  129. --*/
  130. {
  131. FPFWCONFIGURATION_COMPONENT_DATA Controller, CurrentEntry;
  132. FPFWCONFIGURATION_COMPONENT Component;
  133. HWCONTROLLER_DATA ControlData;
  134. FPHWRESOURCE_DESCRIPTOR_LIST DescriptorList;
  135. CM_KEYBOARD_DEVICE_DATA far *KeyboardData;
  136. USHORT z, Length;
  137. //
  138. // Set up Keyboard Controller component
  139. //
  140. ControlData.NumberPortEntries = 0;
  141. ControlData.NumberIrqEntries = 0;
  142. ControlData.NumberMemoryEntries = 0;
  143. ControlData.NumberDmaEntries = 0;
  144. z = 0;
  145. Controller = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
  146. sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
  147. Component = &Controller->ComponentEntry;
  148. Component->Class = ControllerClass;
  149. Component->Type = KeyboardController;
  150. Component->Flags.ConsoleIn = 1;
  151. Component->Flags.Input = 1;
  152. Component->Version = 0;
  153. Component->Key = 0;
  154. Component->AffinityMask = 0xffffffff;
  155. //
  156. // Only fill this on a machine which is not legacy free
  157. //
  158. if (!NoLegacy) {
  159. //
  160. // Set up Port information
  161. //
  162. ControlData.NumberPortEntries = 2;
  163. ControlData.DescriptorList[z].Type = RESOURCE_PORT;
  164. ControlData.DescriptorList[z].ShareDisposition =
  165. CmResourceShareDeviceExclusive;
  166. ControlData.DescriptorList[z].Flags = CM_RESOURCE_PORT_IO;
  167. #if defined(NEC_98)
  168. ControlData.DescriptorList[z].u.Port.Start.LowPart = 0x41;
  169. #else // PC98
  170. ControlData.DescriptorList[z].u.Port.Start.LowPart = 0x60;
  171. #endif // PC98
  172. ControlData.DescriptorList[z].u.Port.Start.HighPart = 0;
  173. ControlData.DescriptorList[z].u.Port.Length = 1;
  174. z++;
  175. ControlData.DescriptorList[z].Type = RESOURCE_PORT;
  176. ControlData.DescriptorList[z].ShareDisposition =
  177. CmResourceShareDeviceExclusive;
  178. ControlData.DescriptorList[z].Flags = CM_RESOURCE_PORT_IO;
  179. #if defined(NEC_98)
  180. ControlData.DescriptorList[z].u.Port.Start.LowPart = 0x43;
  181. #else // PC98
  182. ControlData.DescriptorList[z].u.Port.Start.LowPart = 0x64;
  183. #endif // PC98
  184. ControlData.DescriptorList[z].u.Port.Start.HighPart = 0;
  185. ControlData.DescriptorList[z].u.Port.Length = 1;
  186. z++;
  187. //
  188. // Set up Irq information
  189. //
  190. ControlData.NumberIrqEntries = 1;
  191. ControlData.DescriptorList[z].Type = RESOURCE_INTERRUPT;
  192. ControlData.DescriptorList[z].ShareDisposition =
  193. CmResourceShareUndetermined;
  194. ControlData.DescriptorList[z].u.Interrupt.Affinity = ALL_PROCESSORS;
  195. ControlData.DescriptorList[z].u.Interrupt.Level = 1;
  196. ControlData.DescriptorList[z].u.Interrupt.Vector = 1;
  197. if (HwBusType == MACHINE_TYPE_MCA) {
  198. ControlData.DescriptorList[z].Flags = LEVEL_SENSITIVE;
  199. } else {
  200. //
  201. // For EISA the LevelTriggered is temporarily set to FALSE.
  202. //
  203. ControlData.DescriptorList[z].Flags = EDGE_TRIGGERED;
  204. }
  205. Controller->ConfigurationData =
  206. HwSetUpResourceDescriptor(Component,
  207. NULL,
  208. &ControlData,
  209. 0,
  210. NULL
  211. );
  212. }
  213. //
  214. // Set up Keyboard peripheral component
  215. //
  216. CurrentEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
  217. sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
  218. Component = &CurrentEntry->ComponentEntry;
  219. Component->Class = PeripheralClass;
  220. Component->Type = KeyboardPeripheral;
  221. Component->Flags.ConsoleIn = 1;
  222. Component->Flags.Input = 1;
  223. Component->Version = 0;
  224. Component->Key = 0;
  225. Component->AffinityMask = 0xffffffff;
  226. Component->ConfigurationDataLength = 0;
  227. CurrentEntry->ConfigurationData = (FPVOID)NULL;
  228. Length = strlen(KeyboardIdentifier[KeyboardId]) + 1;
  229. Component->IdentifierLength = Length;
  230. Component->Identifier = HwAllocateHeap(Length, FALSE);
  231. _fstrcpy(Component->Identifier, KeyboardIdentifier[KeyboardId]);
  232. //
  233. // If we are running on a legacy free machine, we still want to report the
  234. // KeyboardFlags to NTOS
  235. //
  236. if (KeyboardId != UNKNOWN_KEYBOARD || NoLegacy) {
  237. Length = sizeof(HWRESOURCE_DESCRIPTOR_LIST) +
  238. sizeof(CM_KEYBOARD_DEVICE_DATA);
  239. DescriptorList = (FPHWRESOURCE_DESCRIPTOR_LIST)HwAllocateHeap(
  240. Length,
  241. TRUE);
  242. CurrentEntry->ConfigurationData = DescriptorList;
  243. Component->ConfigurationDataLength = Length;
  244. DescriptorList->Count = 1;
  245. DescriptorList->PartialDescriptors[0].Type = RESOURCE_DEVICE_DATA;
  246. DescriptorList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
  247. sizeof(CM_KEYBOARD_DEVICE_DATA);
  248. KeyboardData = (CM_KEYBOARD_DEVICE_DATA far *)(DescriptorList + 1);
  249. KeyboardData->KeyboardFlags = GetKeyboardFlags();
  250. KeyboardData->Type = KeyboardType[KeyboardId];
  251. KeyboardData->Subtype = KeyboardSubtype[KeyboardId];
  252. }
  253. Controller->Child = CurrentEntry;
  254. Controller->Sibling = NULL;
  255. CurrentEntry->Parent = Controller;
  256. CurrentEntry->Sibling = NULL;
  257. CurrentEntry->Child = NULL;
  258. return(Controller);
  259. }