console.c revision 8001:3ff970f61e80
14997Sgblack@eecs.umich.edu
25417Sgblack@eecs.umich.edu
34997Sgblack@eecs.umich.edu/* ******************************************
44997Sgblack@eecs.umich.edu * SimOS SRM  Console
54997Sgblack@eecs.umich.edu *
64997Sgblack@eecs.umich.edu * Derived from Lance Berc's SRM console
74997Sgblack@eecs.umich.edu * for the SRC XXM�Machine
84997Sgblack@eecs.umich.edu * ******************************************/
94997Sgblack@eecs.umich.edu
104997Sgblack@eecs.umich.edu
114997Sgblack@eecs.umich.edutypedef unsigned long long uint64_t;
124997Sgblack@eecs.umich.edutypedef unsigned long long uint64;
134997Sgblack@eecs.umich.edutypedef unsigned int uint32_t;
144997Sgblack@eecs.umich.edutypedef unsigned int uint32;
154997Sgblack@eecs.umich.edu
164997Sgblack@eecs.umich.edu#define CONSOLE
174997Sgblack@eecs.umich.edu#include "alpha_access.h"
184997Sgblack@eecs.umich.edu
194997Sgblack@eecs.umich.edu#if 0
204997Sgblack@eecs.umich.edu#include "new_aouthdr.h"
214997Sgblack@eecs.umich.edu#include "srcmax.h"
224997Sgblack@eecs.umich.edu#endif
234997Sgblack@eecs.umich.edu
244997Sgblack@eecs.umich.edu/* from ../h */
254997Sgblack@eecs.umich.edu#include "lib.h"
264997Sgblack@eecs.umich.edu#include "rpb.h"
274997Sgblack@eecs.umich.edu#include "cserve.h"
284997Sgblack@eecs.umich.edu
294997Sgblack@eecs.umich.edu#define CONS_INT_TX   0x01  /* interrupt enable / state bits */
304997Sgblack@eecs.umich.edu#define CONS_INT_RX   0x02
314997Sgblack@eecs.umich.edu
324997Sgblack@eecs.umich.edu#define KSEG   0xfffffc0000000000
334997Sgblack@eecs.umich.edu#define K1BASE 0xfffffc8000000000
344997Sgblack@eecs.umich.edu#define KSEG_TO_PHYS(x)(((ul)x) & ~KSEG)
354997Sgblack@eecs.umich.edu
364997Sgblack@eecs.umich.edu#define ALPHA_ACCESS_BASE 0xfffffc8000a00000
374997Sgblack@eecs.umich.edu
384997Sgblack@eecs.umich.edu
394997Sgblack@eecs.umich.edu#define PHYS_TO_K1(_x) (K1BASE|(_x))
404997Sgblack@eecs.umich.edu
414997Sgblack@eecs.umich.edu#define AOUT_LOAD_ADDR (KSEG|0xf000)
424997Sgblack@eecs.umich.edu
434997Sgblack@eecs.umich.edu#define ROUNDUP8(x) ((ul)(((ul)x)+7) & ~7)
444997Sgblack@eecs.umich.edu#define ROUNDUP128(x) ((ul)(((ul)x)+127) & ~127)
454997Sgblack@eecs.umich.edu#define ROUNDUP8K(x) ((ul)(((ul)(x))+8191) & ~8191)
464997Sgblack@eecs.umich.edu
474997Sgblack@eecs.umich.edu#define FIRST(x)  ((((ul)(x)) >> 33) & 0x3ff)
484997Sgblack@eecs.umich.edu#define SECOND(x) ((((ul)(x)) >> 23) & 0x3ff)
494997Sgblack@eecs.umich.edu#define THIRD(x) ((((ul)(x)) >> 13) & 0x3ff)
504997Sgblack@eecs.umich.edu#define THIRD_XXX(x)  ((((ul)(x)) >> 13) & 0xfff)
514997Sgblack@eecs.umich.edu#define PFN(x)  ((((ul)(x) & ~KSEG) >> 13))
524997Sgblack@eecs.umich.edu
534997Sgblack@eecs.umich.edu/* Kernel write | kernel read | valid */
544997Sgblack@eecs.umich.edu#define KPTE(x) ((ul)((((ul)(x)) << 32) | 0x1101))
554997Sgblack@eecs.umich.edu
564997Sgblack@eecs.umich.edu#define HWRPB_PAGES 4
574997Sgblack@eecs.umich.edu#define MDT_BITMAP_PAGES  4
584997Sgblack@eecs.umich.edu
594997Sgblack@eecs.umich.edu#define CSERVE_K_JTOKERN       0x18
605086Sgblack@eecs.umich.edu
615086Sgblack@eecs.umich.edu#define NUM_KERNEL_THIRD (4)
625912Sgblack@eecs.umich.edu
635124Sgblack@eecs.umich.edu
645086Sgblack@eecs.umich.edustatic unixBoot(int go, int argc, char **argv);
655149Sgblack@eecs.umich.eduvoid jToPal(ul bootadr);
665086Sgblack@eecs.umich.eduvoid SlaveLoop(int cpu);
675086Sgblack@eecs.umich.edu
685237Sgblack@eecs.umich.edu
695086Sgblack@eecs.umich.edustruct AlphaAccess simosConf;
705086Sgblack@eecs.umich.edu
715086Sgblack@eecs.umich.edu/* **************************************************************
725086Sgblack@eecs.umich.edu * Console callbacks use VMS calling conventions
735245Sgblack@eecs.umich.edu * read AXP manual, 2-64.
745245Sgblack@eecs.umich.edu * ***************************************************************/
755245Sgblack@eecs.umich.edutypedef struct OpenVMSFunc {
765895Sgblack@eecs.umich.edu   long dummy;
775895Sgblack@eecs.umich.edu   long func;
785895Sgblack@eecs.umich.edu}OpenVMSFunc;
795245Sgblack@eecs.umich.edu
805086Sgblack@eecs.umich.eduOpenVMSFunc callbackFunc, fixupFunc;
815086Sgblack@eecs.umich.edu
825086Sgblack@eecs.umich.edu
835358Sgblack@eecs.umich.edu
845124Sgblack@eecs.umich.edu
855124Sgblack@eecs.umich.eduul theLock;
865124Sgblack@eecs.umich.edu
875124Sgblack@eecs.umich.edu
885124Sgblack@eecs.umich.eduextern void SpinLock(ul *lock);
895124Sgblack@eecs.umich.edu#define SpinUnlock(_x) *(_x) = 0;
905124Sgblack@eecs.umich.edu
915237Sgblack@eecs.umich.edustruct _kernel_params {
925245Sgblack@eecs.umich.edu   char *bootadr;
935245Sgblack@eecs.umich.edu   ul rpb_percpu;
945245Sgblack@eecs.umich.edu   ul free_pfn;
955236Sgblack@eecs.umich.edu   ul argc;
965236Sgblack@eecs.umich.edu   ul argv;
975895Sgblack@eecs.umich.edu   ul envp; /* NULL */
985124Sgblack@eecs.umich.edu};
995124Sgblack@eecs.umich.edu
1005124Sgblack@eecs.umich.edu
1015124Sgblack@eecs.umich.eduextern consoleCallback[];
1025124Sgblack@eecs.umich.eduextern consoleFixup[];
1035124Sgblack@eecs.umich.edulong CallBackDispatcher();
1045124Sgblack@eecs.umich.edulong CallBackFixup();
1055124Sgblack@eecs.umich.edu
1065124Sgblack@eecs.umich.edu/*
1075124Sgblack@eecs.umich.edu * simos console output
1085124Sgblack@eecs.umich.edu */
1095124Sgblack@eecs.umich.edu
1105124Sgblack@eecs.umich.eduvoid InitConsole(void)
1115124Sgblack@eecs.umich.edu{
1125124Sgblack@eecs.umich.edu#if 0
1135895Sgblack@eecs.umich.edu   CDR->intr_status =(DevRegister)(DEV_CNSLE_RX_INTR |DEV_CNSLE_TX_INTR);
1145124Sgblack@eecs.umich.edu#endif
1155124Sgblack@eecs.umich.edu}
1165360Sgblack@eecs.umich.edu
1175360Sgblack@eecs.umich.educhar GetChar()
1185124Sgblack@eecs.umich.edu{
1195124Sgblack@eecs.umich.edu   struct AlphaAccess *k1Conf = (struct AlphaAccess *)(ALPHA_ACCESS_BASE);
1205124Sgblack@eecs.umich.edu   return k1Conf->inputChar;
1215124Sgblack@eecs.umich.edu}
1225124Sgblack@eecs.umich.edu
1235124Sgblack@eecs.umich.eduvoid PutChar(char c)
1245124Sgblack@eecs.umich.edu{
1255124Sgblack@eecs.umich.edu#if 0
1265360Sgblack@eecs.umich.edu   CDR->data = c;
1275124Sgblack@eecs.umich.edu#endif
1285360Sgblack@eecs.umich.edu#if 0
1295124Sgblack@eecs.umich.edu   *(int*) PHYS_TO_K1(SLOT_D_COM1<<5) = c;
1305360Sgblack@eecs.umich.edu#endif
1315124Sgblack@eecs.umich.edu   struct AlphaAccess *k1Conf = (struct AlphaAccess *)(ALPHA_ACCESS_BASE);
1325124Sgblack@eecs.umich.edu   k1Conf->outputChar = c;
1335360Sgblack@eecs.umich.edu
1345360Sgblack@eecs.umich.edu}
1355360Sgblack@eecs.umich.edu
1365360Sgblack@eecs.umich.edu
1375360Sgblack@eecs.umich.eduint
1385360Sgblack@eecs.umich.edupassArgs(int argc)
1395360Sgblack@eecs.umich.edu{ return 0; }
1405360Sgblack@eecs.umich.edu
1415360Sgblack@eecs.umich.eduint
1425360Sgblack@eecs.umich.edumain(int argc, char **argv)
1435360Sgblack@eecs.umich.edu{
1445124Sgblack@eecs.umich.edu   int x,i;
1455124Sgblack@eecs.umich.edu   struct AlphaAccess *k1Conf = (struct AlphaAccess *)(ALPHA_ACCESS_BASE);
1465124Sgblack@eecs.umich.edu   ui *k1ptr,*ksegptr;
1475124Sgblack@eecs.umich.edu
1485124Sgblack@eecs.umich.edu
1495242Sgblack@eecs.umich.edu   InitConsole();
1505242Sgblack@eecs.umich.edu   printf("SimOS console \n");
1515242Sgblack@eecs.umich.edu   /*
1525242Sgblack@eecs.umich.edu    * get configuration from backdoor
1535242Sgblack@eecs.umich.edu    */
1545242Sgblack@eecs.umich.edu   simosConf.last_offset = k1Conf->last_offset;
1555124Sgblack@eecs.umich.edu   printf(" Got simosConfiguration %d \n",simosConf.last_offset);
1565124Sgblack@eecs.umich.edu
1575124Sgblack@eecs.umich.edu/*   for (i=1;i<=simosConf.last_offset/4;i++) {
1585357Sgblack@eecs.umich.edu      ui *k1ptr = (ui*)k1Conf + i;
1595357Sgblack@eecs.umich.edu      ui *ksegptr = (ui*)(&simosConf.last_offset)+i;
1605357Sgblack@eecs.umich.edu      *ksegptr = *k1ptr;
1615357Sgblack@eecs.umich.edu
1625357Sgblack@eecs.umich.edu   }*/
1635357Sgblack@eecs.umich.edu
1645124Sgblack@eecs.umich.edu    simosConf.last_offset = k1Conf->last_offset;
1655124Sgblack@eecs.umich.edu    simosConf.version = k1Conf->version;
1665242Sgblack@eecs.umich.edu    simosConf.numCPUs = k1Conf->numCPUs;
1675242Sgblack@eecs.umich.edu    simosConf.intrClockFrequency = k1Conf->intrClockFrequency;
1685242Sgblack@eecs.umich.edu    simosConf.cpuClock = k1Conf->cpuClock;
1695242Sgblack@eecs.umich.edu    simosConf.mem_size = k1Conf->mem_size;
1705242Sgblack@eecs.umich.edu    simosConf.kernStart = k1Conf->kernStart;
1715242Sgblack@eecs.umich.edu    simosConf.kernEnd = k1Conf->kernEnd;
1725242Sgblack@eecs.umich.edu    simosConf.entryPoint = k1Conf->entryPoint;
1735242Sgblack@eecs.umich.edu    simosConf.diskUnit = k1Conf->diskUnit;
1745242Sgblack@eecs.umich.edu    simosConf.diskCount = k1Conf->diskCount;
1755242Sgblack@eecs.umich.edu    simosConf.diskPAddr = k1Conf->diskPAddr;
1765124Sgblack@eecs.umich.edu    simosConf.diskBlock = k1Conf->diskBlock;
1775124Sgblack@eecs.umich.edu    simosConf.diskOperation = k1Conf->diskOperation;
1785124Sgblack@eecs.umich.edu    simosConf.outputChar = k1Conf->outputChar;
1795358Sgblack@eecs.umich.edu    simosConf.inputChar = k1Conf->inputChar;
1805086Sgblack@eecs.umich.edu    simosConf.bootStrapImpure = k1Conf->bootStrapImpure;
1815359Sgblack@eecs.umich.edu    simosConf.bootStrapCPU = k1Conf->bootStrapCPU;
1825359Sgblack@eecs.umich.edu
1835359Sgblack@eecs.umich.edu   if (simosConf.version != ALPHA_ACCESS_VERSION)  {
1845359Sgblack@eecs.umich.edu      panic("Console version mismatch. Console expects %d. SimOS has %d \n",
1855359Sgblack@eecs.umich.edu            ALPHA_ACCESS_VERSION,simosConf.version);
1865086Sgblack@eecs.umich.edu   }
1875086Sgblack@eecs.umich.edu
1885086Sgblack@eecs.umich.edu
1896023Snate@binkert.org   /*
1906023Snate@binkert.org    * setup arguments to kernel
1915086Sgblack@eecs.umich.edu    */
1925895Sgblack@eecs.umich.edu   unixBoot(1,argc,argv);
1935124Sgblack@eecs.umich.edu
1945140Sgblack@eecs.umich.edu   x = *(volatile int *)(K1BASE-4);
1955124Sgblack@eecs.umich.edu   while(1) continue;
1965124Sgblack@eecs.umich.edu   return x;
1975140Sgblack@eecs.umich.edu}
1985912Sgblack@eecs.umich.edu
1995124Sgblack@eecs.umich.edu/*
2005124Sgblack@eecs.umich.edu * BOOTING
2015149Sgblack@eecs.umich.edu */
2025149Sgblack@eecs.umich.edustruct rpb xxm_rpb = {
2035149Sgblack@eecs.umich.edu   NULL,		/* 000: physical self-reference */
2045149Sgblack@eecs.umich.edu   ((long)'H') | (((long)'W') << 8) | (((long)'R') << 16) |
2055294Sgblack@eecs.umich.edu   ((long)'P' << 24) | (((long)'B') << 32),  /* 008: contains string "HWRPB" */
2065243Sgblack@eecs.umich.edu   6,			/* 010: HWRPB version number */
2075418Sgblack@eecs.umich.edu   /* the byte count is wrong, but who needs it? - lance */
2085149Sgblack@eecs.umich.edu   0,			/* 018: bytes in RPB perCPU CTB CRB MEDSC */
2095149Sgblack@eecs.umich.edu   0,			/* 020: primary cpu id */
2105149Sgblack@eecs.umich.edu   8192,		/* 028: page size in bytes */
2115418Sgblack@eecs.umich.edu   43,		/* 030: number of phys addr bits */
2125149Sgblack@eecs.umich.edu   127,		/* 038: max valid ASN */
2135149Sgblack@eecs.umich.edu   {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1'},	/* 040: system serial num: 10 ascii chars */
2145149Sgblack@eecs.umich.edu#ifdef undef
2155149Sgblack@eecs.umich.edu/* To be legitimate, the following system type and variation are correct for the XXM.
2165149Sgblack@eecs.umich.edu   But there are too many #ifdefs etc to deal with in Unix, so we tell the kernel
2175149Sgblack@eecs.umich.edu   that we're an Avanti, which is similar enough.
2185360Sgblack@eecs.umich.edu   */
2195360Sgblack@eecs.umich.edu   31,		/* 050: system type - XXM is now in the Alpha SRM */
2205360Sgblack@eecs.umich.edu   (1 << 10) | (2<<1),/* 058: system variation - XXM w/EV5 & embeded console */
2215149Sgblack@eecs.umich.edu#endif
2225149Sgblack@eecs.umich.edu#if 0
2235149Sgblack@eecs.umich.edu   0x12,		/* 050: system type - masquarade as some random 21064 */
2245149Sgblack@eecs.umich.edu#endif
2255149Sgblack@eecs.umich.edu   0, /* masquerade a Tsunami RGD */
2265149Sgblack@eecs.umich.edu   (1<<10),		/* 058: system variation */
2275149Sgblack@eecs.umich.edu   'c'|('o'<<8)|('o'<<16)|('l'<< 24),		/* 060: system revision */
2285149Sgblack@eecs.umich.edu   1024*4096,		/* 068: scaled interval clock intr freq  OVERRIDEN*/
2295149Sgblack@eecs.umich.edu   0,			/* 070: cycle counter frequency */
2305149Sgblack@eecs.umich.edu   0x200000000,	/* 078: virtual page table base */
2315149Sgblack@eecs.umich.edu   0,			/* 080: reserved */
2325149Sgblack@eecs.umich.edu   0,			/* 088: offset to translation buffer hint */
2335149Sgblack@eecs.umich.edu   1,			/* 090: number of processor slots OVERRIDDEN*/
2345149Sgblack@eecs.umich.edu   sizeof(struct rpb_percpu),	/* 098: per-cpu slot size. OVERRIDDEN */
2355149Sgblack@eecs.umich.edu   0,			/* 0A0: offset to per_cpu slots */
2365149Sgblack@eecs.umich.edu   1,			/* 0A8: number of CTBs */
2375149Sgblack@eecs.umich.edu#ifdef bugnion_gone
2385149Sgblack@eecs.umich.edu   sizeof(struct rpb_ctb),	/* 0B0: bytes in largest CTB */
2395149Sgblack@eecs.umich.edu#else
2405149Sgblack@eecs.umich.edu   sizeof(struct ctb_tt),
2415149Sgblack@eecs.umich.edu#endif
2425149Sgblack@eecs.umich.edu   0,			/* 0B8: offset to CTB (cons term block) */
2435149Sgblack@eecs.umich.edu   0,			/* 0C0: offset to CRB (cons routine block) */
2445149Sgblack@eecs.umich.edu   0,			/* 0C8: offset to memory descriptor table */
2455149Sgblack@eecs.umich.edu   0,			/* 0D0: offset to config data block */
2465149Sgblack@eecs.umich.edu   0,			/* 0D8: offset to FRU table */
2475149Sgblack@eecs.umich.edu   0,			/* 0E0: virt addr of save term routine */
2485149Sgblack@eecs.umich.edu   0,			/* 0E8: proc value for save term routine */
2495149Sgblack@eecs.umich.edu   0,			/* 0F0: virt addr of restore term routine */
2505149Sgblack@eecs.umich.edu   0,			/* 0F8: proc value for restore term routine */
2515149Sgblack@eecs.umich.edu   0,			/* 100: virt addr of CPU restart routine */
2525149Sgblack@eecs.umich.edu   0,			/* 108: proc value for CPU restart routine */
2535149Sgblack@eecs.umich.edu   0,			/* 110: used to determine presence of kdebug */
2545149Sgblack@eecs.umich.edu   0,			/* 118: reserved for hardware */
2555149Sgblack@eecs.umich.edu/* the checksum is wrong, but who needs it? - lance */
2565149Sgblack@eecs.umich.edu   0,			/* 120: checksum of prior entries in rpb */
2575149Sgblack@eecs.umich.edu   0,			/* 128: receive ready bitmask */
2585149Sgblack@eecs.umich.edu   0,			/* 130: transmit ready bitmask */
2595149Sgblack@eecs.umich.edu   0,			/* 138: Dynamic System Recog. offset */
2605149Sgblack@eecs.umich.edu};
2615149Sgblack@eecs.umich.edu
2625149Sgblack@eecs.umich.eduul xxm_tbb[] = { 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e,
2635149Sgblack@eecs.umich.edu                 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e, 0x1e1e1e1e1e1e1e1e};
2645149Sgblack@eecs.umich.edu
2655149Sgblack@eecs.umich.edustruct rpb_percpu xxm_rpb_percpu = {
2665149Sgblack@eecs.umich.edu   {0,0,0,0,0,0,0,{0,0},{0,0,0,0,0,0,0,0}},				/* 000: boot/restart HWPCB */
2675149Sgblack@eecs.umich.edu   (STATE_PA | STATE_PP | STATE_CV | STATE_PV | STATE_PMV | STATE_PL), 	/* 080: per-cpu state bits */
2685149Sgblack@eecs.umich.edu   0xc000,				/* 088: palcode memory length */
2695149Sgblack@eecs.umich.edu   0x2000,				/* 090: palcode scratch length */
2705149Sgblack@eecs.umich.edu   0x4000,				/* 098: phys addr of palcode mem space */
2715149Sgblack@eecs.umich.edu   0x2000,				/* 0A0: phys addr of palcode scratch space */
2725149Sgblack@eecs.umich.edu   (2 << 16) | (5 << 8) | 1,		/* 0A8: PALcode rev required */
2735149Sgblack@eecs.umich.edu   5 | (2L  << 32),				/* 0B0: processor type */
2745149Sgblack@eecs.umich.edu   7,					/* 0B8: processor variation */
2755149Sgblack@eecs.umich.edu   'D'|('a'<<8)|('v'<<16)|('e'<<24),	/* 0C0: processor revision */
2765149Sgblack@eecs.umich.edu   {'D','a','v','e','C','o','n','r','o','y',0,0,0,0,0,0},	/* 0C8: proc serial num: 10 ascii chars */
2775149Sgblack@eecs.umich.edu   0,					/* 0D8: phys addr of logout area */
2785149Sgblack@eecs.umich.edu   0,					/* 0E0: length in bytes of logout area */
2795149Sgblack@eecs.umich.edu   0,					/* 0E8: halt pcb base */
2805149Sgblack@eecs.umich.edu   0,					/* 0F0: halt pc */
2815149Sgblack@eecs.umich.edu   0,					/* 0F8: halt ps */
2825149Sgblack@eecs.umich.edu   0,					/* 100: halt arg list (R25) */
2835149Sgblack@eecs.umich.edu   0,					/* 108: halt return address (R26) */
2845149Sgblack@eecs.umich.edu   0,					/* 110: halt procedure value (R27) */
2855149Sgblack@eecs.umich.edu   0,		       			/* 118: reason for halt */
2865149Sgblack@eecs.umich.edu   0,		       			/* 120: for software */
2875149Sgblack@eecs.umich.edu   {0},				/* 128: inter-console communications buffer */
2885149Sgblack@eecs.umich.edu   {1,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0},	/* 1D0: PALcode revs available */
2895149Sgblack@eecs.umich.edu   0					/* 250: reserved for arch use */
2905149Sgblack@eecs.umich.edu/* the dump stack grows from the end of the rpb page not to reach here */
2915149Sgblack@eecs.umich.edu};
2925149Sgblack@eecs.umich.edu
2935149Sgblack@eecs.umich.edustruct _xxm_rpb_mdt {
2945149Sgblack@eecs.umich.edu   long   rpb_checksum;	/* 000: checksum of entire mem desc table */
2955149Sgblack@eecs.umich.edu   long   rpb_impaddr;		/* 008: PA of implementation dep info */
2965149Sgblack@eecs.umich.edu   long   rpb_numcl;		/* 010: number of clusters */
2975149Sgblack@eecs.umich.edu   struct rpb_cluster rpb_cluster[3];	/* first instance of a cluster */
2985149Sgblack@eecs.umich.edu};
2995149Sgblack@eecs.umich.edu
3005149Sgblack@eecs.umich.edustruct _xxm_rpb_mdt xxm_rpb_mdt = {
3015149Sgblack@eecs.umich.edu   0,		/* 000: checksum of entire mem desc table */
3025149Sgblack@eecs.umich.edu   0,		/* 008: PA of implementation dep info */
3035149Sgblack@eecs.umich.edu   0,		/* 010: number of clusters */
3045149Sgblack@eecs.umich.edu   {{	0,		/* 000: starting PFN of this cluster */
3055149Sgblack@eecs.umich.edu        0,		/* 008: count of PFNs in this cluster */
3065149Sgblack@eecs.umich.edu        0,		/* 010: count of tested PFNs in cluster */
3075149Sgblack@eecs.umich.edu        0,		/* 018: va of bitmap */
3085149Sgblack@eecs.umich.edu        0,		/* 020: pa of bitmap */
3095149Sgblack@eecs.umich.edu        0,		/* 028: checksum of bitmap */
3105149Sgblack@eecs.umich.edu        1		/* 030: usage of cluster */
3115149Sgblack@eecs.umich.edu   },
3125149Sgblack@eecs.umich.edu    {   0,		/* 000: starting PFN of this cluster */
3135149Sgblack@eecs.umich.edu        0,		/* 008: count of PFNs in this cluster */
3145149Sgblack@eecs.umich.edu        0,		/* 010: count of tested PFNs in cluster */
3155149Sgblack@eecs.umich.edu        0,		/* 018: va of bitmap */
3165149Sgblack@eecs.umich.edu        0,		/* 020: pa of bitmap */
3175149Sgblack@eecs.umich.edu        0,		/* 028: checksum of bitmap */
3185149Sgblack@eecs.umich.edu        0		/* 030: usage of cluster */
3195149Sgblack@eecs.umich.edu    },
3205149Sgblack@eecs.umich.edu    {   0,		/* 000: starting PFN of this cluster */
3215149Sgblack@eecs.umich.edu        0,		/* 008: count of PFNs in this cluster */
3225149Sgblack@eecs.umich.edu        0,		/* 010: count of tested PFNs in cluster */
3235149Sgblack@eecs.umich.edu        0,		/* 018: va of bitmap */
3245149Sgblack@eecs.umich.edu        0,		/* 020: pa of bitmap */
3255149Sgblack@eecs.umich.edu        0,		/* 028: checksum of bitmap */
3265149Sgblack@eecs.umich.edu        0		/* 030: usage of cluster */
3275149Sgblack@eecs.umich.edu    }}
3285149Sgblack@eecs.umich.edu};
3295149Sgblack@eecs.umich.edu
3305149Sgblack@eecs.umich.edu/* constants for slotinfo bus_type subfield */
3315149Sgblack@eecs.umich.edu#define SLOTINFO_TC	0
3325149Sgblack@eecs.umich.edu#define SLOTINFO_ISA	1
3335149Sgblack@eecs.umich.edu#define SLOTINFO_EISA	2
3345149Sgblack@eecs.umich.edu#define SLOTINFO_PCI	3
3355149Sgblack@eecs.umich.edu
3365149Sgblack@eecs.umich.edustruct rpb_ctb xxm_rpb_ctb = {
3375149Sgblack@eecs.umich.edu   CONS_DZ,	/* 000: console type */
3385149Sgblack@eecs.umich.edu   0,		/* 008: console unit */
3395149Sgblack@eecs.umich.edu   0,		/* 010: reserved */
3405149Sgblack@eecs.umich.edu   0		/* 018: byte length of device dep portion */
3415149Sgblack@eecs.umich.edu};
3425149Sgblack@eecs.umich.edu
3435149Sgblack@eecs.umich.edu/* we don't do any fixup (aka relocate the console) - we hope */
3445149Sgblack@eecs.umich.edustruct rpb_crb xxm_rpb_crb = {
3455149Sgblack@eecs.umich.edu   0,		/* va of call-back dispatch rtn */
3465149Sgblack@eecs.umich.edu   0,		/* pa of call-back dispatch rtn */
3475149Sgblack@eecs.umich.edu   0,		/* va of call-back fixup rtn */
3485149Sgblack@eecs.umich.edu   0,		/* pa of call-back fixup rtn */
3495149Sgblack@eecs.umich.edu   0,		/* number of entries in phys/virt map */
3505149Sgblack@eecs.umich.edu   0		/* Number of pages to be mapped */
3515149Sgblack@eecs.umich.edu};
3525149Sgblack@eecs.umich.edu
3535149Sgblack@eecs.umich.edustruct _rpb_name {
3545149Sgblack@eecs.umich.edu   unsigned long length;
3555149Sgblack@eecs.umich.edu   char name[16];
3565149Sgblack@eecs.umich.edu};
3575149Sgblack@eecs.umich.edu
3585149Sgblack@eecs.umich.eduextern struct _rpb_name xxm_name;
3595419Sgblack@eecs.umich.edu
3605419Sgblack@eecs.umich.edustruct rpb_dsr xxm_rpb_dsr = {
3615419Sgblack@eecs.umich.edu   0,
3625419Sgblack@eecs.umich.edu   0,
3635419Sgblack@eecs.umich.edu   0,
3645419Sgblack@eecs.umich.edu};
3655419Sgblack@eecs.umich.edu
3665419Sgblack@eecs.umich.edustruct _rpb_name xxm_name = {
3675419Sgblack@eecs.umich.edu   16,
3685149Sgblack@eecs.umich.edu   {'D','E','C',' ','S','R','C',' ','X','X','M',' ','D','G','C',0},
3695149Sgblack@eecs.umich.edu};
3705149Sgblack@eecs.umich.edu
3715149Sgblack@eecs.umich.edu/* XXM has one LURT entry - 1050 is for workstations, 1100 is servers (and is needed for CXX) */
3725149Sgblack@eecs.umich.edulong xxm_lurt[10] = { 9, 12, -1, -1, -1, -1, -1, -1, 1100, 1100 };
3735149Sgblack@eecs.umich.edu
3745149Sgblack@eecs.umich.eduul unix_boot_mem;
3755149Sgblack@eecs.umich.eduunsigned long bootadr;
3765149Sgblack@eecs.umich.edu#if 0
3775149Sgblack@eecs.umich.eduunsigned long  aout_bss_addr, aout_bss_size, aout_entry, aout_text_start, aout_data_addr;
3785149Sgblack@eecs.umich.edu#endif
3795149Sgblack@eecs.umich.educhar **kargv;
3805149Sgblack@eecs.umich.eduint kargc;
3815149Sgblack@eecs.umich.eduul free_pfn;
3825149Sgblack@eecs.umich.edustruct rpb_percpu *rpb_percpu;
3835419Sgblack@eecs.umich.edu
3845419Sgblack@eecs.umich.edu
3855419Sgblack@eecs.umich.edu#define MAX_CPUS 32
3865419Sgblack@eecs.umich.edu
3875419Sgblack@eecs.umich.eduul bootStrapImpure[MAX_CPUS];
3885419Sgblack@eecs.umich.edu
3895419Sgblack@eecs.umich.edu
3905419Sgblack@eecs.umich.educhar *unix_boot_alloc(int pages)
3915419Sgblack@eecs.umich.edu{
3925149Sgblack@eecs.umich.edu   char *ret = (char *) unix_boot_mem;
3935149Sgblack@eecs.umich.edu   unix_boot_mem += (pages * 8192);
3945149Sgblack@eecs.umich.edu   return ret;
3955149Sgblack@eecs.umich.edu}
3965149Sgblack@eecs.umich.edu
3975149Sgblack@eecs.umich.eduul *first = 0;
3985149Sgblack@eecs.umich.eduul *third_rpb = 0;
3995149Sgblack@eecs.umich.eduul *reservedFixup = 0;
4005149Sgblack@eecs.umich.edu
4015149Sgblack@eecs.umich.eduint strcpy(char *dst, char *src);
4025149Sgblack@eecs.umich.edu
4035149Sgblack@eecs.umich.edustruct rpb *rpb;
4045149Sgblack@eecs.umich.edu
4055149Sgblack@eecs.umich.eduunixBoot(int go, int argc, char **argv)
4065149Sgblack@eecs.umich.edu{
4075419Sgblack@eecs.umich.edu   ul *second,  *third_kernel, ptr, *tbb, size, *percpu_logout;
4085419Sgblack@eecs.umich.edu   unsigned char *mdt_bitmap;
4095419Sgblack@eecs.umich.edu   long *lp1, *lp2, sum;
4105419Sgblack@eecs.umich.edu   int i, cl;
4115419Sgblack@eecs.umich.edu   int kern_first_page;
4125419Sgblack@eecs.umich.edu   int mem_size = simosConf.mem_size;
4135419Sgblack@eecs.umich.edu
4145419Sgblack@eecs.umich.edu   int mem_pages = mem_size / 8192, cons_pages;
4155419Sgblack@eecs.umich.edu   ul kernel_bytes, ksp, kernel_end, *unix_kernel_stack, bss, ksp_bottom, ksp_top;
4165149Sgblack@eecs.umich.edu   struct rpb_ctb *rpb_ctb;
4175149Sgblack@eecs.umich.edu   struct ctb_tt *ctb_tt;
4185149Sgblack@eecs.umich.edu   struct rpb_dsr *rpb_dsr;
4195149Sgblack@eecs.umich.edu   struct rpb_crb *rpb_crb;
4205149Sgblack@eecs.umich.edu   struct _xxm_rpb_mdt *rpb_mdt;
4215149Sgblack@eecs.umich.edu   int *rpb_lurt;
4225149Sgblack@eecs.umich.edu   char *rpb_name;
4235149Sgblack@eecs.umich.edu   ul nextPtr;
4245149Sgblack@eecs.umich.edu
4255149Sgblack@eecs.umich.edu   printf( "memsize %x pages %x \n",mem_size,mem_pages);
4265149Sgblack@eecs.umich.edu
4275149Sgblack@eecs.umich.edu
4285149Sgblack@eecs.umich.edu
4295149Sgblack@eecs.umich.edu#ifdef notnow
4305149Sgblack@eecs.umich.edu   if (unixArgs()) return;
4315419Sgblack@eecs.umich.edu#endif
4325419Sgblack@eecs.umich.edu
4335419Sgblack@eecs.umich.edu   /* Allocate:
4345419Sgblack@eecs.umich.edu    *   two pages for the HWRPB
4355419Sgblack@eecs.umich.edu    *   five page table pages:
4365419Sgblack@eecs.umich.edu    *     1: First level page table
4375419Sgblack@eecs.umich.edu    *     1: Second level page table
4385419Sgblack@eecs.umich.edu    *     1: Third level page table for HWRPB
4395419Sgblack@eecs.umich.edu    *     2: Third level page table for kernel (for up to 16MB)
4405149Sgblack@eecs.umich.edu    * set up the page tables
4415149Sgblack@eecs.umich.edu    * load the kernel at the physical address 0x230000
4425149Sgblack@eecs.umich.edu    * build the HWRPB
4435149Sgblack@eecs.umich.edu    *   set up memory descriptor table to give up the
4445149Sgblack@eecs.umich.edu    *   physical memory between the end of the page
4455149Sgblack@eecs.umich.edu    *   tables and the start of the kernel
4465149Sgblack@eecs.umich.edu    * enable kseg addressing
4475149Sgblack@eecs.umich.edu    * jump to the kernel
4485149Sgblack@eecs.umich.edu    */
4495149Sgblack@eecs.umich.edu
4505149Sgblack@eecs.umich.edu   unix_boot_mem = ROUNDUP8K(&_end);
4515149Sgblack@eecs.umich.edu
4525149Sgblack@eecs.umich.edu   printf("First free page after ROM 0x%x\n", unix_boot_mem);
4535149Sgblack@eecs.umich.edu
4545149Sgblack@eecs.umich.edu   rpb = (struct rpb *) unix_boot_alloc( HWRPB_PAGES);
4555149Sgblack@eecs.umich.edu
4565149Sgblack@eecs.umich.edu   mdt_bitmap =  (unsigned char *) unix_boot_alloc(MDT_BITMAP_PAGES);
4575149Sgblack@eecs.umich.edu   first = (ul *)unix_boot_alloc(1);
4585149Sgblack@eecs.umich.edu   second = (ul *)unix_boot_alloc(1);
4595149Sgblack@eecs.umich.edu   third_rpb = (ul *)unix_boot_alloc(1);
4605149Sgblack@eecs.umich.edu   reservedFixup = (ul*) unix_boot_alloc(1);
4615149Sgblack@eecs.umich.edu   third_kernel = (ul *)unix_boot_alloc(NUM_KERNEL_THIRD);
4625149Sgblack@eecs.umich.edu   percpu_logout = (ul*)unix_boot_alloc(1);
4635149Sgblack@eecs.umich.edu
4645149Sgblack@eecs.umich.edu
4655149Sgblack@eecs.umich.edu   cons_pages = KSEG_TO_PHYS(unix_boot_mem) / 8192;
4665149Sgblack@eecs.umich.edu
4675149Sgblack@eecs.umich.edu   /* Set up the page tables */
4685149Sgblack@eecs.umich.edu   bzero((char *)first, 8192);
4695149Sgblack@eecs.umich.edu   bzero((char *)second, 8192);
4705149Sgblack@eecs.umich.edu   bzero((char *)reservedFixup,8192);
4715149Sgblack@eecs.umich.edu   bzero((char *)third_rpb, HWRPB_PAGES * 8192);
4725149Sgblack@eecs.umich.edu   bzero((char *)third_kernel, 8192 * NUM_KERNEL_THIRD);
4735149Sgblack@eecs.umich.edu
4745149Sgblack@eecs.umich.edu   first[0] = KPTE(PFN(second));
4755149Sgblack@eecs.umich.edu   first[1] = KPTE(PFN(first)); /* Region 3 */
4765149Sgblack@eecs.umich.edu
4775149Sgblack@eecs.umich.edu   second[SECOND(0x10000000)] = KPTE(PFN(third_rpb));	/* Region 0 */
4785149Sgblack@eecs.umich.edu   for (i=0;i<NUM_KERNEL_THIRD;i++) {
4795149Sgblack@eecs.umich.edu      second[SECOND(0x20000000)+i] = KPTE(PFN(third_kernel)+i);	/* Region 1 */
4805149Sgblack@eecs.umich.edu   }
4815149Sgblack@eecs.umich.edu   second[SECOND(0x40000000)] = KPTE(PFN(second));	/* Region 2 */
4825149Sgblack@eecs.umich.edu
4835149Sgblack@eecs.umich.edu
4845149Sgblack@eecs.umich.edu   {
4855149Sgblack@eecs.umich.edu
4865149Sgblack@eecs.umich.edu      /* For some obscure reason, Dec Unix's database read
4875149Sgblack@eecs.umich.edu       * from /etc/sysconfigtab is written to this fixed
4885149Sgblack@eecs.umich.edu       * mapped memory location. Go figure, since it is
4895149Sgblack@eecs.umich.edu       * not initialized by the console. Maybe it is
4905149Sgblack@eecs.umich.edu       * to look at the database from the console
4915149Sgblack@eecs.umich.edu       * after a boot/crash.
4925149Sgblack@eecs.umich.edu       *
4935149Sgblack@eecs.umich.edu       * Black magic to estimate the max size. SEGVs on overflow
4945149Sgblack@eecs.umich.edu       * bugnion
4955149Sgblack@eecs.umich.edu       */
4965149Sgblack@eecs.umich.edu
4975149Sgblack@eecs.umich.edu#define DATABASE_BASE           0x20000000
4985149Sgblack@eecs.umich.edu#ifdef not_not
4995149Sgblack@eecs.umich.edu#define DATABASE_END            0x20230000 /* don't need all that */
5005149Sgblack@eecs.umich.edu#endif
5015149Sgblack@eecs.umich.edu
5025149Sgblack@eecs.umich.edu#define DATABASE_END            0x20020000
5035149Sgblack@eecs.umich.edu
5045149Sgblack@eecs.umich.edu      int i;
5055149Sgblack@eecs.umich.edu      ul *dbPage = (ul*)unix_boot_alloc(1);
5065149Sgblack@eecs.umich.edu      second[SECOND(DATABASE_BASE)] = KPTE(PFN(dbPage));
5075149Sgblack@eecs.umich.edu      for (i=DATABASE_BASE; i <DATABASE_END ; i+= 8096) {
5085149Sgblack@eecs.umich.edu         ul *db = (ul*)unix_boot_alloc(1);
5095149Sgblack@eecs.umich.edu         dbPage[THIRD(i)] = KPTE(PFN(db));
5105149Sgblack@eecs.umich.edu      }
5115149Sgblack@eecs.umich.edu   }
5125149Sgblack@eecs.umich.edu
5135149Sgblack@eecs.umich.edu   /* Region 0 */
5145149Sgblack@eecs.umich.edu   /* Map the HWRPB */
5155149Sgblack@eecs.umich.edu   for (i = 0; i < HWRPB_PAGES; i++) third_rpb[i] = KPTE(PFN(rpb) + i);
5165149Sgblack@eecs.umich.edu
5175149Sgblack@eecs.umich.edu   /* Map the MDT bitmap table */
5185149Sgblack@eecs.umich.edu   for (i=0;i<MDT_BITMAP_PAGES;i++) {
5195149Sgblack@eecs.umich.edu      third_rpb[HWRPB_PAGES+i] = KPTE(PFN(mdt_bitmap)+i);
5205149Sgblack@eecs.umich.edu   }
5215149Sgblack@eecs.umich.edu
5225149Sgblack@eecs.umich.edu   /* Protect the PAL pages */
5235149Sgblack@eecs.umich.edu   for (i = 1; i < PFN(first); i++) third_rpb[HWRPB_PAGES + MDT_BITMAP_PAGES + i] = KPTE(i);
5245149Sgblack@eecs.umich.edu
5255149Sgblack@eecs.umich.edu   /* Set up third_kernel after it's loaded, when we know where it is */
5265149Sgblack@eecs.umich.edu
5275149Sgblack@eecs.umich.edu#ifdef original__xxm
5285149Sgblack@eecs.umich.edu   if (unixLoadKernel(AOUT_LOAD_ADDR, argv[1]) == -1) return;
5295149Sgblack@eecs.umich.edu   aoutfixup(AOUT_LOAD_ADDR);
5305149Sgblack@eecs.umich.edu#else
5315149Sgblack@eecs.umich.edu   /* aoutfixup(simosConf.kernelFileHdr); */
5325323Sgblack@eecs.umich.edu#endif
5335323Sgblack@eecs.umich.edu#if 0
5345323Sgblack@eecs.umich.edu   bss = aout_bss_addr;
5355323Sgblack@eecs.umich.edu
5365323Sgblack@eecs.umich.edu   kern_first_page = (KSEG_TO_PHYS(aout_text_start) / 8192);
5375323Sgblack@eecs.umich.edu   kernel_end = ksp_top = ROUNDUP8K(aout_bss_addr + aout_bss_size);
5385323Sgblack@eecs.umich.edu   bootadr = aout_entry;
5395323Sgblack@eecs.umich.edu#endif
5405357Sgblack@eecs.umich.edu
5415357Sgblack@eecs.umich.edu   kern_first_page = (KSEG_TO_PHYS(simosConf.kernStart)/8192);
5425357Sgblack@eecs.umich.edu   kernel_end = ksp_top = ROUNDUP8K(simosConf.kernEnd);
5435357Sgblack@eecs.umich.edu   bootadr = simosConf.entryPoint;
5445357Sgblack@eecs.umich.edu
5455357Sgblack@eecs.umich.edu
5465357Sgblack@eecs.umich.edu   printf("HWRPB 0x%x l1pt 0x%x l2pt 0x%x l3pt_rpb 0x%x l3pt_kernel 0x%x l2reserv 0x%x\n",
5475357Sgblack@eecs.umich.edu          rpb, first, second, third_rpb, third_kernel,reservedFixup);
5485837Sgblack@eecs.umich.edu   if (kernel_end - simosConf.kernStart > (0x800000*NUM_KERNEL_THIRD)) {
5495837Sgblack@eecs.umich.edu      printf("Kernel is more than 8MB 0x%x - 0x%x = 0x%x\n",
5505357Sgblack@eecs.umich.edu             kernel_end, simosConf.kernStart,
5515357Sgblack@eecs.umich.edu             kernel_end -simosConf.kernStart );
5525357Sgblack@eecs.umich.edu      panic("kernel too big\n");
5535357Sgblack@eecs.umich.edu
5545323Sgblack@eecs.umich.edu   }
5555149Sgblack@eecs.umich.edu   /* Map the kernel's pages into the third level of region 2 */
5565149Sgblack@eecs.umich.edu
5575149Sgblack@eecs.umich.edu   for (ptr = simosConf.kernStart; ptr < kernel_end; ptr += 8192) {
5585149Sgblack@eecs.umich.edu
5595149Sgblack@eecs.umich.edu      third_kernel[THIRD_XXX(ptr)] = KPTE(PFN(ptr));
5605124Sgblack@eecs.umich.edu   }
5615140Sgblack@eecs.umich.edu   /* blow 2 pages of phys mem for guards since it maintains 1-to-1 mapping */
5625140Sgblack@eecs.umich.edu   ksp = ksp_top + (3 * 8192);
5635140Sgblack@eecs.umich.edu   if (ksp - simosConf.kernStart > (0x800000*NUM_KERNEL_THIRD)) {
5645140Sgblack@eecs.umich.edu      printf("Kernel stack pushd us over 8MB\n");
5655140Sgblack@eecs.umich.edu      panic("ksp too big\n");
5665140Sgblack@eecs.umich.edu   }
5675237Sgblack@eecs.umich.edu   if (THIRD_XXX((ul)ksp_top) >  NUM_KERNEL_THIRD * 1024) {
5685140Sgblack@eecs.umich.edu      panic("increase NUM_KERNEL_THIRD, and change THIRD_XXX\n");
5695140Sgblack@eecs.umich.edu   }
5705140Sgblack@eecs.umich.edu   ptr = (ul) ksp_top;
5715140Sgblack@eecs.umich.edu   bzero((char *)ptr, 8192 * 2);
5725237Sgblack@eecs.umich.edu   third_kernel[THIRD_XXX(ptr)] = 0;			/* Stack Guard Page */
5735431Sgblack@eecs.umich.edu   ptr += 8192;
5745431Sgblack@eecs.umich.edu   third_kernel[THIRD_XXX(ptr)] = KPTE(PFN(ptr));	/* Kernel Stack Pages */
5755431Sgblack@eecs.umich.edu   ptr += 8192;
5765433Sgblack@eecs.umich.edu   third_kernel[THIRD_XXX(ptr)] = KPTE(PFN(ptr));
5775965Sgblack@eecs.umich.edu   ptr += 8192;
5785433Sgblack@eecs.umich.edu   third_kernel[THIRD_XXX(ptr)] = 0;			/* Stack Guard Page */
5796023Snate@binkert.org
5805433Sgblack@eecs.umich.edu   /* put argv into the bottom of the stack - argv starts at 1 because
5816023Snate@binkert.org    * the command thatr got us here (i.e. "unixboot) is in argv[0].
5825433Sgblack@eecs.umich.edu    */
5835433Sgblack@eecs.umich.edu   ksp -= 8;			/* Back up one longword */
5845965Sgblack@eecs.umich.edu   ksp -= argc * sizeof(char *);	/* Make room for argv */
5855433Sgblack@eecs.umich.edu   kargv = (char **) ksp;
5865140Sgblack@eecs.umich.edu   for (i = 1; i < argc; i++) {	/* Copy arguments to stack */
5875140Sgblack@eecs.umich.edu      ksp -= ((strlen(argv[i]) + 1) + 7) & ~0x7;
5885965Sgblack@eecs.umich.edu      kargv[i-1] = (char *) ksp;
5895965Sgblack@eecs.umich.edu      strcpy(kargv[i-1], argv[i]);
5905965Sgblack@eecs.umich.edu   }
5915965Sgblack@eecs.umich.edu   kargc = i - 1;
5925980Snate@binkert.org   kargv[kargc] = NULL;		/* just to be sure; doesn't seem to be used */
5935980Snate@binkert.org   ksp -= sizeof(char *);	/* point above last arg for no real reason */
5945965Sgblack@eecs.umich.edu
5955965Sgblack@eecs.umich.edu   free_pfn = PFN(ptr);
5965965Sgblack@eecs.umich.edu
5975433Sgblack@eecs.umich.edu   bcopy((char *)&xxm_rpb, (char *)rpb, sizeof(struct rpb));
5985237Sgblack@eecs.umich.edu
5995965Sgblack@eecs.umich.edu   rpb->rpb_selfref = (struct rpb *) KSEG_TO_PHYS(rpb);
6005965Sgblack@eecs.umich.edu   rpb->rpb_string = 0x0000004250525748;
6015965Sgblack@eecs.umich.edu
6025140Sgblack@eecs.umich.edu   tbb = (ul *) (((char *) rpb) + ROUNDUP8(sizeof(struct rpb)));
6035965Sgblack@eecs.umich.edu   rpb->rpb_trans_off = (ul)tbb - (ul)rpb;
6045965Sgblack@eecs.umich.edu   bcopy((char *)xxm_tbb, (char *)tbb, sizeof(xxm_tbb));
6055140Sgblack@eecs.umich.edu
6065140Sgblack@eecs.umich.edu
6075140Sgblack@eecs.umich.edu   /*
6085140Sgblack@eecs.umich.edu    * rpb_counter. Use to determine timeouts in OS.
6095237Sgblack@eecs.umich.edu    * XXX must be patched after a checkpoint restore (I guess)
6105140Sgblack@eecs.umich.edu    */
6115140Sgblack@eecs.umich.edu
6125140Sgblack@eecs.umich.edu   printf("CPU Clock at %d MHz IntrClockFrequency=%d \n", simosConf.cpuClock,simosConf.intrClockFrequency);
6135895Sgblack@eecs.umich.edu   rpb->rpb_counter = simosConf.cpuClock * 1000 * 1000;
6146023Snate@binkert.org
6155895Sgblack@eecs.umich.edu   /*
6165895Sgblack@eecs.umich.edu    * By definition, the rpb_clock is scaled by 4096 (in hz)
6175895Sgblack@eecs.umich.edu    */
6185895Sgblack@eecs.umich.edu   rpb->rpb_clock = simosConf.intrClockFrequency * 4096;
6195895Sgblack@eecs.umich.edu
6205895Sgblack@eecs.umich.edu
6215895Sgblack@eecs.umich.edu
6225895Sgblack@eecs.umich.edu   /*
6235895Sgblack@eecs.umich.edu    * Per CPU Slots. Multiprocessor support.
6245895Sgblack@eecs.umich.edu    */
6255895Sgblack@eecs.umich.edu   {
6265895Sgblack@eecs.umich.edu      int i;
6275895Sgblack@eecs.umich.edu      int size = ROUNDUP128(sizeof(struct rpb_percpu));
6285895Sgblack@eecs.umich.edu
6295895Sgblack@eecs.umich.edu      printf("Booting with %d processor(s) \n",simosConf.numCPUs);
6306023Snate@binkert.org
6315895Sgblack@eecs.umich.edu      rpb->rpb_numprocs = simosConf.numCPUs;
6325895Sgblack@eecs.umich.edu      rpb->rpb_slotsize = size;
6335895Sgblack@eecs.umich.edu      rpb_percpu = (struct rpb_percpu *)
6345895Sgblack@eecs.umich.edu         ROUNDUP128(((ul) tbb) +(sizeof(xxm_tbb)));
6355895Sgblack@eecs.umich.edu
6365895Sgblack@eecs.umich.edu      rpb->rpb_percpu_off = (ul)rpb_percpu - (ul)rpb;
6375895Sgblack@eecs.umich.edu
6385895Sgblack@eecs.umich.edu      for (i=0;i<simosConf.numCPUs;i++) {
6395895Sgblack@eecs.umich.edu         struct rpb_percpu *thisCPU = (struct rpb_percpu*)
6405895Sgblack@eecs.umich.edu            ((ul)rpb_percpu + size*i);
6415895Sgblack@eecs.umich.edu
6425895Sgblack@eecs.umich.edu         bzero((char *)thisCPU, size);
6435895Sgblack@eecs.umich.edu         bcopy((char *)&xxm_rpb_percpu,
6445140Sgblack@eecs.umich.edu               (char *)thisCPU,
6455895Sgblack@eecs.umich.edu               sizeof(struct rpb_percpu));
6465917Sgblack@eecs.umich.edu
6475917Sgblack@eecs.umich.edu         thisCPU->rpb_pcb.rpb_ksp = ksp;
6485980Snate@binkert.org         thisCPU->rpb_pcb.rpb_ptbr = PFN(first);
6496023Snate@binkert.org
6505917Sgblack@eecs.umich.edu         thisCPU->rpb_logout = KSEG_TO_PHYS(percpu_logout);
6515917Sgblack@eecs.umich.edu         thisCPU->rpb_logout_len = 8192;
6525917Sgblack@eecs.umich.edu
6536023Snate@binkert.org/*  thisCPU->rpb_pcb.rpb_ptbr = PFN(second);*/
6545917Sgblack@eecs.umich.edu
6555917Sgblack@eecs.umich.edu         printf("KSP: 0x%x PTBR 0x%x\n", thisCPU->rpb_pcb.rpb_ksp, thisCPU->rpb_pcb.rpb_ptbr);
6565917Sgblack@eecs.umich.edu
6575895Sgblack@eecs.umich.edu         if (i) {
6585895Sgblack@eecs.umich.edu            bootStrapImpure[i] = (ul)unix_boot_alloc(1);
6595895Sgblack@eecs.umich.edu         }
6605895Sgblack@eecs.umich.edu
6615895Sgblack@eecs.umich.edu      }
6625140Sgblack@eecs.umich.edu
6635140Sgblack@eecs.umich.edu      nextPtr = (ul)rpb_percpu + size*simosConf.numCPUs;
6645237Sgblack@eecs.umich.edu   }
6655237Sgblack@eecs.umich.edu
6665140Sgblack@eecs.umich.edu   /*
6675140Sgblack@eecs.umich.edu    * Console Terminal Block
6685124Sgblack@eecs.umich.edu    */
6695140Sgblack@eecs.umich.edu
6705237Sgblack@eecs.umich.edu
6715237Sgblack@eecs.umich.edu      rpb_ctb = (struct rpb_ctb *) nextPtr;
6725140Sgblack@eecs.umich.edu      ctb_tt = (struct ctb_tt*) rpb_ctb;
6735124Sgblack@eecs.umich.edu
6745360Sgblack@eecs.umich.edu      rpb->rpb_ctb_off = ((ul)rpb_ctb) - (ul)rpb;
6755374Sgblack@eecs.umich.edu      rpb->rpb_ctb_size  = sizeof(struct rpb_ctb);
6765360Sgblack@eecs.umich.edu
6775648Sgblack@eecs.umich.edu   bzero((char *)rpb_ctb, sizeof(struct ctb_tt));
6785360Sgblack@eecs.umich.edu
6795648Sgblack@eecs.umich.edu#ifdef original_xxm
6805417Sgblack@eecs.umich.edu   if (tga_slot == -1)
6815417Sgblack@eecs.umich.edu      rpb_ctb->rpb_type = CONS_DZ;
6825417Sgblack@eecs.umich.edu  else {
6835417Sgblack@eecs.umich.edu    rpb_ctb->rpb_type = CONS_GRPH;
6845360Sgblack@eecs.umich.edu    rpb_ctb->rpb_unit = (SLOTINFO_PCI << 16) | (0 << 8) | tga_slot;
6855360Sgblack@eecs.umich.edu  }
6865360Sgblack@eecs.umich.edu#else
6875360Sgblack@eecs.umich.edu  rpb_ctb->rpb_type = CONS_DZ;
6885360Sgblack@eecs.umich.edu#endif
6895360Sgblack@eecs.umich.edu
6905417Sgblack@eecs.umich.edu  rpb_ctb->rpb_length = sizeof(ctb_tt)-sizeof(rpb_ctb);
6915648Sgblack@eecs.umich.edu
6925736Snate@binkert.org  /*
6935714Shsul@eecs.umich.edu   * uart initizliation
6945360Sgblack@eecs.umich.edu   */
6955374Sgblack@eecs.umich.edu  ctb_tt->ctb_csr = 0;
6965086Sgblack@eecs.umich.edu  ctb_tt->ctb_tivec = 0x6c0;  /* matches tlaser pal code */
6975086Sgblack@eecs.umich.edu  ctb_tt->ctb_rivec = 0x680;  /* matches tlaser pal code */
6985086Sgblack@eecs.umich.edu  ctb_tt->ctb_baud = 9600;
6995140Sgblack@eecs.umich.edu  ctb_tt->ctb_put_sts = 0;
7006023Snate@binkert.org  ctb_tt->ctb_get_sts = 0;
7015140Sgblack@eecs.umich.edu
7025895Sgblack@eecs.umich.edu
7036023Snate@binkert.org  rpb_crb = (struct rpb_crb *) (((ul)rpb_ctb) + sizeof(struct ctb_tt));
7045140Sgblack@eecs.umich.edu  rpb->rpb_crb_off = ((ul)rpb_crb) - (ul)rpb;
7055140Sgblack@eecs.umich.edu
7065894Sgblack@eecs.umich.edu  bzero((char *)rpb_crb, sizeof(struct rpb_crb));
7076022Sgblack@eecs.umich.edu  /*
7086023Snate@binkert.org   * console callback stuff (simos)
7095894Sgblack@eecs.umich.edu   */
7105895Sgblack@eecs.umich.edu
7115894Sgblack@eecs.umich.edu  rpb_crb->rpb_num = 1;
7126023Snate@binkert.org  rpb_crb->rpb_mapped_pages = HWRPB_PAGES;
7136023Snate@binkert.org  rpb_crb->rpb_map[0].rpb_virt = 0x10000000;
7145895Sgblack@eecs.umich.edu  rpb_crb->rpb_map[0].rpb_phys = ((ul)rpb) & ~0x1fff;
7156023Snate@binkert.org  rpb_crb->rpb_map[0].rpb_pgcount = HWRPB_PAGES;
7165894Sgblack@eecs.umich.edu
7175894Sgblack@eecs.umich.edu
7185086Sgblack@eecs.umich.edu  printf("Console Callback at 0x%x, fixup at 0x%x \n",
7195086Sgblack@eecs.umich.edu          rpb_crb->rpb_va_disp,
7205086Sgblack@eecs.umich.edu          rpb_crb->rpb_va_fixup );
7216022Sgblack@eecs.umich.edu
7225086Sgblack@eecs.umich.edu  rpb_mdt = (struct _xxm_rpb_mdt *) (((ul)rpb_crb) + sizeof(struct rpb_crb));
7235100Ssaidi@eecs.umich.edu  rpb->rpb_mdt_off = (ul)rpb_mdt - (ul)rpb;
7245086Sgblack@eecs.umich.edu  bcopy((char *)&xxm_rpb_mdt, (char *)rpb_mdt, sizeof(struct _xxm_rpb_mdt));
7255086Sgblack@eecs.umich.edu
7265086Sgblack@eecs.umich.edu
7276022Sgblack@eecs.umich.edu  cl = 0;
7285086Sgblack@eecs.umich.edu#ifdef undef
7295100Ssaidi@eecs.umich.edu  /* Until Digital Unix can handle it, account all pages below the kernel
7305086Sgblack@eecs.umich.edu   * as "console" memory. */
7315086Sgblack@eecs.umich.edu  rpb_mdt->rpb_cluster[cl].rpb_pfncount = cons_pages;
7325086Sgblack@eecs.umich.edu#endif
7335086Sgblack@eecs.umich.edu  rpb_mdt->rpb_cluster[cl].rpb_pfncount = kern_first_page;
7345086Sgblack@eecs.umich.edu  cl++;
7355086Sgblack@eecs.umich.edu
7365086Sgblack@eecs.umich.edu  rpb_mdt->rpb_cluster[cl].rpb_pfn = kern_first_page;
7375086Sgblack@eecs.umich.edu  rpb_mdt->rpb_cluster[cl].rpb_pfncount = mem_pages - kern_first_page;
7385086Sgblack@eecs.umich.edu  rpb_mdt->rpb_cluster[cl].rpb_pfntested=rpb_mdt->rpb_cluster[cl].rpb_pfncount;
7395086Sgblack@eecs.umich.edu  rpb_mdt->rpb_cluster[cl].rpb_pa = KSEG_TO_PHYS(mdt_bitmap);
7405086Sgblack@eecs.umich.edu  rpb_mdt->rpb_cluster[cl].rpb_va = 0x10000000 + HWRPB_PAGES * 8192;
7415086Sgblack@eecs.umich.edu  cl++;
7425086Sgblack@eecs.umich.edu
7435086Sgblack@eecs.umich.edu#ifdef undef
7445086Sgblack@eecs.umich.edu  /* The stupid Unix kernel needs to have all mdt clusters in ascending
7455086Sgblack@eecs.umich.edu   * order, and the last cluster is used to compute the top of memory.
7466022Sgblack@eecs.umich.edu   * It can't make use of memory between the console and the kernel.
7476022Sgblack@eecs.umich.edu   */
7484997Sgblack@eecs.umich.edu  rpb_mdt->rpb_cluster[cl].rpb_pfn = cons_pages;
7496022Sgblack@eecs.umich.edu  rpb_mdt->rpb_cluster[cl].rpb_pfncount = kern_first_page - cons_pages;
7504997Sgblack@eecs.umich.edu  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