]>
git.saurik.com Git - apple/bootx.git/blob - bootx.tproj/sl.subproj/main.c
d9a6767d5569fe8206fe46c9d7dec17c70a7cd72
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * main.c - Main functions for BootX.
28 * Copyright (c) 1998-2002 Apple Computer, Inc.
36 static void Start(void *unused1
, void *unused2
, ClientInterfacePtr ciPtr
);
37 static void Main(ClientInterfacePtr ciPtr
);
38 static long InitEverything(ClientInterfacePtr ciPtr
);
39 static long DecodeKernel(void);
40 static long SetUpBootArgs(void);
41 static long CallKernel(void);
42 static void FailToBoot(long num
);
43 static long InitMemoryMap(void);
44 static long GetOFVersion(void);
45 static long TestForKey(long key
);
46 static long GetBootPaths(void);
48 const unsigned long StartTVector
[2] = {(unsigned long)Start
, 0};
50 char gStackBaseAddr
[0x8000];
52 char *gVectorSaveAddr
;
53 long gImageLastKernelAddr
= 0;
54 long gImageFirstBootXAddr
= kLoadAddr
;
55 long gKernelEntryPoint
;
60 long gSymbolTableAddr
;
61 long gSymbolTableSize
;
63 long gBootSourceNumber
= -1;
64 long gBootSourceNumberMax
;
65 long gBootMode
= kBootModeNormal
;
68 char gBootDevice
[256];
74 long *gDeviceTreeMMTmp
= 0;
93 static void Start(void *unused1
, void *unused2
, ClientInterfacePtr ciPtr
)
97 // Move the Stack to a chunk of the BSS
98 newSP
= (long)gStackBaseAddr
+ sizeof(gStackBaseAddr
) - 0x100;
99 __asm__
volatile("mr r1, %0" : : "r" (newSP
));
105 static void Main(ClientInterfacePtr ciPtr
)
109 ret
= InitEverything(ciPtr
);
110 if (ret
!= 0) Exit();
112 // Get or infer the boot paths.
113 ret
= GetBootPaths();
114 if (ret
!= 0) FailToBoot(1);
119 ret
= LoadFile(gBootFile
);
120 if (ret
!= -1) break;
122 ret
= GetBootPaths();
123 if (ret
!= 0) FailToBoot(2);
126 ret
= DecodeKernel();
127 if (ret
!= 0) FailToBoot(3);
129 ret
= LoadDrivers(gRootDir
);
130 if (ret
!= 0) FailToBoot(4);
134 ret
= SetUpBootArgs();
135 if (ret
!= 0) FailToBoot(5);
143 static long InitEverything(ClientInterfacePtr ciPtr
)
145 long ret
, mem_base
, mem_base2
, size
;
147 char name
[32], securityMode
[33];
149 // Init the OF Client Interface.
151 if (ret
!= 0) return -1;
153 // Get the OF Version
154 gOFVersion
= GetOFVersion();
155 if (gOFVersion
== 0) return -1;
157 // Init the SL Words package.
159 if (ret
!= 0) return -1;
161 // Get the phandle for /options
162 gOptionsPH
= FindDevice("/options");
163 if (gOptionsPH
== -1) return -1;
165 // Get the phandle for /chosen
166 gChosenPH
= FindDevice("/chosen");
167 if (gChosenPH
== -1) return -1;
169 // Init the Memory Map.
170 ret
= InitMemoryMap();
171 if (ret
!= 0) return -1;
173 // Get IHandles for the MMU and Memory
174 size
= GetProp(gChosenPH
, "mmu", (char *)&gMMUIH
, 4);
176 printf("Failed to get the IH for the MMU.\n");
179 size
= GetProp(gChosenPH
, "memory", (char *)&gMemoryIH
, 4);
181 printf("Failed to get the IH for the Memory.\n");
185 // Get stdout's IH, so that the boot display can be found.
186 ret
= GetProp(gChosenPH
, "stdout", (char *)&gStdOutIH
, 4);
187 if (ret
== 4) gStdOutPH
= InstanceToPackage(gStdOutIH
);
188 else gStdOutPH
= gStdOutIH
= 0;
190 // Try to find the keyboard using chosen
191 ret
= GetProp(gChosenPH
, "stdin", (char *)&gKeyboardIH
, 4);
192 if (ret
!= 4) gKeyboardIH
= 0;
194 keyboardPH
= InstanceToPackage(gKeyboardIH
);
195 ret
= GetProp(keyboardPH
, "name", name
, 31);
198 if (strcmp(name
, "keyboard") && strcmp(name
, "kbd")) gKeyboardIH
= 0;
199 } else gKeyboardIH
= 0;
202 // Try to the find the keyboard using open if chosen did not work.
203 if (gKeyboardIH
== 0) gKeyboardIH
= Open("keyboard");
204 if (gKeyboardIH
== 0) gKeyboardIH
= Open("kbd");
206 // Get the key map set up, and make it up to date.
207 gKeyMap
= InitKeyMap(gKeyboardIH
);
208 if (gKeyMap
== NULL
) return -1;
211 // Test for Secure Boot Mode.
212 size
= GetProp(gOptionsPH
, "security-mode", securityMode
, 32);
214 securityMode
[size
] = '\0';
215 if (strcmp(securityMode
, "none")) gBootMode
|= kBootModeSecure
;
219 // 'cmd-s' or 'cmd-v' is pressed set outputLevel to kOutputLevelFull
220 if (((gBootMode
& kBootModeSecure
) == 0) && TestForKey(kCommandKey
) &&
221 (TestForKey('s') || TestForKey('v'))) {
222 SetOutputLevel(kOutputLevelFull
);
224 SetOutputLevel(kOutputLevelOff
);
227 SetOutputLevel(kOutputLevelFull
);
231 printf("\n\nMac OS X Loader\n");
233 // Test for Safe Boot Mode.
234 if (((gBootMode
& kBootModeSecure
) == 0) && TestForKey(kShiftKey
)) {
235 gBootMode
|= kBootModeSafe
;
238 if (Claim(kMallocAddr
, kMallocSize
, 0) == 0) {
239 printf("Claim for malloc failed.\n");
242 malloc_init((char *)kMallocAddr
, kMallocSize
);
246 // Claim the memory for the Load Addr
247 mem_base
= Claim(kLoadAddr
, kLoadSize
, 0);
249 printf("Claim for Load Area failed.\n");
253 // Claim the memory for the Image Addr
254 if (gOFVersion
>= kOFVersion3x
) {
255 mem_base
= Claim(kImageAddr
, kImageSize
, 0);
257 printf("Claim for Image Area failed.\n");
261 // Claim the 1:1 mapped chunks first.
262 mem_base
= Claim(kImageAddr0
, kImageSize0
, 0);
263 mem_base2
= Claim(kImageAddr2
, kImageSize2
, 0);
264 if ((mem_base
== 0) || (mem_base2
== 0)) {
265 printf("Claim for Image Area failed.\n");
269 // Unmap the old xcoff stack.
270 CallMethod(2, 0, gMMUIH
, "unmap", 0x00380000, 0x00080000);
272 // Grap the physical memory then the logical.
273 CallMethod(3, 1, gMemoryIH
, "claim",
274 kImageAddr1Phys
, kImageSize1
, 0, &mem_base
);
275 CallMethod(3, 1, gMMUIH
, "claim",
276 kImageAddr1
, kImageSize1
, 0, &mem_base2
);
277 if ((mem_base
== 0) || (mem_base2
== 0)) {
278 printf("Claim for Image Area failed.\n");
282 // Map them together.
283 CallMethod(4, 0, gMMUIH
, "map",
284 kImageAddr1Phys
, kImageAddr1
, kImageSize1
, 0);
287 bzero((char *)kImageAddr
, kImageSize
);
289 // Allocate some space for the Vector Save area.
290 gVectorSaveAddr
= AllocateBootXMemory(kVectorSize
);
291 if (gVectorSaveAddr
== 0) {
292 printf("Allocation for the Vector Save Area failed.\n");
296 // Find all the displays and set them up.
297 ret
= InitDisplays();
299 printf("InitDisplays failed.\n");
307 static long DecodeKernel(void)
312 if (ret
== -1) ret
= DecodeElf();
318 static long SetUpBootArgs(void)
322 long graphicsBoot
= 1;
323 long ret
, cnt
, mem_size
, size
, dash
;
324 long sKey
, vKey
, keyPos
;
325 char ofBootArgs
[128], *ofArgs
, tc
, keyStr
[8];
327 // Save file system cache statistics.
328 SetProp(gChosenPH
, "BootXCacheHits", (char *)&gCacheHits
, 4);
329 SetProp(gChosenPH
, "BootXCacheMisses", (char *)&gCacheMisses
, 4);
330 SetProp(gChosenPH
, "BootXCacheEvicts", (char *)&gCacheEvicts
, 4);
332 // Allocate some memory for the BootArgs.
333 gBootArgsSize
= sizeof(boot_args
);
334 gBootArgsAddr
= AllocateKernelMemory(gBootArgsSize
);
336 // Add the BootArgs to the memory-map.
337 AllocateMemoryRange("BootArgs", gBootArgsAddr
, gBootArgsSize
);
339 args
= (boot_args_ptr
)gBootArgsAddr
;
341 args
->Revision
= kBootArgsRevision
;
342 args
->Version
= kBootArgsVersion
;
343 args
->machineType
= 0;
345 // Check the Keyboard for 'cmd-s' and 'cmd-v'
347 if ((gBootMode
& kBootModeSecure
) == 0) {
348 sKey
= TestForKey(kCommandKey
) && TestForKey('s');
349 vKey
= TestForKey(kCommandKey
) && TestForKey('v');
355 // if 'cmd-s' or 'cmd-v' was pressed do a text boot.
356 if (sKey
|| vKey
) graphicsBoot
= 0;
358 // Create the command line.
359 if (gOFVersion
< kOFVersion3x
) {
361 size
= GetProp(gChosenPH
, "machargs", ofBootArgs
+ 1, 126);
363 size
= GetProp(gOptionsPH
, "boot-command", ofBootArgs
, 127);
364 if (size
== -1) ofBootArgs
[0] = '\0';
365 else ofBootArgs
[size
] = '\0';
366 // Look for " bootr" but skip the number.
367 if (!strncmp(ofBootArgs
+ 1, " bootr", 6)) {
368 strcpy(ofBootArgs
, ofBootArgs
+ 7);
369 } else ofBootArgs
[0] = '\0';
370 SetProp(gChosenPH
, "machargs", ofBootArgs
, strlen(ofBootArgs
) + 1);
371 } else ofBootArgs
[size
] = '\0';
372 // Force boot-command to start with 0 bootr.
373 sprintf(gTempStr
, "0 bootr%s", ofBootArgs
);
374 SetProp(gOptionsPH
, "boot-command", gTempStr
, strlen(gTempStr
));
376 size
= GetProp(gOptionsPH
, "boot-args", ofBootArgs
, 127);
377 if (size
== -1) ofBootArgs
[0] = '\0';
378 else ofBootArgs
[size
] = '\0';
381 if (ofBootArgs
[0] != '\0') {
382 // Look for special options and copy the rest.
385 while ((tc
= *ofArgs
) != '\0') {
388 // Check for entering a dash arg.
395 // Do special stuff if in a dash arg.
401 } else if (tc
== 'v') {
406 // Check for exiting dash arg
407 if (isspace(tc
)) dash
= 0;
409 // Copy any non 's' or 'v'
413 // Not a dash arg so just copy it.
419 // Add any pressed keys (s, v, shift) to the command line
421 if (sKey
|| vKey
|| (gBootMode
& kBootModeSafe
)) {
422 keyStr
[keyPos
++] = '-';
424 if (sKey
) keyStr
[keyPos
++] = 's';
425 if (vKey
) keyStr
[keyPos
++] = 'v';
426 if (gBootMode
& kBootModeSafe
) keyStr
[keyPos
++] = 'x';
428 keyStr
[keyPos
++] = ' ';
430 keyStr
[keyPos
++] = '\0';
432 sprintf(args
->CommandLine
, "%s%s", keyStr
, ofBootArgs
);
434 // Get the memory info
435 memoryPH
= FindDevice("/memory");
436 if (memoryPH
== -1) return -1;
437 size
= GetProp(memoryPH
, "reg", (char *)(args
->PhysicalDRAM
),
438 kMaxDRAMBanks
* sizeof(DRAMBank
));
439 if (size
== 0) return -1;
441 // This is a hack to make the memory look like its all
444 for (cnt
= 0; cnt
< kMaxDRAMBanks
; cnt
++) {
445 mem_size
+= args
->PhysicalDRAM
[cnt
].size
;
446 args
->PhysicalDRAM
[cnt
].base
= 0;
447 args
->PhysicalDRAM
[cnt
].size
= 0;
449 args
->PhysicalDRAM
[0].size
= mem_size
;
451 // Get the video info
452 GetMainScreenPH(&args
->Video
);
453 args
->Video
.v_display
= graphicsBoot
;
455 // Add the DeviceTree to the memory-map.
456 // The actuall address and size must be filled in later.
457 AllocateMemoryRange("DeviceTree", 0, 0);
459 ret
= FlattenDeviceTree();
460 if (ret
!= 0) return -1;
462 // Fill in the address and size of the device tree.
463 if (gDeviceTreeAddr
) {
464 gDeviceTreeMMTmp
[0] = gDeviceTreeAddr
;
465 gDeviceTreeMMTmp
[1] = gDeviceTreeSize
;
468 args
->deviceTreeP
= (void *)gDeviceTreeAddr
;
469 args
->deviceTreeLength
= gDeviceTreeSize
;
470 args
->topOfKernelData
= AllocateKernelMemory(0);
476 static long CallKernel(void)
482 printf("\nCall Kernel!\n");
485 __asm__
volatile("mtmsr %0" : : "r" (msr
));
486 __asm__
volatile("isync");
488 // Move the Execption Vectors
489 bcopy(gVectorSaveAddr
, 0x0, kVectorSize
);
490 for (cnt
= 0; cnt
< kVectorSize
; cnt
+= 0x20) {
491 __asm__
volatile("dcbf 0, %0" : : "r" (cnt
));
492 __asm__
volatile("icbi 0, %0" : : "r" (cnt
));
495 // Move the Image1 save area for OF 1.x / 2.x
496 if (gOFVersion
< kOFVersion3x
) {
497 bcopy((char *)kImageAddr1Phys
, (char *)kImageAddr1
, kImageSize1
);
498 for (cnt
= kImageAddr1
; cnt
< kImageSize1
; cnt
+= 0x20) {
499 __asm__
volatile("dcbf 0, %0" : : "r" (cnt
));
500 __asm__
volatile("icbi 0, %0" : : "r" (cnt
));
504 // Make sure everything get sync'd up.
505 __asm__
volatile("isync");
506 __asm__
volatile("sync");
507 __asm__
volatile("eieio");
509 (*(void (*)())gKernelEntryPoint
)(gBootArgsAddr
, kMacOSXSignature
);
515 static void FailToBoot(long num
)
518 DrawFailedBootPicture();
522 printf("FailToBoot: %d\n", num
);
523 Enter(); // For debugging
528 static long InitMemoryMap(void)
532 result
= Interpret(0, 1,
535 " \" memory-map\" device-name"
544 static long GetOFVersion(void)
547 char versStr
[256], *tmpStr
;
550 // Get the openprom package
551 ph
= FindDevice("/openprom");
552 if (ph
== -1) return 0;
554 // Get it's model property
555 size
= GetProp(ph
, "model", versStr
, 255);
556 if (size
== -1) return -1;
557 versStr
[size
] = '\0';
559 // Find the start of the number.
561 if (!strncmp(versStr
, "Open Firmware, ", 15)) {
562 tmpStr
= versStr
+ 15;
563 } else if (!strncmp(versStr
, "OpenFirmware ", 13)) {
564 tmpStr
= versStr
+ 13;
567 // Clasify by each instance as needed...
590 static long TestForKey(long key
)
596 if (gOFVersion
< kOFVersion3x
) {
598 case 'a' : keyNum
= 7; break;
599 case 's' : keyNum
= 6; break;
600 case 'v' : keyNum
= 14; break;
601 case 'y' : keyNum
= 23; break;
602 case kCommandKey
: keyNum
= 48; break;
603 case kOptKey
: keyNum
= 61; break;
604 case kShiftKey
: keyNum
= 63; break;
605 case kControlKey
: keyNum
= 49; break;
606 default : keyNum
= -1; break;
610 case 'a' : keyNum
= 3; break;
611 case 's' : keyNum
= 17; break;
612 case 'v' : keyNum
= 30; break;
613 case 'y' : keyNum
= 27; break;
614 case kCommandKey
: keyNum
= 228; break;
615 case kOptKey
: keyNum
= 229; break;
616 case kShiftKey
: keyNum
= 230; break;
617 case kControlKey
: keyNum
= 231; break;
618 default : keyNum
= -1; break;
621 // Map the right modifier keys on to the left.
622 gKeyMap
[28] |= gKeyMap
[28] << 4;
625 if (keyNum
== -1) return 0;
628 tc
= gKeyMap
[keyNum
>> 3];
630 return (tc
& (1 << bp
)) != 0;
634 #define kBootpBootFileOffset (108)
636 static long GetBootPaths(void)
638 long ret
, cnt
, cnt2
, cnt3
, cnt4
, size
, partNum
, bootplen
, bsdplen
;
639 char *filePath
, *buffer
;
641 if (gBootSourceNumber
== -1) {
642 // Get the boot-device
643 size
= GetProp(gChosenPH
, "bootpath", gBootDevice
, 255);
644 gBootDevice
[size
] = '\0';
645 if (gBootDevice
[0] == '\0') {
646 size
= GetProp(gOptionsPH
, "boot-device", gBootDevice
, 255);
647 gBootDevice
[size
] = '\0';
649 gBootDeviceType
= GetDeviceType(gBootDevice
);
652 size
= GetProp(gChosenPH
, "bootargs", gBootFile
, 256);
653 gBootFile
[size
] = '\0';
655 if (gBootFile
[0] != '\0') {
656 gBootFileType
= GetDeviceType(gBootFile
);
657 gBootSourceNumberMax
= 0;
659 gBootSourceNumber
= 0;
660 gBootFileType
= gBootDeviceType
;
661 if (gBootFileType
== kNetworkDeviceType
) gBootSourceNumberMax
= 1;
663 if (gOFVersion
< kOFVersion3x
) {
664 gBootSourceNumberMax
= 4;
666 gBootSourceNumberMax
= 6;
671 if (gBootFileType
== kNetworkDeviceType
) {
672 SetProp(Peer(0), "net-boot", NULL
, 0);
676 if (gBootSourceNumber
>= gBootSourceNumberMax
) return -1;
678 if (gBootSourceNumberMax
!= 0) {
679 switch (gBootFileType
) {
680 case kNetworkDeviceType
:
681 // Find the end of the device spec.
683 while (gBootDevice
[cnt
] != ':') cnt
++;
685 // Copy the device spec with the ':'.
686 strncpy(gBootFile
, gBootDevice
, cnt
+ 1);
688 // Check for bootp-responce or bsdp-responce.
689 bootplen
= GetPropLen(gChosenPH
, "bootp-response");
690 bsdplen
= GetPropLen(gChosenPH
, "bsdp-response");
691 if ((bootplen
> 0) || (bsdplen
> 0)) {
693 buffer
= malloc(bootplen
);
694 GetProp(gChosenPH
, "bootp-response", buffer
, bootplen
);
696 buffer
= malloc(bsdplen
);
697 GetProp(gChosenPH
, "bsdp-response", buffer
, bsdplen
);
700 // Flip the slash's to back slash's while looking for the last one.
701 cnt
= cnt2
= kBootpBootFileOffset
;
702 while (buffer
[cnt
] != '\0') {
703 if (buffer
[cnt
] == '/') {
710 // Add a comma at the front.
711 buffer
[kBootpBootFileOffset
- 1] = ',';
713 // Append the the root dir to the device spec.
714 strncat(gBootFile
, buffer
+ kBootpBootFileOffset
- 1,
715 cnt2
- kBootpBootFileOffset
+ 1);
719 // Look for the start of the root dir path.
721 while (gBootDevice
[cnt3
] != ',') cnt3
++;
723 // Find the end of the path. Look for a comma or null.
725 while ((gBootDevice
[cnt2
] != '\0') && (gBootDevice
[cnt2
] != ',')) cnt2
++;
727 // Find the last back slash or comma in the path
729 while ((gBootDevice
[cnt4
] != ',') && (gBootDevice
[cnt4
] != '\\')) cnt4
--;
731 // Copy the IP addresses if needed.
732 if (gOFVersion
< kOFVersion3x
) {
733 strncat(gBootFile
, gBootDevice
+ cnt
+ 1, cnt3
- cnt
- 1);
736 // Add on the directory path
737 strncat(gBootFile
, gBootDevice
+ cnt3
, cnt4
- cnt3
+ 1);
740 // Add on the kernel name
741 strcat(gBootFile
, "mach.macosx");
744 strcat(gBootFile
, gBootDevice
+ cnt2
);
747 case kBlockDeviceType
:
748 // Find the first ':'.
750 while ((gBootDevice
[cnt
] != '\0') && (gBootDevice
[cnt
] != ':')) cnt
++;
751 if (gBootDevice
[cnt
] == '\0') return -1;
753 // Find the comma after the ':'.
755 while ((gBootDevice
[cnt2
] != '\0') && (gBootDevice
[cnt
] != ',')) cnt2
++;
757 // Get just the partition number
758 strncpy(gBootFile
, gBootDevice
+ cnt
+ 1, cnt2
- cnt
- 1);
759 partNum
= atoi(gBootFile
);
761 // Adjust the partition number.
762 // Pass 0 & 1, no offset. Pass 2 & 3, offset 1, Pass 4 & 5, offset 2.
763 partNum
+= gBootSourceNumber
/ 2;
765 // Construct the boot-file
766 strncpy(gBootFile
, gBootDevice
, cnt
+ 1);
767 sprintf(gBootFile
+ cnt
+ 1, "%d,%s\\mach_kernel",
768 partNum
, ((gBootSourceNumber
& 1) ? "" : "\\"));
772 printf("Failed to infer Boot Device Type.\n");
778 // Figure out the root dir.
779 ret
= ConvertFileSpec(gBootFile
, gRootDir
, &filePath
);
780 if (ret
== -1) return -1;
782 strcat(gRootDir
, ",");
784 // Add in any extra path to gRootDir.
786 while (filePath
[cnt
] != '\0') cnt
++;
789 for (cnt2
= cnt
- 1; cnt2
>= 0; cnt2
--) {
790 if (filePath
[cnt2
] == '\\') {
791 strncat(gRootDir
, filePath
, cnt2
+ 1);
797 SetProp(gChosenPH
, "rootpath", gBootFile
, strlen(gBootFile
) + 1);
806 long GetDeviceType(char *devSpec
)
812 ph
= FindDevice(devSpec
);
813 if (ph
== -1) return -1;
815 size
= GetProp(ph
, "device_type", deviceType
, 31);
816 if (size
!= -1) deviceType
[size
] = '\0';
817 else deviceType
[0] = '\0';
819 if (strcmp(deviceType
, "network") == 0) return kNetworkDeviceType
;
820 if (strcmp(deviceType
, "block") == 0) return kBlockDeviceType
;
822 return kUnknownDeviceType
;
826 long ConvertFileSpec(char *fileSpec
, char *devSpec
, char **filePath
)
830 // Find the first ':' in the fileSpec.
832 while ((fileSpec
[cnt
] != '\0') && (fileSpec
[cnt
] != ':')) cnt
++;
833 if (fileSpec
[cnt
] == '\0') return -1;
835 // Find the next ',' in the fileSpec.
836 while ((fileSpec
[cnt
] != '\0') && (fileSpec
[cnt
] != ',')) cnt
++;
838 // Copy the string to devSpec.
839 strncpy(devSpec
, fileSpec
, cnt
);
842 // If there is a filePath start it after the ',', otherwise NULL.
843 if (filePath
!= NULL
) {
844 if (fileSpec
[cnt
] != '\0') {
845 *filePath
= fileSpec
+ cnt
+ 1;
855 long MatchThis(CICell phandle
, char *string
)
858 char *name
, *model
, *compatible
;
860 ret
= GetPackageProperty(phandle
, "name", &name
, &length
);
861 if ((ret
== -1) || (length
== 0)) name
= NULL
;
863 ret
= GetPackageProperty(phandle
, "model", &model
, &length
);
864 if ((ret
== -1) || (length
== 0)) model
= NULL
;
866 ret
= GetPackageProperty(phandle
, "compatible", &compatible
, &length
);
867 if ((ret
== -1) || (length
== 0)) model
= NULL
;
869 if ((name
!= NULL
) && strcmp(name
, string
) == 0) return 0;
870 if ((model
!= NULL
) && strcmp(model
, string
) == 0) return 0;
872 if (compatible
!= NULL
) {
873 while (*compatible
!= '\0') {
874 if (strcmp(compatible
, string
) == 0) return 0;
876 compatible
+= strlen(compatible
) + 1;
884 void *AllocateBootXMemory(long size
)
886 long addr
= gImageFirstBootXAddr
- size
;
888 if (addr
< gImageLastKernelAddr
) return 0;
890 gImageFirstBootXAddr
= addr
;
896 long AllocateKernelMemory(long size
)
898 long addr
= gImageLastKernelAddr
;
900 gImageLastKernelAddr
+= (size
+ 0xFFF) & ~0xFFF;
902 if (gImageLastKernelAddr
> gImageFirstBootXAddr
)
909 long AllocateMemoryRange(char *rangeName
, long start
, long length
)
911 long result
, *buffer
;
913 buffer
= AllocateBootXMemory(2 * sizeof(long));
914 if (buffer
== 0) return -1;
919 result
= SetProp(gMemoryMapPH
, rangeName
, (char *)buffer
, 2 * sizeof(long));
920 if (result
== -1) return -1;
926 unsigned long Alder32(unsigned char *buffer
, long length
)
929 unsigned long result
, lowHalf
, highHalf
;
934 for (cnt
= 0; cnt
< length
; cnt
++) {
935 if ((cnt
% 5000) == 0) {
940 lowHalf
+= buffer
[cnt
];
947 result
= (highHalf
<< 16) | lowHalf
;