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

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