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