console.c revision 7999:9d6c5bc4e1f9
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
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#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{
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
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;
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 *)
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 *)
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
1275