1/* $NetBSD: locore.s,v 1.118 2022/05/30 09:56:03 andvar Exp $ */ 2 3/* 4 * Copyright (c) 1988 University of Utah. 5 * Copyright (c) 1980, 1990, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * the Systems Programming Group of the University of Utah Computer 10 * Science Department. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * from: Utah $Hdr: locore.s 1.66 92/12/22$ 37 * 38 * @(#)locore.s 8.6 (Berkeley) 5/27/94 39 */ 40 41#include "opt_compat_netbsd.h" 42#include "opt_compat_sunos.h" 43#include "opt_fpsp.h" 44#include "opt_ddb.h" 45#include "opt_kgdb.h" 46#include "opt_lockdebug.h" 47#include "opt_m68k_arch.h" 48 49#include "assym.h" 50#include <machine/asm.h> 51#include <machine/trap.h> 52 53#include "ksyms.h" 54 55/* 56 * Temporary stack for a variety of purposes. 57 * Try and make this the first thing is the data segment so it 58 * is page aligned. Note that if we overflow here, we run into 59 * our text segment. 60 */ 61 .data 62 .space PAGE_SIZE 63ASLOCAL(tmpstk) 64 65ASLOCAL(bug_vbr) 66 .long 0 67 68#include <mvme68k/mvme68k/vectors.s> 69 70 71/* 72 * Macro to relocate a symbol, used before MMU is enabled. 73 */ 74#define _RELOC(var, ar) \ 75 lea var,ar 76 77#define RELOC(var, ar) _RELOC(_C_LABEL(var), ar) 78#define ASRELOC(var, ar) _RELOC(_ASM_LABEL(var), ar) 79 80/* 81 * Macro to call into the Bug ROM monitor 82 */ 83#define CALLBUG(func) \ 84 trap #15; .short func 85 86/* 87 * Initialization 88 * 89 * The bootstrap loader loads us in starting at 0, and VBR is non-zero. 90 * On entry, args on stack are boot device, boot filename, console unit, 91 * boot flags (howto), boot device name, filesystem type name. 92 */ 93BSS(lowram,4) 94BSS(esym,4) 95 96 .globl _C_LABEL(edata) 97 .globl _C_LABEL(etext),_C_LABEL(end) 98 99 100/* 101 * This is for kvm_mkdb, and should be the address of the beginning 102 * of the kernel text segment (not necessarily the same as kernbase). 103 */ 104 .text 105GLOBAL(kernel_text) 106 107/* 108 * start of kernel and .text! 109 */ 110ASENTRY_NOPROFILE(start) 111 movw #PSL_HIGHIPL,%sr | no interrupts 112 movl #0,%a5 | RAM starts at 0 (a5) 113 movl %sp@(4), %d7 | get boothowto 114 movl %sp@(8), %d6 | get bootaddr 115 movl %sp@(12),%d5 | get bootctrllun 116 movl %sp@(16),%d4 | get bootdevlun 117 movl %sp@(20),%d3 | get bootpart 118 movl %sp@(24),%d2 | get esyms 119 120 RELOC(bootpart,%a0) 121 movl %d3, %a0@ | save bootpart 122 RELOC(bootdevlun,%a0) 123 movl %d4, %a0@ | save bootdevlun 124 RELOC(bootctrllun,%a0) 125 movl %d5, %a0@ | save booctrllun 126 RELOC(bootaddr,%a0) 127 movl %d6, %a0@ | save bootaddr 128 RELOC(boothowto,%a0) 129 movl %d7, %a0@ | save boothowto 130 /* note: d3-d7 free, d2 still in use */ 131 132 ASRELOC(tmpstk, %a0) 133 movl %a0,%sp | give ourselves a temporary stack 134 135 RELOC(edata,%a0) | clear out BSS 136 movl #_C_LABEL(end) - 4, %d0 | (must be <= 256 kB) 137 subl #_C_LABEL(edata), %d0 138 lsrl #2,%d0 1391: clrl %a0@+ 140 dbra %d0,1b 141 142 RELOC(esym, %a0) 143 movl %d2,%a0@ | store end of symbol table 144 /* d2 now free */ 145 RELOC(lowram, %a0) 146 movl %a5,%a0@ | store start of physical memory 147 movl #CACHE_OFF,%d0 148 movc %d0,%cacr | clear and disable on-chip cache(s) 149 150 /* ask the Bug what we are... */ 151 clrl %sp@- 152 CALLBUG(MVMEPROM_GETBRDID) 153 movl %sp@+,%a1 154 155 /* copy to a struct mvmeprom_brdid */ 156 movl #MVMEPROM_BRDID_SIZE,%d0 157 RELOC(boardid,%a0) 1581: movb %a1@+,%a0@+ 159 subql #1,%d0 160 jbne 1b 161 162 /* 163 * Grab the model number from _boardid and use the value 164 * to setup machineid, cputype, and mmutype. 165 */ 166 clrl %d0 167 RELOC(boardid,%a1) 168 movw %a1@(MVMEPROM_BRDID_MODEL_OFFSET),%d0 169 RELOC(machineid,%a0) 170 movl %d0,%a0@ 171 172 ASRELOC(Lbrdid2mach,%a0) 173Lbrdmatch: 174 cmpw %a0@+,%d0 175 jbeq Lgotmatch 176 addw #0x12,%a0 | Each entry is 20-2 bytes long 177 tstw %a0@ 178 jbne Lbrdmatch 179 180 /* 181 * If we fall to here, the board is not supported. 182 * Print a warning, then drop out to the Bug. 183 */ 184 movl #Lenotconf,%sp@- 185 movl #Lnotconf,%sp@- 186 CALLBUG(MVMEPROM_OUTSTRCRLF) 187 addql #8,%sp | clean up stack after call 188 189 CALLBUG(MVMEPROM_EXIT) 190 /* NOTREACHED */ 191 192 .data 193Lnotconf: 194 .ascii "Sorry, the kernel isn't configured for this model." 195Lenotconf: 196 .even 197 198ASLOCAL(Lbrdid2mach) 199#ifdef MVME147 200 .word MVME_147 201 .word CPU_68030 202 .word MMU_68030 203 .word FPU_68882 204 .long _C_LABEL(busaddrerr2030) 205 .long _C_LABEL(busaddrerr2030) 206 .long Linit147 207#endif 208#ifdef MVME162 209 .word MVME_162 210 .word CPU_68040 211 .word MMU_68040 212 .word FPU_68040 213 .long _C_LABEL(buserr40) 214 .long _C_LABEL(addrerr4060) 215 .long Linit1x2 216#endif 217#ifdef MVME167 218 .word MVME_167 219 .word CPU_68040 220 .word MMU_68040 221 .word FPU_68040 222 .long _C_LABEL(buserr40) 223 .long _C_LABEL(addrerr4060) 224 .long Linit1x7 225#endif 226#ifdef MVME172 227 .word MVME_172 228 .word CPU_68060 229 .word MMU_68040 230 .word FPU_68060 231 .long _C_LABEL(buserr60) 232 .long _C_LABEL(addrerr4060) 233 .long Linit1x2 234#endif 235#ifdef MVME177 236 .word MVME_177 237 .word CPU_68060 238 .word MMU_68040 239 .word FPU_68060 240 .long _C_LABEL(buserr60) 241 .long _C_LABEL(addrerr4060) 242 .long Linit1x7 243#endif 244 .word 0 245 .text 246 .even 247 248/* 249 * We have a match, so the kernel should support this board. 250 * a0 points to the matching entry in Lbrdid2mach. 251 */ 252Lgotmatch: 253 movew %a0@+,%d1 | Copy the CPU type 254 extl %d1 255 RELOC(cputype,%a1) 256 movel %d1,%a1@ 257 movew %a0@+,%d1 | Copy the MMU type 258 extl %d1 259 RELOC(mmutype,%a1) 260 movel %d1,%a1@ 261 movew %a0@+,%d1 | Copy the FPU type 262 extl %d1 263 RELOC(fputype,%a1) 264 movel %d1,%a1@ 265 movel %a0@+,%a2 | Fetch the bus error vector 266 RELOC(vectab,%a1) 267 movl %a2,%a1@(8) 268 movel %a0@+,%a2 | Fetch the address error vector 269 movl %a2,%a1@(12) 270 movel %a0@,%a0 | Finally, the board-specific init code 271 jmp %a0@ 272 273 274#ifdef MVME147 275Linit147: 276 /* MVME-147 - 68030 CPU/MMU, 68882 FPU */ 277 /* XXXCDC SHUTUP 147 CALL */ 278 movb #0, 0xfffe1026 | serial interrupt off 279 movb #0, 0xfffe1018 | timer 1 off 280 movb #0, 0xfffe1028 | ethernet off 281 /* XXXCDC SHUTUP 147 CALL */ 282 283 /* Save our ethernet address */ 284 RELOC(mvme_ea, %a0) 285 lea 0xfffe0778,%a1 | XXXCDC -- HARDWIRED HEX 286 movb #0x08,%a0@+ 287 clrb %a0@+ 288 movb #0x3e,%a0@+ 289 movql #0x0f,%d0 290 andb %a1@+,%d0 291 orb #0x20,%d0 292 movb %d0,%a0@+ 293 movb %a1@+,%a0@+ 294 movb %a1@,%a0@ 295 296 /* 297 * Fix up the physical addresses of the MVME147's onboard 298 * I/O registers. 299 */ 300 RELOC(intiobase_phys, %a0); 301 movl #INTIOBASE147,%a0@ 302 RELOC(intiotop_phys, %a0); 303 movl #INTIOTOP147,%a0@ 304 305 /* initialise list of physical memory segments for pmap_bootstrap */ 306 RELOC(phys_seg_list, %a0) 307 movl %a5,%a0@ | phys_seg_list[0].ps_start 308 movl 0xfffe0774,%d1 | End + 1 of onboard memory 309 movl %d1,%a0@(4) | phys_seg_list[0].ps_end 310 clrl %a0@(8) | phys_seg_list[0].ps_startpage 311 312 /* offboard RAM */ 313 clrl %a0@(0x0c) | phys_seg_list[1].ps_start 314 movl #PAGE_SIZE-1,%d0 315 addl 0xfffe0764,%d0 | Start of offboard segment 316 andl #-PAGE_SIZE,%d0 | Round up to page boundary 317 jbeq Lsavmaxmem | Jump if none defined 318 movl #PAGE_SIZE,%d1 | Note: implicit '+1' 319 addl 0xfffe0768,%d1 | End of offboard segment 320 andl #-PAGE_SIZE,%d1 | Round up to page boundary 321 cmpl %d1,%d0 | Quick and dirty validity check 322 jbcs Loff_ok | Yup, looks good. 323 movel %a0@(4),%d1 | Just use onboard RAM otherwise 324 jbra Lsavmaxmem 325Loff_ok: 326 movl %d0,%a0@(0x0c) | phys_seg_list[1].ps_start 327 movl %d1,%a0@(0x10) | phys_seg_list[1].ps_end 328 clrl %a0@(0x14) | phys_seg_list[1].ps_startpage 329 330 /* 331 * Offboard RAM needs to be cleared to zero to initialise parity 332 * on most VMEbus RAM cards. Without this, some cards will buserr 333 * when first read. 334 */ 335 movel %d0,%a0 | offboard start address again. 336Lclearoff: 337 clrl %a0@+ | zap a word 338 cmpl %a0,%d1 | reached end? 339 jbne Lclearoff 340 341Lsavmaxmem: 342 moveq #PGSHIFT,%d2 343 lsrl %d2,%d1 | convert to page (click) number 344 RELOC(maxmem, %a0) 345 movl %d1,%a0@ | save as maxmem 346 jra Lstart1 347#endif 348 349#if defined(MVME162) || defined(MVME172) 350Linit1x2: 351 /* MVME-162 - 68040 CPU/MMU/FPU */ 352 /* MVME-172 - 68060 CPU/MMU/FPU */ 353 354 /* 355 * Verify the user has removed the GPIO#0 jumper... 356 */ 357 btst #0,0xfff4202d | Clear == jumper installed 358 jne 1f | Ok. 359 360 movl #Le1x2jump,%sp@- 361 movl #L1x2jump,%sp@- 362 CALLBUG(MVMEPROM_OUTSTRCRLF) 363 addql #8,%sp | clean up stack after call 364 365 CALLBUG(MVMEPROM_EXIT) 366 /* NOTREACHED */ 367 3681: 369 /* 370 * Determine if this board has a VMEchip2 371 */ 372 btst #1,0xfff4202e | VMEchip2 presence detect 373 jne 2f | Jump if it doesn't exist. 374 375 /* 376 * Disable all interrupts from VMEchip2. This is especially 377 * useful when the kernel doesn't have the VMEchip2 driver 378 * configured. If we didn't do this, then we're at the mercy 379 * of whatever VMEchip2 interrupts the ROM set up. For example, 380 * hitting the ABORT switch could kill the system... 381 */ 382 movl 0xfff40088,%d0 383 andl #0xff7fffff,%d0 | Clear 'MIEN' 384 movl %d0,0xfff40088 3852: 386 /* 387 * Determine how much onboard memory is installed 388 */ 389 movql #0x07,%d0 390 andb 0xfff42024,%d0 391 ASRELOC(Ldramsize1x2,%a0) 392 movl %a0@(%d0:w:4),%d1 | Lookup the size 393 jeq Lmemcquery | Assume a MEMC chip if this is zero. 394 jra Lis1xx_common 395 396 .data 397 .even 398 /* 399 * Table of DRAM register size values -> actual size in bytes 400 */ 401ASLOCAL(Ldramsize1x2) 402 .long 0x00100000 403 .long 0x00200000 404 .long 0x00000000 405 .long 0x00400000 406 .long 0x00400000 407 .long 0x00800000 408 .long 0x00000000 409 .long 0x01000000 410 411L1x2jump: 412 .ascii "You must remove the jumper from pins 15-16 of J22 (mvme162)" 413 .ascii "or pins 1-2\015\012" 414 .ascii "J11 (mvme162-LX) first! See NetBSD/mvme68k FAQ for details." 415Le1x2jump: 416 .even 417 418 .text 419#endif 420 421#if defined(MVME167) || defined(MVME177) 422Linit1x7: 423 /* MVME-167 - 68040 CPU/MMU/FPU */ 424 /* MVME-177 - 68060 CPU/MMU/FPU */ 425 426 /* 427 * Verify the user has removed the GPIO#0 jumper... 428 */ 429 movel #0x00000001,%d0 430 andl 0xfff40088,%d0 | Clear == jumper installed 431 jne 1f | Ok. 432 433 movl #Le1x7jump,%sp@- 434 movl #L1x7jump,%sp@- 435 CALLBUG(MVMEPROM_OUTSTRCRLF) 436 addql #8,%sp | clean up stack after call 437 438 CALLBUG(MVMEPROM_EXIT) 439 /* NOTREACHED */ 440 4411: 442 /* 443 * Disable all interrupts from VMEchip2. This is especially 444 * useful when the kernel doesn't have the VMEchip2 driver 445 * configured. If we didn't do this, then we're at the mercy 446 * of whatever VMEchip2 interrupts the ROM set up. For example, 447 * hitting the ABORT switch could kill the system... 448 */ 449 movl 0xfff40088,%d0 450 andl #0xff7fffff,%d0 | Clear 'MIEN' 451 movl %d0,0xfff40088 452 453 .data 454 .even 455L1x7jump: 456 .ascii "You must remove the jumper from pins 1-2 of J1!\015\012" 457 .ascii "See NetBSD/mvme68k FAQ for details." 458Le1x7jump: 459 .even 460 461 .text 462#endif 463 464#if defined(MVME162) || defined(MVME167) || defined(MVME172) || defined(MVME177) 465Lmemcquery: 466 /* 467 * Figure out the size of onboard DRAM by querying 468 * the memory controller ASIC(s) 469 */ 470 lea 0xfff43008,%a0 | MEMC040/MEMECC Controller #1 471 jbsr memc040read 472 movl %d0,%d1 473 474 lea 0xfff43108,%a0 | MEMC040/MEMECC Controller #2 475 jbsr memc040read 476 addl %d0,%d1 477 478Lis1xx_common: 479 /* Save our ethernet address */ 480 RELOC(mvme_ea, %a0) 481 lea 0xfffc1f2c,%a1 482 movb %a1@+,%a0@+ 483 movb %a1@+,%a0@+ 484 movb %a1@+,%a0@+ 485 movb %a1@+,%a0@+ 486 movb %a1@+,%a0@+ 487 movb %a1@,%a0@ 488 489 /* 490 * Fix up the physical addresses of the onboard 491 * I/O registers. 492 */ 493 RELOC(intiobase_phys, %a0); 494 movl #INTIOBASE1xx,%a0@ 495 RELOC(intiotop_phys, %a0); 496 movl #INTIOTOP1xx,%a0@ 497 498 /* 499 * Initialise first physical memory segment with onboard RAM details 500 */ 501 RELOC(phys_seg_list, %a0) 502 movl %a5,%a0@ | phys_seg_list[0].ps_start 503 movl %d1,%a0@(4) | phys_seg_list[0].ps_end 504 clrl %a0@(8) | phys_seg_list[0].ps_startpage 505 506 /* offboard RAM */ 507 clrl %a0@(0x0c) | phys_seg_list[1].ps_start 508 movl #PAGE_SIZE-1,%d0 509 addl 0xfffc0000,%d0 | Start of offboard segment 510 andl #-PAGE_SIZE,%d0 | Round up to page boundary 511 jbeq Ldone1xx | Jump if none defined 512 movl #PAGE_SIZE,%d1 | Note: implicit '+1' 513 addl 0xfffc0004,%d1 | End of offboard segment 514 andl #-PAGE_SIZE,%d1 | Round up to page boundary 515 cmpl %d1,%d0 | Quick and dirty validity check 516 jbcs Lramsave1xx | Yup, looks good. 517 movel %a0@(4),%d1 | Just use onboard RAM otherwise 518 jbra Ldone1xx 519 520Lramsave1xx: 521 movl %d0,%a0@(0x0c) | phys_seg_list[1].ps_start 522 movl %d1,%a0@(0x10) | phys_seg_list[1].ps_end 523 clrl %a0@(0x14) | phys_seg_list[1].ps_startpage 524 525 /* 526 * Offboard RAM needs to be cleared to zero to initialise parity 527 * on most VMEbus RAM cards. Without this, some cards will buserr 528 * when first read. 529 */ 530 movel %d0,%a0 | offboard start address again. 531Lramclr1xx: 532 clrl %a0@+ | zap a word 533 cmpl %a0,%d1 | reached end? 534 jbne Lramclr1xx 535 536Ldone1xx: 537 moveq #PGSHIFT,%d2 538 lsrl %d2,%d1 | convert to page (click) number 539 RELOC(maxmem, %a0) 540 movl %d1,%a0@ | save as maxmem 541 542 /* FALLTHROUGH to Lstart1 */ 543#endif 544 545 546Lstart1: 547/* initialize source/destination control registers for movs */ 548 moveq #FC_USERD,%d0 | user space 549 movc %d0,%sfc | as source 550 movc %d0,%dfc | and destination of transfers 551/* 552 * configure kernel and lwp0 VA space so we can get going 553 */ 554#if NKSYMS || defined(DDB) || defined(MODULAR) 555 RELOC(esym,%a0) | end of static kernel text/data syms 556 movl %a0@,%d2 557 jne Lstart2 558#endif 559 movl #_C_LABEL(end),%d2 | end of static kernel text/data 560Lstart2: 561 addl #PAGE_SIZE-1,%d2 562 andl #PG_FRAME,%d2 | round to a page 563 movl %d2,%a4 564 addl %a5,%a4 | convert to PA 565 pea %a5@ | firstpa 566 pea %a4@ | nextpa 567 RELOC(pmap_bootstrap,%a0) 568 jbsr %a0@ | pmap_bootstrap(firstpa, nextpa) 569 addql #8,%sp 570 571/* 572 * Enable the MMU. 573 * Since the kernel is mapped logical == physical, we just turn it on. 574 */ 575 RELOC(Sysseg_pa, %a0) | system segment table addr 576 movl %a0@,%d1 | read value (a PA) 577 RELOC(mmutype, %a0) 578 cmpl #MMU_68040,%a0@ | 68040? 579 jne Lmotommu1 | no, skip 580 .long 0x4e7b1807 | movc d1,srp 581 jra Lstploaddone 582Lmotommu1: 583 RELOC(protorp, %a0) 584 movl #0x80000202,%a0@ | nolimit + share global + 4 byte PTEs 585 movl %d1,%a0@(4) | + segtable address 586 pmove %a0@,%srp | load the supervisor root pointer 587 movl #0x80000002,%a0@ | reinit upper half for CRP loads 588Lstploaddone: 589 RELOC(mmutype, %a0) 590 cmpl #MMU_68040,%a0@ | 68040? 591 jne Lmotommu2 | no, skip 592 moveq #0,%d0 | ensure TT regs are disabled 593 .long 0x4e7b0004 | movc d0,itt0 594 .long 0x4e7b0005 | movc d0,itt1 595 .long 0x4e7b0006 | movc d0,dtt0 596 .long 0x4e7b0007 | movc d0,dtt1 597 .word 0xf4d8 | cinva bc 598 .word 0xf518 | pflusha 599 movl #0x8000,%d0 600 .long 0x4e7b0003 | movc d0,tc 601#ifdef M68060 602 RELOC(cputype, %a0) 603 cmpl #CPU_68060,%a0@ | 68060? 604 jne Lnot060cache 605 movl #1,%d0 606 .long 0x4e7b0808 | movcl d0,pcr 607 movl #0xa0808000,%d0 608 movc %d0,%cacr | enable store buffer, both caches 609 jmp Lenab1 610Lnot060cache: 611#endif 612 movl #0x80008000,%d0 613 movc %d0,%cacr | turn on both caches 614 jmp Lenab1 615Lmotommu2: 616 pflusha 617 movl #0x82c0aa00,%sp@- | value to load TC with 618 pmove %sp@,%tc | load it 619 620/* 621 * Should be running mapped from this point on 622 */ 623Lenab1: 624/* Point the CPU VBR at our vector table */ 625 movc %vbr,%d0 | Preserve Bug's VBR address 626 movl %d0,_ASM_LABEL(bug_vbr) 627 movl #_C_LABEL(vectab),%d0 | get our VBR address 628 movc %d0,%vbr 629 lea _ASM_LABEL(tmpstk),%sp | temporary stack 630/* call final pmap setup */ 631 jbsr _C_LABEL(pmap_bootstrap_finalize) 632/* set kernel stack, user SP */ 633 movl _C_LABEL(lwp0uarea),%a1 | get lwp0 uarea 634 lea %a1@(USPACE-4),%sp | set kernel stack to end of area 635 movl #USRSTACK-4,%a2 636 movl %a2,%usp | init user SP 637 tstl _C_LABEL(fputype) | Have an FPU? 638 jeq Lenab2 | No, skip. 639 clrl %a1@(PCB_FPCTX) | ensure null FP context 640 movl %a1,%sp@- 641 jbsr _C_LABEL(m68881_restore) | restore it (does not kill a1) 642 addql #4,%sp 643Lenab2: 644 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? 645 jeq Ltbia040 | yes, cache already on 646 pflusha 647 movl #CACHE_ON,%d0 648 movc %d0,%cacr | clear cache(s) 649 jra Lenab3 650Ltbia040: 651 .word 0xf518 652Lenab3: 653/* 654 * final setup for C code: 655 * Create a fake exception frame so that cpu_lwp_fork() can copy it. 656 * main() nevers returns; we exit to user mode from a forked process 657 * later on. 658 */ 659 jbsr _C_LABEL(mvme68k_init) | additional pre-main initialization 660 movw #PSL_LOWIPL,%sr | lower SPL 661 clrw %sp@- | vector offset/frame type 662 clrl %sp@- | PC - filled in by "execve" 663 movw #PSL_USER,%sp@- | in user mode 664 clrl %sp@- | stack adjust count and padding 665 lea %sp@(-64),%sp | construct space for D0-D7/A0-A7 666 lea _C_LABEL(lwp0),%a0 | save pointer to frame 667 movl %sp,%a0@(L_MD_REGS) | in lwp0.l_md.md_regs 668 669 jra _C_LABEL(main) | main() 670 671#if defined(MVME162) || defined(MVME167) || defined(MVME172) || defined(MVME177) 672/* 673 * Probe for a memory controller ASIC (MEMC040 or MEMECC) at the 674 * address in a0. If found, return the size in bytes of any RAM 675 * controlled by the ASIC in d0. Otherwise return zero. 676 */ 677ASLOCAL(memc040read) 678 moveml %d1-%d2/%a1-%a2,%sp@- | save scratch regs 679 movc %vbr,%d2 | Save vbr 680 RELOC(vectab,%a2) | Install our own vectab, temporarily 681 movc %a2,%vbr 682 ASRELOC(Lmemc040berr,%a1) | get address of bus error handler 683 movl %a2@(8),%sp@- | Save current bus error handler addr 684 movl %a1,%a2@(8) | Install our own handler 685 movl %sp,%d0 | Save current stack pointer value 686 movql #0x07,%d1 687 andb %a0@,%d1 | Access MEMC040/MEMECC 688 movl #0x400000,%d0 689 lsll %d1,%d0 | Convert to memory size, in bytes 690Lmemc040ret: 691 movc %d2,%vbr | Restore original vbr 692 movl %sp@+,%a2@(8) | Restore original bus error handler 693 moveml %sp@+,%d1-%d2/%a1-%a2 694 rts 695/* 696 * If the memory controller doesn't exist, we get a bus error trying 697 * to access a0@ above. Control passes here, where we flag 'no bytes', 698 * ditch the exception frame and return as normal. 699 */ 700Lmemc040berr: 701 movl %d0,%sp | Get rid of the exception frame 702 movql #0,%d0 | No ASIC at this location, then! 703 jbra Lmemc040ret | Done 704#endif 705 706/* 707 * Trap/interrupt vector routines 708 */ 709#include <m68k/m68k/trap_subr.s> 710 711/* 712 * Use common m68k bus error and address error handlers. 713 */ 714#include <m68k/m68k/busaddrerr.s> 715 716/* 717 * FP exceptions. 718 */ 719ENTRY_NOPROFILE(fpfline) 720#if defined(M68040) 721 cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU? 722 jne Lfp_unimp | no, skip FPSP 723 cmpw #0x202c,%sp@(6) | format type 2? 724 jne _C_LABEL(illinst) | no, not an FP emulation 725#ifdef FPSP 726 jmp _ASM_LABEL(fpsp_unimp) | yes, go handle it 727#else 728 clrl %sp@- | stack adjust count 729 moveml #0xFFFF,%sp@- | save registers 730 moveq #T_FPEMULD,%d0 | denote as FP emulation trap 731 jra _ASM_LABEL(fault) | do it 732#endif 733Lfp_unimp: 734#endif /* M68040 */ 735 jra _C_LABEL(illinst) 736 737ENTRY_NOPROFILE(fpunsupp) 738#if defined(M68040) 739 cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU? 740 jne Lfp_unsupp | No, skip FPSP 741#ifdef FPSP 742 jmp _ASM_LABEL(fpsp_unsupp) | yes, go handle it 743#else 744 clrl %sp@- | stack adjust count 745 moveml #0xFFFF,%sp@- | save registers 746 moveq #T_FPEMULD,%d0 | denote as FP emulation trap 747 jra _ASM_LABEL(fault) | do it 748#endif 749Lfp_unsupp: 750#endif /* M68040 */ 751 jra _C_LABEL(illinst) 752 753/* 754 * Handles all other FP coprocessor exceptions. 755 * Note that since some FP exceptions generate mid-instruction frames 756 * and may cause signal delivery, we need to test for stack adjustment 757 * after the trap call. 758 */ 759ENTRY_NOPROFILE(fpfault) 760 clrl %sp@- | stack adjust count 761 moveml #0xFFFF,%sp@- | save user registers 762 movl %usp,%a0 | and save 763 movl %a0,%sp@(FR_SP) | the user stack pointer 764 clrl %sp@- | no VA arg 765 movl _C_LABEL(curpcb),%a0 | current pcb 766 lea %a0@(PCB_FPCTX),%a0 | address of FP savearea 767 fsave %a0@ | save state 768#if defined(M68040) || defined(M68060) 769 /* always null state frame on 68040, 68060 */ 770 cmpl #FPU_68040,_C_LABEL(fputype) 771 jge Lfptnull 772#endif 773 tstb %a0@ | null state frame? 774 jeq Lfptnull | yes, safe 775 clrw %d0 | no, need to tweak BIU 776 movb %a0@(1),%d0 | get frame size 777 bset #3,%a0@(0,%d0:w) | set exc_pend bit of BIU 778Lfptnull: 779 fmovem %fpsr,%sp@- | push fpsr as code argument 780 frestore %a0@ | restore state 781 movl #T_FPERR,%sp@- | push type arg 782 jra _ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup 783 784 785/* 786 * Other exceptions only cause four and six word stack frame and require 787 * no post-trap stack adjustment. 788 */ 789 790ENTRY_NOPROFILE(badtrap) 791 moveml #0xC0C0,%sp@- | save scratch regs 792 movw %sp@(22),%sp@- | push exception vector info 793 clrw %sp@- 794 movl %sp@(22),%sp@- | and PC 795 jbsr _C_LABEL(straytrap) | report 796 addql #8,%sp | pop args 797 moveml %sp@+,#0x0303 | restore regs 798 jra _ASM_LABEL(rei) | all done 799 800ENTRY_NOPROFILE(trap0) 801 clrl %sp@- | stack adjust count 802 moveml #0xFFFF,%sp@- | save user registers 803 movl %usp,%a0 | save the user SP 804 movl %a0,%sp@(FR_SP) | in the savearea 805 movl %d0,%sp@- | push syscall number 806 jbsr _C_LABEL(syscall) | handle it 807 addql #4,%sp | pop syscall arg 808 tstl _C_LABEL(astpending) | AST pending? 809 jne Lrei1 | Yup, go deal with it. 810 movl %sp@(FR_SP),%a0 | grab and restore 811 movl %a0,%usp | user SP 812 moveml %sp@+,#0x7FFF | restore most registers 813 addql #8,%sp | pop SP and stack adjust 814 rte 815 816/* 817 * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD) 818 * cachectl(command, addr, length) 819 * command in d0, addr in a1, length in d1 820 */ 821ENTRY_NOPROFILE(trap12) 822 movl _C_LABEL(curlwp),%a0 823 movl %a0@(L_PROC),%sp@- | push current proc pointer 824 movl %d1,%sp@- | push length 825 movl %a1,%sp@- | push addr 826 movl %d0,%sp@- | push command 827 jbsr _C_LABEL(cachectl1) | do it 828 lea %sp@(16),%sp | pop args 829 jra _ASM_LABEL(rei) | all done 830 831/* 832 * Trace (single-step) trap. Kernel-mode is special. 833 * User mode traps are simply passed on to trap(). 834 */ 835ENTRY_NOPROFILE(trace) 836 clrl %sp@- | stack adjust count 837 moveml #0xFFFF,%sp@- 838 moveq #T_TRACE,%d0 839 840 | Check PSW and see what happen. 841 | T=0 S=0 (should not happen) 842 | T=1 S=0 trace trap from user mode 843 | T=0 S=1 trace trap on a trap instruction 844 | T=1 S=1 trace trap from system mode (kernel breakpoint) 845 846 movw %sp@(FR_HW),%d1 | get PSW 847 notw %d1 | XXX no support for T0 on 680[234]0 848 andw #PSL_TS,%d1 | from system mode (T=1, S=1)? 849 jeq Lkbrkpt | yes, kernel breakpoint 850 jra _ASM_LABEL(fault) | no, user-mode fault 851 852/* 853 * Trap 15 is used for: 854 * - GDB breakpoints (in user programs) 855 * - KGDB breakpoints (in the kernel) 856 * - trace traps for SUN binaries (not fully supported yet) 857 * User mode traps are simply passed to trap(). 858 */ 859ENTRY_NOPROFILE(trap15) 860 clrl %sp@- | stack adjust count 861 moveml #0xFFFF,%sp@- 862 moveq #T_TRAP15,%d0 863 movw %sp@(FR_HW),%d1 | get PSW 864 andw #PSL_S,%d1 | from system mode? 865 jne Lkbrkpt | yes, kernel breakpoint 866 jra _ASM_LABEL(fault) | no, user-mode fault 867 868Lkbrkpt: | Kernel-mode breakpoint or trace trap. (d0=trap_type) 869 | Save the system sp rather than the user sp. 870 movw #PSL_HIGHIPL,%sr | lock out interrupts 871 lea %sp@(FR_SIZE),%a6 | Save stack pointer 872 movl %a6,%sp@(FR_SP) | from before trap 873 874 | If were are not on tmpstk switch to it. 875 | (so debugger can change the stack pointer) 876 movl %a6,%d1 877 cmpl #_ASM_LABEL(tmpstk),%d1 878 jls Lbrkpt2 | already on tmpstk 879 | Copy frame to the temporary stack 880 movl %sp,%a0 | a0=src 881 lea _ASM_LABEL(tmpstk)-96,%a1 | a1=dst 882 movl %a1,%sp | sp=new frame 883 movql #FR_SIZE,%d1 884Lbrkpt1: 885 movl %a0@+,%a1@+ 886 subql #4,%d1 887 jbgt Lbrkpt1 888 889Lbrkpt2: 890 | Call the trap handler for the kernel debugger. 891 | Do not call trap() to do it, so that we can 892 | set breakpoints in trap() if we want. We know 893 | the trap type is either T_TRACE or T_BREAKPOINT. 894 | If we have both DDB and KGDB, let KGDB see it first, 895 | because KGDB will just return 0 if not connected. 896 | Save args in d2, a2 897 movl %d0,%d2 | trap type 898 movl %sp,%a2 | frame ptr 899#ifdef KGDB 900 | Let KGDB handle it (if connected) 901 movl %a2,%sp@- | push frame ptr 902 movl %d2,%sp@- | push trap type 903 jbsr _C_LABEL(kgdb_trap) | handle the trap 904 addql #8,%sp | pop args 905 cmpl #0,%d0 | did kgdb handle it? 906 jne Lbrkpt3 | yes, done 907#endif 908#ifdef DDB 909 | Let DDB handle it 910 movl %a2,%sp@- | push frame ptr 911 movl %d2,%sp@- | push trap type 912 jbsr _C_LABEL(kdb_trap) | handle the trap 913 addql #8,%sp | pop args 914#endif 915 /* Sun 3 drops into PROM here. */ 916Lbrkpt3: 917 | The stack pointer may have been modified, or 918 | data below it modified (by kgdb push call), 919 | so push the hardware frame at the current sp 920 | before restoring registers and returning. 921 922 movl %sp@(FR_SP),%a0 | modified sp 923 lea %sp@(FR_SIZE),%a1 | end of our frame 924 movl %a1@-,%a0@- | copy 2 longs with 925 movl %a1@-,%a0@- | ... predecrement 926 movl %a0,%sp@(FR_SP) | sp = h/w frame 927 moveml %sp@+,#0x7FFF | restore all but sp 928 movl %sp@,%sp | ... and sp 929 rte | all done 930 931/* 932 * Use common m68k sigreturn routine. 933 */ 934#include <m68k/m68k/sigreturn.s> 935 936/* 937 * Interrupt handlers. 938 * 939 * For auto-vectored interrupts, the CPU provides the 940 * vector 0x18+level. 941 * 942 * intrhand_autovec is the entry point for auto-vectored 943 * interrupts. 944 * 945 * For vectored interrupts, we pull the pc, evec, and exception frame 946 * and pass them to the vectored interrupt dispatcher. The vectored 947 * interrupt dispatcher will deal with strays. 948 * 949 * intrhand_vectored is the entry point for vectored interrupts. 950 */ 951 952ENTRY_NOPROFILE(intrhand_autovec) 953 addql #1,_C_LABEL(interrupt_depth) 954 INTERRUPT_SAVEREG 955 lea %sp@(16),%a1 | get pointer to frame 956 movl %a1,%sp@- 957 jbsr _C_LABEL(isrdispatch_autovec) | call dispatcher 958 addql #4,%sp 959 jbra Lintrhand_exit 960 961ENTRY_NOPROFILE(intrhand_vectored) 962 addql #1,_C_LABEL(interrupt_depth) 963 INTERRUPT_SAVEREG 964 lea %sp@(16),%a1 | get pointer to frame 965 movl %a1,%sp@- 966 movw %sr,%d0 967 bfextu %d0,21,3,%d0 | Get current ipl 968 movl %d0,%sp@- | Push it 969 jbsr _C_LABEL(isrdispatch_vectored) | call dispatcher 970 addql #8,%sp 971Lintrhand_exit: 972 INTERRUPT_RESTOREREG 973 subql #1,_C_LABEL(interrupt_depth) 974 975 /* FALLTHROUGH to rei */ 976 977/* 978 * Emulation of VAX REI instruction. 979 * 980 * This code deals with checking for and servicing ASTs 981 * (profiling, scheduling). 982 * After identifying that we need an AST we drop the IPL to allow device 983 * interrupts. 984 * 985 * This code is complicated by the fact that sendsig may have been called 986 * necessitating a stack cleanup. 987 */ 988ASENTRY_NOPROFILE(rei) 989 tstl _C_LABEL(astpending) | AST pending? 990 jeq Ldorte | Nope. Just return. 991 btst #5,%sp@ | Returning to kernel mode? 992 jne Ldorte | Yup. Can't do ASTs 993 movw #PSL_LOWIPL,%sr | lower SPL 994 clrl %sp@- | stack adjust 995 moveml #0xFFFF,%sp@- | save all registers 996 movl %usp,%a1 | including 997 movl %a1,%sp@(FR_SP) | the users SP 998Lrei1: clrl %sp@- | VA == none 999 clrl %sp@- | code == none 1000 movl #T_ASTFLT,%sp@- | type == async system trap 1001 pea %sp@(12) | fp == address of trap frame 1002 jbsr _C_LABEL(trap) | go handle it 1003 lea %sp@(16),%sp | pop value args 1004 movl %sp@(FR_SP),%a0 | restore user SP 1005 movl %a0,%usp | from save area 1006 movw %sp@(FR_ADJ),%d0 | need to adjust stack? 1007 jne Laststkadj | yes, go to it 1008 moveml %sp@+,#0x7FFF | no, restore most user regs 1009 addql #8,%sp | toss SP and stack adjust 1010Ldorte: rte | and do real RTE 1011 1012Laststkadj: 1013 lea %sp@(FR_HW),%a1 | pointer to HW frame 1014 addql #8,%a1 | source pointer 1015 movl %a1,%a0 | source 1016 addw %d0,%a0 | + hole size = dest pointer 1017 movl %a1@-,%a0@- | copy 1018 movl %a1@-,%a0@- | 8 bytes 1019 movl %a0,%sp@(FR_SP) | new SSP 1020 moveml %sp@+,#0x7FFF | restore user registers 1021 movl %sp@,%sp | and our SP 1022 rte | and do real RTE 1023 1024/* 1025 * Use common m68k sigcode. 1026 */ 1027#include <m68k/m68k/sigcode.s> 1028#ifdef COMPAT_SUNOS 1029#include <m68k/m68k/sunos_sigcode.s> 1030#endif 1031 1032/* 1033 * Primitives 1034 */ 1035 1036/* 1037 * Use common m68k support routines. 1038 */ 1039#include <m68k/m68k/support.s> 1040 1041/* 1042 * Use common m68k process/lwp switch and context save subroutines. 1043 */ 1044#define FPCOPROC /* XXX: Temp. Reqd. */ 1045#include <m68k/m68k/switch_subr.s> 1046 1047 1048#if defined(M68040) || defined(M68060) 1049ENTRY(suline) 1050 movl %sp@(4),%a0 | address to write 1051 movl _C_LABEL(curpcb),%a1 | current pcb 1052 movl #Lslerr,%a1@(PCB_ONFAULT) | where to return to on a fault 1053 movl %sp@(8),%a1 | address of line 1054 movl %a1@+,%d0 | get lword 1055 movsl %d0,%a0@+ | put lword 1056 nop | sync 1057 movl %a1@+,%d0 | get lword 1058 movsl %d0,%a0@+ | put lword 1059 nop | sync 1060 movl %a1@+,%d0 | get lword 1061 movsl %d0,%a0@+ | put lword 1062 nop | sync 1063 movl %a1@+,%d0 | get lword 1064 movsl %d0,%a0@+ | put lword 1065 nop | sync 1066 moveq #0,%d0 | indicate no fault 1067 jra Lsldone 1068Lslerr: 1069 moveq #-1,%d0 1070Lsldone: 1071 movl _C_LABEL(curpcb),%a1 | current pcb 1072 clrl %a1@(PCB_ONFAULT) | clear fault address 1073 rts 1074#endif 1075 1076 1077ENTRY(ecacheon) 1078 rts 1079 1080ENTRY(ecacheoff) 1081 rts 1082 1083/* 1084 * Get callers current SP value. 1085 * Note that simply taking the address of a local variable in a C function 1086 * doesn't work because callee saved registers may be outside the stack frame 1087 * defined by A6 (e.g. GCC generated code). 1088 */ 1089ENTRY_NOPROFILE(getsp) 1090 movl %sp,%d0 | get current SP 1091 addql #4,%d0 | compensate for return address 1092 movl %d0,%a0 1093 rts 1094 1095/* 1096 * Load a new user segment table pointer. 1097 */ 1098ENTRY(loadustp) 1099 movl %sp@(4),%d0 | new USTP 1100 moveq #PGSHIFT, %d1 1101 lsll %d1,%d0 | convert to addr 1102#if defined(M68040) || defined(M68060) 1103 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? 1104 jne LmotommuC | no, skip 1105 .word 0xf518 | pflusha 1106 .long 0x4e7b0806 | movc d0,urp 1107#ifdef M68060 1108 cmpl #CPU_68060,_C_LABEL(cputype) 1109 jne Lldno60 1110 movc %cacr,%d0 1111 orl #IC60_CUBC,%d0 | clear user branch cache entries 1112 movc %d0,%cacr 1113Lldno60: 1114#endif 1115 rts 1116LmotommuC: 1117#endif 1118 pflusha | flush entire TLB 1119 lea _C_LABEL(protorp),%a0 | CRP prototype 1120 movl %d0,%a0@(4) | stash USTP 1121 pmove %a0@,%crp | load root pointer 1122 movl #CACHE_CLR,%d0 1123 movc %d0,%cacr | invalidate cache(s) 1124 rts 1125 1126ENTRY(ploadw) 1127#ifdef M68030 1128#if defined(M68040) || defined(M68060) 1129 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? 1130 jeq Lploadwskp | yes, skip 1131#endif 1132 movl %sp@(4),%a0 | address to load 1133 ploadw #1,%a0@ | pre-load translation 1134Lploadwskp: 1135#endif 1136 rts 1137 1138ENTRY(getsr) 1139 moveq #0,%d0 1140 movw %sr,%d0 1141 rts 1142 1143/* 1144 * _delay(unsigned N) 1145 * 1146 * Delay for at least (N/1024) microseconds. 1147 * This routine depends on the variable: delay_divisor 1148 * which should be set based on the CPU clock rate. 1149 */ 1150ENTRY_NOPROFILE(_delay) 1151 | d0 = arg = (usecs << 10) 1152 movl %sp@(4),%d0 1153 | d1 = delay_divisor 1154 movl _C_LABEL(delay_divisor),%d1 1155 jra L_delay /* Jump into the loop! */ 1156 1157 /* 1158 * Align the branch target of the loop to a half-line (8-byte) 1159 * boundary to minimize cache effects. This guarantees both 1160 * that there will be no prefetch stalls due to cache line burst 1161 * operations and that the loop will run from a single cache 1162 * half-line. 1163 */ 1164#ifdef __ELF__ 1165 .align 8 1166#else 1167 .align 3 1168#endif 1169L_delay: 1170 subl %d1,%d0 1171 jgt L_delay 1172 rts 1173 1174/* 1175 * Handle the nitty-gritty of rebooting the machine. 1176 * Basically we just turn off the MMU, restore the Bug's initial VBR 1177 * and either return to Bug or jump through the ROM reset vector 1178 * depending on how the system was halted. 1179 */ 1180ENTRY_NOPROFILE(doboot) 1181 movw #PSL_HIGHIPL,%sr 1182 movl _C_LABEL(boothowto),%d1 | load howto 1183 movl %sp@(4),%d2 | arg 1184 movl _ASM_LABEL(bug_vbr),%d3 | Fetch Bug's original VBR value 1185 movl _C_LABEL(machineid),%d4 | What type of board is this? 1186 movl #CACHE_OFF,%d0 1187#if defined(M68040) || defined(M68060) 1188 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040/68060? 1189 jne Lnocache0 | no, skip 1190 .word 0xf4f8 | cpusha bc - push and invalidate caches 1191 nop 1192 movl #CACHE40_OFF,%d0 1193#endif 1194Lnocache0: 1195 movc %d0,%cacr | disable on-chip cache(s) 1196 1197#if defined(M68040) || defined(M68060) 1198 cmpl #MMU_68040,_C_LABEL(mmutype) 1199 jne LmotommuF 1200 movql #0,%d0 1201 movc %d0,%cacr 1202 .long 0x4e7b0003 | movc d0,tc 1203 jra Lbootcommon 1204LmotommuF: 1205#endif 1206 clrl %sp@- | value for pmove to TC (turn off MMU) 1207 pmove %sp@,%tc | disable MMU 1208 addql #4,%sp 1209 1210Lbootcommon: 1211 /* 1212 * MMU Switched off by now, so relocate all absolute references 1213 */ 1214 ASRELOC(tmpstk, %sp) | physical SP in case of NMI 1215 movc %d3,%vbr | Restore Bug's VBR 1216 andl #RB_SBOOT, %d1 | mask off 1217 jbne Lsboot | sboot? 1218 /* NOT sboot */ 1219 tstl %d2 | autoboot? 1220 jbeq Ldoreset | yes! 1221 CALLBUG(MVMEPROM_EXIT) | return to bug 1222 /* NOTREACHED */ 1223 1224Ldoreset: 1225 movl #0xff800000,%a0 | Bug's reset vector address 1226 movl %a0@+, %a7 | get SP 1227 movl %a0@, %a0 | get PC 1228 jmp %a0@ | go! 1229 1230Lsboot: /* sboot */ 1231 tstl %d2 | autoboot? 1232 jbeq 1f | yes! 1233 jmp 0x4000 | back to sboot 12341: jmp 0x400a | tell sboot to reboot us 1235 1236 1237/* 1238 * Misc. global variables. 1239 */ 1240 .data 1241 1242GLOBAL(machineid) 1243 .long MVME_147 | default to MVME_147 1244 1245GLOBAL(mmutype) 1246 .long MMU_68030 | default to MMU_68030 1247 1248GLOBAL(cputype) 1249 .long CPU_68030 | default to CPU_68030 1250 1251GLOBAL(fputype) 1252 .long FPU_68882 | default to FPU_68882 1253 1254GLOBAL(protorp) 1255 .long 0,0 | prototype root pointer 1256 1257/* 1258 * Information from first stage boot program 1259 */ 1260GLOBAL(bootpart) 1261 .long 0 1262GLOBAL(bootdevlun) 1263 .long 0 1264GLOBAL(bootctrllun) 1265 .long 0 1266GLOBAL(bootaddr) 1267 .long 0 1268 1269GLOBAL(intiobase) 1270 .long 0 | KVA of base of internal IO space 1271 1272GLOBAL(intiolimit) 1273 .long 0 | KVA of end of internal IO space 1274 1275GLOBAL(intiobase_phys) 1276 .long 0 | PA of board's I/O registers 1277 1278GLOBAL(intiotop_phys) 1279 .long 0 | PA of top of board's I/O registers 1280 1281/* 1282 * interrupt counters. 1283 * XXXSCW: Will go away soon; kept here to keep vmstat happy 1284 */ 1285GLOBAL(intrnames) 1286 .asciz "spur" 1287 .asciz "lev1" 1288 .asciz "lev2" 1289 .asciz "lev3" 1290 .asciz "lev4" 1291 .asciz "clock" 1292 .asciz "lev6" 1293 .asciz "nmi" 1294 .asciz "statclock" 1295GLOBAL(eintrnames) 1296 .even 1297 1298GLOBAL(intrcnt) 1299 .long 0,0,0,0,0,0,0,0,0 1300GLOBAL(eintrcnt) 1301