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