]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo_bsp/ps7_cortexa9_0/libsrc/standalone_v4_1/src/boot.S
Add back Zynq demo - this time using SDK V14.2.
[freertos] / FreeRTOS / Demo / CORTEX_A9_Zynq_ZC702 / RTOSDemo_bsp / ps7_cortexa9_0 / libsrc / standalone_v4_1 / src / boot.S
1 /******************************************************************************
2 *
3 * (c) Copyright 2010-2013 Xilinx, Inc. All rights reserved.
4 *
5 * This file contains confidential and proprietary information of Xilinx, Inc.
6 * and is protected under U.S. and international copyright and other
7 * intellectual property laws.
8 *
9 * DISCLAIMER
10 * This disclaimer is not a license and does not grant any rights to the
11 * materials distributed herewith. Except as otherwise provided in a valid
12 * license issued to you by Xilinx, and to the maximum extent permitted by
13 * applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
14 * FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
15 * IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
16 * MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
17 * and (2) Xilinx shall not be liable (whether in contract or tort, including
18 * negligence, or under any other theory of liability) for any loss or damage
19 * of any kind or nature related to, arising under or in connection with these
20 * materials, including for any direct, or any indirect, special, incidental,
21 * or consequential loss or damage (including loss of data, profits, goodwill,
22 * or any type of loss or damage suffered as a result of any action brought by
23 * a third party) even if such damage or loss was reasonably foreseeable or
24 * Xilinx had been advised of the possibility of the same.
25 *
26 * CRITICAL APPLICATIONS
27 * Xilinx products are not designed or intended to be fail-safe, or for use in
28 * any application requiring fail-safe performance, such as life-support or
29 * safety devices or systems, Class III medical devices, nuclear facilities,
30 * applications related to the deployment of airbags, or any other applications
31 * that could lead to death, personal injury, or severe property or
32 * environmental damage (individually and collectively, "Critical
33 * Applications"). Customer assumes the sole risk and liability of any use of
34 * Xilinx products in Critical Applications, subject only to applicable laws
35 * and regulations governing limitations on product liability.
36 *
37 * THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
38 * AT ALL TIMES.
39 *
40 ******************************************************************************/
41 /*****************************************************************************/
42 /**
43 * @file boot.S
44 *
45 * This file contains the initial startup code for the Cortex A9 processor
46 *
47 * <pre>
48 * MODIFICATION HISTORY:
49 *
50 * Ver   Who     Date     Changes
51 * ----- ------- -------- ---------------------------------------------------
52 * 1.00a ecm/sdm 10/20/09 Initial version
53 * 3.06a sgd     05/15/12 Updated L2CC Auxiliary and Tag RAM Latency control 
54 *                        register settings.
55 * 3.06a asa     06/17/12 Modified the TTBR settings and L2 Cache auxiliary
56 *                        register settings.
57 * 3.07a asa     07/16/12 Modified the L2 Cache controller settings to improve
58 *                        performance. Changed the property of the ".boot"
59 *                        section.
60 * 3.07a sgd     08/21/12 Modified the L2 Cache controller and cp15 Aux Control 
61 *               Register settings
62 * 3.09a sgd     02/06/13 Updated SLCR l2c Ram Control register to a 
63 *               value of 0x00020202. Fix for CR 697094 (SI#687034).
64 * 3.10a srt     04/18/13 Implemented ARM Erratas. Please refer to file
65 *                        'xil_errata.h' for errata description
66 * </pre>
67 *
68 * @note
69 *
70 * None.
71 *
72 ******************************************************************************/
73
74 #include "xparameters.h"
75 #include "xil_errata.h"
76
77 .globl MMUTable
78 .global _prestart
79 .global _boot
80 .global __stack
81 .global __irq_stack
82 .global __supervisor_stack
83 .global __abort_stack
84 .global __fiq_stack
85 .global __undef_stack
86 .global _vector_table
87
88 .set PSS_L2CC_BASE_ADDR, 0xF8F02000
89 .set PSS_SLCR_BASE_ADDR, 0xF8000000
90
91 .set RESERVED,          0x0fffff00
92 .set TblBase ,          MMUTable
93 .set LRemap,            0xFE00000F              /* set the base address of the peripheral block as not shared */
94 .set L2CCWay,           (PSS_L2CC_BASE_ADDR + 0x077C)   /*(PSS_L2CC_BASE_ADDR + PSS_L2CC_CACHE_INVLD_WAY_OFFSET)*/
95 .set L2CCSync,          (PSS_L2CC_BASE_ADDR + 0x0730)   /*(PSS_L2CC_BASE_ADDR + PSS_L2CC_CACHE_SYNC_OFFSET)*/
96 .set L2CCCrtl,          (PSS_L2CC_BASE_ADDR + 0x0100)   /*(PSS_L2CC_BASE_ADDR + PSS_L2CC_CNTRL_OFFSET)*/
97 .set L2CCAuxCrtl,       (PSS_L2CC_BASE_ADDR + 0x0104)   /*(PSS_L2CC_BASE_ADDR + XPSS_L2CC_AUX_CNTRL_OFFSET)*/
98 .set L2CCTAGLatReg,     (PSS_L2CC_BASE_ADDR + 0x0108)   /*(PSS_L2CC_BASE_ADDR + XPSS_L2CC_TAG_RAM_CNTRL_OFFSET)*/
99 .set L2CCDataLatReg,    (PSS_L2CC_BASE_ADDR + 0x010C)   /*(PSS_L2CC_BASE_ADDR + XPSS_L2CC_DATA_RAM_CNTRL_OFFSET)*/
100 .set L2CCIntClear,      (PSS_L2CC_BASE_ADDR + 0x0220)   /*(PSS_L2CC_BASE_ADDR + XPSS_L2CC_IAR_OFFSET)*/
101 .set L2CCIntRaw,        (PSS_L2CC_BASE_ADDR + 0x021C)   /*(PSS_L2CC_BASE_ADDR + XPSS_L2CC_ISR_OFFSET)*/
102
103 .set SLCRlockReg,           (PSS_SLCR_BASE_ADDR + 0x04) /*(PSS_SLCR_BASE_ADDR + XPSS_SLCR_LOCK_OFFSET)*/
104 .set SLCRUnlockReg,     (PSS_SLCR_BASE_ADDR + 0x08)     /*(PSS_SLCR_BASE_ADDR + XPSS_SLCR_UNLOCK_OFFSET)*/
105 .set SLCRL2cRamReg,     (PSS_SLCR_BASE_ADDR + 0xA1C) /*(PSS_SLCR_BASE_ADDR + XPSS_SLCR_L2C_RAM_OFFSET)*/
106
107 /* workaround for simulation not working when L1 D and I caches,MMU and  L2 cache enabled - DT568997 */
108 .if SIM_MODE == 1
109 .set CRValMmuCac,       0b00000000000000        /* Disable IDC, and MMU */
110 .else 
111 .set CRValMmuCac,       0b01000000000101        /* Enable IDC, and MMU */
112 .endif
113
114 .set CRValHiVectorAddr, 0b10000000000000        /* Set the Vector address to high, 0xFFFF0000 */
115
116 .set L2CCAuxControl,    0x72360000              /* Enable all prefetching, Cache replacement policy, Parity enable, 
117                                         Event monitor bus enable and Way Size (64 KB) */
118 .set L2CCControl,       0x01                    /* Enable L2CC */
119 .set L2CCTAGLatency,    0x0111                  /* latency for TAG RAM */
120 .set L2CCDataLatency,   0x0121                  /* latency for DATA RAM */
121
122 .set SLCRlockKey,               0x767B                  /* SLCR lock key */
123 .set SLCRUnlockKey,             0xDF0D                  /* SLCR unlock key */
124 .set SLCRL2cRamConfig,      0x00020202      /* SLCR L2C ram configuration */
125
126 /* Stack Pointer locations for boot code */
127 .set Undef_stack,       __undef_stack
128 .set FIQ_stack,         __fiq_stack
129 .set Abort_stack,       __abort_stack
130 .set SPV_stack,         __supervisor_stack
131 .set IRQ_stack,         __irq_stack
132 .set SYS_stack,         __stack
133
134 .set vector_base,       _vector_table
135
136 .set FPEXC_EN,          0x40000000              /* FPU enable bit, (1 << 30) */
137
138 .section .boot,"ax"
139
140
141 /* this initializes the various processor modes */
142
143 _prestart:
144 _boot:
145
146 #if XPAR_CPU_ID==0
147 /* only allow cpu0 through */
148         mrc     p15,0,r1,c0,c0,5
149         and     r1, r1, #0xf
150         cmp     r1, #0
151         beq     OKToRun
152 EndlessLoop0:
153         wfe
154         b       EndlessLoop0
155
156 #elif XPAR_CPU_ID==1
157 /* only allow cpu1 through */
158         mrc     p15,0,r1,c0,c0,5
159         and     r1, r1, #0xf
160         cmp     r1, #1
161         beq     OKToRun
162 EndlessLoop1:
163         wfe
164         b       EndlessLoop1
165 #endif
166
167 OKToRun:
168         mrc     p15, 0, r0, c0, c0, 0           /* Get the revision */
169         and     r5, r0, #0x00f00000 
170         and     r6, r0, #0x0000000f
171         orr     r6, r6, r5, lsr #20-4
172
173 #ifdef CONFIG_ARM_ERRATA_742230
174         cmp     r6, #0x22                       /* only present up to r2p2 */
175         mrcle   p15, 0, r10, c15, c0, 1         /* read diagnostic register */
176         orrle   r10, r10, #1 << 4               /* set bit #4 */
177         mcrle   p15, 0, r10, c15, c0, 1         /* write diagnostic register */
178 #endif
179
180 #ifdef CONFIG_ARM_ERRATA_743622
181         teq     r5, #0x00200000                 /* only present in r2p* */
182         mrceq   p15, 0, r10, c15, c0, 1         /* read diagnostic register */
183         orreq   r10, r10, #1 << 6               /* set bit #6 */
184         mcreq   p15, 0, r10, c15, c0, 1         /* write diagnostic register */
185 #endif
186
187         /* set VBAR to the _vector_table address in linker script */
188         ldr     r0, =vector_base
189         mcr     p15, 0, r0, c12, c0, 0
190
191         /*set scu enable bit in scu*/
192         ldr     r7, =0xf8f00000
193         ldr     r0, [r7]
194         orr     r0, r0, #0x1  
195         str     r0, [r7]
196
197         /*invalidate scu*/
198         ldr     r7, =0xf8f0000c
199         ldr     r6, =0xffff
200         str     r6, [r7]
201
202         /* Write to ACTLR */
203         mrc     p15, 0, r0, c1, c0, 1           /* Read ACTLR*/
204         orr     r0, r0, #(0x01 << 6)            /* set SMP bit */
205         orr     r0, r0, #(0x01 )                /* */           
206         mcr     p15, 0, r0, c1, c0, 1           /* Write ACTLR*/
207
208 /* Invalidate caches and TLBs */
209         mov     r0,#0                           /* r0 = 0  */
210         mcr     p15, 0, r0, c8, c7, 0           /* invalidate TLBs */
211         mcr     p15, 0, r0, c7, c5, 0           /* invalidate icache */
212         mcr     p15, 0, r0, c7, c5, 6           /* Invalidate branch predictor array */
213         bl      invalidate_dcache               /* invalidate dcache */
214
215 /* Invalidate L2c Cache */
216 /* For AMP, assume running on CPU1. Don't initialize L2 Cache (up to Linux) */
217 #if USE_AMP!=1
218         ldr     r0,=L2CCCrtl                    /* Load L2CC base address base + control register */
219         mov     r1, #0                          /* force the disable bit */
220         str     r1, [r0]                        /* disable the L2 Caches */
221
222         ldr     r0,=L2CCAuxCrtl                 /* Load L2CC base address base + Aux control register */
223         ldr     r1,[r0]                         /* read the register */
224         ldr     r2,=L2CCAuxControl              /* set the default bits */
225         orr     r1,r1,r2
226         str     r1, [r0]                        /* store the Aux Control Register */
227
228         ldr     r0,=L2CCTAGLatReg               /* Load L2CC base address base + TAG Latency address */
229         ldr     r1,=L2CCTAGLatency              /* set the latencies for the TAG*/
230         str     r1, [r0]                        /* store the TAG Latency register Register */
231
232         ldr     r0,=L2CCDataLatReg              /* Load L2CC base address base + Data Latency address */
233         ldr     r1,=L2CCDataLatency             /* set the latencies for the Data*/
234         str     r1, [r0]                        /* store the Data Latency register Register */
235
236         ldr     r0,=L2CCWay                     /* Load L2CC base address base + way register*/
237         ldr     r2, =0xFFFF
238         str     r2, [r0]                        /* force invalidate */
239
240         ldr     r0,=L2CCSync                    /* need to poll 0x730, PSS_L2CC_CACHE_SYNC_OFFSET */
241                                                 /* Load L2CC base address base + sync register*/
242         /* poll for completion */
243 Sync:   ldr     r1, [r0]
244         cmp     r1, #0
245         bne     Sync
246
247         ldr     r0,=L2CCIntRaw                  /* clear pending interrupts */
248         ldr     r1,[r0]
249         ldr     r0,=L2CCIntClear        
250         str     r1,[r0]
251 #endif
252
253         /* Disable MMU, if enabled */
254         mrc     p15, 0, r0, c1, c0, 0           /* read CP15 register 1 */
255         bic     r0, r0, #0x1                    /* clear bit 0 */
256         mcr     p15, 0, r0, c1, c0, 0           /* write value back */
257
258 #ifdef SHAREABLE_DDR
259         /* Mark the entire DDR memory as shareable */
260         ldr     r3, =0x3ff                      /* 1024 entries to cover 1G DDR */
261         ldr     r0, =TblBase                    /* MMU Table address in memory */
262         ldr     r2, =0x15de6                    /* S=b1 TEX=b101 AP=b11, Domain=b1111, C=b0, B=b1 */
263 shareable_loop:
264         str     r2, [r0]                        /* write the entry to MMU table */
265         add     r0, r0, #0x4                    /* next entry in the table */
266         add     r2, r2, #0x100000               /* next section */
267         subs    r3, r3, #1
268         bge     shareable_loop                  /* loop till 1G is covered */
269 #endif
270
271         /* In case of AMP, map virtual address 0x20000000 to 0x00000000  and mark it as non-cacheable */
272 #if USE_AMP==1
273         ldr     r3, =0x1ff                      /* 512 entries to cover 512MB DDR */
274         ldr     r0, =TblBase                    /* MMU Table address in memory */
275         add     r0, r0, #0x800                  /* Address of entry in MMU table, for 0x20000000 */
276         ldr     r2, =0x0c02                     /* S=b0 TEX=b000 AP=b11, Domain=b0, C=b0, B=b0 */
277 mmu_loop:
278         str     r2, [r0]                        /* write the entry to MMU table */
279         add     r0, r0, #0x4                    /* next entry in the table */
280         add     r2, r2, #0x100000               /* next section */
281         subs    r3, r3, #1
282         bge     mmu_loop                        /* loop till 512MB is covered */
283 #endif
284
285         mrs     r0, cpsr                        /* get the current PSR */
286         mvn     r1, #0x1f                       /* set up the irq stack pointer */
287         and     r2, r1, r0
288         orr     r2, r2, #0x12                   /* IRQ mode */
289         msr     cpsr, r2
290         ldr     r13,=IRQ_stack                  /* IRQ stack pointer */
291
292         mrs     r0, cpsr                        /* get the current PSR */
293         mvn     r1, #0x1f                       /* set up the supervisor stack pointer */
294         and     r2, r1, r0
295         orr     r2, r2, #0x13                   /* supervisor mode */
296         msr     cpsr, r2
297         ldr     r13,=SPV_stack                  /* Supervisor stack pointer */
298
299         mrs     r0, cpsr                        /* get the current PSR */
300         mvn     r1, #0x1f                       /* set up the Abort  stack pointer */
301         and     r2, r1, r0
302         orr     r2, r2, #0x17                   /* Abort mode */
303         msr     cpsr, r2
304         ldr     r13,=Abort_stack                /* Abort stack pointer */
305
306         mrs     r0, cpsr                        /* get the current PSR */
307         mvn     r1, #0x1f                       /* set up the FIQ stack pointer */
308         and     r2, r1, r0
309         orr     r2, r2, #0x11                   /* FIQ mode */
310         msr     cpsr, r2
311         ldr     r13,=FIQ_stack                  /* FIQ stack pointer */
312
313         mrs     r0, cpsr                        /* get the current PSR */
314         mvn     r1, #0x1f                       /* set up the Undefine stack pointer */
315         and     r2, r1, r0
316         orr     r2, r2, #0x1b                   /* Undefine mode */
317         msr     cpsr, r2
318         ldr     r13,=Undef_stack                /* Undefine stack pointer */
319
320         mrs     r0, cpsr                        /* get the current PSR */
321         mvn     r1, #0x1f                       /* set up the system stack pointer */
322         and     r2, r1, r0
323         orr     r2, r2, #0x1F                   /* SYS mode */
324         msr     cpsr, r2
325         ldr     r13,=SYS_stack                  /* SYS stack pointer */
326
327         /* enable MMU and cache */
328
329         ldr     r0,=TblBase                     /* Load MMU translation table base */
330         orr     r0, r0, #0x5B                   /* Outer-cacheable, WB */
331         mcr     15, 0, r0, c2, c0, 0            /* TTB0 */
332         
333         
334         mvn     r0,#0                           /* Load MMU domains -- all ones=manager */
335         mcr     p15,0,r0,c3,c0,0
336
337         /* Enable mmu, icahce and dcache */
338         ldr     r0,=CRValMmuCac
339
340         mcr     p15,0,r0,c1,c0,0                /* Enable cache and MMU */
341         dsb                                     /* dsb  allow the MMU to start up */
342
343         isb                                     /* isb  flush prefetch buffer */
344
345 /* For AMP, assume running on CPU1. Don't initialize L2 Cache (up to Linux) */
346 #if USE_AMP!=1
347         ldr     r0,=SLCRUnlockReg               /* Load SLCR base address base + unlock register */
348         ldr     r1,=SLCRUnlockKey           /* set unlock key */
349         str     r1, [r0]                    /* Unlock SLCR */
350
351         ldr     r0,=SLCRL2cRamReg               /* Load SLCR base address base + l2c Ram Control register */
352         ldr     r1,=SLCRL2cRamConfig        /* set the configuration value */
353         str     r1, [r0]                /* store the L2c Ram Control Register */
354
355         ldr     r0,=SLCRlockReg         /* Load SLCR base address base + lock register */
356         ldr     r1,=SLCRlockKey         /* set lock key */
357         str     r1, [r0]                /* lock SLCR */
358
359         ldr     r0,=L2CCCrtl                    /* Load L2CC base address base + control register */
360         ldr     r1,[r0]                         /* read the register */
361         mov     r2, #L2CCControl                /* set the enable bit */
362         orr     r1,r1,r2
363         str     r1, [r0]                        /* enable the L2 Caches */
364 #endif
365
366         mov     r0, r0
367         mrc     p15, 0, r1, c1, c0, 2           /* read cp access control register (CACR) into r1 */
368         orr     r1, r1, #(0xf << 20)            /* enable full access for p10 & p11 */
369         mcr     p15, 0, r1, c1, c0, 2           /* write back into CACR */
370
371         /* enable vfp */
372         fmrx    r1, FPEXC                       /* read the exception register */
373         orr     r1,r1, #FPEXC_EN                /* set VFP enable bit, leave the others in orig state */
374         fmxr    FPEXC, r1                       /* write back the exception register */
375
376         mrc     p15,0,r0,c1,c0,0                /* flow prediction enable */
377         orr     r0, r0, #(0x01 << 11)           /* #0x8000 */           
378         mcr     p15,0,r0,c1,c0,0
379
380         mrc     p15,0,r0,c1,c0,1                /* read Auxiliary Control Register */
381         orr     r0, r0, #(0x1 << 2)             /* enable Dside prefetch */
382         orr     r0, r0, #(0x1 << 1)             /* enable L2 Prefetch hint */
383         mcr     p15,0,r0,c1,c0,1                /* write Auxiliary Control Register */
384
385         b       _start                          /* jump to C startup code */
386         and     r0, r0, r0                      /* no op */
387         
388 .Ldone: b       .Ldone                          /* Paranoia: we should never get here */
389
390
391 /*
392  *************************************************************************
393  *
394  * invalidate_dcache - invalidate the entire d-cache by set/way
395  *
396  * Note: for Cortex-A9, there is no cp instruction for invalidating
397  * the whole D-cache. Need to invalidate each line.
398  *
399  *************************************************************************
400  */
401 invalidate_dcache:
402         mrc     p15, 1, r0, c0, c0, 1           /* read CLIDR */
403         ands    r3, r0, #0x7000000
404         mov     r3, r3, lsr #23                 /* cache level value (naturally aligned) */
405         beq     finished
406         mov     r10, #0                         /* start with level 0 */
407 loop1:
408         add     r2, r10, r10, lsr #1            /* work out 3xcachelevel */
409         mov     r1, r0, lsr r2                  /* bottom 3 bits are the Cache type for this level */
410         and     r1, r1, #7                      /* get those 3 bits alone */
411         cmp     r1, #2
412         blt     skip                            /* no cache or only instruction cache at this level */
413         mcr     p15, 2, r10, c0, c0, 0          /* write the Cache Size selection register */
414         isb                                     /* isb to sync the change to the CacheSizeID reg */
415         mrc     p15, 1, r1, c0, c0, 0           /* reads current Cache Size ID register */
416         and     r2, r1, #7                      /* extract the line length field */
417         add     r2, r2, #4                      /* add 4 for the line length offset (log2 16 bytes) */
418         ldr     r4, =0x3ff
419         ands    r4, r4, r1, lsr #3              /* r4 is the max number on the way size (right aligned) */
420         clz     r5, r4                          /* r5 is the bit position of the way size increment */
421         ldr     r7, =0x7fff
422         ands    r7, r7, r1, lsr #13             /* r7 is the max number of the index size (right aligned) */
423 loop2:
424         mov     r9, r4                          /* r9 working copy of the max way size (right aligned) */
425 loop3:
426         orr     r11, r10, r9, lsl r5            /* factor in the way number and cache number into r11 */
427         orr     r11, r11, r7, lsl r2            /* factor in the index number */
428         mcr     p15, 0, r11, c7, c6, 2          /* invalidate by set/way */
429         subs    r9, r9, #1                      /* decrement the way number */
430         bge     loop3
431         subs    r7, r7, #1                      /* decrement the index */
432         bge     loop2
433 skip:
434         add     r10, r10, #2                    /* increment the cache number */
435         cmp     r3, r10
436         bgt     loop1
437
438 finished:
439         mov     r10, #0                         /* swith back to cache level 0 */
440         mcr     p15, 2, r10, c0, c0, 0          /* select current cache level in cssr */
441         dsb
442         isb
443
444         bx      lr
445
446 .end
447
448