root/arch/sparc/boot/bare.S

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

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