console.c revision 7985:3e932649220c
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"
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
66static unixBoot(int go, int argc, char **argv);
67void jToPal(ul bootadr);
68void SlaveLoop(int cpu);
69
70
71struct AlphaAccess simosConf;
72
73/* **************************************************************
74 * Console callbacks use VMS calling conventions
75 * read AXP manual, 2-64.
76 * ***************************************************************/
77typedef struct OpenVMSFunc {
78   long dummy;
79   long func;
80}OpenVMSFunc;
81
82OpenVMSFunc callbackFunc, fixupFunc;
83
84
85
86
87ul theLock;
88
89
90extern void SpinLock(ul *lock);
91#define SpinUnlock(_x) *(_x) = 0;
92
93struct _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
103extern consoleCallback[];
104extern consoleFixup[];
105long CallBackDispatcher();
106long CallBackFixup();
107
108/*
109 * simos console output
110 */
111
112void InitConsole(void)
113{
114#if 0
115   CDR->intr_status =(DevRegister)(DEV_CNSLE_RX_INTR |DEV_CNSLE_TX_INTR);
116#endif
117}
118
119char GetChar()
120{
121   struct AlphaAccess *k1Conf = (struct AlphaAccess *)(__MAGIC_ZONE(0, 0, MAGIC_ZONE_EV5_ALIAS));
122   return k1Conf->inputChar;
123}
124
125void 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
139int
140passArgs(int argc)
141{ return 0; }
142
143int
144main(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 */
185struct 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   34, /* 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
245ul xxm_tbb[] = { 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e,
246                 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e};
247
248struct 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
276struct _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
283struct _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
319struct 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 */
327struct 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
336struct _rpb_name {
337   unsigned long length;
338   char name[16];
339};
340
341extern struct _rpb_name xxm_name;
342
343struct rpb_dsr xxm_rpb_dsr = {
344   0,
345   0,
346   0,
347};
348
349struct _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) */
355long xxm_lurt[10] = { 9, 12, -1, -1, -1, -1, -1, -1, 1100, 1100 };
356
357ul unix_boot_mem;
358unsigned long bootadr;
359#if 0
360unsigned long  aout_bss_addr, aout_bss_size, aout_entry, aout_text_start, aout_data_addr;
361#endif
362char **kargv;
363int kargc;
364ul free_pfn;
365struct rpb_percpu *rpb_percpu;
366
367
368#define MAX_CPUS 32
369
370ul bootStrapImpure[MAX_CPUS];
371
372
373char *unix_boot_alloc(int pages)
374{
375   char *ret = (char *) unix_boot_mem;
376   unix_boot_mem += (pages * 8192);
377   return ret;
378}
379
380ul *first = 0;
381ul *third_rpb = 0;
382ul *reservedFixup = 0;
383
384int strcpy(char *dst, char *src);
385
386struct rpb *rpb;
387
388unixBoot(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
863aoutfixup(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
900extern ui palJToKern[];
901
902JToKern(bootadr, rpb_percpu, free_pfn, k_argc, k_argv, envp)
903char * bootadr;
904ul rpb_percpu;
905ul free_pfn;
906ul k_argc;
907char **k_argv;
908char **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
933void 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
945int 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
962int numOpenDevices = 11;
963struct {
964   char name[128];
965} deviceState[32];
966
967#define BOOTDEVICE_NAME "SCSI 1 0 0 1 100 0"
968
969void
970DeviceOperation(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
1051char	env_auto_action[MAX_ENVLEN]	= "BOOT";
1052char	env_boot_dev[MAX_ENVLEN]	= "";
1053char	env_bootdef_dev[MAX_ENVLEN]	= "";
1054char	env_booted_dev[MAX_ENVLEN]	= BOOTDEVICE_NAME;
1055char	env_boot_file[MAX_ENVLEN]	= "";
1056char	env_booted_file[MAX_ENVLEN]	= "";
1057char	env_boot_osflags[MAX_ENVLEN]	= "";
1058char	env_booted_osflags[MAX_ENVLEN]	= "";
1059char	env_boot_reset[MAX_ENVLEN]	= "";
1060char	env_dump_dev[MAX_ENVLEN]	= "";
1061char	env_enable_audit[MAX_ENVLEN]	= "";
1062char	env_license[MAX_ENVLEN]		= "";
1063char	env_char_set[MAX_ENVLEN]	= "";
1064char	env_language[MAX_ENVLEN]	= "";
1065char	env_tty_dev[MAX_ENVLEN]		= "0";
1066char	env_scsiid[MAX_ENVLEN]		= "";
1067char	env_scsifast[MAX_ENVLEN]	= "";
1068char	env_com1_baud[MAX_ENVLEN]	= "";
1069char	env_com1_modem[MAX_ENVLEN]	= "";
1070char	env_com1_flow[MAX_ENVLEN]	= "";
1071char	env_com1_misc[MAX_ENVLEN]	= "";
1072char	env_com2_baud[MAX_ENVLEN]	= "";
1073char	env_com2_modem[MAX_ENVLEN]	= "";
1074char	env_com2_flow[MAX_ENVLEN]	= "";
1075char	env_com2_misc[MAX_ENVLEN]	= "";
1076char	env_password[MAX_ENVLEN]	= "";
1077char	env_secure[MAX_ENVLEN]		= "";
1078char	env_logfail[MAX_ENVLEN]		= "";
1079char	env_srm2dev_id[MAX_ENVLEN]	= "";
1080
1081#define MAX_ENV_INDEX 100
1082char *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
1126long
1127CallBackDispatcher(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
1184long 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
1222void 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
1247void 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
1277