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