root/arch/sparc/kernel/head.S

/* [previous][next][first][last][top][bottom][index][help] */
   1 /* boot.S: The initial boot code for the Sparc port of Linux.
   2 
   3    Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
   4 
   5            This file has to serve three purposes.
   6 
   7            1) determine the prom-version and cpu/architecture
   8            2) print enough useful info before we start to execute
   9               c-code that I can possibly begin to debug things
  10            3) Hold the vector of trap entry points
  11 
  12    The Sparc offers many challenges to kernel design. Here I will
  13    document those I have come across thus far. Upon bootup the boot
  14    prom loads your a.out image into memory. This memory the prom has
  15    already mapped for you in two places, however as far as I can tell
  16    the virtual address cache is not turned on although the MMU is
  17    translating things. You get loaded at 0x4000 exactly and you are
  18    aliased to 0xf8004000 with the appropriate mmu entries. So, when
  19    you link a boot-loadable object you want to do something like:
  20 
  21         ld -e start -Ttext 4000 -o mykernel myobj1.o myobj2.o ....
  22 
  23    to produce a proper image.
  24 
  25    At boot time you are given (as far as I can tell at this time)
  26    one key to figure out what machine you are one and what devices
  27    are available. The prom when it loads you leaves a pointer to
  28    the 'rom vector' in register %o0 right before it jumps to your
  29    starting address. This is a pointer to a struct that is full of
  30    pointer to functions (ie. printf, halt, reboot), pointers to
  31    linked lists (ie. memory mappings), and pointer to empirical
  32    constants (ie. stdin and stdout magic cookies + rom version).
  33    Starting with this piece of information you can figure out 
  34    just about anything you want about the machine you are on.
  35 
  36    Although I don't use it now, if you are on a Multiprocessor and
  37    therefore a v3 or above prom, register %o2 at boot contains a
  38    function pointer you must call before you proceed to invoke the
  39    other cpu's on the machine. I have no idea what kind of magic this
  40    is, give me time.
  41 */
  42 
  43 #include <asm/head.h>
  44 #include <asm/version.h>
  45 #include <asm/asi.h>
  46 #include <asm/contregs.h>
  47 
  48         .data
  49 
  50 /* First thing to go in the data segment is the interrupt stack. */
  51 
  52         .globl  _intstack
  53         .globl  _eintstack
  54 _intstack:
  55         .skip   4 * PAGESIZE                ! 16k = 128 128-byte stack frames
  56 _eintstack:
  57 
  58 
  59 
  60 /* 
  61    The following are used with the prom_vector node-ops to figure out
  62    the cpu-type 
  63 */
  64 
  65         .globl  _cputyp
  66 
  67 _cputyp:
  68         .word   1
  69 
  70 _cputypval:
  71         .asciz "sun4c"
  72         .ascii "     "
  73 
  74 /*
  75  * Sun people can't spell worth damn. "compatability" indeed.
  76  * At least we *know* we can't spell, and use a spell-checker.
  77  */
  78 
  79 /* Uh, actually Linus it is I who cannot spell. Too much murky
  80  * Sparc assembly will does this to ya.
  81  */
  82 _cputypvar:
  83         .asciz "compatability"
  84 
  85 _cputypvallen = _cputypvar - _cputypval
  86 
  87 /* This hold the prom-interface-version number for either v0 or v2. */
  88 
  89         .align 4
  90         .globl  _prom_iface_vers
  91 
  92 _prom_iface_vers:       .skip 4
  93 
  94 /* WARNING: evil messages follow */
  95 
  96         .align 4
  97 
  98 sun4_notsup:
  99         .asciz  "Sparc-Linux: sun4 support not implemented yet\n\n"
 100         .align 4
 101 
 102 sun4m_notsup:
 103         .asciz  "Sparc-Linux: sun4m support does not exist\n\n"
 104         .align 4
 105 
 106 sun4d_notsup:
 107         .asciz  "Sparc-Linux: sun4d support does not exist\n\n"
 108         .align 4
 109 
 110 you_lose:
 111         .asciz  "You lose..... Thanks for playing...\n"
 112         .align 4
 113 
 114 
 115         .globl boot_msg
 116 
 117 /* memory descriptor property strings, v2 = yuk yuk yuk  */
 118 /* XXX how to figure out vm mapped by prom? May have to scan magic addresses */
 119 
 120 mem_prop_physavail:     .asciz "available"
 121 mem_prop_phystot:       .asciz "reg"
 122 
 123 /* v2_memory descriptor struct kludged here for assembly, if it ain't broke */
 124 
 125                 .align 4
 126 v2_mem_struct:  .skip 0xff
 127 
 128                         .align 4
 129 v2_printf_physavail:    .asciz "Physical Memory Available: 0x%x bytes"
 130 v2_printf_phystot:      .asciz "Physical Memory: 0x%x bytes"
 131 
 132 /* A place to store property strings returned from the prom 'node' funcs */
 133 
 134                         .align 4
 135 prop_string_buf:        .skip 32
 136 
 137 prop_name:      .asciz "name"
 138                 .align 4
 139 
 140 current_node:   .skip 4
 141                 .align 4
 142 
 143 
 144 /* nice little boot message */
 145 
 146 boot_msg:       
 147         .ascii "Booting Sparc-Linux V0.00PRE-ALPHA "
 148         .ascii WHO_COMPILED_ME 
 149         .asciz " \n"
 150         .align 4
 151 
 152         .globl boot_msg2
 153 
 154 boot_msg2:
 155         .asciz "Booting Sparclinux V0.00 PRE-ALPHA on a (SUN4C)\n\n"
 156 
 157         .align 4
 158 
 159 pstring1:
 160         .asciz "Prom Magic Cookie: 0x%x  "
 161         .align 4
 162 
 163 pstring2:
 164         .asciz "Interface Version: v%d\n"
 165         .align 4
 166 
 167 pstring3:
 168         .asciz "Prom Revision: V%d\n\n"
 169         .align 4
 170 
 171 pstring4:
 172         .ascii "Total Physical Memory: %d bytes\nVM mapped by Prom: %d bytes\n"
 173         .asciz "Available Physical Memory: %d bytes\n"
 174         .align 4
 175 
 176 
 177 newline:
 178         .asciz "\n"
 179         .align 4
 180 
 181         .text
 182 
 183         .globl  _msgbuf
 184 msgbufsize = PAGESIZE                       ! 1 page for msg buffer
 185 _msgbuf =  PAGESIZE
 186 
 187 
 188 IE_reg_addr = _msgbuf + msgbufsize      ! this page not used; points to IEreg
 189 
 190         
 191 /* Ok, things start to get interesting. We get linked such that 'start'
 192    is the entry symbol. However, it is real low in kernel address space
 193    and as such a nifty place to place the trap table. We achieve this goal
 194    by just jumping to 'dostart' for the first trap's entry as the sparc
 195    never receives the zero trap as it is real special (hw reset).
 196 
 197    Each trap entry point is the size of 4 sparc instructions (or 4 bytes
 198    * 4 insns = 16 bytes). There are 128 hardware traps (some undefined
 199    or unimplemented) and 128 software traps (sys-calls, etc.).
 200 
 201    One of the instructions must be a branch. More often than not this
 202    will be to a trap handler entry point because it is completely
 203    impossible to handle any trap in 4 insns. I welcome anyone to 
 204    challenge this theory. :-)
 205 
 206    On entry into this table the hardware has loaded the program counter
 207    at which the trap occurred into register %l1 and the next program
 208    counter into %l2, this way we can return from the trap with a simple
 209 
 210            jmp %l1; rett %l2  ! poof...
 211 
 212    after properly servicing the trap. It wouldn't be a bad idea to load
 213    some more information into the local regs since we have technically
 214    2 or 3 instructions to play with besides the jmp to the 'real' trap
 215    handler (one can even go in the delay slot). For now I am going to put
 216    the %psr (processor status register) and the trap-type value in %l0
 217    and %l3 respectively. Also, for IRQ's I'll put the level in %l4.
 218 
 219 */
 220 
 221         .globl  start
 222         .globl  _trapbase
 223 start:
 224 _trapbase:
 225         b gokernel; WRITE_PAUSE         ! we never get trap #0 it is special
 226 
 227         TRAP_ENTRY(0x1, my_trap_handler) /* Instruction Access Exception */
 228         TRAP_ENTRY(0x2, my_trap_handler) /* Illegal Instruction */
 229         TRAP_ENTRY(0x3, my_trap_handler) /* Privileged Instruction */
 230         TRAP_ENTRY(0x4, my_trap_handler) /* Floating Point Disabled */
 231         TRAP_ENTRY(0x5, spill_window_entry) /* Window Overflow */
 232         TRAP_ENTRY(0x6, fill_window_entry)  /* Window Underflow */
 233         TRAP_ENTRY(0x7, my_trap_handler) /* Memory Address Not Aligned */
 234         TRAP_ENTRY(0x8, my_trap_handler) /* Floating Point Exception */
 235         TRAP_ENTRY(0x9, my_trap_handler) /* Data Miss Exception */
 236         TRAP_ENTRY(0xa, my_trap_handler) /* Tagged Instruction Overflow */
 237         TRAP_ENTRY(0xb, my_trap_handler) /* Watchpoint Detected */
 238         TRAP_ENTRY(0xc, my_trap_handler) /* Undefined... */
 239         TRAP_ENTRY(0xd, my_trap_handler) /* Undefined... */
 240         TRAP_ENTRY(0xe, my_trap_handler) /* Undefined... */
 241         TRAP_ENTRY(0xf, my_trap_handler) /* Undefined... */
 242         TRAP_ENTRY(0x10, my_trap_handler) /* Undefined... */
 243 
 244 /* Level'd interrupt entry points, see macro defs above */
 245 
 246         TRAP_ENTRY_INTERRUPT_SOFT(1, 0x101) /* Interrupt Level 1  */
 247         TRAP_ENTRY_INTERRUPT(2)             /* Interrupt Level 2  */
 248         TRAP_ENTRY_INTERRUPT(3)             /* Interrupt Level 3  */
 249         TRAP_ENTRY_INTERRUPT_SOFT(4, 0x104) /* Interrupt Level 4  */
 250         TRAP_ENTRY_INTERRUPT(5)             /* Interrupt Level 5  */
 251         TRAP_ENTRY_INTERRUPT_SOFT(6, 0x106) /* Interrupt Level 6  */
 252         TRAP_ENTRY_INTERRUPT(7)             /* Interrupt Level 7  */
 253         TRAP_ENTRY_INTERRUPT(8)             /* Interrupt Level 8  */
 254         TRAP_ENTRY_INTERRUPT(9)             /* Interrupt Level 9  */
 255         TRAP_ENTRY_INTERRUPT(10)            /* Interrupt Level 10 */
 256         TRAP_ENTRY_INTERRUPT(11)            /* Interrupt Level 11 */
 257         TRAP_ENTRY_INTERRUPT(12)            /* Interrupt Level 12 */
 258         TRAP_ENTRY_INTERRUPT(13)            /* Interrupt Level 13 */
 259         TRAP_ENTRY_INTERRUPT(14)            /* Interrupt Level 14 */
 260         TRAP_ENTRY_INTERRUPT_NMI(15, linux_trap_nmi) /* Level 15 (nmi) */
 261 
 262         TRAP_ENTRY(0x20, my_trap_handler)   /* General Register Access Error */
 263         TRAP_ENTRY(0x21, my_trap_handler)   /* Instruction Access Error      */
 264         TRAP_ENTRY(0x22, my_trap_handler)   /* Undefined...                  */
 265         TRAP_ENTRY(0x23, my_trap_handler)   /* Undefined...                  */
 266         TRAP_ENTRY(0x24, my_trap_handler)   /* Co-Processor Disabled         */
 267         TRAP_ENTRY(0x25, my_trap_handler)   /* Unimplemented FLUSH inst.     */
 268         TRAP_ENTRY(0x26, my_trap_handler)   /* Undefined...                  */
 269         TRAP_ENTRY(0x27, my_trap_handler)   /* Undefined...                  */
 270         TRAP_ENTRY(0x28, my_trap_handler)   /* Co-Processor Exception        */
 271         TRAP_ENTRY(0x29, my_trap_handler)   /* Data Access Error             */
 272         TRAP_ENTRY(0x2a, my_trap_handler)   /* Division by zero, you lose... */
 273         TRAP_ENTRY(0x2b, my_trap_handler)   /* Data Store Error              */
 274         TRAP_ENTRY(0x2c, my_trap_handler)   /* Data Access MMU-Miss          */
 275         TRAP_ENTRY(0x2d, my_trap_handler)   /* Undefined...                  */
 276         TRAP_ENTRY(0x2e, my_trap_handler)   /* Undefined...                  */
 277         TRAP_ENTRY(0x2f, my_trap_handler)   /* Undefined...                  */
 278         TRAP_ENTRY(0x30, my_trap_handler)   /* Undefined...                  */
 279         TRAP_ENTRY(0x31, my_trap_handler)   /* Undefined...                  */
 280         TRAP_ENTRY(0x32, my_trap_handler)   /* Undefined...                  */
 281         TRAP_ENTRY(0x33, my_trap_handler)   /* Undefined...                  */
 282         TRAP_ENTRY(0x34, my_trap_handler)   /* Undefined...                  */
 283         TRAP_ENTRY(0x35, my_trap_handler)   /* Undefined...                  */
 284         TRAP_ENTRY(0x36, my_trap_handler)   /* Undefined...                  */
 285         TRAP_ENTRY(0x37, my_trap_handler)   /* Undefined...                  */
 286         TRAP_ENTRY(0x38, my_trap_handler)   /* Undefined...                  */
 287         TRAP_ENTRY(0x39, my_trap_handler)   /* Undefined...                  */
 288         TRAP_ENTRY(0x3a, my_trap_handler)   /* Undefined...                  */
 289         TRAP_ENTRY(0x3b, my_trap_handler)   /* Undefined...                  */
 290         TRAP_ENTRY(0x3c, my_trap_handler)   /* Instruction Access MMU-Miss   */
 291         TRAP_ENTRY(0x3d, my_trap_handler)   /* Undefined...                  */
 292         TRAP_ENTRY(0x3e, my_trap_handler)   /* Undefined...                  */
 293         TRAP_ENTRY(0x3f, my_trap_handler)   /* Undefined...                  */
 294         TRAP_ENTRY(0x40, my_trap_handler)   /* Undefined...                  */
 295         TRAP_ENTRY(0x41, my_trap_handler)   /* Undefined...                  */
 296         TRAP_ENTRY(0x42, my_trap_handler)   /* Undefined...                  */
 297         TRAP_ENTRY(0x43, my_trap_handler)   /* Undefined...                  */
 298         TRAP_ENTRY(0x44, my_trap_handler)   /* Undefined...                  */
 299         TRAP_ENTRY(0x45, my_trap_handler)   /* Undefined...                  */
 300         TRAP_ENTRY(0x46, my_trap_handler)   /* Undefined...                  */
 301         TRAP_ENTRY(0x47, my_trap_handler)   /* Undefined...                  */
 302         TRAP_ENTRY(0x48, my_trap_handler)   /* Undefined...                  */
 303         TRAP_ENTRY(0x49, my_trap_handler)   /* Undefined...                  */
 304         TRAP_ENTRY(0x4a, my_trap_handler)   /* Undefined...                  */
 305         TRAP_ENTRY(0x4b, my_trap_handler)   /* Undefined...                  */
 306         TRAP_ENTRY(0x4c, my_trap_handler)   /* Undefined...                  */
 307         TRAP_ENTRY(0x4d, my_trap_handler)   /* Undefined...                  */
 308         TRAP_ENTRY(0x4e, my_trap_handler)   /* Undefined...                  */
 309         TRAP_ENTRY(0x4f, my_trap_handler)   /* Undefined...                  */
 310         TRAP_ENTRY(0x50, my_trap_handler)   /* Undefined...                  */
 311         TRAP_ENTRY(0x51, my_trap_handler)   /* Undefined...                  */
 312         TRAP_ENTRY(0x52, my_trap_handler)   /* Undefined...                  */
 313         TRAP_ENTRY(0x53, my_trap_handler)   /* Undefined...                  */
 314         TRAP_ENTRY(0x54, my_trap_handler)   /* Undefined...                  */
 315         TRAP_ENTRY(0x55, my_trap_handler)   /* Undefined...                  */
 316         TRAP_ENTRY(0x56, my_trap_handler)   /* Undefined...                  */
 317         TRAP_ENTRY(0x57, my_trap_handler)   /* Undefined...                  */
 318         TRAP_ENTRY(0x58, my_trap_handler)   /* Undefined...                  */
 319         TRAP_ENTRY(0x59, my_trap_handler)   /* Undefined...                  */
 320         TRAP_ENTRY(0x5a, my_trap_handler)   /* Undefined...                  */
 321         TRAP_ENTRY(0x5b, my_trap_handler)   /* Undefined...                  */
 322         TRAP_ENTRY(0x5c, my_trap_handler)   /* Undefined...                  */
 323         TRAP_ENTRY(0x5d, my_trap_handler)   /* Undefined...                  */
 324         TRAP_ENTRY(0x5e, my_trap_handler)   /* Undefined...                  */
 325         TRAP_ENTRY(0x5f, my_trap_handler)   /* Undefined...                  */
 326         TRAP_ENTRY(0x60, my_trap_handler)   /* Impl-Dep Exception            */
 327         TRAP_ENTRY(0x61, my_trap_handler)   /* Impl-Dep Exception            */
 328         TRAP_ENTRY(0x62, my_trap_handler)   /* Impl-Dep Exception            */
 329         TRAP_ENTRY(0x63, my_trap_handler)   /* Impl-Dep Exception            */
 330         TRAP_ENTRY(0x64, my_trap_handler)   /* Impl-Dep Exception            */
 331         TRAP_ENTRY(0x65, my_trap_handler)   /* Impl-Dep Exception            */
 332         TRAP_ENTRY(0x66, my_trap_handler)   /* Impl-Dep Exception            */
 333         TRAP_ENTRY(0x67, my_trap_handler)   /* Impl-Dep Exception            */
 334         TRAP_ENTRY(0x68, my_trap_handler)   /* Impl-Dep Exception            */
 335         TRAP_ENTRY(0x69, my_trap_handler)   /* Impl-Dep Exception            */
 336         TRAP_ENTRY(0x6a, my_trap_handler)   /* Impl-Dep Exception            */
 337         TRAP_ENTRY(0x6b, my_trap_handler)   /* Impl-Dep Exception            */
 338         TRAP_ENTRY(0x6c, my_trap_handler)   /* Impl-Dep Exception            */
 339         TRAP_ENTRY(0x6d, my_trap_handler)   /* Impl-Dep Exception            */
 340         TRAP_ENTRY(0x6e, my_trap_handler)   /* Impl-Dep Exception            */
 341         TRAP_ENTRY(0x6f, my_trap_handler)   /* Impl-Dep Exception            */
 342         TRAP_ENTRY(0x70, my_trap_handler)   /* Impl-Dep Exception            */
 343         TRAP_ENTRY(0x71, my_trap_handler)   /* Impl-Dep Exception            */
 344         TRAP_ENTRY(0x72, my_trap_handler)   /* Impl-Dep Exception            */
 345         TRAP_ENTRY(0x73, my_trap_handler)   /* Impl-Dep Exception            */
 346         TRAP_ENTRY(0x74, my_trap_handler)   /* Impl-Dep Exception            */
 347         TRAP_ENTRY(0x75, my_trap_handler)   /* Impl-Dep Exception            */
 348         TRAP_ENTRY(0x76, my_trap_handler)   /* Impl-Dep Exception            */
 349         TRAP_ENTRY(0x77, my_trap_handler)   /* Impl-Dep Exception            */
 350         TRAP_ENTRY(0x78, my_trap_handler)   /* Impl-Dep Exception            */
 351         TRAP_ENTRY(0x79, my_trap_handler)   /* Impl-Dep Exception            */
 352         TRAP_ENTRY(0x7a, my_trap_handler)   /* Impl-Dep Exception            */
 353         TRAP_ENTRY(0x7b, my_trap_handler)   /* Impl-Dep Exception            */
 354         TRAP_ENTRY(0x7c, my_trap_handler)   /* Impl-Dep Exception            */
 355         TRAP_ENTRY(0x7d, my_trap_handler)   /* Impl-Dep Exception            */
 356         TRAP_ENTRY(0x7e, my_trap_handler)   /* Impl-Dep Exception            */
 357         TRAP_ENTRY(0x7f, my_trap_handler)   /* Impl-Dep Exception            */
 358         TRAP_ENTRY(0x80, my_trap_handler)   /* SunOS System Call             */
 359         TRAP_ENTRY(0x81, my_trap_handler)   /* Software Trap                 */
 360         TRAP_ENTRY(0x82, my_trap_handler)   /* Divide by zero trap XXX       */
 361         TRAP_ENTRY(0x83, my_trap_handler)   /* Flush Windows Trap XXX        */
 362         TRAP_ENTRY(0x84, my_trap_handler)   /* Clean Windows Trap XXX        */
 363         TRAP_ENTRY(0x85, my_trap_handler)   /* Software Trap                 */
 364         TRAP_ENTRY(0x86, my_trap_handler)   /* Fix Unaligned Access Trap XXX */
 365         TRAP_ENTRY(0x87, my_trap_handler)   /* Integer Overflow Trap XXX     */
 366         TRAP_ENTRY(0x88, my_trap_handler)   /* Software Trap                 */
 367         TRAP_ENTRY(0x89, my_trap_handler)   /* NetBSD System Call            */
 368         TRAP_ENTRY(0x8a, my_trap_handler)   /* Software Trap                 */
 369         TRAP_ENTRY(0x8b, my_trap_handler)   /* Software Trap                 */
 370         TRAP_ENTRY(0x8c, my_trap_handler)   /* Software Trap                 */
 371         TRAP_ENTRY(0x8d, my_trap_handler)   /* Software Trap                 */
 372         TRAP_ENTRY(0x8e, my_trap_handler)   /* Software Trap                 */
 373         TRAP_ENTRY(0x8f, my_trap_handler)   /* Software Trap                 */
 374         TRAP_ENTRY(0x90, my_trap_handler)   /* SparcLinux System Call        */
 375         TRAP_ENTRY(0x91, my_trap_handler)   /* Software Trap                 */
 376         TRAP_ENTRY(0x92, my_trap_handler)   /* Software Trap                 */
 377         TRAP_ENTRY(0x93, my_trap_handler)   /* Software Trap                 */
 378         TRAP_ENTRY(0x94, my_trap_handler)   /* Software Trap                 */
 379         TRAP_ENTRY(0x95, my_trap_handler)   /* Software Trap                 */
 380         TRAP_ENTRY(0x96, my_trap_handler)   /* Software Trap                 */
 381         TRAP_ENTRY(0x97, my_trap_handler)   /* Software Trap                 */
 382         TRAP_ENTRY(0x98, my_trap_handler)   /* Software Trap                 */
 383         TRAP_ENTRY(0x99, my_trap_handler)   /* Software Trap                 */
 384         TRAP_ENTRY(0x9a, my_trap_handler)   /* Software Trap                 */
 385         TRAP_ENTRY(0x9b, my_trap_handler)   /* Software Trap                 */
 386         TRAP_ENTRY(0x9c, my_trap_handler)   /* Software Trap                 */
 387         TRAP_ENTRY(0x9d, my_trap_handler)   /* Software Trap                 */
 388         TRAP_ENTRY(0x9e, my_trap_handler)   /* Software Trap                 */
 389         TRAP_ENTRY(0x9f, my_trap_handler)   /* Software Trap                 */
 390         TRAP_ENTRY(0xa0, my_trap_handler)   /* Software Trap                 */
 391         TRAP_ENTRY(0xa1, my_trap_handler)   /* Software Trap                 */
 392         TRAP_ENTRY(0xa2, my_trap_handler)   /* Software Trap                 */
 393         TRAP_ENTRY(0xa3, my_trap_handler)   /* Software Trap                 */
 394         TRAP_ENTRY(0xa4, my_trap_handler)   /* Software Trap                 */
 395         TRAP_ENTRY(0xa5, my_trap_handler)   /* Software Trap                 */
 396         TRAP_ENTRY(0xa6, my_trap_handler)   /* Software Trap                 */
 397         TRAP_ENTRY(0xa7, my_trap_handler)   /* Software Trap                 */
 398         TRAP_ENTRY(0xa8, my_trap_handler)   /* Software Trap                 */
 399         TRAP_ENTRY(0xa9, my_trap_handler)   /* Software Trap                 */
 400         TRAP_ENTRY(0xaa, my_trap_handler)   /* Software Trap                 */
 401         TRAP_ENTRY(0xab, my_trap_handler)   /* Software Trap                 */
 402         TRAP_ENTRY(0xac, my_trap_handler)   /* Software Trap                 */
 403         TRAP_ENTRY(0xad, my_trap_handler)   /* Software Trap                 */
 404         TRAP_ENTRY(0xae, my_trap_handler)   /* Software Trap                 */
 405         TRAP_ENTRY(0xaf, my_trap_handler)   /* Software Trap                 */
 406         TRAP_ENTRY(0xb0, my_trap_handler)   /* Software Trap                 */
 407         TRAP_ENTRY(0xb1, my_trap_handler)   /* Software Trap                 */
 408         TRAP_ENTRY(0xb2, my_trap_handler)   /* Software Trap                 */
 409         TRAP_ENTRY(0xb3, my_trap_handler)   /* Software Trap                 */
 410         TRAP_ENTRY(0xb4, my_trap_handler)   /* Software Trap                 */
 411         TRAP_ENTRY(0xb5, my_trap_handler)   /* Software Trap                 */
 412         TRAP_ENTRY(0xb6, my_trap_handler)   /* Software Trap                 */
 413         TRAP_ENTRY(0xb7, my_trap_handler)   /* Software Trap                 */
 414         TRAP_ENTRY(0xb8, my_trap_handler)   /* Software Trap                 */
 415         TRAP_ENTRY(0xb9, my_trap_handler)   /* Software Trap                 */
 416         TRAP_ENTRY(0xba, my_trap_handler)   /* Software Trap                 */
 417         TRAP_ENTRY(0xbb, my_trap_handler)   /* Software Trap                 */
 418         TRAP_ENTRY(0xbc, my_trap_handler)   /* Software Trap                 */
 419         TRAP_ENTRY(0xbd, my_trap_handler)   /* Software Trap                 */
 420         TRAP_ENTRY(0xbe, my_trap_handler)   /* Software Trap                 */
 421         TRAP_ENTRY(0xbf, my_trap_handler)   /* Software Trap                 */
 422         TRAP_ENTRY(0xc0, my_trap_handler)   /* Software Trap                 */
 423         TRAP_ENTRY(0xc1, my_trap_handler)   /* Software Trap                 */
 424         TRAP_ENTRY(0xc2, my_trap_handler)   /* Software Trap                 */
 425         TRAP_ENTRY(0xc3, my_trap_handler)   /* Software Trap                 */
 426         TRAP_ENTRY(0xc4, my_trap_handler)   /* Software Trap                 */
 427         TRAP_ENTRY(0xc5, my_trap_handler)   /* Software Trap                 */
 428         TRAP_ENTRY(0xc6, my_trap_handler)   /* Software Trap                 */
 429         TRAP_ENTRY(0xc7, my_trap_handler)   /* Software Trap                 */
 430         TRAP_ENTRY(0xc8, my_trap_handler)   /* Software Trap                 */
 431         TRAP_ENTRY(0xc9, my_trap_handler)   /* Software Trap                 */
 432         TRAP_ENTRY(0xca, my_trap_handler)   /* Software Trap                 */
 433         TRAP_ENTRY(0xcb, my_trap_handler)   /* Software Trap                 */
 434         TRAP_ENTRY(0xcc, my_trap_handler)   /* Software Trap                 */
 435         TRAP_ENTRY(0xcd, my_trap_handler)   /* Software Trap                 */
 436         TRAP_ENTRY(0xce, my_trap_handler)   /* Software Trap                 */
 437         TRAP_ENTRY(0xcf, my_trap_handler)   /* Software Trap                 */
 438         TRAP_ENTRY(0xd0, my_trap_handler)   /* Software Trap                 */
 439         TRAP_ENTRY(0xd1, my_trap_handler)   /* Software Trap                 */
 440         TRAP_ENTRY(0xd2, my_trap_handler)   /* Software Trap                 */
 441         TRAP_ENTRY(0xd3, my_trap_handler)   /* Software Trap                 */
 442         TRAP_ENTRY(0xd4, my_trap_handler)   /* Software Trap                 */
 443         TRAP_ENTRY(0xd5, my_trap_handler)   /* Software Trap                 */
 444         TRAP_ENTRY(0xd6, my_trap_handler)   /* Software Trap                 */
 445         TRAP_ENTRY(0xd7, my_trap_handler)   /* Software Trap                 */
 446         TRAP_ENTRY(0xd8, my_trap_handler)   /* Software Trap                 */
 447         TRAP_ENTRY(0xd9, my_trap_handler)   /* Software Trap                 */
 448         TRAP_ENTRY(0xda, my_trap_handler)   /* Software Trap                 */
 449         TRAP_ENTRY(0xdb, my_trap_handler)   /* Software Trap                 */
 450         TRAP_ENTRY(0xdc, my_trap_handler)   /* Software Trap                 */
 451         TRAP_ENTRY(0xdd, my_trap_handler)   /* Software Trap                 */
 452         TRAP_ENTRY(0xde, my_trap_handler)   /* Software Trap                 */
 453         TRAP_ENTRY(0xdf, my_trap_handler)   /* Software Trap                 */
 454         TRAP_ENTRY(0xe0, my_trap_handler)   /* Software Trap                 */
 455         TRAP_ENTRY(0xe1, my_trap_handler)   /* Software Trap                 */
 456         TRAP_ENTRY(0xe2, my_trap_handler)   /* Software Trap                 */
 457         TRAP_ENTRY(0xe3, my_trap_handler)   /* Software Trap                 */
 458         TRAP_ENTRY(0xe4, my_trap_handler)   /* Software Trap                 */
 459         TRAP_ENTRY(0xe5, my_trap_handler)   /* Software Trap                 */
 460         TRAP_ENTRY(0xe6, my_trap_handler)   /* Software Trap                 */
 461         TRAP_ENTRY(0xe7, my_trap_handler)   /* Software Trap                 */
 462         TRAP_ENTRY(0xe8, my_trap_handler)   /* Software Trap                 */
 463         TRAP_ENTRY(0xe9, my_trap_handler)   /* Software Trap                 */
 464         TRAP_ENTRY(0xea, my_trap_handler)   /* Software Trap                 */
 465         TRAP_ENTRY(0xeb, my_trap_handler)   /* Software Trap                 */
 466         TRAP_ENTRY(0xec, my_trap_handler)   /* Software Trap                 */
 467         TRAP_ENTRY(0xed, my_trap_handler)   /* Software Trap                 */
 468         TRAP_ENTRY(0xee, my_trap_handler)   /* Software Trap                 */
 469         TRAP_ENTRY(0xef, my_trap_handler)   /* Software Trap                 */
 470         TRAP_ENTRY(0xf0, my_trap_handler)   /* Software Trap                 */
 471         TRAP_ENTRY(0xf1, my_trap_handler)   /* Software Trap                 */
 472         TRAP_ENTRY(0xf2, my_trap_handler)   /* Software Trap                 */
 473         TRAP_ENTRY(0xf3, my_trap_handler)   /* Software Trap                 */
 474         TRAP_ENTRY(0xf4, my_trap_handler)   /* Software Trap                 */
 475         TRAP_ENTRY(0xf5, my_trap_handler)   /* Software Trap                 */
 476         TRAP_ENTRY(0xf6, my_trap_handler)   /* Software Trap                 */
 477         TRAP_ENTRY(0xf7, my_trap_handler)   /* Software Trap                 */
 478         TRAP_ENTRY(0xf8, my_trap_handler)   /* Software Trap                 */
 479         TRAP_ENTRY(0xf9, my_trap_handler)   /* Software Trap                 */
 480         TRAP_ENTRY(0xfa, my_trap_handler)   /* Software Trap                 */
 481         TRAP_ENTRY(0xfb, my_trap_handler)   /* Software Trap                 */
 482         TRAP_ENTRY(0xfc, my_trap_handler)   /* Software Trap                 */
 483         TRAP_ENTRY(0xfd, my_trap_handler)   /* Software Trap                 */
 484         TRAP_ENTRY(0xfe, my_trap_handler)   /* Software Trap                 */
 485         TRAP_ENTRY(0xff, my_trap_handler)   /* Software Trap                 */ 
 486 
 487 _msgbufmapped:
 488         .word   1
 489 
 490 
 491 
 492 /* Cool, here we go. Pick up the romvec pointer in %o0 and stash it in
 493    %g7 and at _prom_vector_p. And also quickly check whether we are on
 494    a v0 or v2 prom.
 495 */
 496 
 497 gokernel:       mov     %o0, %g7
 498                 st      %o0, [_prom_vector_p]   ! we will need it later
 499                 rd      %psr, %l2
 500                 rd      %wim, %l3
 501                 rd      %tbr, %l4
 502                 or      %g0, %o2, %l5           ! could be prom magic value...
 503         
 504 #if 0 /* You think I'm nutz? */
 505                 cmp     %l5, 0x0                ! check for magic SMP pointer
 506                 bne     nosmp   
 507                 nop
 508                 call    %o2                     ! call smp prom setup 
 509                 nop
 510 #endif /* I will be soon... */
 511 
 512 /* Acquire boot time privileged register values, this will help debugging.
 513  * I figure out and store nwindows later on.
 514  */
 515 
 516 nosmp:          sethi   %hi(_boot_psr), %l1
 517                 st      %l2, [%l1 + %lo(_boot_psr)]
 518                 sethi   %hi(_boot_wim), %l1
 519                 st      %l3, [%l1 + %lo(_boot_wim)]
 520                 sethi   %hi(_boot_tbr), %l1
 521                 st      %l4, [%l1 + %lo(_boot_tbr)]
 522                 sethi   %hi(_boot_o_two), %l1
 523                 st      %l5, [%l1 + %lo(_boot_smp_ptr)]
 524 
 525                 mov     %o0, %g7
 526                 sethi   %hi(_prom_vector_p), %g5
 527                 st      %o0, [%g5 + %lo(_prom_vector_p)]   ! we will need it later
 528 
 529                 ld      [%g7 + 0x4], %o3
 530                 cmp     %o3, 2                  ! a v2 prom?
 531                 be      found_v2
 532                 nop
 533 
 534 /* Old sun4's pass our load address into %o0 instead of the prom
 535    pointer. On sun4's you have to hard code the romvec pointer into
 536    your code. Sun probably still does that because they don't even
 537    trust their own "OpenBoot" specifications.
 538 */
 539 
 540                 sethi   %hi(LOAD_ADDR), %g6
 541                 cmp     %o0, %g6                ! an old sun4?
 542                 beq     no_sun4_here
 543                 nop
 544 
 545                 st      %g0, [_prom_iface_vers]
 546                 b       not_v2
 547                 nop
 548 
 549 found_v2:
 550                 or      %%g0, 0x2, %o5
 551                 st      %o5, [_prom_iface_vers]
 552 
 553 not_v2:
 554 
 555 /* Get the machine type via the mysterious romvec node operations.
 556  * Here we can find out whether we are on a sun4 sun4c, sun4m, or
 557  * a sun4m. The "nodes" are set up as a bunch of n-ary trees which
 558  * you can traverse to get information about devices and such. The
 559  * information acquisition happens via the node-ops which are defined
 560  * in the linux_openprom.h header file. Of particular interest is the
 561  * 'nextnode(int node)' function as it does the smart thing when
 562  * presented with a value of '0', it gives you the first node in the
 563  * tree. These node integers probably offset into some internal prom
 564  * pointer table the openboot has. It's completely undocumented, so
 565  * I'm not about to go sifting through the prom address space, but may
 566  * do so if I get suspicious enough. :-)
 567  */
 568 
 569                 or      %g0, %g7, %l1
 570                 add     %l1, 0x1c, %l1          
 571                 ld      [%l1], %l0
 572                 ld      [%l0], %l0
 573                 call    %l0
 574                 or      %g0, %g0, %o0           ! next_node(0) = first_node
 575 
 576                 set     _cputypvar, %o1         ! first node has cpu-arch
 577                 set     _cputypval, %o2         ! information, the string
 578                 ld      [%l1], %l0              ! 'compatibility' tells
 579                 ld      [%l0 + 0x0c], %l0       ! that we want 'sun4x' where
 580                 call    %l0                     ! x is one of '', 'c', 'm',
 581                 nop                             ! 'd' or 'e'. %o2 holds pointer
 582                                                 ! to a buf where above string
 583                                                 ! will get stored by the prom.
 584 
 585                 set     _cputypval, %o2         ! better safe than sorry
 586                 ldub    [%o2 + 4], %o0
 587                 cmp     %o0, 'c'                ! we already know we are not
 588                 beq     is_sun4c                ! on a plain sun4 because of
 589                 nop                             ! the check for 0x4000 in %o0
 590                 cmp     %o0, 'm'                ! at start:
 591                 beq     is_sun4m
 592                 nop
 593                 b       no_sun4d_here           ! god bless the person who
 594                 nop                             ! tried to run this on sun4d
 595 
 596 is_sun4m:
 597 is_sun4c:                                       ! OK, this is a sun4c, yippie
 598                 mov     %g7, %g6                ! load up the promvec offsets
 599                 sethi   %hi(prom_magic), %g5    ! magic mushroom :>
 600                 st      %g6, [%g5 + %lo(prom_magic)]
 601                 add     %g7, 0x4, %g6
 602                 sethi   %hi(prom_rom_vers), %g5
 603                 st      %g6, [%g5 + %lo(prom_rom_vers)]
 604                 add     %g7, 0x8, %g6
 605                 sethi   %hi(prom_pluginvers), %g5
 606                 st      %g6, [%g5 + %lo(prom_pluginvers)]
 607                 add     %g7, 0xc, %g6
 608                 sethi   %hi(prom_revision), %g5
 609                 st      %g6, [%g5 + %lo(prom_revision)]
 610                 add     %g7, 0x10, %g6
 611                 sethi   %hi(prom_v0mem_desc), %g5
 612                 st      %g6, [%g5 + %lo(prom_v0mem_desc)]
 613                 add     %g7, 0x1c, %g6
 614                 sethi   %hi(prom_nodefuncs), %g5
 615                 st      %g6, [%g5 + %lo(prom_nodefuncs)]
 616                 add     %g7, 0x68, %g6
 617                 sethi   %hi(prom_printf), %g5
 618                 st      %g6, [%g5 + %lo(prom_printf)]
 619                 add     %g7, 0x6c, %g6
 620                 sethi   %hi(prom_abort), %g5
 621                 st      %g6, [%g5 + %lo(prom_abort)]
 622                 add     %g7, 0x74, %g6
 623                 sethi   %hi(prom_halt), %g5
 624                 st      %g6, [%g5 + %lo(prom_halt)]
 625                 add     %g7, 0x78, %g6
 626                 sethi   %hi(prom_sync), %g5
 627                 st      %g6, [%g5 + %lo(prom_sync)]
 628                 add     %g7, 0x7c, %g6
 629                 sethi   %hi(prom_eval), %g5
 630                 st      %g6, [%g5 + %lo(prom_eval)]
 631                 add     %g7, 0x80, %g6
 632                 sethi   %hi(prom_v0bootline), %g6
 633                 st      %g6, [%g5 + %lo(prom_v0bootline)]
 634 
 635 
 636 /* That was easy, now lets try to print some message on the screen.
 637  * We don't have to worry about bad address translations when the prom
 638  * addresses our pointers because our pointers are at 0x0-kern_size
 639  * as the prom expects.
 640  */
 641 
 642                 set     boot_msg, %o0   
 643                 ld      [prom_printf], %o1
 644                 ld      [%o1], %o1
 645                 call    %o1                     ! print boot message #1
 646                 nop
 647 
 648 _newline:       set     newline, %o0
 649                 ld      [prom_printf], %o1
 650                 ld      [%o1], %o1
 651                 call    %o1
 652                 nop
 653 
 654                 set     pstring1, %o0
 655                 ld      [prom_printf], %o2
 656                 ld      [%o2], %o2
 657                 ld      [prom_magic], %o1
 658                 ld      [%o1], %o1
 659                 call    %o2
 660 
 661                 set     pstring2, %o0
 662                 ld      [prom_printf], %o2
 663                 ld      [%o2], %o2
 664                 ld      [_prom_iface_vers], %o1
 665                 ld      [%o1], %o1
 666                 call    %o2
 667 
 668                 b       halt_me
 669                 nop
 670 
 671 no_sun4_here:
 672                 ld      [%g7 + 0x68], %o1
 673                 set     sun4_notsup, %o0
 674                 call    %o1
 675                 nop
 676 
 677 rest_of_boot:
 678                 mov     PAGESHIFT_SUN4C, %g5
 679 
 680                 set     AC_CONTEXT, %g1         ! kernel context, safe now
 681                                                 ! the only valid context
 682                                                 ! until we call paging_init()
 683                 stba    %g0, [%g1] ASI_CONTROL
 684 
 685 
 686 /* I make the kernel image sit in memory relative to 0x0 with the text 
 687  * starting at 0x4000. Now it looks like the way memory is set in Linux
 688  * on an ix86.
 689  */
 690 
 691 /* Uh, oh, interrupt time. This crap is real confusing. What I want to do is
 692  * clear all interrupts, map the interrupt enable register which in effect
 693  * enables non-maskable interrupts (or NMI's). Actuall we take no interrupts
 694  * until we frob with the %tbr (trap base register) which the prom has set 
 695  * to all its routines which allows some sanity during bootup.
 696  */
 697 
 698 #if 0 /* paranoid, need to fix this routine now */
 699                 sethi   %hi(IE_reg_addr), %l0
 700                 or      %l0, %lo(IE_reg_addr), %l0
 701                 sethi   %hi(INT_ENABLE_REG_PHYSADR), %l2
 702                 or      %l2, %lo(INT_ENABLE_REG_PHYSADR), %l2
 703                 srl     %l2, %g5, %l1
 704 
 705                 sta     %l1, [%l0] ASI_PTE
 706                 mov     INTS_ALL_ENAB, %l1
 707                 stb     %l1, [%l0]
 708 #endif /* paranoid, see above */
 709         
 710 /* Aieee, now set PC and nPC, enable traps, give ourselves a stack and it's
 711  * show-time!
 712  */
 713 
 714                 set     1f, %g1
 715                 jmp     %g1
 716                 nop
 717 
 718                 .align 4
 719 1:              sethi   %hi(_cputyp), %o0
 720                 st      %g4, [%o0 + %lo(_cputyp)]
 721 
 722                 sethi   %hi(_pgshift), %o0
 723                 st      %g5, [%o0 + %lo(_pgshift)]
 724 
 725                 mov     1, %o0
 726                 sll     %o0, %g5, %g5
 727                 sethi   %hi(_nbpg), %o0
 728                 st      %g5, [%o0 + %lo(_nbpg)]
 729 
 730                 sub     %g5, 1, %g5
 731                 sethi   %hi(_pgofset), %o0
 732                 st      %g5, [%o0 + %lo(_pgofset)]
 733 
 734 
 735                 rd      %psr, %g3
 736                 andn    %g3, PSR_ET, %g3
 737                 wr      %g3, 0, %psr            ! make sure traps are off
 738                                                 ! before we play around
 739                 WRITE_PAUSE                     ! no guarentees until 3 insns
 740 
 741 
 742                 wr      %g0, 0, %wim            ! magical invalid window reg
 743                 WRITE_PAUSE                     ! see above
 744 
 745         
 746 /* I keep the timer interrupt on so that BogoMIPS works and the prom
 747  * keeps updating it's "jiffies" counter. 100HZ clock on sparcstations.
 748  */     
 749                 wr      %g0, (PSR_S | PSR_PS | PSR_PIL), %psr
 750                 WRITE_PAUSE
 751 
 752                 wr      %g0, 2, %wim            ! window 1 invalid
 753                 WRITE_PAUSE
 754                 mov     1, %g1
 755                 sethi   %hi(_task + PCB_WIM), %g2
 756                 st      %g1, [%g2 + %lo(_task + PCB_WIM)]
 757 
 758 /* I want a kernel stack NOW! */
 759 
 760                 set     USRSTACK - C_STACK, %fp 
 761                 set     estack0 - C_STACK - 80, %sp
 762                 rd      %psr, %l0
 763                 wr      %l0, PSR_ET, %psr
 764                 WRITE_PAUSE
 765 
 766 
 767 /*
 768  * Maybe the prom zero's out our BSS section, maybe it doesn't. I certainly 
 769  * don't know, do you?
 770  */
 771 
 772                 set     _edata, %o0
 773                 set     _end, %o1
 774                 sub     %o1, %o0, %g2
 775                 sethi   %hi(_kernel_bss_len), %g3
 776                 st      %g2, [%g3 + %lo(_kernel_bss_len)]
 777                 sethi   %hi(_trapbase), %g3
 778                 or      %g3, %lo(_trapbase), %g3
 779                 sethi   %hi(_etext), %g4
 780                 or      %g4, %lo(_etext), %g4                   
 781                 sub     %g4, %g3, %g2
 782                 sethi   %hi(_kernel_text_len), %g3
 783                 st      %g2, [%g3 + %lo(_kernel_text_len)]
 784                 sethi   %hi(_etext), %g4
 785                 or      %g4, %lo(_etext), %g4
 786                 sethi   %hi(_edata), %g3
 787                 or      %g3, %lo(_edata), %g3
 788                 sub     %g3, %g4, %g2
 789                 sethi   %hi(_kernel_data_len), %g3
 790                 st      %g2, [%g3 + %lo(_kernel_data_len)]
 791                 clr     %g1
 792 
 793 1:      
 794                 st      %g0, [%o0]
 795                 add     %o0, 0x4, %o0
 796                 cmp     %o0, %o1
 797                 bl      1b
 798                 nop
 799 
 800 /* Compute NWINDOWS and stash it away. Now uses %wim trick explained
 801  * in the V8 manual. Ok, this method seems to work, sparc is cool...
 802  */
 803 
 804                 sethi   %hi(0xffffffff), %g1
 805                 rd      %wim, %g2                       ! save current value
 806                 or      %g1, %lo(0xffffffff), %g1
 807                 wr      %g1, 0x0, %wim
 808                 rd      %wim, %g1                       ! get remaining mask
 809                 wr      %g2, 0x0, %wim                  ! restore old value
 810                 WRITE_PAUSE
 811 
 812                 or      %g0, 0x0, %g3
 813 
 814 1:              srl     %g1, 0x1, %g1                   ! shift until highest
 815                 cmp     %g1, 0x0                        ! bit set
 816                 bne     1b
 817                 add     %g3, 0x1, %g3
 818                 sethi   %hi(_nwindows), %g4
 819                 st      %g3, [%g4 + %lo(_nwindows)]     ! store final value
 820                 sub     %g3, 0x1, %g3
 821                 sethi   %hi(_nwindowsm1), %g4
 822                 st      %g3, [%g4 + %lo(_nwindowsm1)]
 823 
 824 
 825 /* Here we go */
 826 
 827 /* start_kernel() wants the command line args at empty_zero_page, copy
 828  * the boot command line from the prom data struct here...
 829  */
 830 
 831 /* I still haven't gotten this right yet... hack hack hack */
 832         
 833 #if 0
 834                 sethi   %hi(prom_v0bootline), %g6
 835                 ld      [%g6 + %lo(prom_v0bootline)], %g6
 836                 ld      [%g6], %g6
 837                 ld      [%g6], %g6
 838                 sethi   %hi(_empty_zero_page + 2048), %g2
 839                 ld      [%g2 + %lo(_empty_zero_page + 2048)], %g2
 840                 ld      [%g6], %g3      ! argv[0]               
 841                 or      %g0, 0x8, %g1   ! argv counter
 842 1:              ld      [%g3], %g4
 843                 st      %g4, [%g2]
 844                 add     %g3, 0x4, %g3
 845                 cmp     %g4, 0
 846                 bne,a   1b
 847                 add     %g2, 0x4, %g2
 848 
 849                 or      %g0, %lo(' '), %g4
 850                 st      %g4, [%g2]
 851                 sub     %g1, 0x1, %g1
 852                 add     %g3, 0x4, %g3
 853                 cmp     %g1, 0
 854                 bne     1b
 855                 add     %g2, 0x4, %g2
 856 #endif
 857 
 858                 sethi   %hi(_prom_vector_p), %g5
 859                 ld      [%g5 + %lo(_prom_vector_p)], %o0
 860                 call    _start_kernel
 861                 nop
 862         
 863                 call    halt_me
 864                 nop
 865 
 866 /* There, happy now adrian? */
 867 
 868 no_sun4d_here:
 869                 ld      [%g7 + 0x68], %o1
 870                 set     sun4d_notsup, %o0
 871                 call    %o1
 872                 nop
 873                 b       halt_me
 874                 nop
 875 
 876 halt_me:
 877                 ld      [%g7 + 0x74], %o0
 878                 call    %o0                     ! get us out of here...
 879                 nop                             ! apparently solaris is better
 880 
 881         .data
 882         .align 4
 883 
 884 /*
 885  * Fill up the prom vector, note in particular the kind first element,
 886  * no joke. I don't need all of them in here as the entire prom vector
 887  * gets initialized in c-code so all routines can use it.
 888  */
 889 
 890                         .globl _prom_vector_p
 891 
 892 _prom_vector_p:         .skip 4
 893 prom_magic:             .skip 4                 ! magic mushroom, beware...
 894 prom_rom_vers:          .skip 4                 ! interface version (v0 or v2)
 895 prom_pluginvers:        .skip 4                 ! XXX help help help ???
 896 prom_revision:          .skip 4                 ! PROM revision (ie. 1.4)
 897 prom_halt:              .skip 4                 ! void halt(void)  solaris friend
 898 prom_eval:              .skip 4                 ! void eval(int len, char* string)
 899 prom_v0bootline:        .skip 4                 ! boot command line
 900 prom_v0mem_desc:        .skip 4                 ! V0 memory descriptor list ptr.
 901 prom_nodefuncs:         .skip 4                 ! Magical Node functions
 902 prom_printf:            .skip 4                 ! minimal printf()
 903 
 904 /* The prom_abort pointer MUST be mapped in all contexts, because if you
 905  * don't then if a user process is running when you press the abort key
 906  * sequence, all sorts of bad things can happen
 907  */
 908 
 909 prom_abort:             .skip 4         ! "L1-A" magic cookie
 910                                         ! must be mapped in ALL contexts
 911 
 912 /* prom_sync is a place where the kernel should place a pointer to a kernel
 913  * function that when called will sync all pending information to the drives
 914  * and then promptly return. If the kernel gets aborted with 'L1-A' one can
 915  * give the 'sync' command to the boot prompt and this magic cookie gets
 916  * executed. Nice feature eh?
 917  */
 918 
 919 prom_sync:              .skip 4                 ! hook in prom for "sync" func
 920 
 921         .align 4
 922 
 923 /* We calculate the following at boot time, window fills/spills and trap entry
 924  * code uses these to keep track of the register windows.
 925  */
 926 
 927         .globl _nwindows
 928         .globl _nwindowsm1
 929 _nwindows:      .skip 4
 930 _nwindowsm1:    .skip 4
 931 
 932         .align 4
 933 /* Boot time priviledged register values, plus magic %o2 value */
 934 
 935         .globl _boot_wim
 936         .globl _boot_psr
 937         .globl _boot_tbr
 938         .globl _boot_o_two
 939 _boot_wim:              .skip 4
 940 _boot_psr:              .skip 4
 941 _boot_tbr:              .skip 4
 942 _boot_smp_ptr:          .skip 4
 943 

/* [previous][next][first][last][top][bottom][index][help] */