![]() |
|
|||
File indexing completed on 2025-05-11 08:23:58
0001 /* 0002 * Authorship 0003 * ---------- 0004 * This software was created by 0005 * Till Straumann <strauman@slac.stanford.edu>, 2005, 0006 * Stanford Linear Accelerator Center, Stanford University. 0007 * 0008 * Acknowledgement of sponsorship 0009 * ------------------------------ 0010 * This software was produced by 0011 * the Stanford Linear Accelerator Center, Stanford University, 0012 * under Contract DE-AC03-76SFO0515 with the Department of Energy. 0013 * 0014 * Government disclaimer of liability 0015 * ---------------------------------- 0016 * Neither the United States nor the United States Department of Energy, 0017 * nor any of their employees, makes any warranty, express or implied, or 0018 * assumes any legal liability or responsibility for the accuracy, 0019 * completeness, or usefulness of any data, apparatus, product, or process 0020 * disclosed, or represents that its use would not infringe privately owned 0021 * rights. 0022 * 0023 * Stanford disclaimer of liability 0024 * -------------------------------- 0025 * Stanford University makes no representations or warranties, express or 0026 * implied, nor assumes any liability for the use of this software. 0027 * 0028 * Stanford disclaimer of copyright 0029 * -------------------------------- 0030 * Stanford University, owner of the copyright, hereby disclaims its 0031 * copyright and all other rights in this software. Hence, anyone may 0032 * freely use it for any purpose without restriction. 0033 * 0034 * Maintenance of notices 0035 * ---------------------- 0036 * In the interest of clarity regarding the origin and status of this 0037 * SLAC software, this and all the preceding Stanford University notices 0038 * are to remain affixed to any copy or derivative of this software made 0039 * or distributed by the recipient and are to be affixed to any copy of 0040 * software made or distributed by the recipient that contains a copy or 0041 * derivative of this software. 0042 * 0043 * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 0044 */ 0045 0046 #include <bsp.h> 0047 #include <libcpu/spr.h> 0048 #include <libcpu/cpuIdent.h> 0049 #include <rtems/bspIo.h> 0050 #include <inttypes.h> 0051 0052 /* Simple memory probing routine 0053 * 0054 * - call from MMU-disabled section to avoid having to 0055 * set up mappings. 0056 * NOTE: this implies WIMG = 0011 0057 * - call AFTER image is at its destination and PRIOR 0058 * to setting up the heap or using any memory beyond 0059 * __rtems_end, i.e., the probing algorithm may safely 0060 * tamper with memory > __rtems_end. 0061 * - MUST lock caches since we're gonna hit space with 0062 * no memory attached. 0063 * 0064 * ASSUMPTIONS: 0065 * o image occupies addresses between 0..__rtems_end 0066 * o memory size is a multiple of 1<<LD_MEM_PROBE_STEP 0067 * 0068 * CAVEATS: 0069 * o all caches must be disabled or locked (some 0070 * boards really don't like it if you try to 0071 * cache physical addresses with nothing attached) 0072 * and this is highly CPU dependent :-(... 0073 * 0074 * - RETURNS size of memory detected in bytes or 0 on 0075 * error. 0076 */ 0077 0078 /* declare as an array so the compiler doesn't generate 0079 * a reloc to .sdata & friends 0080 */ 0081 extern uint32_t __rtems_end[]; 0082 0083 #ifndef LD_MEM_PROBE_STEP 0084 #define LD_MEM_PROBE_STEP (24) /* 16MB */ 0085 #endif 0086 0087 #define TAG 0xfeedcafe 0088 0089 #define __DO_ALIGN(a, s) (((uint32_t)(a) + (s)-1) & ~((s)-1)) 0090 #define __ALIGN(a) __DO_ALIGN(a, (1<<LD_MEM_PROBE_STEP)) 0091 0092 #define SWITCH_MSR(msr) \ 0093 do { \ 0094 register uint32_t __rr; \ 0095 asm volatile( \ 0096 " mtsrr1 %0 \n" \ 0097 " bl 1f \n" \ 0098 "1: mflr %0 \n" \ 0099 " addi %0, %0, 1f-1b \n"\ 0100 " mtsrr0 %0 \n" \ 0101 " sync \n" \ 0102 " rfi \n" \ 0103 "1: \n" \ 0104 :"=b&"(__rr) \ 0105 :"0"(msr) \ 0106 :"lr","memory" \ 0107 ); \ 0108 } while (0) 0109 0110 SPR_RW(L2CR) 0111 SPR_RW(L3CR) 0112 SPR_RO(PPC_PVR) 0113 SPR_RW(HID0) 0114 0115 0116 /* Shouldn't matter if the caches are enabled or not... */ 0117 0118 /* FIXME: This should go into libcpu, really... */ 0119 static int 0120 CPU_lockUnlockCaches(register int doLock) 0121 { 0122 register uint32_t v, x; 0123 if ( _read_MSR() & MSR_VE ) { 0124 #define DSSALL 0x7e00066c /* dssall opcode */ 0125 __asm__ volatile(" .long %0"::"i"(DSSALL)); 0126 #undef DSSALL 0127 } 0128 asm volatile("sync"); 0129 switch ( _read_PPC_PVR()>>16 ) { 0130 default: printk(__FILE__" CPU_lockUnlockCaches(): unknown CPU (PVR = 0x%08" PRIx32 ")\n",_read_PPC_PVR()); 0131 return -1; 0132 case PPC_750: printk("CPU_lockUnlockCaches(): Can't lock L2 on a mpc750, sorry :-(\n"); 0133 return -2; /* cannot lock L2 :-( */ 0134 case PPC_7455: 0135 case PPC_7457: 0136 v = _read_L3CR(); 0137 x = 1<<(31-9); 0138 v = doLock ? v | x : v & ~x; 0139 _write_L3CR(v); 0140 0141 v = _read_L2CR(); 0142 x = 1<<(31-11); 0143 v = doLock ? v | x : v & ~x; 0144 _write_L2CR(v); 0145 break; 0146 0147 case PPC_7400: 0148 v = _read_L2CR(); 0149 x = 1<<(31-21); 0150 v = doLock ? v | x : v & ~x; 0151 _write_L2CR(v); 0152 break; 0153 case PPC_603: 0154 case PPC_604: 0155 case PPC_604e: 0156 break; 0157 } 0158 0159 v = _read_HID0(); 0160 x = 1<<(31-19); 0161 v = doLock ? v | x : v & ~x; 0162 _write_HID0(v); 0163 asm volatile("sync":::"memory"); 0164 return 0; 0165 } 0166 0167 uint32_t 0168 probeMemoryEnd(void) 0169 { 0170 register volatile uint32_t *probe; 0171 register uint32_t scratch; 0172 register uint32_t tag = TAG; 0173 register uint32_t flags; 0174 0175 probe = (volatile uint32_t *)__ALIGN(__rtems_end); 0176 0177 /* Start with some checks. We avoid using any services 0178 * such as 'printk' so we can run at a very early stage. 0179 * Also, we *try* to avoid to really rely on the memory 0180 * being unused by restoring the probed locations and 0181 * keeping everything in registers. Hence we could 0182 * even probe our own stack :-) 0183 */ 0184 0185 if ( CPU_lockUnlockCaches(1) ) 0186 return 0; 0187 0188 _CPU_MSR_GET(flags); 0189 0190 SWITCH_MSR( flags & ~(MSR_EE|MSR_DR|MSR_IR) ); 0191 0192 for ( ; (uint32_t)probe ; probe += (1<<LD_MEM_PROBE_STEP)/sizeof(*probe) ) { 0193 0194 /* see if by chance our tag is already there */ 0195 if ( tag == (scratch = *probe) ) { 0196 /* try another tag */ 0197 tag = ~tag; 0198 } 0199 *probe = tag; 0200 0201 /* make sure it's written out */ 0202 asm volatile ("sync":::"memory"); 0203 0204 /* try to read back */ 0205 if ( tag != *probe ) { 0206 break; 0207 } 0208 /* restore */ 0209 *probe = scratch; 0210 /* make sure the icache is not contaminated */ 0211 asm volatile ("sync; icbi 0, %0"::"r"(probe):"memory"); 0212 } 0213 0214 SWITCH_MSR(flags); 0215 0216 CPU_lockUnlockCaches(0); 0217 0218 return (uint32_t) probe; 0219 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |