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