1 /* $NetBSD: e32boot.cpp,v 1.3 2013/06/20 15:30:00 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 if (m > 0) 177 Mem::Copy(bootargs->bootargs, &(*netbsd->GetArgs())[0], 178 n < m ? n : m); 179 bootargs->bootargs[n < m ? n - 1 : m] = '\0'; 180 181 netbsd->ParseHeader(); 182 183 /* Load logical device(kernel part of e32boot). */ 184 if (_L(model->model).CompareF(_L("SERIES5 R1")) == 0) 185 ldd = _L("e32boot-s5.ldd"); 186 else if (_L(model->model).CompareF(_L("SERIES5mx")) == 0) 187 ldd = _L("e32boot-s5mx.ldd"); 188 // else if (_L(model->model).CompareF(_L("SERIES7")) == 0) 189 // ldd = _L("e32boot-s7.ldd"); // not yet. 190 else { 191 console->Printf(_L("Not Supported machine\n")); 192 console->Getch(); 193 User::Leave(KErrNotSupported); 194 } 195 err = User::LoadLogicalDevice(ldd); 196 if (err != KErrNone && err != KErrAlreadyExists) { 197 console->Printf(_L("LoadLogicalDevice failed: %d\n"), err); 198 console->Getch(); 199 User::Leave(err); 200 } 201 /* Create channel to kernel part. */ 202 err = E32BootChannel->DoCreate(NULL, KNullUnit, NULL, NULL); 203 if (err == KErrNone) { 204 E32BootChannel->DoControl(KE32BootSetSafeAddress, safeAddress); 205 E32BootChannel->DoControl(KE32BootBootNetBSD, netbsd, bootinfo); 206 } else { 207 console->Printf(_L("DoCreate failed: %d\n"), err); 208 console->Getch(); 209 } 210 211 User::FreeLogicalDevice(ldd); 212 if (err != KErrNone) 213 User::Leave(err); 214 } 215 216 GLDEF_C TInt E32Main(void) /* main function called by E32 */ 217 { 218 219 __UHEAP_MARK; 220 CTrapCleanup *cleanup = CTrapCleanup::New(); 221 222 TRAPD(error, E32BootL()); 223 __ASSERT_ALWAYS(!error, User::Panic(E32BootName, error)); 224 225 delete cleanup; 226 __UHEAP_MARKEND; 227 return 0; 228 } 229 230 LOCAL_C NetBSD * 231 LoadNetBSDL(void) 232 { 233 NetBSD *netbsd = NULL; 234 TBuf<KMaxCommandLine> input, *args; 235 TPtrC Default = _L("C:\\netbsd"); 236 TPtrC Prompt = _L("Boot: "); 237 TInt pos, err; 238 TBool retry; 239 240 input.Zero(); 241 args = new TBuf<KMaxCommandLine>; 242 args->Zero(); 243 retry = false; 244 console->Printf(Prompt); 245 console->Printf(_L("[")); 246 console->Printf(Default); 247 console->Printf(_L("]: ")); 248 console->SetPos(Prompt.Length() + 249 _L("[").Length() + 250 Default.Length() + 251 _L("]: ").Length()); 252 pos = 0; 253 while (1) { 254 TChar gChar = console->Getch(); 255 switch (gChar) { 256 case EKeyEscape: 257 return NULL; 258 259 case EKeyEnter: 260 break; 261 262 case EKeyBackspace: 263 if (pos > 0) { 264 pos--; 265 input.Delete(pos, 1); 266 } 267 break; 268 269 default: 270 if (gChar.IsPrint()) { 271 if (input.Length() < KMaxCommandLine) { 272 TBuf<0x02> b; 273 b.Append(gChar); 274 input.Insert(pos++, b); 275 } 276 } 277 break; 278 } 279 if (gChar == EKeyEnter) { 280 input.TrimAll(); 281 if (input[0] == '-') 282 input.Swap(*args); 283 for (int i = 0; i < input.Length(); i++) 284 if (input[i] == ' ') { 285 args->Copy(input); 286 input.SetLength(i); 287 args->Delete(0, i + 1); 288 break; 289 } 290 args->ZeroTerminate(); 291 292 if (input.Length() > 0) { 293 TRAP(err, netbsd = NetBSD::New(input, *args)); 294 } else { 295 TRAP(err, netbsd = NetBSD::New(Default, *args)); 296 } 297 if (err == 0 && netbsd != NULL) 298 break; 299 console->Printf(_L("\nLoad failed: %d\n"), err); 300 301 input.Zero(); 302 args->Zero(); 303 console->Printf(Prompt); 304 pos = 0; 305 retry = true; 306 } 307 TInt base = Prompt.Length(); 308 if (!retry) 309 base += (_L("[").Length() + Default.Length() + 310 _L("]: ").Length()); 311 console->SetPos(base + pos); 312 console->ClearToEndOfLine(); 313 console->SetPos(base); 314 console->Write(input); 315 console->SetPos(base + pos); 316 } 317 318 return netbsd; 319 } 320 321 #define KB * 1024 322 323 LOCAL_C struct btinfo_common * 324 CreateBootInfo(TAny *buf) 325 { 326 TMachineInfoV1Buf MachInfo; 327 TMemoryInfoV1Buf MemInfo; 328 struct btinfo_common *bootinfo, *common; 329 struct btinfo_model *model; 330 struct btinfo_memory *memory; 331 struct btinfo_video *video; 332 struct btinfo_bootargs *bootargs; 333 struct memmap *memmap; 334 TUint memsize; 335 TUint i; 336 337 UserHal::MachineInfo(MachInfo); 338 UserHal::MemoryInfo(MemInfo); 339 340 common = bootinfo = (struct btinfo_common *)buf; 341 342 /* Set machine name to bootinfo. */ 343 common->len = sizeof(struct btinfo_model); 344 common->type = BTINFO_MODEL; 345 model = (struct btinfo_model *)common; 346 Mem::Copy(model->model, &MachInfo().iMachineName[0], 347 sizeof(model->model)); 348 common = &(model + 1)->common; 349 350 /* Set video width/height to bootinfo. */ 351 common->len = sizeof(struct btinfo_video); 352 common->type = BTINFO_VIDEO; 353 video = (struct btinfo_video *)common; 354 video->width = MachInfo().iDisplaySizeInPixels.iWidth; 355 video->height = MachInfo().iDisplaySizeInPixels.iHeight; 356 common = &(video + 1)->common; 357 358 /* Set memory size to bootinfo. */ 359 memsize = MemInfo().iTotalRamInBytes / 1024; 360 for (i = 0; i < sizeof(memmaps) / sizeof(memmaps[0]); i++) { 361 if (_L(memmaps[i].model).CompareF(_L(model->model)) == 0 && 362 memmaps[i].width == video->width && 363 memmaps[i].height == video->height && 364 memmaps[i].memsize == memsize) { 365 memmap = memmaps[i].memmaps; 366 while (memsize > 0) { 367 common->len = sizeof(struct btinfo_memory); 368 common->type = BTINFO_MEMORY; 369 memory = (struct btinfo_memory *)common; 370 memory->address = memmap->address; 371 memory->size = memmap->size KB; 372 common = &(memory + 1)->common; 373 memsize -= memmap->size; 374 memmap++; 375 } 376 break; 377 } 378 } 379 if (i == sizeof(memmaps) / sizeof(memmaps[0])) { 380 common->len = sizeof(struct btinfo_memory); 381 common->type = BTINFO_MEMORY; 382 memory = (struct btinfo_memory *)common; 383 memory->address = 0xc0000000; /* default is here */ 384 memory->size = 4096 KB; /* XXXXX */ 385 common = &(memory + 1)->common; 386 } 387 388 common->len = sizeof(struct btinfo_bootargs); 389 common->type = BTINFO_BOOTARGS; 390 bootargs = (struct btinfo_bootargs *)common; 391 bootargs->bootargs[0] = '\0'; 392 common = &(bootargs + 1)->common; 393 394 common->len = 0; 395 common->type = BTINFO_NONE; 396 397 /* Terminate bootinfo. */ 398 return bootinfo; 399 } 400 401 #undef KB 402 403 LOCAL_C struct btinfo_common * 404 FindBootInfoL(struct btinfo_common *bootinfo, int type) 405 { 406 struct btinfo_common *entry; 407 408 entry = bootinfo; 409 while (entry->type != BTINFO_NONE) { 410 if (entry->type == type) 411 return entry; 412 entry = (struct btinfo_common *)((int)entry + entry->len); 413 } 414 User::Leave(KErrNotFound); 415 416 /* NOTREACHED */ 417 418 return NULL; 419 } 420 421 TUint 422 SummaryBootInfoMemory(struct btinfo_common *bootinfo) 423 { 424 struct btinfo_common *entry; 425 struct btinfo_memory *memory; 426 TUint memsize = 0; 427 428 entry = bootinfo; 429 while (entry->type != BTINFO_NONE) { 430 if (entry->type == BTINFO_MEMORY) { 431 memory = (struct btinfo_memory *)entry; 432 memsize += memory->size; 433 } 434 entry = (struct btinfo_common *)((int)entry + entry->len); 435 } 436 return memsize; 437 } 438