Home | History | Annotate | Line # | Download | only in exe
e32boot.cpp revision 1.2
      1 /*	$NetBSD: e32boot.cpp,v 1.2 2013/06/20 13:36:48 kiyohara Exp $	*/
      2 /*
      3  * Copyright (c) 2012, 2013 KIYOHARA Takashi
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     19  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     23  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     24  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  * POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #include <e32base.h>
     29 #include <e32cons.h>
     30 #include <e32def.h>
     31 #include <e32hal.h>
     32 #include <e32svr.h>	/* XXXXX */
     33 #include <w32std.h>
     34 
     35 #include "e32boot.h"
     36 #include "netbsd.h"
     37 #include "../../../include/bootinfo.h"
     38 
     39 CConsoleBase *console;
     40 LOCAL_C NetBSD *LoadNetBSDL(void);
     41 LOCAL_C struct btinfo_common *CreateBootInfo(TAny *);
     42 LOCAL_C struct btinfo_common *FindBootInfoL(struct btinfo_common *, int);
     43 TUint SummaryBootInfoMemory(struct btinfo_common *);
     44 LOCAL_C void E32BootL(void);
     45 
     46 struct memmap {
     47 	TUint address;
     48 	TUint size;	/* KB */
     49 };
     50 struct memmap series5_4m[] = {{ 0xc0000000, 512 }, { 0xc0100000, 512 },
     51 			      { 0xc0400000, 512 }, { 0xc0500000, 512 },
     52 			      { 0xc1000000, 512 }, { 0xc1100000, 512 },
     53 			      { 0xc1400000, 512 }, { 0xc1500000, 512 }};
     54 struct memmap series5_8m[] = {{ 0xc0000000, 512 }, { 0xc0100000, 512 },
     55 			      { 0xc0400000, 512 }, { 0xc0500000, 512 },
     56 			      { 0xc1000000, 512 }, { 0xc1100000, 512 },
     57 			      { 0xc1400000, 512 }, { 0xc1500000, 512 },
     58 			      { 0xd0000000, 512 }, { 0xd0100000, 512 },
     59 			      { 0xd0400000, 512 }, { 0xd0500000, 512 },
     60 			      { 0xd1000000, 512 }, { 0xd1100000, 512 },
     61 			      { 0xd1400000, 512 }, { 0xd1500000, 512 }};
     62 struct memmap revo[] = {{ 0xc0000000, 4096 }, { 0xc0800000, 4096 }};
     63 struct memmap revopuls[] = {{ 0xc0000000, 4096 }, { 0xc0800000, 4096 },
     64 			    { 0xd0000000, 4096 }, { 0xd0800000, 4096 }};
     65 struct memmap series5mx_16m[] = {{ 0xc0000000, 8192 }, { 0xc1000000, 8192 }};
     66 struct memmap series5mxpro_24m[] = {{ 0xc0000000, 8192 }, { 0xc1000000, 8192 },
     67 				    { 0xd0000000, 4096 }, { 0xd0800000, 4096 }};
     68 struct memmap series5mxpro_32m[] = {{ 0xc0000000, 8192 }, { 0xc1000000, 8192 },
     69 				    { 0xd0000000, 8192 }, { 0xd1000000, 8192 }};
     70 struct memmap series7_16m[] = {{ 0xc0000000, 16384 }};
     71 struct memmap series7_32m[] = {{ 0xc0000000, 16384 }, { 0xc8000000, 16384 }};
     72 
     73 struct {
     74 	char *model;
     75 	TInt width;
     76 	TInt height;
     77 	TUint memsize;
     78 	struct memmap *memmaps;
     79 } memmaps[] = {
     80 	{ "SERIES5 R1",	640, 240,  4096, series5_4m },
     81 	{ "SERIES5 R1",	640, 240,  8192, series5_8m },
     82 	{ "SERIES5 R1",	640, 320,  4096, series5_4m },	/* Geofox One */
     83 	{ "SERIES5 R1",	640, 320,  8192, series5_8m },	/* Geofox One */
     84 //	{ "SERIES5 R1",	640, 320, 16384, one_16m },
     85 	{ "SERIES5 R1",	320, 200,  4096, series5_4m },	/* Osaris */
     86 //	{ "SERIES5 R1",	320, 200, 16384, osaris_16m },
     87 	{ "SERIES5mx",	480, 160,  8192, revo },
     88 	{ "SERIES5mx",	480, 160, 16384, revopuls },
     89 	{ "SERIES5mx",	640, 240, 16384, series5mx_16m },
     90 	{ "SERIES5mx",	640, 240, 24576, series5mxpro_24m },
     91 	{ "SERIES5mx",	640, 240, 32768, series5mxpro_32m },
     92 	{ "SERIES7",	800, 600, 16384, series7_16m },
     93 	{ "SERIES7",	800, 600, 32768, series7_32m },
     94 };
     95 
     96 class E32BootLogicalChannel : public RLogicalChannel {
     97 public:
     98 	TInt DoCreate(const TDesC *aChan, TInt aUnit, const TDesC *aDriver,
     99 							const TDesC8 *anInfo)
    100 	{
    101 
    102 		return RLogicalChannel::DoCreate(E32BootName, TVersion(0, 0, 0),
    103 						aChan, aUnit, aDriver, anInfo);
    104 	}
    105 
    106 	TInt DoControl(TInt aFunction, TAny *a1)
    107 	{
    108 
    109 		return RLogicalChannel::DoControl(aFunction, a1);
    110 	}
    111 
    112 	TInt DoControl(TInt aFunction, TAny *a1, TAny *a2)
    113 	{
    114 
    115 		return RLogicalChannel::DoControl(aFunction, a1, a2);
    116 	}
    117 };
    118 
    119 
    120 LOCAL_C void
    121 E32BootL(void)
    122 {
    123 	E32BootLogicalChannel *E32BootChannel = new E32BootLogicalChannel;
    124 	NetBSD *netbsd = NULL;
    125 	TScreenInfoV01 screenInfo;
    126 	TPckg<TScreenInfoV01> sI(screenInfo);
    127 	TBuf<32> ldd;
    128 	TInt err;
    129 	TUint membytes;
    130 	TAny *buf, *safeAddress;
    131 	struct btinfo_common *bootinfo;
    132 	struct btinfo_model *model;
    133 	struct btinfo_video *video;
    134 	struct btinfo_bootargs *bootargs;
    135 
    136 	console =
    137 	    Console::NewL(E32BootName, TSize(KConsFullScreen, KConsFullScreen));
    138 
    139 	buf = User::AllocL(ALIGN_SAFE_PAGE_SIZE);	/* bootinfo buffer */
    140 
    141 	/* Put banner */
    142 	console->Printf(_L("\n"));
    143 	console->Printf(_L(">> %s, Revision %s\n"),
    144 	    bootprog_name, bootprog_rev);
    145 
    146 	UserSvr::ScreenInfo(sI);
    147 	if (!screenInfo.iScreenAddressValid)
    148 		User::Leave(KErrNotSupported);
    149 	safeAddress = screenInfo.iScreenAddress;
    150 
    151 	bootinfo = CreateBootInfo((TAny *)PAGE_ALIGN(buf));
    152 
    153 	model = (struct btinfo_model *)FindBootInfoL(bootinfo, BTINFO_MODEL);
    154 	console->Printf(_L(">> Model %s\n"), model->model);
    155 
    156 	membytes = SummaryBootInfoMemory(bootinfo);
    157 	console->Printf(_L(">> Memory %d k\n"), membytes / 1024);
    158 
    159 	video = (struct btinfo_video *)FindBootInfoL(bootinfo, BTINFO_VIDEO);
    160 	console->Printf(_L(">> Video %d x %d\n"), video->width, video->height);
    161 
    162 	console->Printf(_L("\n"));
    163 
    164 	bootargs =
    165 	    (struct btinfo_bootargs *)FindBootInfoL(bootinfo, BTINFO_BOOTARGS);
    166 	TRAP(err, netbsd = LoadNetBSDL());
    167 	if (err != KErrNone)
    168 		User::Leave(err);
    169 	else if (netbsd == NULL)
    170 		return;
    171 	console->Printf(_L("\nLoaded\n"));
    172 
    173 	int n, m;
    174 	n = sizeof(bootargs->bootargs);
    175 	m = (*netbsd->GetArgs()).Length();
    176 	Mem::Copy(bootargs->bootargs, &(*netbsd->GetArgs())[0], n < m ? n : m);
    177 	bootargs->bootargs[n < m ? n - 1 : m] = '\0';
    178 
    179 	netbsd->ParseHeader();
    180 
    181 	/* Load logical device(kernel part of e32boot). */
    182 	if (_L(model->model).CompareF(_L("SERIES5 R1")) == 0)
    183 		ldd = _L("e32boot-s5.ldd");
    184 	else if (_L(model->model).CompareF(_L("SERIES5mx")) == 0)
    185 		ldd = _L("e32boot-s5mx.ldd");
    186 //	else if (_L(model->model).CompareF(_L("SERIES7")) == 0)
    187 //		ldd = _L("e32boot-s7.ldd");	// not yet.
    188 	else {
    189 		console->Printf(_L("Not Supported machine\n"));
    190 		console->Getch();
    191 		User::Leave(KErrNotSupported);
    192 	}
    193 	err = User::LoadLogicalDevice(ldd);
    194 	if (err != KErrNone && err != KErrAlreadyExists) {
    195 		console->Printf(_L("LoadLogicalDevice failed: %d\n"), err);
    196 		console->Getch();
    197 		User::Leave(err);
    198 	}
    199 	/* Create channel to kernel part. */
    200 	err = E32BootChannel->DoCreate(NULL, KNullUnit, NULL, NULL);
    201 	if (err == KErrNone) {
    202 		E32BootChannel->DoControl(KE32BootSetSafeAddress, safeAddress);
    203 		E32BootChannel->DoControl(KE32BootBootNetBSD, netbsd, bootinfo);
    204 	} else {
    205 		console->Printf(_L("DoCreate failed: %d\n"), err);
    206 		console->Getch();
    207 	}
    208 
    209 	User::FreeLogicalDevice(ldd);
    210 	if (err != KErrNone)
    211 		User::Leave(err);
    212 }
    213 
    214 GLDEF_C TInt E32Main(void)	/* main function called by E32 */
    215 {
    216 
    217 	__UHEAP_MARK;
    218 	CTrapCleanup *cleanup = CTrapCleanup::New();
    219 
    220 	TRAPD(error, E32BootL());
    221 	__ASSERT_ALWAYS(!error, User::Panic(E32BootName, error));
    222 
    223 	delete cleanup;
    224 	__UHEAP_MARKEND;
    225 	return 0;
    226 }
    227 
    228 LOCAL_C NetBSD *
    229 LoadNetBSDL(void)
    230 {
    231 	NetBSD *netbsd = NULL;
    232 	TBuf<KMaxCommandLine> input, *args;
    233 	TPtrC Default = _L("C:\\netbsd");
    234 	TPtrC Prompt = _L("Boot: ");
    235 	TInt pos, err;
    236 	TBool retry;
    237 
    238 	input.Zero();
    239 	args = new TBuf<KMaxCommandLine>;
    240 	args->Zero();
    241 	retry = false;
    242 	console->Printf(Prompt);
    243 	console->Printf(_L("["));
    244 	console->Printf(Default);
    245 	console->Printf(_L("]: "));
    246 	console->SetPos(Prompt.Length() +
    247 			_L("[").Length() +
    248 			Default.Length() +
    249 			_L("]: ").Length());
    250 	pos = 0;
    251 	while (1) {
    252 		TChar gChar = console->Getch();
    253 		switch (gChar) {
    254 		case EKeyEscape:
    255 			return NULL;
    256 
    257 		case EKeyEnter:
    258 			break;
    259 
    260 		case EKeyBackspace:
    261 			if (pos > 0) {
    262 				pos--;
    263 				input.Delete(pos, 1);
    264 			}
    265 			break;
    266 
    267 		default:
    268 			if (gChar.IsPrint()) {
    269 				if (input.Length() < KMaxCommandLine) {
    270 					TBuf<0x02> b;
    271 					b.Append(gChar);
    272 					input.Insert(pos++, b);
    273 				}
    274 			}
    275 			break;
    276 		}
    277 		if (gChar == EKeyEnter) {
    278 			input.TrimAll();
    279 			if (input[0] == '-')
    280 				input.Swap(*args);
    281 			for (int i = 0; i < input.Length(); i++)
    282 				if (input[i] == ' ') {
    283 					args->Copy(input);
    284 					input.SetLength(i);
    285 					args->Delete(0, i + 1);
    286 					break;
    287 				}
    288 			args->ZeroTerminate();
    289 
    290 			if (input.Length() > 0) {
    291 				TRAP(err, netbsd = NetBSD::New(input, *args));
    292 			} else {
    293 				TRAP(err, netbsd = NetBSD::New(Default, *args));
    294 			}
    295 			if (err == 0 && netbsd != NULL)
    296 				break;
    297 			console->Printf(_L("\nLoad failed: %d\n"), err);
    298 
    299 			input.Zero();
    300 			args->Zero();
    301 			console->Printf(Prompt);
    302 			pos = 0;
    303 			retry = true;
    304 		}
    305 		TInt base = Prompt.Length();
    306 		if (!retry)
    307 			base += (_L("[").Length() + Default.Length() +
    308 							_L("]: ").Length());
    309 		console->SetPos(base + pos);
    310 		console->ClearToEndOfLine();
    311 		console->SetPos(base);
    312 		console->Write(input);
    313 		console->SetPos(base + pos);
    314 	}
    315 
    316 	return netbsd;
    317 }
    318 
    319 #define KB	* 1024
    320 
    321 LOCAL_C struct btinfo_common *
    322 CreateBootInfo(TAny *buf)
    323 {
    324 	TMachineInfoV1Buf MachInfo;
    325 	TMemoryInfoV1Buf MemInfo;
    326 	struct btinfo_common *bootinfo, *common;
    327 	struct btinfo_model *model;
    328 	struct btinfo_memory *memory;
    329 	struct btinfo_video *video;
    330 	struct btinfo_bootargs *bootargs;
    331 	struct memmap *memmap;
    332 	TUint memsize;
    333 	TUint i;
    334 
    335 	UserHal::MachineInfo(MachInfo);
    336 	UserHal::MemoryInfo(MemInfo);
    337 
    338 	common = bootinfo = (struct btinfo_common *)buf;
    339 
    340 	/* Set machine name to bootinfo. */
    341 	common->len = sizeof(struct btinfo_model);
    342 	common->type = BTINFO_MODEL;
    343 	model = (struct btinfo_model *)common;
    344 	Mem::Copy(model->model, &MachInfo().iMachineName[0],
    345 	    sizeof(model->model));
    346 	common = &(model + 1)->common;
    347 
    348 	/* Set video width/height to bootinfo. */
    349 	common->len = sizeof(struct btinfo_video);
    350 	common->type = BTINFO_VIDEO;
    351 	video = (struct btinfo_video *)common;
    352 	video->width = MachInfo().iDisplaySizeInPixels.iWidth;
    353 	video->height = MachInfo().iDisplaySizeInPixels.iHeight;
    354 	common = &(video + 1)->common;
    355 
    356 	/* Set memory size to bootinfo. */
    357 	memsize = MemInfo().iTotalRamInBytes / 1024;
    358 	for (i = 0; i < sizeof(memmaps) / sizeof(memmaps[0]); i++) {
    359 		if (_L(memmaps[i].model).CompareF(_L(model->model)) == 0 &&
    360 		    memmaps[i].width == video->width &&
    361 		    memmaps[i].height == video->height &&
    362 		    memmaps[i].memsize == memsize) {
    363 			memmap = memmaps[i].memmaps;
    364 			while (memsize > 0) {
    365 				common->len = sizeof(struct btinfo_memory);
    366 				common->type = BTINFO_MEMORY;
    367 				memory = (struct btinfo_memory *)common;
    368 				memory->address = memmap->address;
    369 				memory->size = memmap->size KB;
    370 				common = &(memory + 1)->common;
    371 				memsize -= memmap->size;
    372 				memmap++;
    373 			}
    374 			break;
    375 		}
    376 	}
    377 	if (i == sizeof(memmaps) / sizeof(memmaps[0])) {
    378 		common->len = sizeof(struct btinfo_memory);
    379 		common->type = BTINFO_MEMORY;
    380 		memory = (struct btinfo_memory *)common;
    381 		memory->address = 0xc0000000;		/* default is here */
    382 		memory->size = 4096 KB;			/* XXXXX */
    383 		common = &(memory + 1)->common;
    384 	}
    385 
    386 	common->len = sizeof(struct btinfo_bootargs);
    387 	common->type = BTINFO_BOOTARGS;
    388 	bootargs = (struct btinfo_bootargs *)common;
    389 	bootargs->bootargs[0] = '\0';
    390 	common = &(bootargs + 1)->common;
    391 
    392 	common->len = 0;
    393 	common->type = BTINFO_NONE;
    394 
    395 	/* Terminate bootinfo. */
    396 	return bootinfo;
    397 }
    398 
    399 #undef KB
    400 
    401 LOCAL_C struct btinfo_common *
    402 FindBootInfoL(struct btinfo_common *bootinfo, int type)
    403 {
    404 	struct btinfo_common *entry;
    405 
    406 	entry = bootinfo;
    407 	while (entry->type != BTINFO_NONE) {
    408 		if (entry->type == type)
    409 			return entry;
    410 		entry = (struct btinfo_common *)((int)entry + entry->len);
    411 	}
    412 	User::Leave(KErrNotFound);
    413 
    414 	/* NOTREACHED */
    415 
    416 	return NULL;
    417 }
    418 
    419 TUint
    420 SummaryBootInfoMemory(struct btinfo_common *bootinfo)
    421 {
    422 	struct btinfo_common *entry;
    423 	struct btinfo_memory *memory;
    424 	TUint memsize = 0;
    425 
    426 	entry = bootinfo;
    427 	while (entry->type != BTINFO_NONE) {
    428 		if (entry->type == BTINFO_MEMORY) {
    429 			memory = (struct btinfo_memory *)entry;
    430 			memsize += memory->size;
    431 		}
    432 		entry = (struct btinfo_common *)((int)entry + entry->len);
    433 	}
    434 	return memsize;
    435 }
    436