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