Root/
Source at commit 1328 created 12 years 8 months ago. By meklort, Add work loop to ppc boot file.\n | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 2000-2007 Apple Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * This file contains Original Code and/or Modifications of Original Code␊ |
7 | * as defined in and that are subject to the Apple Public Source License␊ |
8 | * Version 2.0 (the 'License'). You may not use this file except in␊ |
9 | * compliance with the License. The rights granted to you under the License␊ |
10 | * may not be used to create, or enable the creation or redistribution of,␊ |
11 | * unlawful or unlicensed copies of an Apple operating system, or to␊ |
12 | * circumvent, violate, or enable the circumvention or violation of, any␊ |
13 | * terms of an Apple operating system software license agreement.␊ |
14 | * ␊ |
15 | * Please obtain a copy of the License at␊ |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file.␊ |
17 | * ␊ |
18 | * The Original Code and all software distributed under the License are␊ |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.␊ |
23 | * Please see the License for the specific language governing rights and␊ |
24 | * limitations under the License.␊ |
25 | * ␊ |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@␊ |
27 | */␊ |
28 | ␊ |
29 | /*␊ |
30 | * main.c - Main functions for BootX.␊ |
31 | *␊ |
32 | * Copyright (c) 1998-2004 Apple Computer, Inc.␊ |
33 | *␊ |
34 | * DRI: Josh de Cesare␊ |
35 | */␊ |
36 | ␊ |
37 | ␊ |
38 | #include <sl.h>␊ |
39 | #include <stdio.h>␊ |
40 | #include <string.h>␊ |
41 | ␊ |
42 | extern void␉malloc_init(char * start, int size, int nodes, void (*malloc_error)(char *, size_t, const char *, int));␊ |
43 | extern void init_module_system();␊ |
44 | extern int␉execute_hook(const char* name, void*, void*, void*, void*);␊ |
45 | ␊ |
46 | static void Start(void *unused1, void *unused2, ClientInterfacePtr ciPtr);␊ |
47 | static void Main(ClientInterfacePtr ciPtr);␊ |
48 | static long InitEverything(ClientInterfacePtr ciPtr);␊ |
49 | static long InitMemoryMap(void);␊ |
50 | static long GetOFVersion(void);␊ |
51 | static void malloc_error(char *addr, size_t size, const char *file, int line);␊ |
52 | ␊ |
53 | const unsigned long StartTVector[2] = {(unsigned long)Start, 0};␊ |
54 | ␊ |
55 | ␊ |
56 | char gStackBaseAddr[0x8000];␊ |
57 | ␊ |
58 | long gOFVersion = 0;␊ |
59 | ␊ |
60 | char *gKeyMap;␊ |
61 | ␊ |
62 | long gRootAddrCells;␊ |
63 | long gRootSizeCells;␊ |
64 | ␊ |
65 | CICell gChosenPH;␊ |
66 | CICell gMemoryMapPH;␊ |
67 | CICell gStdOutPH;␊ |
68 | ␊ |
69 | CICell gMMUIH;␊ |
70 | CICell gMemoryIH;␊ |
71 | CICell gStdOutIH;␊ |
72 | CICell gKeyboardIH;␊ |
73 | ␊ |
74 | ␊ |
75 | // Private Functions␊ |
76 | ␊ |
77 | static void malloc_error(char *addr, size_t size, const char *file, int line)␊ |
78 | {␊ |
79 | ␉printf("\nMemory allocation error! Addr=0x%x, Size=0x%x, File=%s, Line=%d\n", (unsigned)addr, (unsigned)size, file, line);␊ |
80 | ␉while(1);␊ |
81 | }␊ |
82 | ␊ |
83 | ␊ |
84 | static void Start(void *unused1, void *unused2, ClientInterfacePtr ciPtr)␊ |
85 | {␊ |
86 | ␉long newSP;␊ |
87 | ␉␊ |
88 | ␉// Move the Stack to a chunk of the BSS␊ |
89 | ␉newSP = (long)gStackBaseAddr + sizeof(gStackBaseAddr) - 0x100;␊ |
90 | ␉__asm__ volatile("mr r1, %0" : : "r" (newSP));␊ |
91 | ␉␊ |
92 | ␉Main(ciPtr);␊ |
93 | }␊ |
94 | ␊ |
95 | static void Main(ClientInterfacePtr ciPtr)␊ |
96 | {␊ |
97 | ␉int loopCount = 0;␊ |
98 | ␉long ret;␊ |
99 | ␉␊ |
100 | ␉ret = InitEverything(ciPtr);␊ |
101 | ␉if (ret != 0) Exit();␊ |
102 | ␉␊ |
103 | ␉// Intialize module system ␊ |
104 | ␉init_module_system();␊ |
105 | ␊ |
106 | ␉execute_hook("Initialize", (void*)loopCount++, (void*)ciPtr, 0, 0);␉// Main work loop␊ |
107 | ␊ |
108 | ␉while(1)␊ |
109 | {␊ |
110 | execute_hook("WorkLoop", (void*)loopCount++, (void*)ciPtr, 0, 0);␉// Main work loop␊ |
111 | }␉␊ |
112 | ␉␊ |
113 | }␊ |
114 | static long InitEverything(ClientInterfacePtr ciPtr)␊ |
115 | {␊ |
116 | ␉long ret, size;␊ |
117 | ␉CICell keyboardPH;␊ |
118 | ␉char name[32];␊ |
119 | ␉␊ |
120 | ␉// Init the OF Client Interface.␊ |
121 | ␉ret = InitCI(ciPtr);␊ |
122 | ␉if (ret != 0) return -1;␊ |
123 | ␉␊ |
124 | ␉// Get the OF Version␊ |
125 | ␉gOFVersion = GetOFVersion();␊ |
126 | ␉if (gOFVersion == 0) return -1;␊ |
127 | ␉␊ |
128 | ␉// Get the address and size cells for the root.␊ |
129 | ␉GetProp(Peer(0), "#address-cells", (char *)&gRootAddrCells, 4);␊ |
130 | ␉GetProp(Peer(0), "#size-cells", (char *)&gRootSizeCells, 4);␊ |
131 | ␉if ((gRootAddrCells > 2) || (gRootAddrCells > 2)) return -1;␊ |
132 | ␉␊ |
133 | ␉// Init the SL Words package.␊ |
134 | ␉ret = InitSLWords();␊ |
135 | ␉if (ret != 0) return -1;␊ |
136 | ␉␊ |
137 | ␉␊ |
138 | ␉// Get the phandle for /chosen␊ |
139 | ␉gChosenPH = FindDevice("/chosen");␊ |
140 | ␉if (gChosenPH == -1) return -1;␊ |
141 | ␉␊ |
142 | ␉// Init the Memory Map.␊ |
143 | ␉ret = InitMemoryMap();␊ |
144 | ␉if (ret != 0) return -1;␊ |
145 | ␉␊ |
146 | ␉// Get IHandles for the MMU and Memory␊ |
147 | ␉size = GetProp(gChosenPH, "mmu", (char *)&gMMUIH, 4);␊ |
148 | ␉if (size != 4) {␊ |
149 | ␉␉printf("Failed to get the IH for the MMU.\n");␊ |
150 | ␉␉return -1;␊ |
151 | ␉}␊ |
152 | ␉size = GetProp(gChosenPH, "memory", (char *)&gMemoryIH, 4);␊ |
153 | ␉if (size != 4) {␊ |
154 | ␉␉printf("Failed to get the IH for the Memory.\n");␊ |
155 | ␉␉return -1;␊ |
156 | ␉}␊ |
157 | ␉␉␊ |
158 | ␉// Get stdout's IH, so that the boot display can be found.␊ |
159 | ␉ret = GetProp(gChosenPH, "stdout", (char *)&gStdOutIH, 4);␊ |
160 | ␉if (ret == 4) gStdOutPH = InstanceToPackage(gStdOutIH);␊ |
161 | ␉else gStdOutPH = gStdOutIH = 0;␊ |
162 | ␉␊ |
163 | ␉// Try to find the keyboard using chosen␊ |
164 | ␉ret = GetProp(gChosenPH, "stdin", (char *)&gKeyboardIH, 4);␊ |
165 | ␉if (ret != 4) gKeyboardIH = 0;␊ |
166 | ␉else {␊ |
167 | ␉␉keyboardPH = InstanceToPackage(gKeyboardIH);␊ |
168 | ␉␉ret = GetProp(keyboardPH, "name", name, 31);␊ |
169 | ␉␉if (ret != -1) {␊ |
170 | ␉␉␉name[ret] = '\0';␊ |
171 | ␉␉␉if (strcmp(name, "keyboard") && strcmp(name, "kbd")) gKeyboardIH = 0;␊ |
172 | ␉␉} else gKeyboardIH = 0;␊ |
173 | ␉}␊ |
174 | ␉␊ |
175 | ␉// Try to the find the keyboard using open if chosen did not work.␊ |
176 | ␉if (gKeyboardIH == 0) gKeyboardIH = Open("keyboard");␊ |
177 | ␉if (gKeyboardIH == 0) gKeyboardIH = Open("kbd");␊ |
178 | ␉␊ |
179 | ␉// Get the key map set up, and make it up to date.␊ |
180 | ␉gKeyMap = InitKeyMap(gKeyboardIH);␊ |
181 | ␉if (gKeyMap == NULL) return -1;␊ |
182 | ␉UpdateKeyMap();␊ |
183 | ␉␊ |
184 | ␉SetOutputLevel(kOutputLevelFull);␊ |
185 | ␉␊ |
186 | ␉// printf now works.␊ |
187 | ␉printf("\n\nMac OS X Loader\n");␊ |
188 | ␉␊ |
189 | ␉// Claim memory for malloc.␊ |
190 | ␉if (Claim(kMallocAddr, kMallocSize, 0) == 0) {␊ |
191 | ␉␉printf("Claim for malloc failed.\n");␊ |
192 | ␉␉return -1;␊ |
193 | ␉}␊ |
194 | ␉malloc_init((char *)kMallocAddr, kMallocSize, 768, malloc_error);␊ |
195 | ␉␊ |
196 | ␉␊ |
197 | ␉return 0;␊ |
198 | }␊ |
199 | ␊ |
200 | static long InitMemoryMap(void)␊ |
201 | {␊ |
202 | ␉long result;␊ |
203 | ␉␊ |
204 | ␉result = Interpret(0, 1,␊ |
205 | ␉␉␉␉␉ " dev /chosen"␊ |
206 | ␉␉␉␉␉ " new-device"␊ |
207 | ␉␉␉␉␉ " \" memory-map\" device-name"␊ |
208 | ␉␉␉␉␉ " active-package"␊ |
209 | ␉␉␉␉␉ " device-end"␊ |
210 | ␉␉␉␉␉ , &gMemoryMapPH);␊ |
211 | ␉␊ |
212 | ␉return result;␊ |
213 | }␊ |
214 | ␊ |
215 | ␊ |
216 | static long GetOFVersion(void)␊ |
217 | {␊ |
218 | ␉CICell ph;␊ |
219 | ␉char versStr[256], *tmpStr;␊ |
220 | ␉long vers, size;␊ |
221 | ␉␊ |
222 | ␉// Get the openprom package␊ |
223 | ␉ph = FindDevice("/openprom");␊ |
224 | ␉if (ph == -1) return 0;␊ |
225 | ␉␊ |
226 | ␉// Get it's model property␊ |
227 | ␉size = GetProp(ph, "model", versStr, 255);␊ |
228 | ␉if (size == -1) return -1;␊ |
229 | ␉versStr[size] = '\0';␊ |
230 | ␉␊ |
231 | ␉// Find the start of the number.␊ |
232 | ␉tmpStr = NULL;␊ |
233 | ␉if (!strncmp(versStr, "Open Firmware, ", 15)) {␊ |
234 | ␉␉tmpStr = versStr + 15;␊ |
235 | ␉} else if (!strncmp(versStr, "OpenFirmware ", 13)) {␊ |
236 | ␉␉tmpStr = versStr + 13;␊ |
237 | ␉} else return -1;␊ |
238 | ␉␊ |
239 | ␉// Clasify by each instance as needed...␊ |
240 | ␉switch (*tmpStr) {␊ |
241 | ␉␉case '1' :␊ |
242 | ␉␉␉vers = kOFVersion1x;␊ |
243 | ␉␉␉break;␊ |
244 | ␉␉␉␊ |
245 | ␉␉case '2' :␊ |
246 | ␉␉␉vers = kOFVersion2x;␊ |
247 | ␉␉␉break;␊ |
248 | ␉␉␉␊ |
249 | ␉␉case '3' :␊ |
250 | ␉␉␉vers = kOFVersion3x;␊ |
251 | ␉␉␉break;␊ |
252 | ␉␉␉␊ |
253 | ␉␉case '4' :␊ |
254 | ␉␉␉vers = kOFVersion4x;␊ |
255 | ␉␉␉break;␊ |
256 | ␉␉␉␊ |
257 | ␉␉default :␊ |
258 | ␉␉␉vers = 0;␊ |
259 | ␉␉␉break;␊ |
260 | ␉}␊ |
261 | ␉␊ |
262 | ␉return vers;␊ |
263 | } |