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