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