![]() |
|
|||
File indexing completed on 2025-05-11 08:23:58
0001 /* 0002 * Mini-loader for the SVGM BSP. 0003 * 0004 * Author: Till Straumann, 10/2001 <strauman@slac.stanford.edu> 0005 * 0006 * Some ideas are borrowed from the powerpc/shared/bootloader 0007 * by 0008 * Copyright (C) 1998, 1999 Gabriel Paubert, paubert@iram.es 0009 * Copyright (C) 1999 Eric Valette. valette@crf.canon.fr 0010 * 0011 * The SMON firmware is unable to load the RTEMS image below 0012 * 0x2000 (I believe their stack is growing below 0x1000). 0013 * 0014 * The code provided by this file is responsible for the performing 0015 * the following steps: 0016 * 0017 * 1) Save commandline parameters to an area that is 0018 * a) not covered by the downloaded image 0019 * b) will not be overwritten by the moved image 0020 * nor the final BSS segment (rtems clears BSS 0021 * before saving the command line). 0022 * 2) Move the entire image (including this very file) to 0023 * its final location starting at 0x0000. 0024 * It is important to note that _NO_STACK_ is available 0025 * during this step. Also, there is probably no return to 0026 * SMON because relocating RTEMS will destroy vital SMON 0027 * data (such as its stack). 0028 * 3) Flush the cache to make sure the relocated image is actually 0029 * in memory. 0030 * 4) setup RTEMS environment (initial register values), most 0031 * notably an initial STACK. The initial stack may be small and 0032 * is used by RTEMS only at a very early stage. 0033 * A safe place for the stack seems to be the 00..0x7f area. 0034 * NOTE: we should respect the MAILBOX area 0x80..0xff! 0035 * 5) switch the MMU off (because that's what RTEMS is expecting 0036 * it to be at startup). 0037 * 6) fire up rtems... 0038 * 0039 * 0040 * Calling convention: 0041 * R1: SMON SP 0042 * R3: command line string start 0043 * R4: command line string end + 1 0044 * R5: where SMON put the image 0045 * if R5 is 0, the preloader will use its entry point 0046 * as the image starting address. 0047 * See NOTE below. 0048 * R6: end of the image (i.e. R6-R5 is the image length) 0049 * if R6 is 0, _edata will be used as the image length 0050 * See NOTE below. 0051 * 0052 * NOTE: if the symbol DONT_USE_R5_ENTRY is defined, 0053 * R5/R6 are never used and the necessary parameters are 0054 * determined at runtime (R5) / linkage (R6) [_edata] 0055 * 0056 * ASSUMPTIONS: 0057 * The code RELIES on the assumption that the image will be 0058 * moved DOWNWARDS in memory and that the this loader is 0059 * prepended to the image, i.e. it is safe to do 0060 * codemove(codemove,0,codemove_end - codemove); 0061 * (*0)(codemove_end, codemove_end-codemove, __rtems_end-codemove_end); 0062 * where codemove(from, to, nbytes) is defined as 0063 * codemove(from, to, nbytes) { while (nbytes--) *(to++)=*(from++); } 0064 * Implicit to these assumptions is the assumption that the destination 0065 * address is cache block aligned. 0066 * Furthermore, the byte count is assumed to be a multiple 0067 * of four 0068 * 0069 */ 0070 #if 0 0071 #include <rtems/score/powerpc.h> 0072 #else 0073 #ifndef PPC_CACHE_ALIGNMENT 0074 #define PPC_CACHE_ALIGNMENT 32 0075 #endif 0076 #endif 0077 0078 #include <rtems/score/cpu.h> 0079 #include <rtems/asm.h> 0080 0081 /* Note that major modifications may be needed 0082 * if DESTINATION_ADDR is not 0 0083 */ 0084 #define KERNELBASE 0x0 0085 #define INITIAL_STACK 0x70 /* 16-byte aligned */ 0086 #define CACHE_LINE_SIZE PPC_CACHE_ALIGNMENT /* autodetect doesn't work, see below */ 0087 #define ASSUME_RTEMS_INSTALLS_VECTORS /* assume we need not load vectors */ 0088 #define DONT_USE_R5_ENTRY /* always dynamically determine the address we're running from */ 0089 0090 /* put this into its own section which we want to 0091 * be loaded at the very beginning. We should probably 0092 * not use more than 255 bytes. 0093 */ 0094 PUBLIC_VAR(__rtems_start) 0095 PUBLIC_VAR(__rtems_entry_point) 0096 PUBLIC_VAR(__rtems_end) 0097 .section .entry_point_section,"awx",@progbits 0098 preload: 0099 /* find out where we are */ 0100 bl here 0101 here: 0102 xor r0,r0,r0 0103 mtmsr r0 /* clear MSR to known state */ 0104 mflr r5 0105 addi r5,r5,-(here-preload) 0106 lis r27,_edata@h 0107 ori r27,r27,_edata@l 0108 0109 /* at this point the register contents are 0110 * R3: command line start 0111 * R4: R3 + command line length 0112 * R5: address we are running from / loaded to 0113 * R27: image end 0114 */ 0115 0116 /* save command line start */ 0117 mr r6, r3 0118 /* save the command line parameters if they are to be overwritten */ 0119 sub. r17, r4, r3 /* string length */ 0120 ble leaveparms /* <=0 -> no parameters */ 0121 /* copy has to be out of the way of the bss; therefore we must 0122 * put the string out of the way of both, the current end of 0123 * the image (without bss) AND the end of the loaded image 0124 * (including bss): 0125 * |......image.........| downloaded image 0126 * |image_bss...........| loaded image with bss appended 0127 * 0128 * ^ safe place for string 0129 * 0130 * the alternative scenario looks like this: 0131 * |..image.............| downloaded image 0132 * |image_bss...........| loaded image with bss appended 0133 * ^ safe place for string 0134 */ 0135 lis r18, __rtems_end+0x10000@h /* round up, save one instruction */ 0136 add r16, r5, r27 /* image end + 1 */ 0137 cmpw r16, r18 0138 bge ishighenough 0139 mr r16,r18 /* __rtems_end is higher than the image end 0140 * (without bss) 0141 */ 0142 ishighenough: 0143 cmpw r16, r3 /* destination start > current string start ? */ 0144 ble leaveparms /* string already after dst, leave it */ 0145 /* copy string from the last byte downwards */ 0146 add r6, r16, r17 /* last byte of destination + 1 */ 0147 mtctr r17 0148 1: 0149 lbzu r3, -1(r4) 0150 stbu r3, -1(r6) 0151 bdnz 1b 0152 leaveparms: 0153 add r7, r6, r17 /* destination + strlen */ 0154 0155 #ifndef CACHE_LINE_SIZE 0156 /* Oh well, SMON has inhibited the cache, so this 0157 * nice routine doesn't work... 0158 */ 0159 /* figure out the cache line size */ 0160 li r16, 0x80 0161 cmpw r5, r16 /* 'from' must be > 0x80 */ 0162 blt panic 0163 0164 1: /* store some arbitrary, nonzero stuff in 0..0x7c */ 0165 stwu r16,-4(r16) 0166 cmpwi r16,0 0167 bne 1b 0168 dcbz 0,r16 /* zero out one cache line */ 0169 subi r16,r16,4 0170 2: lwzu r0,4(r16) /* search for a non-zero word */ 0171 cmpwi r0,0 0172 beq 2b 0173 /* OK, r16 now hold the size of a cache line in bytes */ 0174 #else 0175 li r16,CACHE_LINE_SIZE 0176 #endif 0177 0178 lis r3,preload@h 0179 ori r3,r3,preload@l 0180 mr r4,r5 /* from-addr */ 0181 li r5,_preload_size/* this is never > 16k */ 0182 /* now move ourselves to the link address ('preload'). 0183 * We set up the LR, so domove() 'returns' to the 0184 * relocated copy 0185 */ 0186 lis r0,return_here@h 0187 ori r0,r0,return_here@l 0188 mtlr r0 0189 b domove /* move the preloader itself */ 0190 return_here: 0191 /* now we move the entire rest of the image */ 0192 #ifdef ASSUME_RTEMS_INSTALLS_VECTORS 0193 lis r3,__rtems_start@h 0194 ori r3,r3,__rtems_start@l 0195 lis r0,preload@h /* calculate/adjust from address */ 0196 ori r0,r0,preload@l 0197 sub r0,r3,r0 0198 add r4,r4,r0 0199 sub r5,r27,r3 0200 #else 0201 add r3,r3,r5 /* add preloader size to destination */ 0202 add r4,r4,r5 /* and source addresses */ 0203 sub r5,r27,r5 /* length of the remaining rest */ 0204 #endif 0205 bl domove 0206 /* OK, now everything should be in place. 0207 * we are ready to start... 0208 */ 0209 0210 /* setup initial stack for rtems early boot */ 0211 li r1,INITIAL_STACK 0212 /* tag TOS with a NULL pointer (for stack trace) */ 0213 li r0, 0 0214 stw r0, 0(r1) 0215 /* disable the MMU and fire up rtems */ 0216 mfmsr r0 0217 ori r0,r0,MSR_IR|MSR_DR|MSR_IP|MSR_ME 0218 xori r0,r0,MSR_IR|MSR_DR 0219 mtsrr1 r0 0220 lis r0,__rtems_entry_point@h 0221 ori r0,r0,__rtems_entry_point@l 0222 mtsrr0 r0 0223 /* R6: start of command line */ 0224 /* R7: end of command line +1 */ 0225 rfi 0226 0227 /* domove(to, from, nbytes): 0228 * 0229 * move a R5 bytes from R4 to R3 and flush 0230 * the caches for the destination memory 0231 * region. R16 provides the cache line size. 0232 * DESTROYS: R0, R17, R18, CTR, CR 0233 */ 0234 domove: 0235 addi r0,r5,3 /* convert to word count */ 0236 srwi. r0,r0,2 0237 beq 3f /* nothing to do */ 0238 cmpw r3,r4 /* from == to ? */ 0239 beq 3f 0240 mtctr r0 0241 la r18,-4(r4) 0242 la r17,-4(r3) 0243 1: lwzu r0,4(r18) 0244 stwu r0,4(r17) 0245 bdnz 1b /* move data */ 0246 /* now, we must flush the destination cache region */ 0247 #ifndef CACHE_LINE_SIZE 0248 cmpwi r16,0 0249 beq 3f /* nothing to do */ 0250 #endif 0251 #if defined(CACHE_LINE_SIZE) && CACHE_LINE_SIZE > 0 0252 add r17,r3,r5 /* target end pointer */ 0253 subi r0,r16,1 0254 add r17,r17,r0 0255 andc r17,r17,r0 /* cache aligned target end pointer */ 0256 mr r18,r3 0257 2: cmpw r18,r17 0258 dcbst 0,r18 /* write out data cache line */ 0259 icbi 0,r18 /* invalidate corresponding i-cache line */ 0260 add r18,r18,r16 0261 blt 2b 0262 sync /* make sure data is written back */ 0263 isync /* invalidate possibly preloaded instructions */ 0264 #endif 0265 3: 0266 blr 0267 0268 #if !defined(CACHE_LINE_SIZE) 0269 panic: 0270 li r10,0x63 0271 mfmsr r0 0272 ori r0,r0,MSR_IP 0273 mtmsr r0 0274 sc 0275 #endif 0276 0277 /* DONT PUT ANY CODE BELOW HERE */ 0278 _preload_size = . - preload
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |