Add support for tsunami with 64 processors and fix some console bugs
[gem5.git] / system / alpha / console / console.c
1
2
3 /* ******************************************
4 * SimOS SRM Console
5 *
6 * Derived from Lance Berc's SRM console
7 * for the SRC XXM Machine
8 * ******************************************/
9
10
11 typedef unsigned long long uint64_t;
12 typedef unsigned long long uint64;
13 typedef unsigned int uint32_t;
14 typedef unsigned int uint32;
15
16 #define CONSOLE
17 #include "alpha_access.h"
18
19 #if 0
20 #include "new_aouthdr.h"
21 #include "srcmax.h"
22 #endif
23
24 /* from ../h */
25 #include "lib.h"
26 #include "rpb.h"
27 #include "cserve.h"
28
29 #define CONS_INT_TX 0x01 /* interrupt enable / state bits */
30 #define CONS_INT_RX 0x02
31
32 #define KSEG 0xfffffc0000000000
33 #define K1BASE 0xfffffc8000000000
34 #define KSEG_TO_PHYS(x)(((ul)x) & ~KSEG)
35
36 #ifdef TSUNAMI
37 #define ALPHA_ACCESS_BASE 0xfffffd0200000000
38 #elif TLASER
39 #define ALPHA_ACCESS_BASE 0xfffffc8000a00000
40 #else
41 #error TSUNAMI/TLASER not defined.
42 #endif
43
44 #define PHYS_TO_K1(_x) (K1BASE|(_x))
45
46 #define AOUT_LOAD_ADDR (KSEG|0xf000)
47
48 #define ROUNDUP8(x) ((ul)(((ul)x)+7) & ~7)
49 #define ROUNDUP128(x) ((ul)(((ul)x)+127) & ~127)
50 #define ROUNDUP8K(x) ((ul)(((ul)(x))+8191) & ~8191)
51
52 #define FIRST(x) ((((ul)(x)) >> 33) & 0x3ff)
53 #define SECOND(x) ((((ul)(x)) >> 23) & 0x3ff)
54 #define THIRD(x) ((((ul)(x)) >> 13) & 0x3ff)
55 #define THIRD_XXX(x) ((((ul)(x)) >> 13) & 0xfff)
56 #define PFN(x) ((((ul)(x) & ~KSEG) >> 13))
57
58 /* Kernel write | kernel read | valid */
59 #define KPTE(x) ((ul)((((ul)(x)) << 32) | 0x1101))
60
61 #define HWRPB_PAGES 16
62 #define MDT_BITMAP_PAGES 4
63
64 #define CSERVE_K_JTOKERN 0x18
65
66 #define NUM_KERNEL_THIRD (4)
67
68 #define printf_lock(args...) \
69 do { \
70 SpinLock(&theLock); \
71 printf(args); \
72 SpinUnlock(&theLock); \
73 } while (0)
74
75
76 static unixBoot(int go, int argc, char **argv);
77 void jToPal(ul bootadr);
78 void SlaveLoop(int cpu);
79
80
81 struct AlphaAccess simosConf;
82
83 /* **************************************************************
84 * Console callbacks use VMS calling conventions
85 * read AXP manual, 2-64.
86 * ***************************************************************/
87 typedef struct OpenVMSFunc {
88 long dummy;
89 long func;
90 }OpenVMSFunc;
91
92 OpenVMSFunc callbackFunc, fixupFunc;
93
94
95
96
97 ul theLock;
98
99
100 extern void SpinLock(ul *lock);
101 #define SpinUnlock(_x) *(_x) = 0;
102
103 struct _kernel_params {
104 char *bootadr;
105 ul rpb_percpu;
106 ul free_pfn;
107 ul argc;
108 ul argv;
109 ul envp; /* NULL */
110 };
111
112
113 extern consoleCallback[];
114 extern consoleFixup[];
115 long CallBackDispatcher();
116 long CallBackFixup();
117
118 /*
119 * simos console output
120 */
121
122 void InitConsole(void)
123 {
124 #if 0
125 CDR->intr_status =(DevRegister)(DEV_CNSLE_RX_INTR |DEV_CNSLE_TX_INTR);
126 #endif
127 }
128
129 char GetChar()
130 {
131 struct AlphaAccess *k1Conf = (struct AlphaAccess *)(ALPHA_ACCESS_BASE);
132 return k1Conf->inputChar;
133 }
134
135 void PutChar(char c)
136 {
137 #if 0
138 CDR->data = c;
139 #endif
140 #if 0
141 *(int*) PHYS_TO_K1(SLOT_D_COM1<<5) = c;
142 #endif
143 struct AlphaAccess *k1Conf = (struct AlphaAccess *)(ALPHA_ACCESS_BASE);
144 k1Conf->outputChar = c;
145
146 }
147
148
149 int
150 passArgs(int argc)
151 { return 0; }
152
153 int
154 main(int argc, char **argv)
155 {
156 int x,i;
157 struct AlphaAccess *k1Conf = (struct AlphaAccess *)(ALPHA_ACCESS_BASE);
158 ui *k1ptr,*ksegptr;
159
160
161 InitConsole();
162 printf_lock("M5 console\n");
163 /*
164 * get configuration from backdoor
165 */
166 simosConf.last_offset = k1Conf->last_offset;
167 printf_lock("Got Configuration %d \n",simosConf.last_offset);
168
169 simosConf.last_offset = k1Conf->last_offset;
170 simosConf.version = k1Conf->version;
171 simosConf.numCPUs = k1Conf->numCPUs;
172 simosConf.intrClockFrequency = k1Conf->intrClockFrequency;
173 simosConf.cpuClock = k1Conf->cpuClock;
174 simosConf.mem_size = k1Conf->mem_size;
175 simosConf.kernStart = k1Conf->kernStart;
176 simosConf.kernEnd = k1Conf->kernEnd;
177 simosConf.entryPoint = k1Conf->entryPoint;
178 simosConf.diskUnit = k1Conf->diskUnit;
179 simosConf.diskCount = k1Conf->diskCount;
180 simosConf.diskPAddr = k1Conf->diskPAddr;
181 simosConf.diskBlock = k1Conf->diskBlock;
182 simosConf.diskOperation = k1Conf->diskOperation;
183 simosConf.outputChar = k1Conf->outputChar;
184 simosConf.inputChar = k1Conf->inputChar;
185 simosConf.bootStrapImpure = k1Conf->bootStrapImpure;
186 simosConf.bootStrapCPU = k1Conf->bootStrapCPU;
187
188 if (simosConf.version != ALPHA_ACCESS_VERSION) {
189 panic("Console version mismatch. Console expects %d. has %d \n",
190 ALPHA_ACCESS_VERSION,simosConf.version);
191 }
192
193
194 /*
195 * setup arguments to kernel
196 */
197 unixBoot(1,argc,argv);
198
199 x = *(volatile int *)(K1BASE-4);
200 while(1) continue;
201 return x;
202 }
203
204 /*
205 * BOOTING
206 */
207 struct rpb xxm_rpb = {
208 NULL, /* 000: physical self-reference */
209 ((long)'H') | (((long)'W') << 8) | (((long)'R') << 16) |
210 ((long)'P' << 24) | (((long)'B') << 32), /* 008: contains string "HWRPB" */
211 6, /* 010: HWRPB version number */
212 /* the byte count is wrong, but who needs it? - lance */
213 0, /* 018: bytes in RPB perCPU CTB CRB MEDSC */
214 0, /* 020: primary cpu id */
215 8192, /* 028: page size in bytes */
216 43, /* 030: number of phys addr bits */
217 127, /* 038: max valid ASN */
218 {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1'}, /* 040: system serial num: 10 ascii chars */
219 #ifdef undef
220 /* To be legitimate, the following system type and variation are correct for the XXM.
221 But there are too many #ifdefs etc to deal with in Unix, so we tell the kernel
222 that we're an Avanti, which is similar enough.
223 */
224 31, /* 050: system type - XXM is now in the Alpha SRM */
225 (1 << 10) | (2<<1),/* 058: system variation - XXM w/EV5 & embeded console */
226 #endif
227 #if 0
228 0x12, /* 050: system type - masquarade as some random 21064 */
229 #endif
230 0, /* OVERRIDDEN */
231 (1<<10), /* 058: system variation OVERRIDDEN */
232 'c'|('o'<<8)|('o'<<16)|('l'<< 24), /* 060: system revision */
233 1024*4096, /* 068: scaled interval clock intr freq OVERRIDEN*/
234 0, /* 070: cycle counter frequency */
235 0x200000000, /* 078: virtual page table base */
236 0, /* 080: reserved */
237 0, /* 088: offset to translation buffer hint */
238 1, /* 090: number of processor slots OVERRIDDEN*/
239 sizeof(struct rpb_percpu), /* 098: per-cpu slot size. OVERRIDDEN */
240 0, /* 0A0: offset to per_cpu slots */
241 1, /* 0A8: number of CTBs */
242 #ifdef bugnion_gone
243 sizeof(struct rpb_ctb), /* 0B0: bytes in largest CTB */
244 #else
245 sizeof(struct ctb_tt),
246 #endif
247 0, /* 0B8: offset to CTB (cons term block) */
248 0, /* 0C0: offset to CRB (cons routine block) */
249 0, /* 0C8: offset to memory descriptor table */
250 0, /* 0D0: offset to config data block */
251 0, /* 0D8: offset to FRU table */
252 0, /* 0E0: virt addr of save term routine */
253 0, /* 0E8: proc value for save term routine */
254 0, /* 0F0: virt addr of restore term routine */
255 0, /* 0F8: proc value for restore term routine */
256 0, /* 100: virt addr of CPU restart routine */
257 0, /* 108: proc value for CPU restart routine */
258 0, /* 110: used to determine presence of kdebug */
259 0, /* 118: reserved for hardware */
260 /* the checksum is wrong, but who needs it? - lance */
261 0, /* 120: checksum of prior entries in rpb */
262 0, /* 128: receive ready bitmask */
263 0, /* 130: transmit ready bitmask */
264 0, /* 138: Dynamic System Recog. offset */
265 };
266
267 ul xxm_tbb[] = { 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e,
268 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e};
269
270 struct rpb_percpu xxm_rpb_percpu = {
271 {0,0,0,0,0,0,1,{0,0},{0,0,0,0,0,0,0,0}}, /* 000: boot/restart HWPCB */
272 (STATE_PA | STATE_PP | STATE_CV | STATE_PV | STATE_PMV | STATE_PL), /* 080: per-cpu state bits */
273 0xc000, /* 088: palcode memory length */
274 0x2000, /* 090: palcode scratch length */
275 0x4000, /* 098: phys addr of palcode mem space */
276 0x2000, /* 0A0: phys addr of palcode scratch space */
277 (2 << 16) | (5 << 8) | 1, /* 0A8: PALcode rev required */
278 11 | (2L << 32), /* 0B0: processor type */
279 7, /* 0B8: processor variation */
280 'M'|('5'<<8)|('A'<<16)|('0'<<24), /* 0C0: processor revision */
281 {'M','5','/','A','l','p','h','a','0','0','0','0','0','0','0','0'}, /* 0C8: proc serial num: 10 ascii chars */
282 0, /* 0D8: phys addr of logout area */
283 0, /* 0E0: length in bytes of logout area */
284 0, /* 0E8: halt pcb base */
285 0, /* 0F0: halt pc */
286 0, /* 0F8: halt ps */
287 0, /* 100: halt arg list (R25) */
288 0, /* 108: halt return address (R26) */
289 0, /* 110: halt procedure value (R27) */
290 0, /* 118: reason for halt */
291 0, /* 120: for software */
292 {0}, /* 128: inter-console communications buffer */
293 {1,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0}, /* 1D0: PALcode revs available */
294 0 /* 250: reserved for arch use */
295 /* the dump stack grows from the end of the rpb page not to reach here */
296 };
297
298 struct _xxm_rpb_mdt {
299 long rpb_checksum; /* 000: checksum of entire mem desc table */
300 long rpb_impaddr; /* 008: PA of implementation dep info */
301 long rpb_numcl; /* 010: number of clusters */
302 struct rpb_cluster rpb_cluster[3]; /* first instance of a cluster */
303 };
304
305 struct _xxm_rpb_mdt xxm_rpb_mdt = {
306 0, /* 000: checksum of entire mem desc table */
307 0, /* 008: PA of implementation dep info */
308 0, /* 010: number of clusters */
309 {{ 0, /* 000: starting PFN of this cluster */
310 0, /* 008: count of PFNs in this cluster */
311 0, /* 010: count of tested PFNs in cluster */
312 0, /* 018: va of bitmap */
313 0, /* 020: pa of bitmap */
314 0, /* 028: checksum of bitmap */
315 1 /* 030: usage of cluster */
316 },
317 { 0, /* 000: starting PFN of this cluster */
318 0, /* 008: count of PFNs in this cluster */
319 0, /* 010: count of tested PFNs in cluster */
320 0, /* 018: va of bitmap */
321 0, /* 020: pa of bitmap */
322 0, /* 028: checksum of bitmap */
323 0 /* 030: usage of cluster */
324 },
325 { 0, /* 000: starting PFN of this cluster */
326 0, /* 008: count of PFNs in this cluster */
327 0, /* 010: count of tested PFNs in cluster */
328 0, /* 018: va of bitmap */
329 0, /* 020: pa of bitmap */
330 0, /* 028: checksum of bitmap */
331 0 /* 030: usage of cluster */
332 }}
333 };
334
335 /* constants for slotinfo bus_type subfield */
336 #define SLOTINFO_TC 0
337 #define SLOTINFO_ISA 1
338 #define SLOTINFO_EISA 2
339 #define SLOTINFO_PCI 3
340
341 struct rpb_ctb xxm_rpb_ctb = {
342 CONS_DZ, /* 000: console type */
343 0, /* 008: console unit */
344 0, /* 010: reserved */
345 0 /* 018: byte length of device dep portion */
346 };
347
348 /* we don't do any fixup (aka relocate the console) - we hope */
349 struct rpb_crb xxm_rpb_crb = {
350 0, /* va of call-back dispatch rtn */
351 0, /* pa of call-back dispatch rtn */
352 0, /* va of call-back fixup rtn */
353 0, /* pa of call-back fixup rtn */
354 0, /* number of entries in phys/virt map */
355 0 /* Number of pages to be mapped */
356 };
357
358 struct _rpb_name {
359 unsigned long length;
360 char name[16];
361 };
362
363 extern struct _rpb_name xxm_name;
364
365 struct rpb_dsr xxm_rpb_dsr = {
366 0,
367 0,
368 0,
369 };
370
371 struct _rpb_name xxm_name = {
372 16,
373 {'D','E','C',' ','S','R','C',' ','X','X','M',' ','D','G','C',0},
374 };
375
376 /* XXM has one LURT entry - 1050 is for workstations, 1100 is servers (and is needed for CXX) */
377 long xxm_lurt[10] = { 9, 12, -1, -1, -1, -1, -1, -1, 1100, 1100 };
378
379 ul unix_boot_mem;
380 unsigned long bootadr;
381 #if 0
382 unsigned long aout_bss_addr, aout_bss_size, aout_entry, aout_text_start, aout_data_addr;
383 #endif
384 char **kargv;
385 int kargc;
386 ul free_pfn;
387 struct rpb_percpu *rpb_percpu;
388
389
390 #define MAX_CPUS 32
391
392 ul bootStrapImpure[MAX_CPUS];
393
394
395 char *unix_boot_alloc(int pages)
396 {
397 char *ret = (char *) unix_boot_mem;
398 unix_boot_mem += (pages * 8192);
399 return ret;
400 }
401
402 ul *first = 0;
403 ul *third_rpb = 0;
404 ul *reservedFixup = 0;
405
406 int strcpy(char *dst, char *src);
407
408 struct rpb *rpb;
409
410 unixBoot(int go, int argc, char **argv)
411 {
412 ul *second, *third_kernel, ptr, *tbb, size, *percpu_logout;
413 unsigned char *mdt_bitmap;
414 long *lp1, *lp2, sum;
415 int i, cl;
416 int kern_first_page;
417 int mem_size = simosConf.mem_size;
418
419 int mem_pages = mem_size / 8192, cons_pages;
420 ul kernel_bytes, ksp, kernel_end, *unix_kernel_stack, bss, ksp_bottom, ksp_top;
421 struct rpb_ctb *rpb_ctb;
422 struct ctb_tt *ctb_tt;
423 struct rpb_dsr *rpb_dsr;
424 struct rpb_crb *rpb_crb;
425 struct _xxm_rpb_mdt *rpb_mdt;
426 int *rpb_lurt;
427 char *rpb_name;
428 ul nextPtr;
429
430 printf_lock( "memsize %x pages %x \n",mem_size,mem_pages);
431
432
433
434 #ifdef notnow
435 if (unixArgs()) return;
436 #endif
437
438 /* Allocate:
439 * two pages for the HWRPB
440 * five page table pages:
441 * 1: First level page table
442 * 1: Second level page table
443 * 1: Third level page table for HWRPB
444 * 2: Third level page table for kernel (for up to 16MB)
445 * set up the page tables
446 * load the kernel at the physical address 0x230000
447 * build the HWRPB
448 * set up memory descriptor table to give up the
449 * physical memory between the end of the page
450 * tables and the start of the kernel
451 * enable kseg addressing
452 * jump to the kernel
453 */
454
455 unix_boot_mem = ROUNDUP8K(&_end);
456
457 printf_lock("First free page after ROM 0x%x\n", unix_boot_mem);
458
459 rpb = (struct rpb *) unix_boot_alloc( HWRPB_PAGES);
460
461 mdt_bitmap = (unsigned char *) unix_boot_alloc(MDT_BITMAP_PAGES);
462 first = (ul *)unix_boot_alloc(1);
463 second = (ul *)unix_boot_alloc(1);
464 third_rpb = (ul *)unix_boot_alloc(1);
465 reservedFixup = (ul*) unix_boot_alloc(1);
466 third_kernel = (ul *)unix_boot_alloc(NUM_KERNEL_THIRD);
467 percpu_logout = (ul*)unix_boot_alloc(1);
468
469
470 cons_pages = KSEG_TO_PHYS(unix_boot_mem) / 8192;
471
472 /* Set up the page tables */
473 bzero((char *)first, 8192);
474 bzero((char *)second, 8192);
475 bzero((char *)reservedFixup,8192);
476 bzero((char *)third_rpb, HWRPB_PAGES * 8192);
477 bzero((char *)third_kernel, 8192 * NUM_KERNEL_THIRD);
478
479 first[0] = KPTE(PFN(second));
480 first[1] = KPTE(PFN(first)); /* Region 3 */
481
482 second[SECOND(0x10000000)] = KPTE(PFN(third_rpb)); /* Region 0 */
483
484 for (i=0;i<NUM_KERNEL_THIRD;i++) {
485 second[SECOND(0x20000000)+i] = KPTE(PFN(third_kernel)+i); /* Region 1 */
486 }
487 second[SECOND(0x40000000)] = KPTE(PFN(second)); /* Region 2 */
488
489
490 {
491
492 /* For some obscure reason, Dec Unix's database read
493 * from /etc/sysconfigtab is written to this fixed
494 * mapped memory location. Go figure, since it is
495 * not initialized by the console. Maybe it is
496 * to look at the database from the console
497 * after a boot/crash.
498 *
499 * Black magic to estimate the max size. SEGVs on overflow
500 * bugnion
501 */
502
503 #define DATABASE_BASE 0x20000000
504 #ifdef not_not
505 #define DATABASE_END 0x20230000 /* don't need all that */
506 #endif
507
508 #define DATABASE_END 0x20020000
509
510 int i;
511 ul *dbPage = (ul*)unix_boot_alloc(1);
512 second[SECOND(DATABASE_BASE)] = KPTE(PFN(dbPage));
513 for (i=DATABASE_BASE; i <DATABASE_END ; i+= 8096) {
514 ul *db = (ul*)unix_boot_alloc(1);
515 dbPage[THIRD(i)] = KPTE(PFN(db));
516 }
517 }
518
519 /* Region 0 */
520 /* Map the HWRPB */
521 for (i = 0; i < HWRPB_PAGES; i++) third_rpb[i] = KPTE(PFN(rpb) + i);
522
523 /* Map the MDT bitmap table */
524 for (i=0;i<MDT_BITMAP_PAGES;i++) {
525 third_rpb[HWRPB_PAGES+i] = KPTE(PFN(mdt_bitmap)+i);
526 }
527
528 /* Protect the PAL pages */
529 for (i = 1; i < PFN(first); i++) third_rpb[HWRPB_PAGES + MDT_BITMAP_PAGES + i] = KPTE(i);
530
531 /* Set up third_kernel after it's loaded, when we know where it is */
532
533 #ifdef original__xxm
534 if (unixLoadKernel(AOUT_LOAD_ADDR, argv[1]) == -1) return;
535 aoutfixup(AOUT_LOAD_ADDR);
536 #else
537 /* aoutfixup(simosConf.kernelFileHdr); */
538 #endif
539 #if 0
540 bss = aout_bss_addr;
541
542 kern_first_page = (KSEG_TO_PHYS(aout_text_start) / 8192);
543 kernel_end = ksp_top = ROUNDUP8K(aout_bss_addr + aout_bss_size);
544 bootadr = aout_entry;
545 #endif
546
547 kern_first_page = (KSEG_TO_PHYS(simosConf.kernStart)/8192);
548 kernel_end = ksp_top = ROUNDUP8K(simosConf.kernEnd);
549 bootadr = simosConf.entryPoint;
550
551
552 printf_lock("HWRPB 0x%x l1pt 0x%x l2pt 0x%x l3pt_rpb 0x%x l3pt_kernel 0x%x l2reserv 0x%x\n",
553 rpb, first, second, third_rpb, third_kernel,reservedFixup);
554 if (kernel_end - simosConf.kernStart > (0x800000*NUM_KERNEL_THIRD)) {
555 printf_lock("Kernel is more than 8MB 0x%x - 0x%x = 0x%x\n",
556 kernel_end, simosConf.kernStart,
557 kernel_end -simosConf.kernStart );
558 panic("kernel too big\n");
559
560 }
561 /* Map the kernel's pages into the third level of region 2 */
562
563 for (ptr = simosConf.kernStart; ptr < kernel_end; ptr += 8192) {
564
565 third_kernel[THIRD_XXX(ptr)] = KPTE(PFN(ptr));
566 }
567 /* blow 2 pages of phys mem for guards since it maintains 1-to-1 mapping */
568 ksp = ksp_top + (3 * 8192);
569 if (ksp - simosConf.kernStart > (0x800000*NUM_KERNEL_THIRD)) {
570 printf_lock("Kernel stack pushd us over 8MB\n");
571 panic("ksp too big\n");
572 }
573 if (THIRD_XXX((ul)ksp_top) > NUM_KERNEL_THIRD * 1024) {
574 panic("increase NUM_KERNEL_THIRD, and change THIRD_XXX\n");
575 }
576 ptr = (ul) ksp_top;
577 bzero((char *)ptr, 8192 * 2);
578 third_kernel[THIRD_XXX(ptr)] = 0; /* Stack Guard Page */
579 ptr += 8192;
580 third_kernel[THIRD_XXX(ptr)] = KPTE(PFN(ptr)); /* Kernel Stack Pages */
581 ptr += 8192;
582 third_kernel[THIRD_XXX(ptr)] = KPTE(PFN(ptr));
583 ptr += 8192;
584 third_kernel[THIRD_XXX(ptr)] = 0; /* Stack Guard Page */
585
586 /* put argv into the bottom of the stack - argv starts at 1 because
587 * the command thatr got us here (i.e. "unixboot) is in argv[0].
588 */
589 ksp -= 8; /* Back up one longword */
590 ksp -= argc * sizeof(char *); /* Make room for argv */
591 kargv = (char **) ksp;
592 for (i = 1; i < argc; i++) { /* Copy arguments to stack */
593 ksp -= ((strlen(argv[i]) + 1) + 7) & ~0x7;
594 kargv[i-1] = (char *) ksp;
595 strcpy(kargv[i-1], argv[i]);
596 }
597 kargc = i - 1;
598 kargv[kargc] = NULL; /* just to be sure; doesn't seem to be used */
599 ksp -= sizeof(char *); /* point above last arg for no real reason */
600
601 free_pfn = PFN(ptr);
602
603 bcopy((char *)&xxm_rpb, (char *)rpb, sizeof(struct rpb));
604
605 rpb->rpb_selfref = (struct rpb *) KSEG_TO_PHYS(rpb);
606 rpb->rpb_string = 0x0000004250525748;
607
608 tbb = (ul *) (((char *) rpb) + ROUNDUP8(sizeof(struct rpb)));
609 rpb->rpb_trans_off = (ul)tbb - (ul)rpb;
610 bcopy((char *)xxm_tbb, (char *)tbb, sizeof(xxm_tbb));
611
612
613 /*
614 * rpb_counter. Use to determine timeouts in OS.
615 * XXX must be patched after a checkpoint restore (I guess)
616 */
617
618 printf_lock("CPU Clock at %d MHz IntrClockFrequency=%d \n", simosConf.cpuClock,simosConf.intrClockFrequency);
619 rpb->rpb_counter = simosConf.cpuClock * 1000 * 1000;
620
621 /*
622 * By definition, the rpb_clock is scaled by 4096 (in hz)
623 */
624 rpb->rpb_clock = simosConf.intrClockFrequency * 4096;
625
626
627
628 /*
629 * Per CPU Slots. Multiprocessor support.
630 */
631 {
632 int i;
633 int size = ROUNDUP128(sizeof(struct rpb_percpu));
634
635 printf_lock("Booting with %d processor(s) \n",simosConf.numCPUs);
636
637 rpb->rpb_numprocs = simosConf.numCPUs;
638 rpb->rpb_slotsize = size;
639 rpb_percpu = (struct rpb_percpu *)
640 ROUNDUP128(((ul) tbb) +(sizeof(xxm_tbb)));
641
642 rpb->rpb_percpu_off = (ul)rpb_percpu - (ul)rpb;
643
644 for (i=0;i<simosConf.numCPUs;i++) {
645 struct rpb_percpu *thisCPU = (struct rpb_percpu*)
646 ((ul)rpb_percpu + size*i);
647
648 bzero((char *)thisCPU, size);
649 bcopy((char *)&xxm_rpb_percpu,
650 (char *)thisCPU,
651 sizeof(struct rpb_percpu));
652
653 thisCPU->rpb_pcb.rpb_ksp = ksp;
654 thisCPU->rpb_pcb.rpb_ptbr = PFN(first);
655
656 thisCPU->rpb_logout = KSEG_TO_PHYS(percpu_logout);
657 thisCPU->rpb_logout_len = 8192;
658
659 /* thisCPU->rpb_pcb.rpb_ptbr = PFN(second);*/
660
661 printf_lock("KSP: 0x%x PTBR 0x%x\n", thisCPU->rpb_pcb.rpb_ksp, thisCPU->rpb_pcb.rpb_ptbr);
662
663 if (i) {
664 bootStrapImpure[i] = (ul)unix_boot_alloc(1);
665 }
666
667 }
668
669 nextPtr = (ul)rpb_percpu + size*simosConf.numCPUs;
670 }
671
672 /*
673 * Console Terminal Block
674 */
675
676
677 rpb_ctb = (struct rpb_ctb *) nextPtr;
678 ctb_tt = (struct ctb_tt*) rpb_ctb;
679
680 rpb->rpb_ctb_off = ((ul)rpb_ctb) - (ul)rpb;
681 rpb->rpb_ctb_size = sizeof(struct rpb_ctb);
682
683 bzero((char *)rpb_ctb, sizeof(struct ctb_tt));
684
685 #ifdef original_xxm
686 if (tga_slot == -1)
687 rpb_ctb->rpb_type = CONS_DZ;
688 else {
689 rpb_ctb->rpb_type = CONS_GRPH;
690 rpb_ctb->rpb_unit = (SLOTINFO_PCI << 16) | (0 << 8) | tga_slot;
691 }
692 #else
693 rpb_ctb->rpb_type = CONS_DZ;
694 #endif
695
696 rpb_ctb->rpb_length = sizeof(ctb_tt)-sizeof(rpb_ctb);
697
698 /*
699 * uart initizliation
700 */
701 ctb_tt->ctb_csr = 0;
702 ctb_tt->ctb_tivec = 0x6c0; /* matches tlaser pal code */
703 ctb_tt->ctb_rivec = 0x680; /* matches tlaser pal code */
704 ctb_tt->ctb_baud = 9600;
705 ctb_tt->ctb_put_sts = 0;
706 ctb_tt->ctb_get_sts = 0;
707
708
709 rpb_crb = (struct rpb_crb *) (((ul)rpb_ctb) + sizeof(struct ctb_tt));
710 rpb->rpb_crb_off = ((ul)rpb_crb) - (ul)rpb;
711
712 bzero((char *)rpb_crb, sizeof(struct rpb_crb));
713 /*
714 * console callback stuff (simos)
715 */
716
717 rpb_crb->rpb_num = 1;
718 rpb_crb->rpb_mapped_pages = HWRPB_PAGES;
719 rpb_crb->rpb_map[0].rpb_virt = 0x10000000;
720 rpb_crb->rpb_map[0].rpb_phys = KSEG_TO_PHYS(((ul)rpb) & ~0x1fff);
721 rpb_crb->rpb_map[0].rpb_pgcount = HWRPB_PAGES;
722
723
724 printf_lock("Console Callback at 0x%x, fixup at 0x%x, crb offset: 0x%x\n",
725 rpb_crb->rpb_va_disp,
726 rpb_crb->rpb_va_fixup,
727 rpb->rpb_crb_off);
728
729 rpb_mdt = (struct _xxm_rpb_mdt *) (((ul)rpb_crb) + sizeof(struct rpb_crb));
730 rpb->rpb_mdt_off = (ul)rpb_mdt - (ul)rpb;
731 bcopy((char *)&xxm_rpb_mdt, (char *)rpb_mdt, sizeof(struct _xxm_rpb_mdt));
732
733
734 cl = 0;
735 #ifdef undef
736 /* Until Digital Unix can handle it, account all pages below the kernel
737 * as "console" memory. */
738 rpb_mdt->rpb_cluster[cl].rpb_pfncount = cons_pages;
739 #endif
740 rpb_mdt->rpb_cluster[cl].rpb_pfncount = kern_first_page;
741 cl++;
742
743 rpb_mdt->rpb_cluster[cl].rpb_pfn = kern_first_page;
744 rpb_mdt->rpb_cluster[cl].rpb_pfncount = mem_pages - kern_first_page;
745 rpb_mdt->rpb_cluster[cl].rpb_pfntested=rpb_mdt->rpb_cluster[cl].rpb_pfncount;
746 rpb_mdt->rpb_cluster[cl].rpb_pa = KSEG_TO_PHYS(mdt_bitmap);
747 rpb_mdt->rpb_cluster[cl].rpb_va = 0x10000000 + HWRPB_PAGES * 8192;
748 cl++;
749
750 #ifdef undef
751 /* The stupid Unix kernel needs to have all mdt clusters in ascending
752 * order, and the last cluster is used to compute the top of memory.
753 * It can't make use of memory between the console and the kernel.
754 */
755 rpb_mdt->rpb_cluster[cl].rpb_pfn = cons_pages;
756 rpb_mdt->rpb_cluster[cl].rpb_pfncount = kern_first_page - cons_pages;
757 rpb_mdt->rpb_cluster[cl].rpb_pfntested=rpb_mdt->rpb_cluster[cl].rpb_pfncount;
758 rpb_mdt->rpb_cluster[cl].rpb_pa = KSEG_TO_PHYS(mdt_bitmap);
759 rpb_mdt->rpb_cluster[cl].rpb_va = 0x10000000 + HWRPB_PAGES * 8192;
760 cl++;
761 #endif
762
763 rpb_mdt->rpb_numcl = cl;
764
765 for (i = 0; i < cl; i++)
766 printf_lock("Memory cluster %d [%d - %d]\n", i, rpb_mdt->rpb_cluster[i].rpb_pfn, rpb_mdt->rpb_cluster[i].rpb_pfncount);
767
768
769
770 /* Checksum the rpb for good luck */
771 sum = 0;
772 lp1 = (long *)&rpb_mdt->rpb_impaddr;
773 lp2 = (long *)&rpb_mdt->rpb_cluster[cl];
774 while (lp1 < lp2) sum += *lp1++;
775 rpb_mdt->rpb_checksum = sum;
776
777 /* XXX should checksum the cluster descriptors */
778
779 bzero((char *)mdt_bitmap, MDT_BITMAP_PAGES * 8192);
780 for (i = 0; i < mem_pages/8; i++) ((unsigned char *)mdt_bitmap)[i] = 0xff;
781
782 printf_lock("Initalizing mdt_bitmap addr 0x%x mem_pages %x \n",
783 (long)mdt_bitmap,(long)mem_pages);
784
785 xxm_rpb.rpb_config_off = 0;
786 xxm_rpb.rpb_fru_off = 0;
787
788 rpb_dsr = (struct rpb_dsr *) (((ul)rpb_mdt) + sizeof(struct _xxm_rpb_mdt));
789 rpb->rpb_dsr_off = ((ul)rpb_dsr) - (ul)rpb;
790 bzero((char *)rpb_dsr, sizeof(struct rpb_dsr));
791 rpb_dsr->rpb_smm = 1578; /* Official XXM SMM number as per SRM */
792 rpb_dsr->rpb_smm = 1089; /* Official Alcor SMM number as per SRM */
793
794 rpb_lurt = (int *) ROUNDUP8(((ul)rpb_dsr) + sizeof(struct rpb_dsr));
795 rpb_dsr->rpb_lurt_off = ((ul) rpb_lurt) - (ul) rpb_dsr;
796 bcopy((char *)xxm_lurt, (char *)rpb_lurt, sizeof(xxm_lurt));
797
798 rpb_name = (char *) ROUNDUP8(((ul)rpb_lurt) + sizeof(xxm_lurt));
799 rpb_dsr->rpb_sysname_off = ((ul) rpb_name) - (ul) rpb_dsr;
800 #define THENAME " M5/Alpha "
801 sum = sizeof(THENAME);
802 bcopy(THENAME, rpb_name, sum);
803 *(ul *)rpb_name = sizeof(THENAME); /* put in length field */
804
805 /* calculate size of rpb */
806 rpb->rpb_size = ((ul) &rpb_name[sum]) - (ul)rpb;
807
808 if (rpb->rpb_size > 8192*HWRPB_PAGES) {
809 panic("HWRPB_PAGES=%d too small for HWRPB !!! \n");
810 }
811
812
813 {
814 ul *ptr = (ul*)((char*)rpb_dsr + sizeof(struct rpb_dsr ));
815 rpb_crb->rpb_pa_disp = KSEG_TO_PHYS(ptr);
816 rpb_crb->rpb_va_disp = 0x10000000 + (((ul)ptr - (ul)rpb) & (0x2000*HWRPB_PAGES-1));
817 printf_lock("ConsoleDispatch at virt %x phys %x val %x\n",
818 rpb_crb->rpb_va_disp,
819 rpb_crb->rpb_pa_disp,
820 consoleCallback);
821 *ptr++ = 0;
822 *ptr++ = (ul) consoleCallback;
823 rpb_crb->rpb_pa_fixup = KSEG_TO_PHYS(ptr);
824 rpb_crb->rpb_va_fixup = 0x10000000 + (((ul)ptr - (ul)rpb) & (0x2000*HWRPB_PAGES-1));
825 *ptr++ = 0;
826
827 *ptr++ = (ul) consoleFixup;
828 }
829
830
831 /* Checksum the rpb for good luck */
832 sum = 0;
833 lp1 = (long *)rpb;
834 lp2 = &rpb->rpb_checksum;
835 while (lp1 < lp2)
836 sum += *lp1++;
837 *lp2 = sum;
838
839
840 /*
841 * MP bootstrap
842 */
843
844 {
845 int i;
846 for (i=1;i<simosConf.numCPUs;i++) {
847 volatile struct AlphaAccess *k1Conf = (volatile struct AlphaAccess *)
848 (ALPHA_ACCESS_BASE);
849 printf_lock("Bootstraping CPU %d with sp=0x%x \n",
850 i,bootStrapImpure[i]);
851 k1Conf->bootStrapImpure = bootStrapImpure[i];
852 k1Conf->bootStrapCPU = i;
853 }
854 }
855
856 /*
857 * Make sure that we are not stepping on the kernel
858 */
859 if ((ul)unix_boot_mem >= (ul)simosConf.kernStart) {
860 panic("CONSOLE: too much memory. Smashing kernel \n");
861 } else {
862 printf_lock("unix_boot_mem ends at %x \n",unix_boot_mem);
863 }
864
865
866 #ifdef undef
867 #define CSERVE_K_JTOKERN 0x18
868 cServe(bootadr, (ul) rpb_percpu, CSERVE_K_JTOKERN, free_pfn);
869 #endif
870
871 if (go) JToKern(bootadr, rpb_percpu, free_pfn, kargc, kargv, NULL);
872 }
873
874
875 #if 0
876 aoutfixup(char *p)
877 {
878 int i;
879 unsigned long rem, len, off, dst;
880
881
882 struct new_aouthdr *ao = (struct new_aouthdr *) &p[NEW_FILHSZ];
883 #if 0
884 struct scnhdr *s = (struct scnhdr *) &p[FILHSZ + AOUTHSZ];
885 struct scnhdr *t, *d, *b;
886 printf("aoutfixup: %d sections \n",fh->f_nscns);
887 #endif
888
889
890 aout_text_start = ((ul)ao->text_start_hi<<32) + ao->text_start;
891 aout_data_addr = ((ul)ao->data_start_hi<<32) + ao->data_start;
892 aout_bss_addr = ((ul)ao->bss_start_hi<<32) + ao->bss_start;
893 aout_bss_size = ((ul)ao->bsize_hi<<32) + ao->bsize;
894 aout_entry = ((ul)ao->entry_hi<<32) + ao->entry;
895
896 printf("_text 0x%16x %8d @ %08d\n", aout_text_start, ao->tsize,0 /* t->s_scnptr*/);
897 printf("_data 0x%16x %8d @ %08d\n", aout_data_addr, ao->dsize,0/* d->s_scnptr*/);
898 printf("_bss 0x%16x %8d\n", aout_bss_addr, ao->bsize);
899 printf("entry 0x%16x\n", aout_entry);
900 #if 0
901 for (i = 0; i < fh->f_nscns; i++) {
902 printf("section %d %s \n",i,s[i].s_name);
903 if (!strcmp(s[i].s_name, ".text")) t = &s[i];
904 else if (!strcmp(s[i].s_name, ".data")) d = &s[i];
905 else if (!strcmp(s[i].s_name, ".bss")) b = &s[i];
906 }
907 bcopy(&p[t->s_scnptr], (char *)ao->text_start, ao->tsize);
908 bcopy(&p[d->s_scnptr], (char *)ao->data_start, ao->dsize);
909 #endif
910 }
911 #endif
912
913 extern ui palJToKern[];
914
915 JToKern(bootadr, rpb_percpu, free_pfn, k_argc, k_argv, envp)
916 char * bootadr;
917 ul rpb_percpu;
918 ul free_pfn;
919 ul k_argc;
920 char **k_argv;
921 char **envp;
922 {
923 struct _kernel_params *kernel_params = (struct _kernel_params *) KSEG;
924 int i;
925
926 printf_lock("k_argc = %d ", k_argc);
927 for (i = 0; i < k_argc; i++) {
928 printf_lock("'%s' ", k_argv[i]);
929 }
930 printf_lock("\n");
931
932 /* rpb_percpu |= 0xfffffc0000000000;*/
933 kernel_params->bootadr = bootadr;
934 kernel_params->rpb_percpu = KSEG_TO_PHYS(rpb_percpu);
935 kernel_params->free_pfn = free_pfn;
936 kernel_params->argc = k_argc;
937 kernel_params->argv = (ul)k_argv;
938 kernel_params->envp = (ul)envp;
939 printf_lock("jumping to kernel at 0x%x, (PCBB 0x%x pfn %d)\n", bootadr, rpb_percpu, free_pfn);
940 jToPal(KSEG_TO_PHYS((ul)palJToKern));
941 printf_lock("returned from jToPal. Looping\n");
942 while(1) continue;
943 }
944
945
946 void jToPal(ul bootadr)
947 {
948 cServe(bootadr, 0, CSERVE_K_JTOPAL);
949
950 /*
951 * Make sure that floating point is enabled incase
952 * it was disabled by the user program.
953 */
954 wrfen(1);
955 }
956
957
958 int strcpy(char *dst, char *src)
959 {
960 int i=0;
961 while(*src) {
962 *dst++ = *src++;
963 i++;
964 }
965 return i;
966 }
967
968
969
970
971 /* *****************************************
972 * Console I/O
973 * ******************************************/
974
975 int numOpenDevices = 11;
976 struct {
977 char name[128];
978 } deviceState[32];
979
980 #define BOOTDEVICE_NAME "SCSI 1 0 0 1 100 0"
981
982 void
983 DeviceOperation(long op, long channel, long count, long address, long block)
984 {
985 struct AlphaAccess *k1Conf = (struct AlphaAccess *)
986 (ALPHA_ACCESS_BASE);
987
988 long pAddr;
989
990 #if 0
991 printf("Console::DeviceRead count=0x%x address=0x%x block=0x%x\n",
992 count,address,block);
993 #endif
994
995 if (strcmp(deviceState[channel].name, BOOTDEVICE_NAME )) {
996 panic("DeviceRead: only implemented for root disk \n");
997 }
998 pAddr = KSEG_TO_PHYS(address);
999 if (pAddr + count > simosConf.mem_size) {
1000 panic("DeviceRead: request out of range \n");
1001 }
1002
1003 k1Conf->diskCount = count;
1004 k1Conf->diskPAddr = pAddr;
1005 k1Conf->diskBlock = block;
1006 k1Conf->diskOperation = op; /* launch */
1007 }
1008
1009
1010
1011 /* *************************************************************************
1012 * SimoS Console callbacks
1013 * **************************************************/
1014
1015 /* AXP manual 2-31 */
1016 #define CONSCB_GETC 0x1
1017 #define CONSCB_PUTS 0x2
1018 #define CONSCB_RESET_TERM 0x3
1019 #define CONSCB_SET_TERM_INT 0x4
1020 #define CONSCB_SET_TERM_CTL 0x5
1021 #define CONSCB_PROCESS_KEY 0x6
1022 #define CONSCB_OPEN_CONSOLE 0x7
1023 #define CONSCB_CLOSE_CONSOLE 0x8
1024
1025 #define CONSCB_OPEN 0x10
1026 #define CONSCB_CLOSE 0x11
1027 #define CONSCB_READ 0x13
1028
1029 #define CONSCB_GETENV 0x22
1030
1031 /* AXP manual 2-26 */
1032 #define ENV_AUTO_ACTION 0X01
1033 #define ENV_BOOT_DEV 0X02
1034 #define ENV_BOOTDEF_DEV 0X03
1035 #define ENV_BOOTED_DEV 0X04
1036 #define ENV_BOOT_FILE 0X05
1037 #define ENV_BOOTED_FILE 0X06
1038 #define ENV_BOOT_OSFLAGS 0X07
1039 #define ENV_BOOTED_OSFLAGS 0X08
1040 #define ENV_BOOT_RESET 0X09
1041 #define ENV_DUMP_DEV 0X0A
1042 #define ENV_ENABLE_AUDIT 0X0B
1043 #define ENV_LICENSE 0X0C
1044 #define ENV_CHAR_SET 0X0D
1045 #define ENV_LANGUAGE 0X0E
1046 #define ENV_TTY_DEV 0X0F
1047 #define ENV_SCSIID 0X42
1048 #define ENV_SCSIFAST 0X43
1049 #define ENV_COM1_BAUD 0X44
1050 #define ENV_COM1_MODEM 0X45
1051 #define ENV_COM1_FLOW 0X46
1052 #define ENV_COM1_MISC 0X47
1053 #define ENV_COM2_BAUD 0X48
1054 #define ENV_COM2_MODEM 0X49
1055 #define ENV_COM2_FLOW 0X4A
1056 #define ENV_COM2_MISC 0X4B
1057 #define ENV_PASSWORD 0X4C
1058 #define ENV_SECURE 0X4D
1059 #define ENV_LOGFAIL 0X4E
1060 #define ENV_SRM2DEV_ID 0X4F
1061
1062 #define MAX_ENVLEN 32
1063
1064 char env_auto_action[MAX_ENVLEN] = "BOOT";
1065 char env_boot_dev[MAX_ENVLEN] = "";
1066 char env_bootdef_dev[MAX_ENVLEN] = "";
1067 char env_booted_dev[MAX_ENVLEN] = BOOTDEVICE_NAME;
1068 char env_boot_file[MAX_ENVLEN] = "";
1069 char env_booted_file[MAX_ENVLEN] = "";
1070 char env_boot_osflags[MAX_ENVLEN] = "";
1071 char env_booted_osflags[MAX_ENVLEN] = "";
1072 char env_boot_reset[MAX_ENVLEN] = "";
1073 char env_dump_dev[MAX_ENVLEN] = "";
1074 char env_enable_audit[MAX_ENVLEN] = "";
1075 char env_license[MAX_ENVLEN] = "";
1076 char env_char_set[MAX_ENVLEN] = "";
1077 char env_language[MAX_ENVLEN] = "";
1078 char env_tty_dev[MAX_ENVLEN] = "0";
1079 char env_scsiid[MAX_ENVLEN] = "";
1080 char env_scsifast[MAX_ENVLEN] = "";
1081 char env_com1_baud[MAX_ENVLEN] = "";
1082 char env_com1_modem[MAX_ENVLEN] = "";
1083 char env_com1_flow[MAX_ENVLEN] = "";
1084 char env_com1_misc[MAX_ENVLEN] = "";
1085 char env_com2_baud[MAX_ENVLEN] = "";
1086 char env_com2_modem[MAX_ENVLEN] = "";
1087 char env_com2_flow[MAX_ENVLEN] = "";
1088 char env_com2_misc[MAX_ENVLEN] = "";
1089 char env_password[MAX_ENVLEN] = "";
1090 char env_secure[MAX_ENVLEN] = "";
1091 char env_logfail[MAX_ENVLEN] = "";
1092 char env_srm2dev_id[MAX_ENVLEN] = "";
1093
1094 #define MAX_ENV_INDEX 100
1095 char *env_ptr[MAX_ENV_INDEX] =
1096 {
1097 0, /* 0x00 */
1098 env_auto_action, /* 0x01 */
1099 env_boot_dev, /* 0x02 */
1100 env_bootdef_dev, /* 0x03 */
1101 env_booted_dev, /* 0x04 */
1102 env_boot_file, /* 0x05 */
1103 env_booted_file, /* 0x06 */
1104 env_boot_osflags, /* 0x07 */
1105 env_booted_osflags, /* 0x08 */
1106 env_boot_reset, /* 0x09 */
1107 env_dump_dev, /* 0x0A */
1108 env_enable_audit, /* 0x0B */
1109 env_license, /* 0x0C */
1110 env_char_set, /* 0x0D */
1111 (char *)&env_language, /* 0x0E */
1112 env_tty_dev, /* 0x0F */
1113 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0x10 - 0x1F */
1114 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0x20 - 0x2F */
1115 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0x30 - 0x3F */
1116 0, /* 0x40 */
1117 0, /* 0x41 */
1118 env_scsiid, /* 0x42 */
1119 env_scsifast, /* 0x43 */
1120 env_com1_baud, /* 0x44 */
1121 env_com1_modem, /* 0x45 */
1122 env_com1_flow, /* 0x46 */
1123 env_com1_misc, /* 0x47 */
1124 env_com2_baud, /* 0x48 */
1125 env_com2_modem, /* 0x49 */
1126 env_com2_flow, /* 0x4A */
1127 env_com2_misc, /* 0x4B */
1128 env_password, /* 0x4C */
1129 env_secure, /* 0x4D */
1130 env_logfail, /* 0x4E */
1131 env_srm2dev_id, /* 0x4F */
1132 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* 0x50 - 0x5F */
1133 0, /* 0x60 */
1134 0, /* 0x61 */
1135 0, /* 0x62 */
1136 0, /* 0x63 */
1137 };
1138
1139 long
1140 CallBackDispatcher(long a0, long a1, long a2, long a3, long a4)
1141 {
1142 long i;
1143 switch (a0) {
1144 case CONSCB_GETC:
1145 return GetChar();
1146
1147 case CONSCB_PUTS:
1148 for(i = 0; i < a3; i++)
1149 PutChar(*((char *)a2+i));
1150 return a3;
1151
1152 case CONSCB_GETENV:
1153 if (a1 >= 0 && a1 < MAX_ENV_INDEX && env_ptr[a1] != 0 && *env_ptr[a1]) {
1154 i = strcpy((char*)a2, env_ptr[a1]);
1155 } else {
1156 strcpy((char*)a2, "");
1157 i = (long)0xc000000000000000;
1158 if (a1 >= 0 && a1 < MAX_ENV_INDEX)
1159 printf_lock("GETENV unsupported option %d (0x%x)\n", a1, a1);
1160 else
1161 printf_lock("GETENV unsupported option %s\n", a1);
1162 }
1163
1164 if (i > a3)
1165 panic("CONSCB_GETENV overwrote buffer\n");
1166 return i;
1167
1168 case CONSCB_OPEN:
1169 bcopy((char*)a1,deviceState[numOpenDevices].name,a2);
1170 deviceState[numOpenDevices].name[a2] = '\0';
1171 printf_lock("CONSOLE OPEN : %s --> success \n",
1172 deviceState[numOpenDevices].name);
1173 return numOpenDevices++;
1174
1175 case CONSCB_READ:
1176 DeviceOperation(a0,a1,a2,a3,a4);
1177 break;
1178
1179 case CONSCB_CLOSE:
1180 break;
1181 case CONSCB_OPEN_CONSOLE:
1182 printf_lock("CONSOLE OPEN\n");
1183 return 0; /* success */
1184 break; /* not rearched */
1185 case CONSCB_CLOSE_CONSOLE:
1186 printf_lock("CONSOLE CLOSE\n");
1187 return 0; /* success */
1188 break; /* not reached */
1189
1190 default:
1191 panic("cher (%x,%x,%x,%x)\n", a0, a1, a2, a3);
1192 }
1193
1194 return 0;
1195 }
1196
1197 long CallBackFixup(int a0, int a1, int a2)
1198 {
1199 long temp;
1200 /* Linux uses r8 for the current pointer (pointer to data structure
1201 contating info about currently running process). It is set when the
1202 kernel starts and is expected to remain there... Problem is that the
1203 unlike the kernel, the console does not prevent the assembler from
1204 using r8. So here is a work around. So far this has only been a problem
1205 in CallBackFixup() but any other call back functions could cause a problem
1206 at some point */
1207
1208 /* save off the current pointer to a temp variable */
1209 asm("bis $8, $31, %0" : "=r" (temp));
1210
1211 /* call original code */
1212 printf_lock("CallbackFixup %x %x, t7=%x\n",a0,a1,temp);
1213
1214 /* restore the current pointer */
1215 asm("bis %0, $31, $8" : : "r" (temp) : "$8");
1216
1217 #if 0
1218 if (first[FIRST(a1)]==0) {
1219 first[FIRST(a1)] = KPTE(PFN(reservedFixup));
1220 } else {
1221 panic("CallBakcfixup\n");
1222 }
1223 second[SECOND(a1)] = KPTE(PFN(third_rpb)); /* Region 0 */
1224 printf("Fixup: FISRT(a1)=0x%x SECOND(a1)=0x%x THIRD(a1)=0x%x\n",
1225 FIRST(a1),SECOND(a1),THIRD(a1));
1226
1227 #endif
1228 return 0;
1229 }
1230
1231
1232
1233
1234
1235 void SlaveCmd(int cpu, struct rpb_percpu *my_rpb)
1236 {
1237 /* extern void palJToSlave[]; */
1238 extern unsigned int palJToSlave[];
1239
1240 printf_lock("Slave CPU %d console command %s", cpu,my_rpb->rpb_iccb.iccb_rxbuf);
1241
1242 my_rpb->rpb_state |= STATE_BIP;
1243 my_rpb->rpb_state &= ~STATE_RC;
1244
1245 printf_lock("SlaveCmd: restart %x %x vptb %x my_rpb %x my_rpb_phys %x\n",
1246 rpb->rpb_restart,
1247 rpb->rpb_restart_pv,
1248 rpb->rpb_vptb, my_rpb,
1249 KSEG_TO_PHYS(my_rpb));
1250
1251 cServe(KSEG_TO_PHYS((ul)palJToSlave),
1252 (ul)rpb->rpb_restart,
1253 CSERVE_K_JTOPAL,
1254 rpb->rpb_restart_pv,
1255 rpb->rpb_vptb,
1256 KSEG_TO_PHYS(my_rpb));
1257
1258 panic("SlaveCmd returned \n");
1259 }
1260
1261 void SlaveLoop( int cpu)
1262 {
1263 int size = ROUNDUP128(sizeof(struct rpb_percpu));
1264 struct rpb_percpu *my_rpb = (struct rpb_percpu*)
1265 ((ul)rpb_percpu + size*cpu);
1266
1267 if (cpu==0) {
1268 panic("CPU 0 entering slaveLoop. Reenetering the console. HOSED \n");
1269 } else {
1270 printf_lock("Entering slaveloop for cpu %d my_rpb=%x \n",cpu,my_rpb);
1271 }
1272
1273 // swap the processors context to the one in the
1274 // rpb_percpu struct very carefully (i.e. no stack usage)
1275 // so that linux knows which processor ends up in __smp_callin
1276 // and we don't trash any data is the process
1277 SlaveSpin(cpu,my_rpb,&my_rpb->rpb_iccb.iccb_rxlen);
1278 }