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