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