Chameleon

Chameleon Svn Source Tree

Root/branches/ErmaC/Enoch/i386/libsaio/bootstruct.c

1/*
2 * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 2.0 (the "License").You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/*
25 * Copyright 1993 NeXT, Inc.
26 * All rights reserved.
27 */
28
29#include "config.h"
30#include "libsaio.h"
31#include "boot.h"
32#include "bootstruct.h"
33
34#if DEBUG_BOOTSTRUCT
35#define DBG(x...)printf(x)
36#else
37#define DBG(x...)msglog(x)
38#endif
39
40#define MEG(1024*1024)
41
42/*==========================================================================
43 * Initialize the structure of parameters passed to
44 * the kernel by the booter.
45 */
46
47boot_args*bootArgs= NULL;
48boot_args_legacy*bootArgsLegacy= NULL;
49
50PrivateBootInfo_t*bootInfo= NULL;
51Node*gMemoryMapNode;
52
53static char platformName[64];
54
55void initKernBootStruct( void )
56{
57Node *node;
58int nameLen;
59
60static int init_done = 0;
61
62if ( !init_done )
63{
64bootArgs = (boot_args *)malloc(sizeof(boot_args));
65bootArgsLegacy = (boot_args_legacy *)malloc(sizeof(boot_args_legacy));
66bootInfo = (PrivateBootInfo_t *)malloc(sizeof(PrivateBootInfo_t));
67
68if (bootArgs == 0 || bootArgsLegacy == 0 || bootInfo == 0)
69{
70stop("Couldn't allocate boot info\n");
71}
72
73bzero(bootArgs, sizeof(boot_args));
74bzero(bootArgsLegacy, sizeof(boot_args_legacy));
75bzero(bootInfo, sizeof(PrivateBootInfo_t));
76
77// Get system memory map. Also update the size of the
78// conventional/extended memory for backwards compatibility.
79
80bootInfo->memoryMapCount =
81getMemoryMap( bootInfo->memoryMap, kMemoryMapCountMax,
82 (unsigned long *) &bootInfo->convmem,
83 (unsigned long *) &bootInfo->extmem );
84
85if ( bootInfo->memoryMapCount == 0 )
86{
87// BIOS did not provide a memory map, systems with
88// discontiguous memory or unusual memory hole locations
89// may have problems.
90
91bootInfo->convmem= getConventionalMemorySize();
92bootInfo->extmem= getExtendedMemorySize();
93}
94
95bootInfo->configEnd= bootInfo->config;
96bootArgs->Video.v_display= VGA_TEXT_MODE;
97
98DT__Initialize();
99
100node = DT__FindNode("/", true);
101if (node == 0)
102{
103stop("Couldn't create root node");
104}
105
106getPlatformName(platformName, sizeof(platformName));
107
108nameLen = strlen(platformName) + 1;
109DT__AddProperty(node, "compatible", nameLen, platformName);
110DT__AddProperty(node, "model", nameLen, platformName);
111
112gMemoryMapNode = DT__FindNode("/chosen/memory-map", true);
113
114bootArgs->Version = kBootArgsVersion;
115bootArgs->Revision = kBootArgsRevision;
116
117bootArgsLegacy->Version = kBootArgsLegacyVersion;
118bootArgsLegacy->Revision = kBootArgsLegacyRevision;
119
120init_done = 1;
121}
122}
123
124/* Copy boot args after kernel and record address. */
125
126void reserveKernBootStruct(void)
127{
128if ( MacOSVerCurrent < MacOSVer2Int("10.7") )
129{
130// for 10.4 10.5 10.6
131void *oldAddr = bootArgsLegacy;
132bootArgsLegacy = (boot_args_legacy *)AllocateKernelMemory(sizeof(boot_args_legacy));
133bcopy(oldAddr, bootArgsLegacy, sizeof(boot_args_legacy));
134}
135else
136{
137// for 10.7 10.8 10.9 10.10 10.11 10.12 10.13 10.14
138void *oldAddr = bootArgs;
139bootArgs = (boot_args *)AllocateKernelMemory(sizeof(boot_args));
140bcopy(oldAddr, bootArgs, sizeof(boot_args));
141}
142
143// 10.12, 10.13 and 10.14 new bootArgs?
144}
145
146//==============================================================================
147
148void finalizeBootStruct(void)
149{
150uint32_t size;
151void *addr;
152int i;
153
154/* Memory size to use for defaults calculations (cparm) */
155uint64_tsane_size = 0;
156
157EfiMemoryRange*memoryMap= NULL;
158MemoryRange*range= NULL;
159int memoryMapCount = bootInfo->memoryMapCount;
160
161if (memoryMapCount == 0)
162{
163// XXX could make a two-part map here
164stop("No memory map found!\n");
165return;
166}
167
168// convert memory map to boot_args memory map
169memoryMap = (EfiMemoryRange *)AllocateKernelMemory(sizeof(EfiMemoryRange) * memoryMapCount);
170if (memoryMap == NULL)
171{
172stop("Unable to allocate kernel space for the memory map!\n");
173return;
174}
175
176bootArgs->MemoryMap= (uint32_t)memoryMap;
177bootArgs->MemoryMapSize= sizeof(EfiMemoryRange) * memoryMapCount;
178bootArgs->MemoryMapDescriptorSize= sizeof(EfiMemoryRange);
179bootArgs->MemoryMapDescriptorVersion= 0;
180
181for (i = 0; i < memoryMapCount; i++, memoryMap++)
182{
183range = &bootInfo->memoryMap[i];
184
185if (!range || !memoryMap)
186{
187stop("Error while computing kernel memory map\n");
188return;
189}
190
191switch(range->type)
192{
193case kMemoryRangeACPI:
194memoryMap->Type = kEfiACPIReclaimMemory;
195break;
196
197case kMemoryRangeNVS:
198memoryMap->Type = kEfiACPIMemoryNVS;
199break;
200
201case kMemoryRangeUsable:
202memoryMap->Type = kEfiConventionalMemory;
203break;
204
205case kMemoryRangeReserved:
206
207default:
208memoryMap->Type = kEfiReservedMemoryType;
209break;
210}
211
212memoryMap->PhysicalStart= range->base;
213memoryMap->VirtualStart= range->base;
214memoryMap->NumberOfPages= range->length >> I386_PGSHIFT;
215memoryMap->Attribute= 0;
216
217switch (memoryMap->Type)
218{
219case kEfiLoaderCode:
220case kEfiLoaderData:
221case kEfiBootServicesCode:
222case kEfiBootServicesData:
223case kEfiConventionalMemory:
224/*
225 * Consolidate usable memory types into one (cparm).
226 */
227sane_size += (uint64_t)(memoryMap->NumberOfPages << I386_PGSHIFT);
228break;
229
230case kEfiRuntimeServicesCode:
231case kEfiRuntimeServicesData:
232case kEfiACPIReclaimMemory:
233case kEfiACPIMemoryNVS:
234case kEfiPalCode:
235/*
236 * sane_size should reflect the total amount of physical ram
237 * in the system, not just the amount that is available for
238 * the OS to use (cparm)
239 */
240sane_size += (uint64_t)(memoryMap->NumberOfPages << I386_PGSHIFT);
241break;
242default:
243break;
244}
245
246if (sane_size == 0)
247{
248
249// I Guess that if sane_size == 0 we've got a big problem here,
250// and it means that the memory map was not converted properly (cparm)
251stop("Unable to convert memory map into proper format\n");
252return;
253}
254
255/*
256 * For user visible memory size, round up to 128 Mb - accounting for the various stolen memory
257 * not reported by EFI. (cparm)
258 */
259#if DEBUG_BOOTSTRUCT
260sane_size = (sane_size + 128 * MEG - 1) & ~((uint64_t)(128 * MEG - 1));
261DBG( "Total amount of physical RAM in the system : %d\n", ((sane_size + 128 * MEG - 1) & ~((uint64_t)(128 * MEG - 1))) );
262#else
263DBG( "Total amount of RAM in the system : %d\n", sane_size );
264#endif
265bootArgs->PhysicalMemorySize = sane_size;
266}
267
268// copy bootFile into device tree
269// XXX
270
271// add PCI info somehow into device tree
272// XXX
273
274// Flatten device tree
275DT__FlattenDeviceTree(0, &size);
276addr = (void *)AllocateKernelMemory(size);
277if (addr == 0)
278{
279stop("Couldn't allocate device tree\n");
280return;
281}
282
283DT__FlattenDeviceTree((void **)&addr, &size);
284if (!size)
285{
286stop("Couldn't get flatten device tree\n");
287return;
288}
289bootArgs->deviceTreeP = (uint32_t)addr;
290bootArgs->deviceTreeLength = size;
291
292//
293// MinusZwei:
294// Dump the new video struct fields in the old one.
295// This will avoid a black screen issue with OS X between 10.8 and 10.11
296//
297// In order to be 100% safe, the new struct fields will also be seroed
298// afterwards.
299//
300if ( MacOSVerCurrent < MacOSVer2Int("10.12") )
301{
302bootArgs->VideoV1.v_baseAddr = bootArgs->Video.v_baseAddr;
303bootArgs->VideoV1.v_display = bootArgs->Video.v_display;
304bootArgs->VideoV1.v_rowBytes = bootArgs->Video.v_rowBytes;
305bootArgs->VideoV1.v_width = bootArgs->Video.v_width;
306bootArgs->VideoV1.v_height = bootArgs->Video.v_height;
307bootArgs->VideoV1.v_depth = bootArgs->Video.v_depth;
308
309bzero(&bootArgs->Video, sizeof(Boot_Video));
310
311bootArgs->apfsDataStart = 0;
312bootArgs->apfsDataSize = 0;
313}
314
315// Copy BootArgs values to older structure
316
317memcpy(&bootArgsLegacy->CommandLine, &bootArgs->CommandLine, BOOT_LINE_LENGTH);
318memcpy(&bootArgsLegacy->Video, &bootArgs->VideoV1, sizeof(Boot_VideoV1));
319
320bootArgsLegacy->MemoryMap = bootArgs->MemoryMap;
321bootArgsLegacy->MemoryMapSize = bootArgs->MemoryMapSize;
322bootArgsLegacy->MemoryMapDescriptorSize = bootArgs->MemoryMapDescriptorSize;
323bootArgsLegacy->MemoryMapDescriptorVersion = bootArgs->MemoryMapDescriptorVersion;
324
325bootArgsLegacy->deviceTreeP = bootArgs->deviceTreeP;
326bootArgsLegacy->deviceTreeLength = bootArgs->deviceTreeLength;
327
328bootArgsLegacy->kaddr = bootArgs->kaddr;
329bootArgsLegacy->ksize = bootArgs->ksize;
330
331bootArgsLegacy->efiRuntimeServicesPageStart = bootArgs->efiRuntimeServicesPageStart;
332bootArgsLegacy->efiRuntimeServicesPageCount = bootArgs->efiRuntimeServicesPageCount;
333bootArgsLegacy->efiSystemTable = bootArgs->efiSystemTable;
334
335bootArgsLegacy->efiMode = bootArgs->efiMode;
336
337bootArgsLegacy->performanceDataStart = bootArgs->performanceDataStart;
338bootArgsLegacy->performanceDataSize = bootArgs->performanceDataSize;
339bootArgsLegacy->efiRuntimeServicesVirtualPageStart = bootArgs->efiRuntimeServicesVirtualPageStart;
340}
341

Archive Download this file

Revision: HEAD