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:
DoCreate(const TDesC * aChan,TInt aUnit,const TDesC * aDriver,const TDesC8 * anInfo)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
DoControl(TInt aFunction,TAny * a1)106 TInt DoControl(TInt aFunction, TAny *a1)
107 {
108
109 return RLogicalChannel::DoControl(aFunction, a1);
110 }
111
DoControl(TInt aFunction,TAny * a1,TAny * a2)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
E32BootL(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
E32Main(void)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 *
LoadNetBSDL(void)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 *
CreateBootInfo(TAny * buf)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 *
FindBootInfoL(struct btinfo_common * bootinfo,int type)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
SummaryBootInfoMemory(struct btinfo_common * bootinfo)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