]>
git.saurik.com Git - apple/bootx.git/blob - bootx.tproj/sl.subproj/main.c
b1d194a1479a514d63c6f142d55e6b3c7fdff4d9
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * main.c - Main functions for BootX.
25 * Copyright (c) 1998-2002 Apple Computer, Inc.
33 static void Start(void *unused1
, void *unused2
, ClientInterfacePtr ciPtr
);
34 static void Main(ClientInterfacePtr ciPtr
);
35 static long InitEverything(ClientInterfacePtr ciPtr
);
36 static long DecodeKernel(void);
37 static long SetUpBootArgs(void);
38 static long CallKernel(void);
39 static void FailToBoot(long num
);
40 static long InitMemoryMap(void);
41 static long GetOFVersion(void);
42 static long TestForKey(long key
);
43 static long GetBootPaths(void);
45 const unsigned long StartTVector
[2] = {(unsigned long)Start
, 0};
47 char gStackBaseAddr
[0x8000];
49 char *gVectorSaveAddr
;
50 long gImageLastKernelAddr
= 0;
51 long gImageFirstBootXAddr
= kLoadAddr
;
52 long gKernelEntryPoint
;
57 long gSymbolTableAddr
;
58 long gSymbolTableSize
;
60 long gBootSourceNumber
= -1;
61 long gBootSourceNumberMax
;
62 long gBootMode
= kBootModeNormal
;
65 char gBootDevice
[256];
71 long *gDeviceTreeMMTmp
= 0;
90 static void Start(void *unused1
, void *unused2
, ClientInterfacePtr ciPtr
)
94 // Move the Stack to a chunk of the BSS
95 newSP
= (long)gStackBaseAddr
+ sizeof(gStackBaseAddr
) - 0x100;
96 __asm__
volatile("mr r1, %0" : : "r" (newSP
));
102 static void Main(ClientInterfacePtr ciPtr
)
106 ret
= InitEverything(ciPtr
);
107 if (ret
!= 0) Exit();
109 // Get or infer the boot paths.
110 ret
= GetBootPaths();
111 if (ret
!= 0) FailToBoot(1);
116 ret
= LoadFile(gBootFile
);
117 if (ret
!= -1) break;
119 ret
= GetBootPaths();
120 if (ret
!= 0) FailToBoot(2);
123 ret
= DecodeKernel();
124 if (ret
!= 0) FailToBoot(3);
126 ret
= LoadDrivers(gRootDir
);
127 if (ret
!= 0) FailToBoot(4);
131 ret
= SetUpBootArgs();
132 if (ret
!= 0) FailToBoot(5);
140 static long InitEverything(ClientInterfacePtr ciPtr
)
142 long ret
, mem_base
, mem_base2
, size
;
144 char name
[32], securityMode
[33];
146 // Init the OF Client Interface.
148 if (ret
!= 0) return -1;
150 // Get the OF Version
151 gOFVersion
= GetOFVersion();
152 if (gOFVersion
== 0) return -1;
154 // Init the SL Words package.
156 if (ret
!= 0) return -1;
158 // Get the phandle for /options
159 gOptionsPH
= FindDevice("/options");
160 if (gOptionsPH
== -1) return -1;
162 // Get the phandle for /chosen
163 gChosenPH
= FindDevice("/chosen");
164 if (gChosenPH
== -1) return -1;
166 // Init the Memory Map.
167 ret
= InitMemoryMap();
168 if (ret
!= 0) return -1;
170 // Get IHandles for the MMU and Memory
171 size
= GetProp(gChosenPH
, "mmu", (char *)&gMMUIH
, 4);
173 printf("Failed to get the IH for the MMU.\n");
176 size
= GetProp(gChosenPH
, "memory", (char *)&gMemoryIH
, 4);
178 printf("Failed to get the IH for the Memory.\n");
182 // Get stdout's IH, so that the boot display can be found.
183 ret
= GetProp(gChosenPH
, "stdout", (char *)&gStdOutIH
, 4);
184 if (ret
== 4) gStdOutPH
= InstanceToPackage(gStdOutIH
);
185 else gStdOutPH
= gStdOutIH
= 0;
187 // Try to find the keyboard using chosen
188 ret
= GetProp(gChosenPH
, "stdin", (char *)&gKeyboardIH
, 4);
189 if (ret
!= 4) gKeyboardIH
= 0;
191 keyboardPH
= InstanceToPackage(gKeyboardIH
);
192 ret
= GetProp(keyboardPH
, "name", name
, 31);
195 if (strcmp(name
, "keyboard") && strcmp(name
, "kbd")) gKeyboardIH
= 0;
196 } else gKeyboardIH
= 0;
199 // Try to the find the keyboard using open if chosen did not work.
200 if (gKeyboardIH
== 0) gKeyboardIH
= Open("keyboard");
201 if (gKeyboardIH
== 0) gKeyboardIH
= Open("kbd");
203 // Get the key map set up, and make it up to date.
204 gKeyMap
= InitKeyMap(gKeyboardIH
);
205 if (gKeyMap
== NULL
) return -1;
208 // Test for Secure Boot Mode.
209 size
= GetProp(gOptionsPH
, "security-mode", securityMode
, 32);
211 securityMode
[size
] = '\0';
212 if (strcmp(securityMode
, "none")) gBootMode
|= kBootModeSecure
;
216 // 'cmd-s' or 'cmd-v' is pressed set outputLevel to kOutputLevelFull
217 if (((gBootMode
& kBootModeSecure
) == 0) && TestForKey(kCommandKey
) &&
218 (TestForKey('s') || TestForKey('v'))) {
219 SetOutputLevel(kOutputLevelFull
);
221 SetOutputLevel(kOutputLevelOff
);
224 SetOutputLevel(kOutputLevelFull
);
228 printf("\n\nMac OS X Loader\n");
230 // Test for Safe Boot Mode.
231 if (((gBootMode
& kBootModeSecure
) == 0) && TestForKey(kShiftKey
)) {
232 gBootMode
|= kBootModeSafe
;
235 if (Claim(kMallocAddr
, kMallocSize
, 0) == 0) {
236 printf("Claim for malloc failed.\n");
239 malloc_init((char *)kMallocAddr
, kMallocSize
);
243 // Claim the memory for the Load Addr
244 mem_base
= Claim(kLoadAddr
, kLoadSize
, 0);
246 printf("Claim for Load Area failed.\n");
250 // Claim the memory for the Image Addr
251 if (gOFVersion
>= kOFVersion3x
) {
252 mem_base
= Claim(kImageAddr
, kImageSize
, 0);
254 printf("Claim for Image Area failed.\n");
258 // Claim the 1:1 mapped chunks first.
259 mem_base
= Claim(kImageAddr0
, kImageSize0
, 0);
260 mem_base2
= Claim(kImageAddr2
, kImageSize2
, 0);
261 if ((mem_base
== 0) || (mem_base2
== 0)) {
262 printf("Claim for Image Area failed.\n");
266 // Unmap the old xcoff stack.
267 CallMethod(2, 0, gMMUIH
, "unmap", 0x00380000, 0x00080000);
269 // Grap the physical memory then the logical.
270 CallMethod(3, 1, gMemoryIH
, "claim",
271 kImageAddr1Phys
, kImageSize1
, 0, &mem_base
);
272 CallMethod(3, 1, gMMUIH
, "claim",
273 kImageAddr1
, kImageSize1
, 0, &mem_base2
);
274 if ((mem_base
== 0) || (mem_base2
== 0)) {
275 printf("Claim for Image Area failed.\n");
279 // Map them together.
280 CallMethod(4, 0, gMMUIH
, "map",
281 kImageAddr1Phys
, kImageAddr1
, kImageSize1
, 0);
284 bzero((char *)kImageAddr
, kImageSize
);
286 // Allocate some space for the Vector Save area.
287 gVectorSaveAddr
= AllocateBootXMemory(kVectorSize
);
288 if (gVectorSaveAddr
== 0) {
289 printf("Allocation for the Vector Save Area failed.\n");
293 // Find all the displays and set them up.
294 ret
= InitDisplays();
296 printf("InitDisplays failed.\n");
304 static long DecodeKernel(void)
309 if (ret
== -1) ret
= DecodeElf();
315 static long SetUpBootArgs(void)
319 long graphicsBoot
= 1;
320 long ret
, cnt
, mem_size
, size
, dash
;
321 long sKey
, vKey
, keyPos
;
322 char ofBootArgs
[128], *ofArgs
, tc
, keyStr
[8];
324 // Save file system cache statistics.
325 SetProp(gChosenPH
, "BootXCacheHits", (char *)&gCacheHits
, 4);
326 SetProp(gChosenPH
, "BootXCacheMisses", (char *)&gCacheMisses
, 4);
327 SetProp(gChosenPH
, "BootXCacheEvicts", (char *)&gCacheEvicts
, 4);
329 // Allocate some memory for the BootArgs.
330 gBootArgsSize
= sizeof(boot_args
);
331 gBootArgsAddr
= AllocateKernelMemory(gBootArgsSize
);
333 // Add the BootArgs to the memory-map.
334 AllocateMemoryRange("BootArgs", gBootArgsAddr
, gBootArgsSize
);
336 args
= (boot_args_ptr
)gBootArgsAddr
;
338 args
->Revision
= kBootArgsRevision
;
339 args
->Version
= kBootArgsVersion
;
340 args
->machineType
= 0;
342 // Check the Keyboard for 'cmd-s' and 'cmd-v'
344 if ((gBootMode
& kBootModeSecure
) == 0) {
345 sKey
= TestForKey(kCommandKey
) && TestForKey('s');
346 vKey
= TestForKey(kCommandKey
) && TestForKey('v');
352 // if 'cmd-s' or 'cmd-v' was pressed do a text boot.
353 if (sKey
|| vKey
) graphicsBoot
= 0;
355 // Create the command line.
356 if (gOFVersion
< kOFVersion3x
) {
358 size
= GetProp(gChosenPH
, "machargs", ofBootArgs
+ 1, 126);
360 size
= GetProp(gOptionsPH
, "boot-command", ofBootArgs
, 127);
361 if (size
== -1) ofBootArgs
[0] = '\0';
362 else ofBootArgs
[size
] = '\0';
363 // Look for " bootr" but skip the number.
364 if (!strncmp(ofBootArgs
+ 1, " bootr", 6)) {
365 strcpy(ofBootArgs
, ofBootArgs
+ 7);
366 } else ofBootArgs
[0] = '\0';
367 SetProp(gChosenPH
, "machargs", ofBootArgs
, strlen(ofBootArgs
) + 1);
368 } else ofBootArgs
[size
] = '\0';
369 // Force boot-command to start with 0 bootr.
370 sprintf(gTempStr
, "0 bootr%s", ofBootArgs
);
371 SetProp(gOptionsPH
, "boot-command", gTempStr
, strlen(gTempStr
));
373 size
= GetProp(gOptionsPH
, "boot-args", ofBootArgs
, 127);
374 if (size
== -1) ofBootArgs
[0] = '\0';
375 else ofBootArgs
[size
] = '\0';
378 if (ofBootArgs
[0] != '\0') {
379 // Look for special options and copy the rest.
382 while ((tc
= *ofArgs
) != '\0') {
385 // Check for entering a dash arg.
392 // Do special stuff if in a dash arg.
398 } else if (tc
== 'v') {
403 // Check for exiting dash arg
404 if (isspace(tc
)) dash
= 0;
406 // Copy any non 's' or 'v'
410 // Not a dash arg so just copy it.
416 // Add any pressed keys (s, v, shift) to the command line
418 if (sKey
|| vKey
|| (gBootMode
& kBootModeSafe
)) {
419 keyStr
[keyPos
++] = '-';
421 if (sKey
) keyStr
[keyPos
++] = 's';
422 if (vKey
) keyStr
[keyPos
++] = 'v';
423 if (gBootMode
& kBootModeSafe
) keyStr
[keyPos
++] = 'x';
425 keyStr
[keyPos
++] = ' ';
427 keyStr
[keyPos
++] = '\0';
429 sprintf(args
->CommandLine
, "%s%s", keyStr
, ofBootArgs
);
431 // Get the memory info
432 memoryPH
= FindDevice("/memory");
433 if (memoryPH
== -1) return -1;
434 size
= GetProp(memoryPH
, "reg", (char *)(args
->PhysicalDRAM
),
435 kMaxDRAMBanks
* sizeof(DRAMBank
));
436 if (size
== 0) return -1;
438 // This is a hack to make the memory look like its all
441 for (cnt
= 0; cnt
< kMaxDRAMBanks
; cnt
++) {
442 mem_size
+= args
->PhysicalDRAM
[cnt
].size
;
443 args
->PhysicalDRAM
[cnt
].base
= 0;
444 args
->PhysicalDRAM
[cnt
].size
= 0;
446 args
->PhysicalDRAM
[0].size
= mem_size
;
448 // Get the video info
449 GetMainScreenPH(&args
->Video
);
450 args
->Video
.v_display
= graphicsBoot
;
452 // Add the DeviceTree to the memory-map.
453 // The actuall address and size must be filled in later.
454 AllocateMemoryRange("DeviceTree", 0, 0);
456 ret
= FlattenDeviceTree();
457 if (ret
!= 0) return -1;
459 // Fill in the address and size of the device tree.
460 if (gDeviceTreeAddr
) {
461 gDeviceTreeMMTmp
[0] = gDeviceTreeAddr
;
462 gDeviceTreeMMTmp
[1] = gDeviceTreeSize
;
465 args
->deviceTreeP
= (void *)gDeviceTreeAddr
;
466 args
->deviceTreeLength
= gDeviceTreeSize
;
467 args
->topOfKernelData
= AllocateKernelMemory(0);
473 static long CallKernel(void)
479 printf("\nCall Kernel!\n");
482 __asm__
volatile("mtmsr %0" : : "r" (msr
));
483 __asm__
volatile("isync");
485 // Move the Execption Vectors
486 bcopy(gVectorSaveAddr
, 0x0, kVectorSize
);
487 for (cnt
= 0; cnt
< kVectorSize
; cnt
+= 0x20) {
488 __asm__
volatile("dcbf 0, %0" : : "r" (cnt
));
489 __asm__
volatile("icbi 0, %0" : : "r" (cnt
));
492 // Move the Image1 save area for OF 1.x / 2.x
493 if (gOFVersion
< kOFVersion3x
) {
494 bcopy((char *)kImageAddr1Phys
, (char *)kImageAddr1
, kImageSize1
);
495 for (cnt
= kImageAddr1
; cnt
< kImageSize1
; cnt
+= 0x20) {
496 __asm__
volatile("dcbf 0, %0" : : "r" (cnt
));
497 __asm__
volatile("icbi 0, %0" : : "r" (cnt
));
501 // Make sure everything get sync'd up.
502 __asm__
volatile("isync");
503 __asm__
volatile("sync");
504 __asm__
volatile("eieio");
506 (*(void (*)())gKernelEntryPoint
)(gBootArgsAddr
, kMacOSXSignature
);
512 static void FailToBoot(long num
)
515 DrawFailedBootPicture();
519 printf("FailToBoot: %d\n", num
);
520 Enter(); // For debugging
525 static long InitMemoryMap(void)
529 result
= Interpret(0, 1,
532 " \" memory-map\" device-name"
541 static long GetOFVersion(void)
544 char versStr
[256], *tmpStr
;
547 // Get the openprom package
548 ph
= FindDevice("/openprom");
549 if (ph
== -1) return 0;
551 // Get it's model property
552 size
= GetProp(ph
, "model", versStr
, 255);
553 if (size
== -1) return -1;
554 versStr
[size
] = '\0';
556 // Find the start of the number.
558 if (!strncmp(versStr
, "Open Firmware, ", 15)) {
559 tmpStr
= versStr
+ 15;
560 } else if (!strncmp(versStr
, "OpenFirmware ", 13)) {
561 tmpStr
= versStr
+ 13;
564 // Clasify by each instance as needed...
587 static long TestForKey(long key
)
593 if (gOFVersion
< kOFVersion3x
) {
595 case 'a' : keyNum
= 7; break;
596 case 's' : keyNum
= 6; break;
597 case 'v' : keyNum
= 14; break;
598 case 'y' : keyNum
= 23; break;
599 case kCommandKey
: keyNum
= 48; break;
600 case kOptKey
: keyNum
= 61; break;
601 case kShiftKey
: keyNum
= 63; break;
602 case kControlKey
: keyNum
= 49; break;
603 default : keyNum
= -1; break;
607 case 'a' : keyNum
= 3; break;
608 case 's' : keyNum
= 17; break;
609 case 'v' : keyNum
= 30; break;
610 case 'y' : keyNum
= 27; break;
611 case kCommandKey
: keyNum
= 228; break;
612 case kOptKey
: keyNum
= 229; break;
613 case kShiftKey
: keyNum
= 230; break;
614 case kControlKey
: keyNum
= 231; break;
615 default : keyNum
= -1; break;
618 // Map the right modifier keys on to the left.
619 gKeyMap
[28] |= gKeyMap
[28] << 4;
622 if (keyNum
== -1) return 0;
625 tc
= gKeyMap
[keyNum
>> 3];
627 return (tc
& (1 << bp
)) != 0;
631 #define kBootpBootFileOffset (108)
633 static long GetBootPaths(void)
635 long ret
, cnt
, cnt2
, cnt3
, cnt4
, size
, partNum
, bootplen
, bsdplen
;
636 char *filePath
, *buffer
;
638 if (gBootSourceNumber
== -1) {
639 // Get the boot-device
640 size
= GetProp(gChosenPH
, "bootpath", gBootDevice
, 255);
641 gBootDevice
[size
] = '\0';
642 if (gBootDevice
[0] == '\0') {
643 size
= GetProp(gOptionsPH
, "boot-device", gBootDevice
, 255);
644 gBootDevice
[size
] = '\0';
646 gBootDeviceType
= GetDeviceType(gBootDevice
);
649 size
= GetProp(gChosenPH
, "bootargs", gBootFile
, 256);
650 gBootFile
[size
] = '\0';
652 if (gBootFile
[0] != '\0') {
653 gBootFileType
= GetDeviceType(gBootFile
);
654 gBootSourceNumberMax
= 0;
656 gBootSourceNumber
= 0;
657 gBootFileType
= gBootDeviceType
;
658 if (gBootFileType
== kNetworkDeviceType
) gBootSourceNumberMax
= 1;
660 if (gOFVersion
< kOFVersion3x
) {
661 gBootSourceNumberMax
= 4;
663 gBootSourceNumberMax
= 6;
668 if (gBootFileType
== kNetworkDeviceType
) {
669 SetProp(Peer(0), "net-boot", NULL
, 0);
673 if (gBootSourceNumber
>= gBootSourceNumberMax
) return -1;
675 if (gBootSourceNumberMax
!= 0) {
676 switch (gBootFileType
) {
677 case kNetworkDeviceType
:
678 // Find the end of the device spec.
680 while (gBootDevice
[cnt
] != ':') cnt
++;
682 // Copy the device spec with the ':'.
683 strncpy(gBootFile
, gBootDevice
, cnt
+ 1);
685 // Check for bootp-responce or bsdp-responce.
686 bootplen
= GetPropLen(gChosenPH
, "bootp-response");
687 bsdplen
= GetPropLen(gChosenPH
, "bsdp-response");
688 if ((bootplen
> 0) || (bsdplen
> 0)) {
690 buffer
= malloc(bootplen
);
691 GetProp(gChosenPH
, "bootp-response", buffer
, bootplen
);
693 buffer
= malloc(bsdplen
);
694 GetProp(gChosenPH
, "bsdp-response", buffer
, bsdplen
);
697 // Flip the slash's to back slash's while looking for the last one.
698 cnt
= cnt2
= kBootpBootFileOffset
;
699 while (buffer
[cnt
] != '\0') {
700 if (buffer
[cnt
] == '/') {
707 // Add a comma at the front.
708 buffer
[kBootpBootFileOffset
- 1] = ',';
710 // Append the the root dir to the device spec.
711 strncat(gBootFile
, buffer
+ kBootpBootFileOffset
- 1,
712 cnt2
- kBootpBootFileOffset
+ 1);
716 // Look for the start of the root dir path.
718 while (gBootDevice
[cnt3
] != ',') cnt3
++;
720 // Find the end of the path. Look for a comma or null.
722 while ((gBootDevice
[cnt2
] != '\0') && (gBootDevice
[cnt2
] != ',')) cnt2
++;
724 // Find the last back slash or comma in the path
726 while ((gBootDevice
[cnt4
] != ',') && (gBootDevice
[cnt4
] != '\\')) cnt4
--;
728 // Copy the IP addresses if needed.
729 if (gOFVersion
< kOFVersion3x
) {
730 strncat(gBootFile
, gBootDevice
+ cnt
+ 1, cnt3
- cnt
- 1);
733 // Add on the directory path
734 strncat(gBootFile
, gBootDevice
+ cnt3
, cnt4
- cnt3
+ 1);
737 // Add on the kernel name
738 strcat(gBootFile
, "mach.macosx");
741 strcat(gBootFile
, gBootDevice
+ cnt2
);
744 case kBlockDeviceType
:
745 // Find the first ':'.
747 while ((gBootDevice
[cnt
] != '\0') && (gBootDevice
[cnt
] != ':')) cnt
++;
748 if (gBootDevice
[cnt
] == '\0') return -1;
750 // Find the comma after the ':'.
752 while ((gBootDevice
[cnt2
] != '\0') && (gBootDevice
[cnt
] != ',')) cnt2
++;
754 // Get just the partition number
755 strncpy(gBootFile
, gBootDevice
+ cnt
+ 1, cnt2
- cnt
- 1);
756 partNum
= atoi(gBootFile
);
758 // Adjust the partition number.
759 // Pass 0 & 1, no offset. Pass 2 & 3, offset 1, Pass 4 & 5, offset 2.
760 partNum
+= gBootSourceNumber
/ 2;
762 // Construct the boot-file
763 strncpy(gBootFile
, gBootDevice
, cnt
+ 1);
764 sprintf(gBootFile
+ cnt
+ 1, "%d,%s\\mach_kernel",
765 partNum
, ((gBootSourceNumber
& 1) ? "" : "\\"));
769 printf("Failed to infer Boot Device Type.\n");
775 // Figure out the root dir.
776 ret
= ConvertFileSpec(gBootFile
, gRootDir
, &filePath
);
777 if (ret
== -1) return -1;
779 strcat(gRootDir
, ",");
781 // Add in any extra path to gRootDir.
783 while (filePath
[cnt
] != '\0') cnt
++;
786 for (cnt2
= cnt
- 1; cnt2
>= 0; cnt2
--) {
787 if (filePath
[cnt2
] == '\\') {
788 strncat(gRootDir
, filePath
, cnt2
+ 1);
794 SetProp(gChosenPH
, "rootpath", gBootFile
, strlen(gBootFile
) + 1);
803 long GetDeviceType(char *devSpec
)
809 ph
= FindDevice(devSpec
);
810 if (ph
== -1) return -1;
812 size
= GetProp(ph
, "device_type", deviceType
, 31);
813 if (size
!= -1) deviceType
[size
] = '\0';
814 else deviceType
[0] = '\0';
816 if (strcmp(deviceType
, "network") == 0) return kNetworkDeviceType
;
817 if (strcmp(deviceType
, "block") == 0) return kBlockDeviceType
;
819 return kUnknownDeviceType
;
823 long ConvertFileSpec(char *fileSpec
, char *devSpec
, char **filePath
)
827 // Find the first ':' in the fileSpec.
829 while ((fileSpec
[cnt
] != '\0') && (fileSpec
[cnt
] != ':')) cnt
++;
830 if (fileSpec
[cnt
] == '\0') return -1;
832 // Find the next ',' in the fileSpec.
833 while ((fileSpec
[cnt
] != '\0') && (fileSpec
[cnt
] != ',')) cnt
++;
835 // Copy the string to devSpec.
836 strncpy(devSpec
, fileSpec
, cnt
);
839 // If there is a filePath start it after the ',', otherwise NULL.
840 if (filePath
!= NULL
) {
841 if (fileSpec
[cnt
] != '\0') {
842 *filePath
= fileSpec
+ cnt
+ 1;
852 long MatchThis(CICell phandle
, char *string
)
855 char *name
, *model
, *compatible
;
857 ret
= GetPackageProperty(phandle
, "name", &name
, &length
);
858 if ((ret
== -1) || (length
== 0)) name
= NULL
;
860 ret
= GetPackageProperty(phandle
, "model", &model
, &length
);
861 if ((ret
== -1) || (length
== 0)) model
= NULL
;
863 ret
= GetPackageProperty(phandle
, "compatible", &compatible
, &length
);
864 if ((ret
== -1) || (length
== 0)) model
= NULL
;
866 if ((name
!= NULL
) && strcmp(name
, string
) == 0) return 0;
867 if ((model
!= NULL
) && strcmp(model
, string
) == 0) return 0;
869 if (compatible
!= NULL
) {
870 while (*compatible
!= '\0') {
871 if (strcmp(compatible
, string
) == 0) return 0;
873 compatible
+= strlen(compatible
) + 1;
881 void *AllocateBootXMemory(long size
)
883 long addr
= gImageFirstBootXAddr
- size
;
885 if (addr
< gImageLastKernelAddr
) return 0;
887 gImageFirstBootXAddr
= addr
;
893 long AllocateKernelMemory(long size
)
895 long addr
= gImageLastKernelAddr
;
897 gImageLastKernelAddr
+= (size
+ 0xFFF) & ~0xFFF;
899 if (gImageLastKernelAddr
> gImageFirstBootXAddr
)
906 long AllocateMemoryRange(char *rangeName
, long start
, long length
)
908 long result
, *buffer
;
910 buffer
= AllocateBootXMemory(2 * sizeof(long));
911 if (buffer
== 0) return -1;
916 result
= SetProp(gMemoryMapPH
, rangeName
, (char *)buffer
, 2 * sizeof(long));
917 if (result
== -1) return -1;
923 unsigned long Alder32(unsigned char *buffer
, long length
)
926 unsigned long result
, lowHalf
, highHalf
;
931 for (cnt
= 0; cnt
< length
; cnt
++) {
932 if ((cnt
% 5000) == 0) {
937 lowHalf
+= buffer
[cnt
];
944 result
= (highHalf
<< 16) | lowHalf
;