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.

372 lines
8.1 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. initia64.c
  5. Abstract:
  6. Does any ia64-specific initialization, then starts the common ARC osloader
  7. Author:
  8. John Vert (jvert) 4-Nov-1993
  9. Revision History:
  10. --*/
  11. #include "bldria64.h"
  12. #include "msg.h"
  13. #include <netboot.h>
  14. #include <string.h>
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #include <efi.h>
  18. UCHAR Argv0String[100];
  19. UCHAR BootPartitionName[80];
  20. UCHAR KernelBootDevice[80];
  21. UCHAR OsLoadFilename[100];
  22. UCHAR OsLoaderFilename[100];
  23. UCHAR SystemPartition[100];
  24. UCHAR OsLoadPartition[100];
  25. UCHAR OsLoadOptions[100];
  26. UCHAR ConsoleInputName[50];
  27. UCHAR ConsoleOutputName[50];
  28. UCHAR FullKernelPath[200];
  29. ARC_STATUS
  30. BlGetEfiBootOptions(
  31. OUT PUCHAR Argv0String OPTIONAL,
  32. OUT PUCHAR SystemPartition OPTIONAL,
  33. OUT PUCHAR OsLoaderFilename OPTIONAL,
  34. OUT PUCHAR OsLoadPartition OPTIONAL,
  35. OUT PUCHAR OsLoadFilename OPTIONAL,
  36. OUT PUCHAR FullKernelPath OPTIONAL,
  37. OUT PUCHAR OsLoadOptions OPTIONAL
  38. );
  39. BlPreProcessLoadOptions(
  40. PCHAR szOsLoadOptions
  41. );
  42. #define MAXBOOTVARSIZE 1024
  43. VOID
  44. BlpTruncateMemory (
  45. IN ULONG MaxMemory
  46. );
  47. #if defined(_MERCED_A0_)
  48. VOID
  49. KiProcessorWorkAround(
  50. );
  51. #endif
  52. VOID
  53. BlStartup(
  54. IN PCHAR PartitionName
  55. )
  56. /*++
  57. Routine Description:
  58. Does Intel-specific initialization, particularly presenting the boot.ini
  59. menu and running NTDETECT, then calls to the common osloader.
  60. Arguments:
  61. PartitionName - Supplies the ARC name of the partition (or floppy) that
  62. setupldr was loaded from.
  63. Return Value:
  64. Does not return
  65. --*/
  66. {
  67. ULONG Argc = 0;
  68. PUCHAR Argv[10];
  69. ARC_STATUS Status;
  70. ULONG BootFileId;
  71. PCHAR BootFile;
  72. ULONG Read;
  73. #if !defined(NO_LEGACY_DRIVERS)
  74. PCHAR p;
  75. #endif
  76. ULONG i;
  77. ULONG DriveId;
  78. ULONG FileSize;
  79. ULONG Count;
  80. LARGE_INTEGER SeekPosition;
  81. PCHAR LoadOptions = NULL;
  82. #ifdef FW_HEAP
  83. extern BOOLEAN FwDescriptorsValid;
  84. #endif
  85. PCHAR BadLinkName = NULL;
  86. UNREFERENCED_PARAMETER( PartitionName );
  87. //
  88. // Initialize ARC StdIo functionality
  89. //
  90. strcpy(ConsoleInputName,"consolein=multi(0)key(0)keyboard(0)");
  91. strcpy(ConsoleOutputName,"consoleout=multi(0)video(0)monitor(0)");
  92. Argv[0]=ConsoleInputName;
  93. Argv[1]=ConsoleOutputName;
  94. BlInitStdio (2, Argv);
  95. //
  96. // Check ntldr partition for hiberation image
  97. //
  98. do {
  99. BlClearScreen();
  100. Status = BlGetEfiBootOptions(
  101. Argv0String,
  102. SystemPartition,
  103. OsLoaderFilename,
  104. OsLoadPartition,
  105. OsLoadFilename,
  106. FullKernelPath,
  107. OsLoadOptions
  108. );
  109. if ( Status != ESUCCESS ) {
  110. BlPrint(BlFindMessage(BL_EFI_OPTION_FAILURE));
  111. goto BootFailed;
  112. }
  113. BlClearScreen();
  114. #if !defined(NO_LEGACY_DRIVERS)
  115. p = FullKernelPath;
  116. //
  117. // Initialize SCSI boot driver, if necessary.
  118. //
  119. if(!_strnicmp(p,"scsi(",5)) {
  120. AEInitializeIo(DriveId);
  121. }
  122. #endif // NO_LEGACY_DRIVERS
  123. #if FW_HEAP
  124. //
  125. // Indicate that fw memory descriptors cannot be changed from
  126. // now on.
  127. //
  128. FwDescriptorsValid = FALSE;
  129. #endif
  130. //
  131. // convert it to all one case
  132. //
  133. if (OsLoadOptions[0]) {
  134. _strupr(OsLoadOptions);
  135. }
  136. Argv[Argc++]=Argv0String;
  137. Argv[Argc++]=OsLoaderFilename;
  138. Argv[Argc++]=SystemPartition;
  139. Argv[Argc++]=OsLoadFilename;
  140. Argv[Argc++]=OsLoadPartition;
  141. Argv[Argc++]=OsLoadOptions;
  142. BlPreProcessLoadOptions( OsLoadOptions );
  143. //
  144. // In the x86 case, we would have already initialized the
  145. // headless port so that the user could actually make his
  146. // boot selection over the headless port. However, on ia64,
  147. // that selection is happening during firmware.
  148. //
  149. // If the user wants us to redirect (via the OsLoadOptions), then
  150. // we should try to do it here.
  151. //
  152. if( strstr(OsLoadOptions, "/REDIRECT")) {
  153. //
  154. // Yep, then want us to redirect. Try and initialize the
  155. // port.
  156. //
  157. BlInitializeHeadlessPort();
  158. #if 0
  159. if( LoaderRedirectionInformation.PortNumber == 0 ) {
  160. //
  161. // We couldn't get any redirection information
  162. // from the firmware. But the user really wants
  163. // us to redirect. Better guess.
  164. //
  165. LoaderRedirectionInformation.PortNumber = 1;
  166. LoaderRedirectionInformation.BaudRate = 9600;
  167. //
  168. // Now try again, this time with feeling...
  169. //
  170. BlInitializeHeadlessPort();
  171. }
  172. #endif
  173. }
  174. Status = BlOsLoader( Argc, Argv, NULL );
  175. BootFailed:
  176. if (Status != ESUCCESS) {
  177. //
  178. // Boot failed, wait for reboot
  179. //
  180. while (TRUE) {
  181. while (!BlGetKey()); // BOOT FAILED!
  182. if (BlTerminalHandleLoaderFailure()) {
  183. ArcRestart();
  184. }
  185. }
  186. }
  187. } while (TRUE);
  188. }
  189. BlPreProcessLoadOptions(
  190. PCHAR szOsLoadOptions
  191. )
  192. {
  193. CHAR szTemp[MAXBOOTVARSIZE];
  194. PCHAR p;
  195. ULONG MaxMemory = 0;
  196. ULONG ConfigFlagValue=0;
  197. strcpy( szTemp, szOsLoadOptions );
  198. _strupr( szTemp );
  199. #if 0
  200. if( p = strstr( szTemp, ";" ) ) {
  201. *p = '\0';
  202. }
  203. #endif
  204. //
  205. // Process MAXMEM
  206. //
  207. if( p = strstr( szTemp, "/MAXMEM=" ) ) {
  208. MaxMemory = atoi( p + sizeof("/MAXMEM=") - 1 );
  209. BlpTruncateMemory( MaxMemory );
  210. }
  211. #if defined(_MERCED_A0_)
  212. //
  213. // Process CONFIGFLAG
  214. //
  215. if ( p = strstr(szTemp, "CONFIGFLAG") ) {
  216. if ( p = strstr(p, "=") ) {
  217. ConfigFlagValue = atol(p+1);
  218. KiProcessorWorkAround(ConfigFlagValue);
  219. }
  220. }
  221. #endif
  222. }
  223. BOOLEAN
  224. WillMemoryBeUsableByOs(
  225. IN MEMORY_TYPE Type
  226. )
  227. {
  228. BOOLEAN RetVal = FALSE;
  229. switch (Type) {
  230. case MemoryFree:
  231. case MemoryFreeContiguous:
  232. case MemoryFirmwareTemporary:
  233. case MemorySpecialMemory:
  234. RetVal = TRUE;
  235. }
  236. return(RetVal);
  237. }
  238. VOID
  239. BlpTruncateMemory (
  240. IN ULONG MaxMemory
  241. )
  242. /*++
  243. Routine Description:
  244. Eliminates all the memory descriptors above a given boundary
  245. Arguments:
  246. MaxMemory - Supplies the maximum memory boundary in megabytes
  247. Return Value:
  248. None.
  249. --*/
  250. {
  251. ULONG MaxPage = (MaxMemory * _1MB );
  252. PLIST_ENTRY Current;
  253. PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
  254. if (MaxMemory == 0) {
  255. return;
  256. }
  257. Current = BlLoaderBlock->MemoryDescriptorListHead.Flink;
  258. while (Current != &BlLoaderBlock->MemoryDescriptorListHead) {
  259. MemoryDescriptor = CONTAINING_RECORD(Current,
  260. MEMORY_ALLOCATION_DESCRIPTOR,
  261. ListEntry);
  262. Current = Current->Flink;
  263. if (WillMemoryBeUsableByOs(MemoryDescriptor->MemoryType)) {
  264. if (MemoryDescriptor->BasePage >= MaxPage) {
  265. //
  266. // This memory descriptor lies entirely above the boundary,
  267. // mark it as firmware permanent. this is easier than
  268. // unlinking the entry and has the same effect since no one
  269. // can use this memory.
  270. //
  271. MemoryDescriptor->MemoryType = MemoryFirmwarePermanent;
  272. } else if (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount > MaxPage) {
  273. //
  274. // This memory descriptor crosses the boundary, truncate it.
  275. //
  276. MemoryDescriptor->PageCount = MaxPage - MemoryDescriptor->BasePage;
  277. } else {
  278. //
  279. // This one's ok, keep it.
  280. //
  281. }
  282. } else {
  283. //
  284. // skip it
  285. //
  286. }
  287. }
  288. }