Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/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 "libsaio.h"
30#include "bootstruct.h"
31#include "platform.h"
32
33
34/*==========================================================================
35 * structure of parameters passed to
36 * the kernel by the booter.
37 */
38boot_args_legacy *bootArgsLegacy= NULL;
39boot_args *bootArgs= NULL;
40
41PrivateBootInfo_t *bootInfo = NULL;
42
43static char platformName[64];
44static MemoryRange memoryMap[kMemoryMapCountMax];
45
46void initKernBootStruct( void )
47{
48 static int init_done = 0;
49
50 if ( !init_done )
51 {
52int convmem; // conventional memory
53int extmem; // extended memory
54
55unsigned long memoryMapCount = 0;
56
57 bootArgs = (boot_args *)malloc(sizeof(boot_args));
58 bootInfo = (PrivateBootInfo_t *)malloc(sizeof(PrivateBootInfo_t));
59 if (bootArgs == NULL || bootInfo == NULL)
60 stop("Couldn't allocate boot info\n");
61 else
62 {
63 bzero(bootArgs, sizeof(boot_args));
64 bzero(bootInfo, sizeof(PrivateBootInfo_t));
65
66 // Get system memory map. Also update the size of the
67 // conventional/extended memory for backwards compatibility.
68
69
70 memoryMapCount =
71 getMemoryMap( memoryMap, kMemoryMapCountMax,
72 (unsigned long *) &convmem,
73 (unsigned long *) &extmem );
74
75
76
77 if ( memoryMapCount == 0 )
78 {
79 // BIOS did not provide a memory map, systems with
80 // discontiguous memory or unusual memory hole locations
81 // may have problems.
82
83 convmem = getConventionalMemorySize();
84 extmem = getExtendedMemorySize();
85
86 }
87
88 bootArgs->Video.v_display = VGA_TEXT_MODE;
89
90 DT__Initialize();
91
92 {
93 Node *node;
94 node = DT__FindNode("/", true);
95 if (node == 0) {
96 stop("Couldn't create root node");
97 }
98 getPlatformName(platformName);
99
100 {
101 int nameLen;
102 nameLen = strlen(platformName) + 1;
103 DT__AddProperty(node, "compatible", nameLen, platformName);
104 DT__AddProperty(node, "model", nameLen, platformName);
105 }
106 }
107
108 Node *gMemoryMapNode = DT__FindNode("/chosen/memory-map", true);
109
110 set_env(envConvMem, convmem);
111 set_env(envExtMem, extmem);
112 set_env(envMemoryMap, (uint32_t)memoryMap);
113 set_env(envMemoryMapCnt, memoryMapCount);
114set_env(envMemoryMapNode, (uint32_t)gMemoryMapNode);
115
116
117 init_done = 1;
118 }
119
120 }
121
122}
123
124/* boot args getters/setters. */
125
126void setBootArgsVideoMode(int mode)
127{
128 bootArgs->Video.v_display = mode;
129}
130//==========================================================================
131// Return the current video mode.
132uint32_t getVideoMode(void)
133{
134 return bootArgs->Video.v_display;
135}
136void setBootArgsVideoStruct(Boot_Video*Video)
137{
138 bootArgs->Video.v_display = Video->v_display;
139 bootArgs->Video.v_width = Video->v_width;
140 bootArgs->Video.v_height = Video->v_height;
141 bootArgs->Video.v_depth = Video->v_depth;
142 bootArgs->Video.v_rowBytes = Video->v_rowBytes;
143 bootArgs->Video.v_baseAddr = Video->v_baseAddr;
144 return;
145}
146boot_args * getBootArgs(void)
147{
148 return bootArgs;
149}
150
151/* Copy boot args after kernel and record address. */
152
153void
154reserveKernBootStruct(void)
155{
156 void *oldAddr = bootArgs;
157
158 bootArgs = (boot_args *)AllocateKernelMemory(sizeof(boot_args));
159 bcopy(oldAddr, bootArgs, sizeof(boot_args));
160
161}
162
163void
164reserveKernLegacyBootStruct(void)
165{
166 bootArgsLegacy = (boot_args_legacy *)AllocateKernelMemory(sizeof(boot_args_legacy));
167
168bootArgsLegacy->Revision = bootArgs->Revision ;
169bootArgsLegacy->Version = bootArgs->Version ;
170bcopy(bootArgs->CommandLine, bootArgsLegacy->CommandLine, BOOT_LINE_LENGTH);
171bootArgsLegacy->MemoryMap = bootArgs->MemoryMap ;
172bootArgsLegacy->MemoryMapSize = bootArgs->MemoryMapSize ;
173bootArgsLegacy->MemoryMapDescriptorSize = bootArgs->MemoryMapDescriptorSize ;
174bootArgsLegacy->MemoryMapDescriptorVersion = bootArgs->MemoryMapDescriptorVersion ;
175bootArgsLegacy->Video = bootArgs->Video ;
176bootArgsLegacy->deviceTreeP = bootArgs->deviceTreeP ;
177bootArgsLegacy->deviceTreeLength = bootArgs->deviceTreeLength ;
178bootArgsLegacy->kaddr = bootArgs->kaddr ;
179bootArgsLegacy->ksize = bootArgs->ksize ;
180bootArgsLegacy->efiRuntimeServicesPageStart = bootArgs->efiRuntimeServicesPageStart ;
181bootArgsLegacy->efiRuntimeServicesPageCount = bootArgs->efiRuntimeServicesPageCount ;
182bootArgsLegacy->efiSystemTable = bootArgs->efiSystemTable ;
183bootArgsLegacy->efiMode = bootArgs->efiMode ;
184bootArgsLegacy->performanceDataStart = bootArgs->performanceDataStart ;
185bootArgsLegacy->performanceDataSize = bootArgs->performanceDataSize ;
186bootArgsLegacy->efiRuntimeServicesVirtualPageStart = bootArgs->efiRuntimeServicesVirtualPageStart ;
187
188
189}
190
191void
192finalizeBootStruct(void)
193{
194{
195int i;
196EfiMemoryRange *kMemoryMap = NULL;
197MemoryRange *range = NULL;
198
199uint64_tsane_size = 0; /* Memory size to use for defaults calculations */
200
201int memoryMapCount = (int)get_env(envMemoryMapCnt);
202
203if (memoryMapCount == 0) {
204
205// XXX could make a two-part map here
206stop("No memory map found\n");
207}
208
209
210
211// convert memory map to boot_args memory map
212kMemoryMap = (EfiMemoryRange *)AllocateKernelMemory(sizeof(EfiMemoryRange) * memoryMapCount);
213if (kMemoryMap == NULL) {
214
215stop("Unable to allocate kernel space for the memory map\n");
216 return;
217}
218bootArgs->MemoryMap = (uint32_t)kMemoryMap;
219bootArgs->MemoryMapSize = sizeof(EfiMemoryRange) * memoryMapCount;
220bootArgs->MemoryMapDescriptorSize = sizeof(EfiMemoryRange);
221bootArgs->MemoryMapDescriptorVersion = 0;
222
223for (i=0; i<memoryMapCount; i++, kMemoryMap++) {
224range = &memoryMap[i];
225 if (!range || !kMemoryMap) {
226 stop("Error while computing kernel memory map\n");
227 return;
228 }
229switch(range->type) {
230case kMemoryRangeACPI:
231kMemoryMap->Type = kEfiACPIReclaimMemory;
232break;
233case kMemoryRangeNVS:
234kMemoryMap->Type = kEfiACPIMemoryNVS;
235break;
236case kMemoryRangeUsable:
237kMemoryMap->Type = kEfiConventionalMemory;
238break;
239case kMemoryRangeReserved:
240default:
241kMemoryMap->Type = kEfiReservedMemoryType;
242break;
243}
244kMemoryMap->PhysicalStart = range->base;
245kMemoryMap->VirtualStart = range->base;
246kMemoryMap->NumberOfPages = range->length >> I386_PGSHIFT;
247kMemoryMap->Attribute = 0;
248
249switch (kMemoryMap->Type) {
250case kEfiLoaderCode:
251case kEfiLoaderData:
252case kEfiBootServicesCode:
253case kEfiBootServicesData:
254case kEfiConventionalMemory:
255/*
256 * Consolidate usable memory types into one.
257 */
258sane_size += (uint64_t)(kMemoryMap->NumberOfPages << I386_PGSHIFT);
259break;
260
261case kEfiRuntimeServicesCode:
262case kEfiRuntimeServicesData:
263case kEfiACPIReclaimMemory:
264case kEfiACPIMemoryNVS:
265case kEfiPalCode:
266/*
267 * sane_size should reflect the total amount of physical ram
268 * in the system, not just the amount that is available for
269 * the OS to use
270 */
271sane_size += (uint64_t)(kMemoryMap->NumberOfPages << I386_PGSHIFT);
272break;
273default:
274break;
275
276}
277}
278
279if (sane_size == 0) {
280
281// I Guess that if sane_size == 0 we've got a big problem here,
282// and it means that the memory map was not converted properly
283stop("Unable to convert memory map into proper format\n");
284}
285
286#define MEG(1024*1024)
287
288/*
289 * For user visible memory size, round up to 128 Mb - accounting for the various stolen memory
290 * not reported by EFI.
291 */
292
293sane_size = (sane_size + 128 * MEG - 1) & ~((uint64_t)(128 * MEG - 1));
294bootArgs->PhysicalMemorySize = sane_size;
295bootArgs->FSBFrequency = get_env(envFSBFreq);
296
297}
298
299
300{
301uint32_t size;
302void *addr;
303// Flatten device tree
304DT__FlattenDeviceTree(0, &size);
305addr = (void *)AllocateKernelMemory(size);
306if (addr == 0) {
307stop("Couldn't allocate device tree\n");
308}
309
310DT__FlattenDeviceTree((void **)&addr, &size);
311 if (!size) {
312 stop("Couldn't get flatten device tree\n");
313 }
314bootArgs->deviceTreeP = (uint32_t)addr;
315bootArgs->deviceTreeLength = size;
316}
317
318}
319

Archive Download this file

Revision: 2006