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.

660 lines
11 KiB

  1. /*++
  2. Copyright (c) 1996 Intel Corporation
  3. Copyright (c) 1994 Microsoft Corporation
  4. Module Name:
  5. i64bios.c copied from hali64\x86bios.c
  6. Abstract:
  7. This module implements the platform specific interface between a device
  8. driver and the execution of x86 ROM bios code for the device.
  9. Author:
  10. William K. Cheung (wcheung) 20-Mar-1996
  11. based on the version by David N. Cutler (davec) 17-Jun-1994
  12. Environment:
  13. Kernel mode only.
  14. Revision History:
  15. Bernard Lint, M.Jayakumar November 1998
  16. --*/
  17. #include "halp.h"
  18. #include "emulate.h"
  19. #define LOW_MEM_SEGMET 0
  20. #define LOW_MEM_OFFSET 0
  21. #define SIZE_OF_VECTOR_TABLE 0x400
  22. #define SIZE_OF_BIOS_DATA_AREA 0x400
  23. extern XM_STATUS x86BiosExecuteInterrupt (
  24. IN UCHAR Number,
  25. IN OUT PXM86_CONTEXT Context,
  26. IN PVOID BiosIoSpace OPTIONAL,
  27. IN PVOID BiosIoMemory OPTIONAL
  28. );
  29. extern PVOID x86BiosTranslateAddress (
  30. IN USHORT Segment,
  31. IN USHORT Offset
  32. );
  33. extern BOOLEAN HalpVideoBiosPresent;
  34. extern ULONG HalpMaxPciBus;
  35. ULONG
  36. HalpBiosGetPciConfig(
  37. IN ULONG BusNumber,
  38. IN ULONG SlotNumber,
  39. IN PVOID Buffer,
  40. IN ULONG Offset,
  41. IN ULONG Length
  42. );
  43. ULONG
  44. HalpBiosSetPciConfig(
  45. IN ULONG BusNumber,
  46. IN ULONG SlotNumber,
  47. IN PVOID Buffer,
  48. IN ULONG Offset,
  49. IN ULONG Length
  50. );
  51. //
  52. // Initialize Default X86 bios spaces
  53. //
  54. #define NUMBER_X86_PAGES (0x100000 / PAGE_SIZE) // map through 0xfffff
  55. PVOID HalpIoControlBase = NULL;
  56. PVOID HalpIoMemoryBase = NULL;
  57. PVOID HalpFrameBufferBase = NULL;
  58. PVOID HalpLowMemoryBase = NULL;
  59. #define VGA_FRAMEBUFFER_SIZE (0xc0000 - 0xa0000)
  60. //
  61. // Define global data.
  62. //
  63. ULONG HalpX86BiosInitialized = FALSE;
  64. ULONG HalpEnableInt10Calls = FALSE;
  65. VOID
  66. HalpInitIoMemoryBase(
  67. VOID
  68. )
  69. /*++
  70. Routine Description:
  71. This routine completes any mappings needed by the bios emulation engine. HalpEfiInitialization maps
  72. any EFI descriptor that cover the 1st MB of physical memory. Those mappngs are done according to
  73. the cachable requirements in the descriptors. Most EFI implementations do not cover the VGA range so
  74. this function does that if it is not already mapped.
  75. Arguements:
  76. Return Value:
  77. --*/
  78. {
  79. PHYSICAL_ADDRESS COMPATIBLE_PCI_PHYSICAL_BASE_ADDRESS = { 0xA0000 };
  80. if (HalpFrameBufferBase == NULL) {
  81. HalpFrameBufferBase = MmMapIoSpace (COMPATIBLE_PCI_PHYSICAL_BASE_ADDRESS,
  82. VGA_FRAMEBUFFER_SIZE,
  83. MmNonCached);
  84. ASSERT(HalpFrameBufferBase != NULL);
  85. //
  86. // Adjust to a zero base.
  87. //
  88. HalpFrameBufferBase = (PVOID)((ULONG64) HalpFrameBufferBase - 0XA0000);
  89. }
  90. ASSERT(HalpIoMemoryBase);
  91. }
  92. ULONG
  93. HalpSetCmosData (
  94. IN PVOID BusHandler,
  95. IN PVOID RootHandler,
  96. IN ULONG SlotNumber,
  97. IN PVOID Buffer,
  98. IN ULONG Offset,
  99. IN ULONG Length
  100. )
  101. /*++
  102. Routine Description:
  103. Arguements:
  104. Return Value:
  105. --*/
  106. {
  107. return 0;
  108. }
  109. ULONG
  110. HalpGetCmosData (
  111. IN ULONG BusNumber,
  112. IN ULONG SlotNumber,
  113. IN PVOID Buffer,
  114. IN ULONG Length
  115. )
  116. /*++
  117. Routine Description:
  118. Arguements:
  119. Return Value:
  120. --*/
  121. {
  122. return 0;
  123. }
  124. VOID
  125. HalpAcquireCmosSpinLock (
  126. VOID
  127. )
  128. /*++
  129. Routine Description:
  130. Arguements:
  131. Return Value:
  132. --*/
  133. {
  134. return;
  135. }
  136. VOID
  137. HalpReleaseCmosSpinLock (
  138. VOID
  139. )
  140. /*++
  141. Routine Description:
  142. Arguements:
  143. Return Value:
  144. --*/
  145. {
  146. return ;
  147. }
  148. HAL_DISPLAY_BIOS_INFORMATION
  149. HalpGetDisplayBiosInformation (
  150. VOID
  151. )
  152. /*++
  153. Routine Description:
  154. Arguements:
  155. Return Value:
  156. --*/
  157. {
  158. return HalpVideoBiosPresent ? HalDisplayEmulatedBios : HalDisplayNoBios;
  159. }
  160. VOID
  161. HalpInitializeCmos (
  162. VOID
  163. )
  164. /*++
  165. Routine Description:
  166. Arguements:
  167. Return Value:
  168. --*/
  169. {
  170. return ;
  171. }
  172. VOID
  173. HalpReadCmosTime (
  174. PTIME_FIELDS TimeFields
  175. )
  176. /*++
  177. Routine Description:
  178. Arguements:
  179. Return Value:
  180. --*/
  181. {
  182. return ;
  183. }
  184. VOID
  185. HalpWriteCmosTime (
  186. PTIME_FIELDS TimeFields
  187. )
  188. /*++
  189. Routine Description:
  190. Arguements:
  191. Return Value:
  192. --*/
  193. {
  194. return;
  195. }
  196. BOOLEAN
  197. HalpBiosDisplayReset (
  198. VOID
  199. )
  200. /*++
  201. Routine Description:
  202. Arguements:
  203. Return Value:
  204. --*/
  205. {
  206. //
  207. // Make an int10 call to set the display into 640x480 16 color mode
  208. //
  209. // mov ax, 12h
  210. // int 10h
  211. //
  212. ULONG Eax = 0x12;
  213. ULONG Exx = 0x00;
  214. BOOLEAN Success;
  215. Success = HalCallBios(0x10,
  216. &Eax,
  217. &Exx,
  218. &Exx,
  219. &Exx,
  220. &Exx,
  221. &Exx,
  222. &Exx);
  223. return Success;
  224. }
  225. BOOLEAN
  226. HalCallBios (
  227. IN ULONG BiosCommand,
  228. IN OUT PULONG Eax,
  229. IN OUT PULONG Ebx,
  230. IN OUT PULONG Ecx,
  231. IN OUT PULONG Edx,
  232. IN OUT PULONG Esi,
  233. IN OUT PULONG Edi,
  234. IN OUT PULONG Ebp
  235. )
  236. /*++
  237. Routine Description:
  238. This function provides the platform specific interface between a device
  239. driver and the execution of the x86 ROM bios code for the specified ROM
  240. bios command.
  241. Arguments:
  242. BiosCommand - Supplies the ROM bios command to be emulated.
  243. Eax to Ebp - Supplies the x86 emulation context.
  244. Return Value:
  245. A value of TRUE is returned if the specified function is executed.
  246. Otherwise, a value of FALSE is returned.
  247. --*/
  248. {
  249. XM86_CONTEXT Context;
  250. HalDebugPrint(( HAL_INFO, "HAL: HalCallBios - Cmd = 0x%x, eax = 0x%p\n", BiosCommand, Eax ));
  251. //
  252. // If the x86 BIOS Emulator has not been initialized, then return FALSE.
  253. //
  254. if (HalpX86BiosInitialized == FALSE) {
  255. return FALSE;
  256. }
  257. //
  258. // If the Adapter BIOS initialization failed and an Int10 command is
  259. // specified, then return FALSE.
  260. //
  261. if ((BiosCommand == 0x10) && (HalpEnableInt10Calls == FALSE)) {
  262. return FALSE;
  263. }
  264. //
  265. // Copy the x86 bios context and emulate the specified command.
  266. //
  267. Context.Eax = *Eax;
  268. Context.Ebx = *Ebx;
  269. Context.Ecx = *Ecx;
  270. Context.Edx = *Edx;
  271. Context.Esi = *Esi;
  272. Context.Edi = *Edi;
  273. Context.Ebp = *Ebp;
  274. if (x86BiosExecuteInterruptShadowed((UCHAR)BiosCommand,
  275. &Context,
  276. (PVOID)HalpIoControlBase,
  277. (PVOID)HalpIoMemoryBase,
  278. (PVOID)HalpFrameBufferBase
  279. ) != XM_SUCCESS) {
  280. HalDebugPrint(( HAL_ERROR, "HAL: HalCallBios - ERROR in Cmd = 0x%x\n", BiosCommand ));
  281. return FALSE;
  282. }
  283. //
  284. // Copy the x86 bios context and return TRUE.
  285. //
  286. *Eax = Context.Eax;
  287. *Ebx = Context.Ebx;
  288. *Ecx = Context.Ecx;
  289. *Edx = Context.Edx;
  290. *Esi = Context.Esi;
  291. *Edi = Context.Edi;
  292. *Ebp = Context.Ebp;
  293. return TRUE;
  294. }
  295. VOID
  296. HalpInitializeX86Int10Call(
  297. VOID
  298. )
  299. /*++
  300. Routine Description:
  301. This function initializes x86 bios emulator, display data area and
  302. interrupt vector area.
  303. Arguments:
  304. None.
  305. Return Value:
  306. None.
  307. --*/
  308. {
  309. XM86_CONTEXT State;
  310. PXM86_CONTEXT Context;
  311. PULONG x86BiosLowMemoryPtr, PhysicalMemoryPtr;
  312. if (HalpLowMemoryBase == NULL) {
  313. //
  314. // There is no memory at zero so there cannot be any bios.
  315. //
  316. return;
  317. }
  318. //
  319. // Initialize the x86 bios emulator.
  320. //
  321. x86BiosInitializeBiosShadowedPci(HalpIoControlBase,
  322. HalpIoMemoryBase,
  323. HalpFrameBufferBase,
  324. (UCHAR)(HalpMaxPciBus == 255 ? 255 : (HalpMaxPciBus + 1)),
  325. HalpBiosGetPciConfig,
  326. HalpBiosSetPciConfig
  327. );
  328. x86BiosLowMemoryPtr = (PULONG)(x86BiosTranslateAddress(LOW_MEM_SEGMET, LOW_MEM_OFFSET));
  329. PhysicalMemoryPtr = (PULONG) HalpLowMemoryBase;
  330. //
  331. // Copy the VECTOR TABLE from 0 to 2k. This is because we are not executing
  332. // the initialization of Adapter since SAL takes care of it. However, the
  333. // emulation memory needs to be updated from the interrupt vector and BIOS
  334. // data area.
  335. //
  336. RtlCopyMemory(x86BiosLowMemoryPtr,
  337. PhysicalMemoryPtr,
  338. (SIZE_OF_VECTOR_TABLE+SIZE_OF_BIOS_DATA_AREA)
  339. );
  340. HalpX86BiosInitialized = TRUE;
  341. //
  342. // Check to see if a video bios appears to be present and int10 vector
  343. // points somewhere inside of the video bios
  344. //
  345. {
  346. PUSHORT pBiosSignature = (PUSHORT)(x86BiosTranslateAddress(0xc000, // VIDEO_BIOS_SEGMENT
  347. 0x0000));
  348. ULONG Address = *(PULONG)(x86BiosTranslateAddress(0x0, 0x40));
  349. Address = ((Address & 0xFFFF0000) >> 12) + (Address & 0xFFFF); // Normalize
  350. HalpEnableInt10Calls = (*pBiosSignature == 0xAA55) &&
  351. (Address >= 0xC0000) && (Address < 0xD0000);
  352. }
  353. return;
  354. }
  355. VOID
  356. HalpResetX86DisplayAdapter(
  357. VOID
  358. )
  359. /*++
  360. Routine Description:
  361. This function resets a display adapter using the x86 bios emulator.
  362. Arguments:
  363. None.
  364. Return Value:
  365. None.
  366. --*/
  367. {
  368. ULONG Eax;
  369. ULONG Ebx;
  370. ULONG Ecx;
  371. ULONG Edx;
  372. ULONG Esi;
  373. ULONG Edi;
  374. ULONG Ebp;
  375. //
  376. // Initialize the x86 bios context and make the INT 10 call to initialize
  377. // the display adapter to 80x25 color text mode.
  378. //
  379. Eax = 0x0003; // Function 0, Mode 3
  380. Ebx = 0;
  381. Ecx = 0;
  382. Edx = 0;
  383. Esi = 0;
  384. Edi = 0;
  385. Ebp = 0;
  386. HalCallBios(0x10,
  387. &Eax,
  388. &Ebx,
  389. &Ecx,
  390. &Edx,
  391. &Esi,
  392. &Edi,
  393. &Ebp);
  394. }
  395. ULONG
  396. HalpBiosGetPciConfig(
  397. IN ULONG BusNumber,
  398. IN ULONG SlotNumber,
  399. IN PVOID Buffer,
  400. IN ULONG Offset,
  401. IN ULONG Length
  402. )
  403. /*++
  404. Routine Description:
  405. This function wraps HalGetBusDataByOffset for use by the x86 emulator.
  406. Arguments:
  407. None.
  408. Return Value:
  409. None.
  410. --*/
  411. {
  412. return HalGetBusDataByOffset(PCIConfiguration,
  413. BusNumber,
  414. SlotNumber,
  415. Buffer,
  416. Offset,
  417. Length
  418. );
  419. }
  420. ULONG
  421. HalpBiosSetPciConfig(
  422. IN ULONG BusNumber,
  423. IN ULONG SlotNumber,
  424. IN PVOID Buffer,
  425. IN ULONG Offset,
  426. IN ULONG Length
  427. )
  428. /*++
  429. Routine Description:
  430. This function wraps HalGetBusDataByOffset for use by the x86 emulator.
  431. Arguments:
  432. None.
  433. Return Value:
  434. None.
  435. --*/
  436. {
  437. return HalSetBusDataByOffset(PCIConfiguration,
  438. BusNumber,
  439. SlotNumber,
  440. Buffer,
  441. Offset,
  442. Length
  443. );
  444. }