console.c revision 7982:7d084eb47a86
1
2
3/* ******************************************
4 * SimOS SRM  Console
5 *
6 * Derived from Lance Berc's SRM console
7 * for the SRC XXM�Machine
8 * ******************************************/
9
10
11/* from simos */
12typedef unsigned long long uint64;
13typedef unsigned int uint32;
14
15#define CONSOLE
16#include "alpha_access.h"
17#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
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 0;
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   12, /* masquerade a DEC_3000_500 (bugnion) */
209   (2<<1),		/* 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      break;
1133
1134   case CONSCB_PUTS:
1135      for(i = 0; i < a3; i++) {
1136         PutChar(*((char *)a2+i));
1137      }
1138      return a3;
1139
1140   case CONSCB_GETENV:
1141     if (a1 >= 0 && a1 < MAX_ENV_INDEX && env_ptr[a1] != 0 && *env_ptr[a1]) {
1142         i = strcpy((char*)a2, env_ptr[a1]);
1143     } else {
1144         strcpy((char*)a2, "");
1145         i = (long)0xc000000000000000;
1146         if (a1 >= 0 && a1 < MAX_ENV_INDEX)
1147             printf ("GETENV unsupported option %d (0x%x)\n", a1, a1);
1148         else
1149             printf ("GETENV unsupported option %s\n", a1);
1150     }
1151
1152     if (i > a3)
1153         panic("CONSCB_GETENV overwrote buffer\n");
1154     return i;
1155
1156   case CONSCB_OPEN:
1157      bcopy((char*)a1,deviceState[numOpenDevices].name,a2);
1158      deviceState[numOpenDevices].name[a2] = '\0';
1159      printf("CONSOLE OPEN : %s --> success \n",
1160             deviceState[numOpenDevices].name);
1161      return numOpenDevices++;
1162
1163   case CONSCB_READ:
1164      DeviceOperation(a0,a1,a2,a3,a4);
1165      break;
1166
1167   case CONSCB_CLOSE:
1168      break;
1169   case CONSCB_OPEN_CONSOLE:
1170      printf("CONSOLE OPEN\n");
1171      return 0; /* success */
1172      break; /* not rearched */
1173   case CONSCB_CLOSE_CONSOLE:
1174      printf("CONSOLE CLOSE\n");
1175      return 0; /* success */
1176      break; /* not reached */
1177
1178   default:
1179      panic("cher (%x,%x,%x,%x)\n", a0, a1, a2, a3);
1180   }
1181
1182   return 0;
1183}
1184
1185long CallBackFixup(int a0, int a1, int a2)
1186{
1187   printf("CallbackFixup %x %x \n",a0,a1);
1188
1189#if 0
1190  if (first[FIRST(a1)]==0) {
1191      first[FIRST(a1)] = KPTE(PFN(reservedFixup));
1192   } else {
1193      panic("CallBakcfixup\n");
1194   }
1195   second[SECOND(a1)] = KPTE(PFN(third_rpb));	/* Region 0 */
1196   printf("Fixup: FISRT(a1)=0x%x SECOND(a1)=0x%x THIRD(a1)=0x%x\n",
1197          FIRST(a1),SECOND(a1),THIRD(a1));
1198
1199#endif
1200   return 0;
1201}
1202
1203
1204
1205
1206
1207void SlaveCmd(int cpu, struct rpb_percpu *my_rpb)
1208{
1209/*   extern void palJToSlave[]; */
1210   extern unsigned int palJToSlave[];
1211
1212
1213   my_rpb->rpb_state |= STATE_BIP;
1214   my_rpb->rpb_state &= ~STATE_RC;
1215
1216   SpinLock(&theLock);
1217   printf("SlaveCmd: restart %x %x vptb %x my_rpb %x my_rpb_phys %x\n",
1218          rpb->rpb_restart,
1219          rpb->rpb_restart_pv,
1220          rpb->rpb_vptb, my_rpb,
1221          KSEG_TO_PHYS(my_rpb));
1222   SpinUnlock(&theLock);
1223
1224   cServe(KSEG_TO_PHYS((ul)palJToSlave),
1225          (ul)rpb->rpb_restart,
1226          CSERVE_K_JTOPAL,
1227          rpb->rpb_restart_pv,
1228          rpb->rpb_vptb,
1229          KSEG_TO_PHYS(my_rpb));
1230}
1231
1232void SlaveLoop( int cpu)
1233{
1234   int size = ROUNDUP128(sizeof(struct rpb_percpu));
1235   struct rpb_percpu *my_rpb = (struct rpb_percpu*)
1236      ((ul)rpb_percpu + size*cpu);
1237
1238
1239   SpinLock(&theLock);
1240   if (cpu==0) {
1241      panic("CPU�0 entering slaveLoop. Reenetering the console. HOSED \n");
1242   } else {
1243      printf("Entering slaveloop for cpu %d my_rpb=%x \n",cpu,my_rpb);
1244   }
1245   SpinUnlock(&theLock);
1246   while(1) {
1247      int i;
1248      for (i=0; i < 1000000 ; i++) {
1249         if (my_rpb->rpb_iccb.iccb_rxlen) {
1250            SpinLock(&theLock);
1251            printf("Slave CPU %d console command %s",
1252                   cpu,my_rpb->rpb_iccb.iccb_rxbuf);
1253            SpinUnlock(&theLock);
1254            SlaveCmd(cpu,my_rpb);
1255            panic("SlaveCmd returned \n");
1256         }
1257      }
1258      printf("*");
1259   }
1260}
1261
1262