root/arch/sparc/boot/bare.S

/* [previous][next][first][last][top][bottom][index][help] */
   1 /* $Id: bare.S,v 1.2 1995/11/25 00:57:39 davem Exp $
   2  * base.S:      Ugly low-level boot program entry code.  The job of this
   3  *              module is to parse the boot flags, try to mount the remote
   4  *              root filesystem and load the kernel into virtual memory.
   5  *
   6  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
   7  */
   8 
   9 #include "bare.h"
  10 #include <asm/ptrace.h>
  11 
  12         .data
  13         .globl C_LABEL(romvec)
  14         .globl C_LABEL(idp_ptr)
  15 
  16 C_LABEL(romvec):
  17         .word 0
  18 C_LABEL(idp_ptr):
  19         .word 0
  20 
  21         .text
  22         .align 8
  23         .globl C_LABEL(first_adr_in_text)
  24 
  25 C_LABEL(first_adr_in_text):
  26 
  27         /* Grrr, boot block, scratching my head... */
  28         .globl C_LABEL(b_block)       /* Start of actual boot block */
  29         .globl C_LABEL(b_block_size)  /* In bytes */
  30         .globl C_LABEL(b_block_cksum) /* Checksum of boot block bytes */
  31 
  32         b       start_of_execution    /* XXX Hack */
  33         nop
  34 
  35         .align  8
  36 C_LABEL(b_block):       
  37         .skip   (BOOTBLOCK_NENTRIES * BOOTBLOCK_ENTSIZE)
  38 
  39 C_LABEL(b_block_size):
  40         .word   0
  41 
  42 C_LABEL(b_block_cksum):
  43         .word   0
  44 
  45 /* Ok, the prom has left in %o0 the PROM pointer.  We leave it here
  46  * for when we jump into the kernel.  So save out of this window before
  47  * you dick with %o0.  As far as I know we could be loaded *anywhere*, so
  48  * we relocate ourselves to the "linked" location.  Self modifying code rules.
  49  */
  50 
  51 start_of_execution:
  52         sethi   %hi(C_LABEL(first_adr_in_text)), %o1            ! This is our top
  53         or      %o1, %lo(C_LABEL(first_adr_in_text)), %o1       ! of stack too.
  54         sub     %o1, STACKFRAME_SZ, %o1
  55         add     %o1, 0x7, %o1
  56         andn    %o1, 0x7, %o1
  57         save    %o1, 0x0, %sp                                   ! save is an add
  58 here:
  59         call    there
  60         sethi   %hi(here), %o4
  61 there:  
  62         sub     %o7, here-C_LABEL(first_adr_in_text), %o5
  63         or      %o4, %lo(here), %o4
  64         cmp     %o4, %o7
  65         be      loaded_ok
  66         nop
  67 
  68         /* Gotta relocate, compute our size sans bss segment. */
  69         set     C_LABEL(edata)+4, %o3
  70         set     C_LABEL(first_adr_in_text), %o2
  71         sub     %o3, %o2, %o3
  72 rel_loop:
  73         ld      [%o5], %o4
  74         add     %o5, 0x4, %o5
  75         st      %o4, [%o2]
  76         subcc   %o3, 0x4, %o3
  77         bg      rel_loop
  78         add     %o2, 0x4, %o2
  79 
  80         /* Pray that we are now in a sane place in memory */
  81         sethi   %hi(loaded_ok), %o2
  82         or      %o2, %lo(loaded_ok), %o2
  83         jmp     %o2
  84         nop
  85 
  86 loaded_ok:
  87         /* Save the PROM pointer */
  88         sethi   %hi(C_LABEL(romvec)), %o1
  89         or      %o1, %lo(C_LABEL(romvec)), %o1
  90         st      %i0, [%o1]
  91 
  92         /* Build a PSR we can live with */
  93         rd      %psr, %o1
  94 
  95 #if 0
  96         andn    %o1, PSR_PIL, %o1
  97         sethi   %hi(SANE_PSR), %g4
  98         or      %g4, %lo(SANE_PSR), %g4
  99         or      %o1, %g4, %o1
 100 #endif
 101 
 102         /* V8 book says this works to calculate num_windows */
 103         sethi   %hi(0xffffffff), %g2
 104         rd      %wim, %g3
 105         or      %g2, %lo(0xffffffff), %g2
 106         wr      %g2, 0x0, %wim
 107         WRITE_PAUSE
 108 
 109         rd      %wim, %g4
 110         WRITE_PAUSE
 111 
 112         wr      %g3, 0x0, %wim
 113         WRITE_PAUSE
 114 
 115         /* Restore old %psr */
 116         wr      %o1, 0x0, %psr
 117         WRITE_PAUSE
 118 
 119         or      %g0, 0x0, %g3
 120 1:
 121         srl     %g4, 0x1, %g4
 122         subcc   %g4, 0x0, %g0
 123         bne     1b
 124         add     %g3, 0x1, %g3
 125         
 126         /* %g3 now contains nwindows */
 127         sethi   %hi(C_LABEL(nwindows)), %o4
 128         st      %g3, [%o4 + %lo(C_LABEL(nwindows))]
 129 
 130         /* Now zero out our bss segment, lord knows the nasty prom monster
 131          * didn't do it for us.
 132          */
 133         sethi   %hi(C_LABEL(end)), %g1
 134         or      %g1, %lo(C_LABEL(end)), %g1
 135         add     %g1, 0x4, %g1
 136         sethi   %hi(C_LABEL(edata)), %g2
 137         or      %g2, %lo(C_LABEL(edata)), %g2
 138 
 139         /* Slow, inefficient, who cares, this is messy boot code */
 140 bzero_bss_loop:
 141         st      %g0, [%g2]
 142         add     %g2, 0x4, %g2
 143         cmp     %g2, %g1
 144         bl      bzero_bss_loop
 145         nop
 146 
 147         call    C_LABEL(init_me)        ! Fun with imperical constants and prom
 148         nop
 149 
 150         /* Dump back into the prom */
 151 get_me_out_of_here:
 152         set     C_LABEL(romvec), %g2
 153         ld      [%g2], %g2
 154         ld      [%g2 + 0x74], %g2
 155         restore
 156         call    %g2
 157         nop
 158 
 159 
 160 

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