1*4bcd07ddSkiyohara /*	$NetBSD: e32boot.cpp,v 1.3 2013/06/20 15:30:00 kiyohara Exp $	*/
268122621Skiyohara /*
368122621Skiyohara  * Copyright (c) 2012, 2013 KIYOHARA Takashi
468122621Skiyohara  * All rights reserved.
568122621Skiyohara  *
668122621Skiyohara  * Redistribution and use in source and binary forms, with or without
768122621Skiyohara  * modification, are permitted provided that the following conditions
868122621Skiyohara  * are met:
968122621Skiyohara  * 1. Redistributions of source code must retain the above copyright
1068122621Skiyohara  *    notice, this list of conditions and the following disclaimer.
1168122621Skiyohara  * 2. Redistributions in binary form must reproduce the above copyright
1268122621Skiyohara  *    notice, this list of conditions and the following disclaimer in the
1368122621Skiyohara  *    documentation and/or other materials provided with the distribution.
1468122621Skiyohara  *
1568122621Skiyohara  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1668122621Skiyohara  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1768122621Skiyohara  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1868122621Skiyohara  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
1968122621Skiyohara  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2068122621Skiyohara  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2168122621Skiyohara  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2268122621Skiyohara  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2368122621Skiyohara  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
2468122621Skiyohara  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2568122621Skiyohara  * POSSIBILITY OF SUCH DAMAGE.
2668122621Skiyohara  */
2768122621Skiyohara 
2868122621Skiyohara #include <e32base.h>
2968122621Skiyohara #include <e32cons.h>
3068122621Skiyohara #include <e32def.h>
3168122621Skiyohara #include <e32hal.h>
3268122621Skiyohara #include <e32svr.h>	/* XXXXX */
3368122621Skiyohara #include <w32std.h>
3468122621Skiyohara 
3568122621Skiyohara #include "e32boot.h"
3668122621Skiyohara #include "netbsd.h"
3768122621Skiyohara #include "../../../include/bootinfo.h"
3868122621Skiyohara 
3968122621Skiyohara CConsoleBase *console;
4068122621Skiyohara LOCAL_C NetBSD *LoadNetBSDL(void);
4168122621Skiyohara LOCAL_C struct btinfo_common *CreateBootInfo(TAny *);
4268122621Skiyohara LOCAL_C struct btinfo_common *FindBootInfoL(struct btinfo_common *, int);
4368122621Skiyohara TUint SummaryBootInfoMemory(struct btinfo_common *);
4468122621Skiyohara LOCAL_C void E32BootL(void);
4568122621Skiyohara 
4668122621Skiyohara struct memmap {
4768122621Skiyohara 	TUint address;
4868122621Skiyohara 	TUint size;	/* KB */
4968122621Skiyohara };
5068122621Skiyohara struct memmap series5_4m[] = {{ 0xc0000000, 512 }, { 0xc0100000, 512 },
5168122621Skiyohara 			      { 0xc0400000, 512 }, { 0xc0500000, 512 },
5268122621Skiyohara 			      { 0xc1000000, 512 }, { 0xc1100000, 512 },
5368122621Skiyohara 			      { 0xc1400000, 512 }, { 0xc1500000, 512 }};
5468122621Skiyohara struct memmap series5_8m[] = {{ 0xc0000000, 512 }, { 0xc0100000, 512 },
5568122621Skiyohara 			      { 0xc0400000, 512 }, { 0xc0500000, 512 },
5668122621Skiyohara 			      { 0xc1000000, 512 }, { 0xc1100000, 512 },
5768122621Skiyohara 			      { 0xc1400000, 512 }, { 0xc1500000, 512 },
5868122621Skiyohara 			      { 0xd0000000, 512 }, { 0xd0100000, 512 },
5968122621Skiyohara 			      { 0xd0400000, 512 }, { 0xd0500000, 512 },
6068122621Skiyohara 			      { 0xd1000000, 512 }, { 0xd1100000, 512 },
6168122621Skiyohara 			      { 0xd1400000, 512 }, { 0xd1500000, 512 }};
6268122621Skiyohara struct memmap revo[] = {{ 0xc0000000, 4096 }, { 0xc0800000, 4096 }};
6368122621Skiyohara struct memmap revopuls[] = {{ 0xc0000000, 4096 }, { 0xc0800000, 4096 },
6468122621Skiyohara 			    { 0xd0000000, 4096 }, { 0xd0800000, 4096 }};
6568122621Skiyohara struct memmap series5mx_16m[] = {{ 0xc0000000, 8192 }, { 0xc1000000, 8192 }};
6668122621Skiyohara struct memmap series5mxpro_24m[] = {{ 0xc0000000, 8192 }, { 0xc1000000, 8192 },
6768122621Skiyohara 				    { 0xd0000000, 4096 }, { 0xd0800000, 4096 }};
6868122621Skiyohara struct memmap series5mxpro_32m[] = {{ 0xc0000000, 8192 }, { 0xc1000000, 8192 },
6968122621Skiyohara 				    { 0xd0000000, 8192 }, { 0xd1000000, 8192 }};
7068122621Skiyohara struct memmap series7_16m[] = {{ 0xc0000000, 16384 }};
7168122621Skiyohara struct memmap series7_32m[] = {{ 0xc0000000, 16384 }, { 0xc8000000, 16384 }};
7268122621Skiyohara 
7368122621Skiyohara struct {
7468122621Skiyohara 	char *model;
7568122621Skiyohara 	TInt width;
7668122621Skiyohara 	TInt height;
7768122621Skiyohara 	TUint memsize;
7868122621Skiyohara 	struct memmap *memmaps;
7968122621Skiyohara } memmaps[] = {
8068122621Skiyohara 	{ "SERIES5 R1",	640, 240,  4096, series5_4m },
8168122621Skiyohara 	{ "SERIES5 R1",	640, 240,  8192, series5_8m },
8268122621Skiyohara 	{ "SERIES5 R1",	640, 320,  4096, series5_4m },	/* Geofox One */
8368122621Skiyohara 	{ "SERIES5 R1",	640, 320,  8192, series5_8m },	/* Geofox One */
8468122621Skiyohara //	{ "SERIES5 R1",	640, 320, 16384, one_16m },
8568122621Skiyohara 	{ "SERIES5 R1",	320, 200,  4096, series5_4m },	/* Osaris */
8668122621Skiyohara //	{ "SERIES5 R1",	320, 200, 16384, osaris_16m },
8768122621Skiyohara 	{ "SERIES5mx",	480, 160,  8192, revo },
8868122621Skiyohara 	{ "SERIES5mx",	480, 160, 16384, revopuls },
8968122621Skiyohara 	{ "SERIES5mx",	640, 240, 16384, series5mx_16m },
9068122621Skiyohara 	{ "SERIES5mx",	640, 240, 24576, series5mxpro_24m },
9168122621Skiyohara 	{ "SERIES5mx",	640, 240, 32768, series5mxpro_32m },
9268122621Skiyohara 	{ "SERIES7",	800, 600, 16384, series7_16m },
9368122621Skiyohara 	{ "SERIES7",	800, 600, 32768, series7_32m },
9468122621Skiyohara };
9568122621Skiyohara 
9668122621Skiyohara class E32BootLogicalChannel : public RLogicalChannel {
9768122621Skiyohara public:
DoCreate(const TDesC * aChan,TInt aUnit,const TDesC * aDriver,const TDesC8 * anInfo)9868122621Skiyohara 	TInt DoCreate(const TDesC *aChan, TInt aUnit, const TDesC *aDriver,
9968122621Skiyohara 							const TDesC8 *anInfo)
10068122621Skiyohara 	{
10168122621Skiyohara 
10268122621Skiyohara 		return RLogicalChannel::DoCreate(E32BootName, TVersion(0, 0, 0),
10368122621Skiyohara 						aChan, aUnit, aDriver, anInfo);
10468122621Skiyohara 	}
10568122621Skiyohara 
DoControl(TInt aFunction,TAny * a1)10668122621Skiyohara 	TInt DoControl(TInt aFunction, TAny *a1)
10768122621Skiyohara 	{
10868122621Skiyohara 
10968122621Skiyohara 		return RLogicalChannel::DoControl(aFunction, a1);
11068122621Skiyohara 	}
11168122621Skiyohara 
DoControl(TInt aFunction,TAny * a1,TAny * a2)11268122621Skiyohara 	TInt DoControl(TInt aFunction, TAny *a1, TAny *a2)
11368122621Skiyohara 	{
11468122621Skiyohara 
11568122621Skiyohara 		return RLogicalChannel::DoControl(aFunction, a1, a2);
11668122621Skiyohara 	}
11768122621Skiyohara };
11868122621Skiyohara 
11968122621Skiyohara 
12068122621Skiyohara LOCAL_C void
E32BootL(void)12168122621Skiyohara E32BootL(void)
12268122621Skiyohara {
12368122621Skiyohara 	E32BootLogicalChannel *E32BootChannel = new E32BootLogicalChannel;
12468122621Skiyohara 	NetBSD *netbsd = NULL;
12568122621Skiyohara 	TScreenInfoV01 screenInfo;
12668122621Skiyohara 	TPckg<TScreenInfoV01> sI(screenInfo);
12768122621Skiyohara 	TBuf<32> ldd;
12868122621Skiyohara 	TInt err;
12968122621Skiyohara 	TUint membytes;
13068122621Skiyohara 	TAny *buf, *safeAddress;
13168122621Skiyohara 	struct btinfo_common *bootinfo;
13268122621Skiyohara 	struct btinfo_model *model;
13368122621Skiyohara 	struct btinfo_video *video;
134781c2fb3Skiyohara 	struct btinfo_bootargs *bootargs;
13568122621Skiyohara 
13668122621Skiyohara 	console =
13768122621Skiyohara 	    Console::NewL(E32BootName, TSize(KConsFullScreen, KConsFullScreen));
13868122621Skiyohara 
13968122621Skiyohara 	buf = User::AllocL(ALIGN_SAFE_PAGE_SIZE);	/* bootinfo buffer */
14068122621Skiyohara 
14168122621Skiyohara 	/* Put banner */
14268122621Skiyohara 	console->Printf(_L("\n"));
14368122621Skiyohara 	console->Printf(_L(">> %s, Revision %s\n"),
14468122621Skiyohara 	    bootprog_name, bootprog_rev);
14568122621Skiyohara 
14668122621Skiyohara 	UserSvr::ScreenInfo(sI);
14768122621Skiyohara 	if (!screenInfo.iScreenAddressValid)
14868122621Skiyohara 		User::Leave(KErrNotSupported);
14968122621Skiyohara 	safeAddress = screenInfo.iScreenAddress;
15068122621Skiyohara 
15168122621Skiyohara 	bootinfo = CreateBootInfo((TAny *)PAGE_ALIGN(buf));
15268122621Skiyohara 
15368122621Skiyohara 	model = (struct btinfo_model *)FindBootInfoL(bootinfo, BTINFO_MODEL);
15468122621Skiyohara 	console->Printf(_L(">> Model %s\n"), model->model);
15568122621Skiyohara 
15668122621Skiyohara 	membytes = SummaryBootInfoMemory(bootinfo);
15768122621Skiyohara 	console->Printf(_L(">> Memory %d k\n"), membytes / 1024);
15868122621Skiyohara 
15968122621Skiyohara 	video = (struct btinfo_video *)FindBootInfoL(bootinfo, BTINFO_VIDEO);
16068122621Skiyohara 	console->Printf(_L(">> Video %d x %d\n"), video->width, video->height);
16168122621Skiyohara 
16268122621Skiyohara 	console->Printf(_L("\n"));
16368122621Skiyohara 
164781c2fb3Skiyohara 	bootargs =
165781c2fb3Skiyohara 	    (struct btinfo_bootargs *)FindBootInfoL(bootinfo, BTINFO_BOOTARGS);
16668122621Skiyohara 	TRAP(err, netbsd = LoadNetBSDL());
16768122621Skiyohara 	if (err != KErrNone)
16868122621Skiyohara 		User::Leave(err);
16968122621Skiyohara 	else if (netbsd == NULL)
17068122621Skiyohara 		return;
17168122621Skiyohara 	console->Printf(_L("\nLoaded\n"));
17268122621Skiyohara 
173781c2fb3Skiyohara 	int n, m;
174781c2fb3Skiyohara 	n = sizeof(bootargs->bootargs);
175781c2fb3Skiyohara 	m = (*netbsd->GetArgs()).Length();
176*4bcd07ddSkiyohara 	if (m > 0)
177*4bcd07ddSkiyohara 		Mem::Copy(bootargs->bootargs, &(*netbsd->GetArgs())[0],
178*4bcd07ddSkiyohara 		    n < m ? n : m);
179781c2fb3Skiyohara 	bootargs->bootargs[n < m ? n - 1 : m] = '\0';
180781c2fb3Skiyohara 
18168122621Skiyohara 	netbsd->ParseHeader();
18268122621Skiyohara 
18368122621Skiyohara 	/* Load logical device(kernel part of e32boot). */
18468122621Skiyohara 	if (_L(model->model).CompareF(_L("SERIES5 R1")) == 0)
18568122621Skiyohara 		ldd = _L("e32boot-s5.ldd");
18668122621Skiyohara 	else if (_L(model->model).CompareF(_L("SERIES5mx")) == 0)
18768122621Skiyohara 		ldd = _L("e32boot-s5mx.ldd");
18868122621Skiyohara //	else if (_L(model->model).CompareF(_L("SERIES7")) == 0)
18968122621Skiyohara //		ldd = _L("e32boot-s7.ldd");	// not yet.
19068122621Skiyohara 	else {
19168122621Skiyohara 		console->Printf(_L("Not Supported machine\n"));
19268122621Skiyohara 		console->Getch();
19368122621Skiyohara 		User::Leave(KErrNotSupported);
19468122621Skiyohara 	}
19568122621Skiyohara 	err = User::LoadLogicalDevice(ldd);
19668122621Skiyohara 	if (err != KErrNone && err != KErrAlreadyExists) {
19768122621Skiyohara 		console->Printf(_L("LoadLogicalDevice failed: %d\n"), err);
19868122621Skiyohara 		console->Getch();
19968122621Skiyohara 		User::Leave(err);
20068122621Skiyohara 	}
20168122621Skiyohara 	/* Create channel to kernel part. */
20268122621Skiyohara 	err = E32BootChannel->DoCreate(NULL, KNullUnit, NULL, NULL);
20368122621Skiyohara 	if (err == KErrNone) {
20468122621Skiyohara 		E32BootChannel->DoControl(KE32BootSetSafeAddress, safeAddress);
20568122621Skiyohara 		E32BootChannel->DoControl(KE32BootBootNetBSD, netbsd, bootinfo);
20668122621Skiyohara 	} else {
20768122621Skiyohara 		console->Printf(_L("DoCreate failed: %d\n"), err);
20868122621Skiyohara 		console->Getch();
20968122621Skiyohara 	}
21068122621Skiyohara 
21168122621Skiyohara 	User::FreeLogicalDevice(ldd);
21268122621Skiyohara 	if (err != KErrNone)
21368122621Skiyohara 		User::Leave(err);
21468122621Skiyohara }
21568122621Skiyohara 
E32Main(void)21668122621Skiyohara GLDEF_C TInt E32Main(void)	/* main function called by E32 */
21768122621Skiyohara {
21868122621Skiyohara 
21968122621Skiyohara 	__UHEAP_MARK;
22068122621Skiyohara 	CTrapCleanup *cleanup = CTrapCleanup::New();
22168122621Skiyohara 
22268122621Skiyohara 	TRAPD(error, E32BootL());
22368122621Skiyohara 	__ASSERT_ALWAYS(!error, User::Panic(E32BootName, error));
22468122621Skiyohara 
22568122621Skiyohara 	delete cleanup;
22668122621Skiyohara 	__UHEAP_MARKEND;
22768122621Skiyohara 	return 0;
22868122621Skiyohara }
22968122621Skiyohara 
23068122621Skiyohara LOCAL_C NetBSD *
LoadNetBSDL(void)23168122621Skiyohara LoadNetBSDL(void)
23268122621Skiyohara {
23368122621Skiyohara 	NetBSD *netbsd = NULL;
234781c2fb3Skiyohara 	TBuf<KMaxCommandLine> input, *args;
23568122621Skiyohara 	TPtrC Default = _L("C:\\netbsd");
23668122621Skiyohara 	TPtrC Prompt = _L("Boot: ");
23768122621Skiyohara 	TInt pos, err;
23868122621Skiyohara 	TBool retry;
23968122621Skiyohara 
24068122621Skiyohara 	input.Zero();
241781c2fb3Skiyohara 	args = new TBuf<KMaxCommandLine>;
242781c2fb3Skiyohara 	args->Zero();
24368122621Skiyohara 	retry = false;
24468122621Skiyohara 	console->Printf(Prompt);
24568122621Skiyohara 	console->Printf(_L("["));
24668122621Skiyohara 	console->Printf(Default);
24768122621Skiyohara 	console->Printf(_L("]: "));
24868122621Skiyohara 	console->SetPos(Prompt.Length() +
24968122621Skiyohara 			_L("[").Length() +
25068122621Skiyohara 			Default.Length() +
25168122621Skiyohara 			_L("]: ").Length());
25268122621Skiyohara 	pos = 0;
25368122621Skiyohara 	while (1) {
25468122621Skiyohara 		TChar gChar = console->Getch();
25568122621Skiyohara 		switch (gChar) {
25668122621Skiyohara 		case EKeyEscape:
25768122621Skiyohara 			return NULL;
25868122621Skiyohara 
25968122621Skiyohara 		case EKeyEnter:
26068122621Skiyohara 			break;
26168122621Skiyohara 
26268122621Skiyohara 		case EKeyBackspace:
26368122621Skiyohara 			if (pos > 0) {
26468122621Skiyohara 				pos--;
26568122621Skiyohara 				input.Delete(pos, 1);
26668122621Skiyohara 			}
26768122621Skiyohara 			break;
26868122621Skiyohara 
26968122621Skiyohara 		default:
27068122621Skiyohara 			if (gChar.IsPrint()) {
27168122621Skiyohara 				if (input.Length() < KMaxCommandLine) {
27268122621Skiyohara 					TBuf<0x02> b;
27368122621Skiyohara 					b.Append(gChar);
27468122621Skiyohara 					input.Insert(pos++, b);
27568122621Skiyohara 				}
27668122621Skiyohara 			}
27768122621Skiyohara 			break;
27868122621Skiyohara 		}
27968122621Skiyohara 		if (gChar == EKeyEnter) {
280781c2fb3Skiyohara 			input.TrimAll();
281781c2fb3Skiyohara 			if (input[0] == '-')
282781c2fb3Skiyohara 				input.Swap(*args);
283781c2fb3Skiyohara 			for (int i = 0; i < input.Length(); i++)
284781c2fb3Skiyohara 				if (input[i] == ' ') {
285781c2fb3Skiyohara 					args->Copy(input);
286781c2fb3Skiyohara 					input.SetLength(i);
287781c2fb3Skiyohara 					args->Delete(0, i + 1);
288781c2fb3Skiyohara 					break;
289781c2fb3Skiyohara 				}
290781c2fb3Skiyohara 			args->ZeroTerminate();
29168122621Skiyohara 
292781c2fb3Skiyohara 			if (input.Length() > 0) {
293781c2fb3Skiyohara 				TRAP(err, netbsd = NetBSD::New(input, *args));
29468122621Skiyohara 			} else {
295781c2fb3Skiyohara 				TRAP(err, netbsd = NetBSD::New(Default, *args));
29668122621Skiyohara 			}
29768122621Skiyohara 			if (err == 0 && netbsd != NULL)
29868122621Skiyohara 				break;
29968122621Skiyohara 			console->Printf(_L("\nLoad failed: %d\n"), err);
30068122621Skiyohara 
30168122621Skiyohara 			input.Zero();
302781c2fb3Skiyohara 			args->Zero();
30368122621Skiyohara 			console->Printf(Prompt);
30468122621Skiyohara 			pos = 0;
30568122621Skiyohara 			retry = true;
30668122621Skiyohara 		}
30768122621Skiyohara 		TInt base = Prompt.Length();
30868122621Skiyohara 		if (!retry)
30968122621Skiyohara 			base += (_L("[").Length() + Default.Length() +
31068122621Skiyohara 							_L("]: ").Length());
31168122621Skiyohara 		console->SetPos(base + pos);
31268122621Skiyohara 		console->ClearToEndOfLine();
31368122621Skiyohara 		console->SetPos(base);
31468122621Skiyohara 		console->Write(input);
31568122621Skiyohara 		console->SetPos(base + pos);
31668122621Skiyohara 	}
31768122621Skiyohara 
31868122621Skiyohara 	return netbsd;
31968122621Skiyohara }
32068122621Skiyohara 
32168122621Skiyohara #define KB	* 1024
32268122621Skiyohara 
32368122621Skiyohara LOCAL_C struct btinfo_common *
CreateBootInfo(TAny * buf)32468122621Skiyohara CreateBootInfo(TAny *buf)
32568122621Skiyohara {
32668122621Skiyohara 	TMachineInfoV1Buf MachInfo;
32768122621Skiyohara 	TMemoryInfoV1Buf MemInfo;
32868122621Skiyohara 	struct btinfo_common *bootinfo, *common;
32968122621Skiyohara 	struct btinfo_model *model;
33068122621Skiyohara 	struct btinfo_memory *memory;
33168122621Skiyohara 	struct btinfo_video *video;
332781c2fb3Skiyohara 	struct btinfo_bootargs *bootargs;
33368122621Skiyohara 	struct memmap *memmap;
33468122621Skiyohara 	TUint memsize;
33568122621Skiyohara 	TUint i;
33668122621Skiyohara 
33768122621Skiyohara 	UserHal::MachineInfo(MachInfo);
33868122621Skiyohara 	UserHal::MemoryInfo(MemInfo);
33968122621Skiyohara 
34068122621Skiyohara 	common = bootinfo = (struct btinfo_common *)buf;
34168122621Skiyohara 
34268122621Skiyohara 	/* Set machine name to bootinfo. */
34368122621Skiyohara 	common->len = sizeof(struct btinfo_model);
34468122621Skiyohara 	common->type = BTINFO_MODEL;
34568122621Skiyohara 	model = (struct btinfo_model *)common;
34668122621Skiyohara 	Mem::Copy(model->model, &MachInfo().iMachineName[0],
34768122621Skiyohara 	    sizeof(model->model));
34868122621Skiyohara 	common = &(model + 1)->common;
34968122621Skiyohara 
35068122621Skiyohara 	/* Set video width/height to bootinfo. */
35168122621Skiyohara 	common->len = sizeof(struct btinfo_video);
35268122621Skiyohara 	common->type = BTINFO_VIDEO;
35368122621Skiyohara 	video = (struct btinfo_video *)common;
35468122621Skiyohara 	video->width = MachInfo().iDisplaySizeInPixels.iWidth;
35568122621Skiyohara 	video->height = MachInfo().iDisplaySizeInPixels.iHeight;
35668122621Skiyohara 	common = &(video + 1)->common;
35768122621Skiyohara 
35868122621Skiyohara 	/* Set memory size to bootinfo. */
35968122621Skiyohara 	memsize = MemInfo().iTotalRamInBytes / 1024;
36068122621Skiyohara 	for (i = 0; i < sizeof(memmaps) / sizeof(memmaps[0]); i++) {
36168122621Skiyohara 		if (_L(memmaps[i].model).CompareF(_L(model->model)) == 0 &&
36268122621Skiyohara 		    memmaps[i].width == video->width &&
36368122621Skiyohara 		    memmaps[i].height == video->height &&
36468122621Skiyohara 		    memmaps[i].memsize == memsize) {
36568122621Skiyohara 			memmap = memmaps[i].memmaps;
36668122621Skiyohara 			while (memsize > 0) {
36768122621Skiyohara 				common->len = sizeof(struct btinfo_memory);
36868122621Skiyohara 				common->type = BTINFO_MEMORY;
36968122621Skiyohara 				memory = (struct btinfo_memory *)common;
37068122621Skiyohara 				memory->address = memmap->address;
37168122621Skiyohara 				memory->size = memmap->size KB;
37268122621Skiyohara 				common = &(memory + 1)->common;
37368122621Skiyohara 				memsize -= memmap->size;
37468122621Skiyohara 				memmap++;
37568122621Skiyohara 			}
37668122621Skiyohara 			break;
37768122621Skiyohara 		}
37868122621Skiyohara 	}
37968122621Skiyohara 	if (i == sizeof(memmaps) / sizeof(memmaps[0])) {
38068122621Skiyohara 		common->len = sizeof(struct btinfo_memory);
38168122621Skiyohara 		common->type = BTINFO_MEMORY;
38268122621Skiyohara 		memory = (struct btinfo_memory *)common;
38368122621Skiyohara 		memory->address = 0xc0000000;		/* default is here */
38468122621Skiyohara 		memory->size = 4096 KB;			/* XXXXX */
38568122621Skiyohara 		common = &(memory + 1)->common;
38668122621Skiyohara 	}
38768122621Skiyohara 
388781c2fb3Skiyohara 	common->len = sizeof(struct btinfo_bootargs);
389781c2fb3Skiyohara 	common->type = BTINFO_BOOTARGS;
390781c2fb3Skiyohara 	bootargs = (struct btinfo_bootargs *)common;
391781c2fb3Skiyohara 	bootargs->bootargs[0] = '\0';
392781c2fb3Skiyohara 	common = &(bootargs + 1)->common;
393781c2fb3Skiyohara 
39468122621Skiyohara 	common->len = 0;
39568122621Skiyohara 	common->type = BTINFO_NONE;
39668122621Skiyohara 
39768122621Skiyohara 	/* Terminate bootinfo. */
39868122621Skiyohara 	return bootinfo;
39968122621Skiyohara }
40068122621Skiyohara 
40168122621Skiyohara #undef KB
40268122621Skiyohara 
40368122621Skiyohara LOCAL_C struct btinfo_common *
FindBootInfoL(struct btinfo_common * bootinfo,int type)40468122621Skiyohara FindBootInfoL(struct btinfo_common *bootinfo, int type)
40568122621Skiyohara {
40668122621Skiyohara 	struct btinfo_common *entry;
40768122621Skiyohara 
40868122621Skiyohara 	entry = bootinfo;
40968122621Skiyohara 	while (entry->type != BTINFO_NONE) {
41068122621Skiyohara 		if (entry->type == type)
41168122621Skiyohara 			return entry;
41268122621Skiyohara 		entry = (struct btinfo_common *)((int)entry + entry->len);
41368122621Skiyohara 	}
41468122621Skiyohara 	User::Leave(KErrNotFound);
41568122621Skiyohara 
41668122621Skiyohara 	/* NOTREACHED */
41768122621Skiyohara 
41868122621Skiyohara 	return NULL;
41968122621Skiyohara }
42068122621Skiyohara 
42168122621Skiyohara TUint
SummaryBootInfoMemory(struct btinfo_common * bootinfo)42268122621Skiyohara SummaryBootInfoMemory(struct btinfo_common *bootinfo)
42368122621Skiyohara {
42468122621Skiyohara 	struct btinfo_common *entry;
42568122621Skiyohara 	struct btinfo_memory *memory;
42668122621Skiyohara 	TUint memsize = 0;
42768122621Skiyohara 
42868122621Skiyohara 	entry = bootinfo;
42968122621Skiyohara 	while (entry->type != BTINFO_NONE) {
43068122621Skiyohara 		if (entry->type == BTINFO_MEMORY) {
43168122621Skiyohara 			memory = (struct btinfo_memory *)entry;
43268122621Skiyohara 			memsize += memory->size;
43368122621Skiyohara 		}
43468122621Skiyohara 		entry = (struct btinfo_common *)((int)entry + entry->len);
43568122621Skiyohara 	}
43668122621Skiyohara 	return memsize;
43768122621Skiyohara }
438