source: rtems/c/src/lib/libbsp/powerpc/shared/startup/probeMemEnd.c @ 6c6a21c

4.115
Last change on this file since 6c6a21c was 6c6a21c, checked in by Joel Sherrill <joel.sherrill@…>, on 10/16/14 at 18:11:47

powerpc/shared/startup/probeMemEnd.c: Fix warning

  • Property mode set to 100644
File size: 5.9 KB
Line 
1/*
2 * Authorship
3 * ----------
4 * This software was created by
5 *     Till Straumann <strauman@slac.stanford.edu>, 2005,
6 *         Stanford Linear Accelerator Center, Stanford University.
7 *
8 * Acknowledgement of sponsorship
9 * ------------------------------
10 * This software was produced by
11 *     the Stanford Linear Accelerator Center, Stanford University,
12 *         under Contract DE-AC03-76SFO0515 with the Department of Energy.
13 *
14 * Government disclaimer of liability
15 * ----------------------------------
16 * Neither the United States nor the United States Department of Energy,
17 * nor any of their employees, makes any warranty, express or implied, or
18 * assumes any legal liability or responsibility for the accuracy,
19 * completeness, or usefulness of any data, apparatus, product, or process
20 * disclosed, or represents that its use would not infringe privately owned
21 * rights.
22 *
23 * Stanford disclaimer of liability
24 * --------------------------------
25 * Stanford University makes no representations or warranties, express or
26 * implied, nor assumes any liability for the use of this software.
27 *
28 * Stanford disclaimer of copyright
29 * --------------------------------
30 * Stanford University, owner of the copyright, hereby disclaims its
31 * copyright and all other rights in this software.  Hence, anyone may
32 * freely use it for any purpose without restriction.
33 *
34 * Maintenance of notices
35 * ----------------------
36 * In the interest of clarity regarding the origin and status of this
37 * SLAC software, this and all the preceding Stanford University notices
38 * are to remain affixed to any copy or derivative of this software made
39 * or distributed by the recipient and are to be affixed to any copy of
40 * software made or distributed by the recipient that contains a copy or
41 * derivative of this software.
42 *
43 * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
44 */
45
46#include <bsp.h>
47#include <libcpu/spr.h>
48#include <libcpu/cpuIdent.h>
49#include <rtems/bspIo.h>
50
51/* Simple memory probing routine
52 *
53 *  - call from MMU-disabled section to avoid having to
54 *        set up mappings.
55 *    NOTE: this implies WIMG = 0011
56 *  - call AFTER image is at its destination and PRIOR
57 *    to setting up the heap or using any memory beyond
58 *    __rtems_end, i.e., the probing algorithm may safely
59 *    tamper with memory > __rtems_end.
60 *  - MUST lock caches since we're gonna hit space with
61 *    no memory attached.
62 *
63 * ASSUMPTIONS:
64 *              o image occupies addresses between 0..__rtems_end
65 *              o memory size is a multiple of 1<<LD_MEM_PROBE_STEP
66 *
67 * CAVEATS:
68 *      o all caches must be disabled or locked (some
69 *        boards really don't like it if you try to
70 *        cache physical addresses with nothing attached)
71 *        and this is highly CPU dependent :-(...
72 *
73 *      - RETURNS size of memory detected in bytes or 0 on
74 *    error.
75 */
76
77/* declare as an array so the compiler doesn't generate
78 * a reloc to .sdata & friends
79 */
80extern uint32_t __rtems_end[];
81
82#ifndef LD_MEM_PROBE_STEP
83#define LD_MEM_PROBE_STEP       (24) /* 16MB */
84#endif
85
86#define TAG 0xfeedcafe
87
88#define __DO_ALIGN(a, s)        (((uint32_t)(a) + (s)-1) & ~((s)-1))
89#define __ALIGN(a)      __DO_ALIGN(a, (1<<LD_MEM_PROBE_STEP))
90
91#define SWITCH_MSR(msr)         \
92        do {                                    \
93        register uint32_t __rr; \
94        asm volatile(                   \
95                "       mtsrr1  %0      \n"     \
96                "   bl 1f               \n"     \
97                "1:     mflr    %0      \n"     \
98                "       addi %0, %0, 1f-1b      \n"\
99                "       mtsrr0  %0      \n"     \
100                "       sync            \n"     \
101                "       rfi                     \n"     \
102                "1:                             \n"     \
103                :"=b&"(__rr)            \
104                :"0"(msr)                       \
105                :"lr","memory"          \
106        );                                              \
107        } while (0)
108
109SPR_RW(L2CR)
110SPR_RW(L3CR)
111SPR_RO(PPC_PVR)
112SPR_RW(HID0)
113
114
115/* Shouldn't matter if the caches are enabled or not... */
116
117/* FIXME: This should go into libcpu, really... */
118static int
119CPU_lockUnlockCaches(register int doLock)
120{
121register uint32_t v, x;
122        if ( _read_MSR() & MSR_VE ) {
123#define DSSALL  0x7e00066c  /* dssall opcode */
124        __asm__ volatile("  .long %0"::"i"(DSSALL));
125#undef  DSSALL
126        }
127        asm volatile("sync");
128        switch ( _read_PPC_PVR()>>16 ) {
129                default:                printk(__FILE__" CPU_lockUnlockCaches(): unknown CPU (PVR = 0x%08x)\n",_read_PPC_PVR());
130                                                return -1;
131                case PPC_750:   printk("CPU_lockUnlockCaches(): Can't lock L2 on a mpc750, sorry :-(\n");
132                                                return -2;      /* cannot lock L2 :-( */
133                case PPC_7455:
134                case PPC_7457:
135                                                v = _read_L3CR();
136                                                x = 1<<(31-9);
137                                                v = doLock ? v | x : v & ~x;
138                                                _write_L3CR(v);
139
140                                                v = _read_L2CR();
141                                                x = 1<<(31-11);
142                                                v = doLock ? v | x : v & ~x;
143                                                _write_L2CR(v);
144                                break;
145
146                case PPC_7400:
147                                                v = _read_L2CR();
148                                                x = 1<<(31-21);
149                                                v = doLock ? v | x : v & ~x;
150                                                _write_L2CR(v);
151                                break;
152                case PPC_603:
153                case PPC_604:
154                case PPC_604e:
155                                break;
156        }
157
158        v = _read_HID0();
159        x = 1<<(31-19);
160        v = doLock ? v | x : v & ~x;
161        _write_HID0(v);
162        asm volatile("sync":::"memory");
163        return 0;
164}
165
166uint32_t
167probeMemoryEnd(void)
168{
169register volatile uint32_t *probe;
170register          uint32_t scratch;
171register          uint32_t tag = TAG;
172register          uint32_t flags;
173
174        probe = (volatile uint32_t *)__ALIGN(__rtems_end);
175
176        /* Start with some checks. We avoid using any services
177         * such as 'printk' so we can run at a very early stage.
178         * Also, we *try* to avoid to really rely on the memory
179         * being unused by restoring the probed locations and
180         * keeping everything in registers. Hence we could
181         * even probe our own stack :-)
182         */
183
184        if ( CPU_lockUnlockCaches(1) )
185                return 0;
186
187        _CPU_MSR_GET(flags);
188
189        SWITCH_MSR( flags & ~(MSR_EE|MSR_DR|MSR_IR) );
190
191        for ( ; (uint32_t)probe ;  probe += (1<<LD_MEM_PROBE_STEP)/sizeof(*probe) ) {
192
193                /* see if by chance our tag is already there */
194                if ( tag == (scratch = *probe) ) {
195                        /* try another tag */
196                        tag = ~tag;
197                }
198                *probe = tag;
199
200                /* make sure it's written out */
201                asm volatile ("sync":::"memory");
202
203                /* try to read back */
204                if ( tag != *probe ) {
205                                break;
206                }
207                /* restore */
208                *probe = scratch;
209                /* make sure the icache is not contaminated */
210                asm volatile ("sync; icbi 0, %0"::"r"(probe):"memory");
211        }
212
213        SWITCH_MSR(flags);
214
215        CPU_lockUnlockCaches(0);
216
217        return (uint32_t) probe;
218}
Note: See TracBrowser for help on using the repository browser.