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