comparison src/cs/system/main/int.s @ 0:4e78acac3d88

src/{condat,cs,gpf,nucleus}: import from Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:23:26 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4e78acac3d88
1 ;******************************************************************************
2 ; TEXAS INSTRUMENTS INCORPORATED PROPRIETARY INFORMATION
3 ;
4 ; Property of Texas Instruments -- For Unrestricted Internal Use Only
5 ; Unauthorized reproduction and/or distribution is strictly prohibited. This
6 ; product is protected under copyright law and trade secret law as an
7 ; unpublished work. Created 1987, (C) Copyright 1997 Texas Instruments. All
8 ; rights reserved.
9 ;
10 ;
11 ; Filename : int.s
12 ;
13 ; Description : Nucleus initialization
14 ;
15 ; Project : Drivers
16 ;
17 ; Author : proussel@ti.com Patrick Roussel.
18 ;
19 ; Version number : 1.3
20 ;
21 ; Date and time : 07/23/98 15:36:07
22 ;
23 ; Previous delta : 07/23/98 15:36:06
24 ;
25 ; SCCS file : /db/gsm_asp/db_ht96/dsp_0/gsw/rel_0/mcu_l1/release1.5/mod/emu/EMU_MCMP/eva3_drivers/source/SCCS/s.int.s
26 ;
27 ; Sccs Id (SID) : '@(#) int.s 1.3 07/23/98 15:36:07 '
28 ;/*************************************************************************/
29 ;/* */
30 ;/* Copyright (c) 1993 - 1996 Accelerated Technology, Inc. */
31 ;/* */
32 ;/* PROPRIETARY RIGHTS of Accelerated Technology are involved in the */
33 ;/* subject matter of this material. All manufacturing, reproduction, */
34 ;/* use, and sales rights pertaining to this subject matter are governed */
35 ;/* by the license agreement. The recipient of this software implicitly */
36 ;/* accepts the terms of the license. */
37 ;/* */
38 ;/*************************************************************************/
39 ;
40 ;/*************************************************************************/
41 ;/* */
42 ;/* FILE NAME VERSION */
43 ;/* */
44 ;/* int.s PLUS/THUMB/T 1.3 */
45 ;/* */
46 ;/* COMPONENT */
47 ;/* */
48 ;/* IN - Initialization */
49 ;/* */
50 ;/* DESCRIPTION */
51 ;/* */
52 ;/* This file contains the target processor dependent initialization */
53 ;/* routines and data. */
54 ;/* */
55 ;/* AUTHOR */
56 ;/* */
57 ;/* Barry Sellew, Accelerated Technology, Inc. */
58 ;/* */
59 ;/* DATA STRUCTURES */
60 ;/* */
61 ;/* INT_Vectors Interrupt vector table */
62 ;/* */
63 ;/* FUNCTIONS */
64 ;/* */
65 ;/* INT_Initialize Target initialization */
66 ;/* INT_Vectors_Loaded Returns a NU_TRUE if all the */
67 ;/* default vectors are loaded */
68 ;/* INT_Setup_Vector Sets up an actual vector */
69 ;/* */
70 ;/* DEPENDENCIES */
71 ;/* */
72 ;/* nucleus.h System constants */
73 ;/* */
74 ;/* HISTORY */
75 ;/* */
76 ;/* NAME DATE REMARKS */
77 ;/* */
78 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
79 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
80 ;/* B. Sellew 03-14-1996 Modified to use the ROM */
81 ;/* initialization method, */
82 ;/* resulting in version 1.1 */
83 ;/* B. Sellew 03-14-1996 Verified version 1.1 */
84 ;/* B. Sellew 02-06-1997 Created version 1.3 */
85 ;/* B. Sellew 02-06-1997 Verified version 1.3 */
86 ;/* M. Manning 06-02-1997 Added support for FIQ */
87 ;/* interrupts. Bumped to 1.4 */
88 ;/* M. Manning 06-03-1997 Verified version 1.4 */
89 ;/* */
90 ;/*************************************************************************/
91 ;#define NU_SOURCE_FILE
92 ;
93 ;#include "nucleus.h" /* System constants */
94 ;
95 ;
96 ;/* Define constants used in low-level initialization. */
97 ;
98 ;
99
100
101 .if LONG_JUMP >= 3
102 .global IND_CALL
103 .global _f_load_int_mem
104 .global _ResetVector
105
106 ; Initialization for variable S_D_Mem
107 .sect ".cinit"
108 .align 4
109
110 ; S_D_Mem is a UWORD32, See mem_load.c
111 ;
112 .field 4,32
113 .field _S_D_Mem+0,32
114 .field 0,32 ; _S_D_Mem @ 0
115
116 .sect ".text"
117 .global _S_D_Mem
118 _S_D_Mem: .usect "S_D_Mem",4,4
119 .sym _S_D_Mem,_S_D_Mem,14,2,32 ; For debug only
120
121
122 ; Initialization for variable E_D_Mem
123
124 .sect ".cinit"
125 .align 4
126
127
128 ; E_D_Mem is a UWORD32, See mem_load.c
129 ;
130 .field 4,32
131 .field _E_D_Mem+0,32
132 .field 0,32 ; _E_D_Mem @ 0
133
134 .sect ".text"
135 .global _E_D_Mem
136 _E_D_Mem: .usect "E_D_Mem",4,4
137 .sym _E_D_Mem,_E_D_Mem,14,2,32 ; For debug only
138
139 .endif ; (LONG_JUMP >= 3)
140
141 .if CHIPSET == 12
142 .global _f_load_int_mem
143 .global _ResetVector
144 .global _ResetVectorTestMode ; CALYPSO PLUS TEST MODE - TO BE ERASED
145 .endif
146
147 LOCKOUT .equ 00C0h ; Interrupt lockout value
148 LOCK_MSK .equ 00C0h ; Interrupt lockout mask value
149 MODE_MASK .equ 001Fh ; Processor Mode Mask
150 SUP_MODE .equ 0013h ; Supervisor Mode (SVC)
151 IRQ_MODE .equ 0012h ; Interrupt Mode (IRQ)
152 FIQ_MODE .equ 0011h ; Fast Interrupt Mode (FIQ)
153 ABORT_MODE .equ 0017h ; Abort Interrupt Mode
154 UNDEF_MODE .equ 001Bh ; Undefined Interrupt Mode (should not happen)
155
156 IRQ_STACK_SIZE .equ 128 ; Number of bytes in IRQ stack (must be align(8))
157 ; Note that the IRQ interrupt,
158 ; by default, is managed by
159 ; Nucleus PLUS. Only several
160 ; words are actually used. The
161 ; system stack is what will
162 ; actually be used for Nuclues
163 ; PLUS managed IRQ interrupts.
164 FIQ_STACK_SIZE .equ 512 ; Number of bytes in FIQ stack. (must be align(8))
165 ; This value is application
166 ; specific. By default, Nucleus
167 ; does not manage FIQ interrupts
168 ; and furthermore, leaves them
169 ; enabled virtually all the time.
170 SYSTEM_SIZE .equ 1024 ; Define the system stack size (must be align(8))
171 TIMER_SIZE .equ 1024 ; Define timer HISR stack size (must be align(8))
172 TIMER_PRIORITY .equ 2 ; Timer HISR priority (values from
173
174 .if BOARD = 34
175 ; Name value offset type W/E W/S D/Cycles
176 CS0_CONFIG .short 0x044F ; 0 Flash 32 N F 2
177 CS1_CONFIG .short 0x02CF ; 2 RAM 32 Y F 1
178 CS2_CONFIG .short 0x02CF ; 4
179 CS3_CONFIG .short 0x02CF ; 6
180 CS7_CONFIG .short 0x02C0 ; 8 Int-RAM 32 Y 0 1
181 CS5_CONFIG .short 0x02CF ; A
182 CS6_CONFIG .short 0x02C0 ; C Int-RAM 32 Y 0 1
183 RHEA_CONFIG .short 0x002A ; E ARM -> RHEA/API adaptation
184 NUM_CS_REGS .equ 8 ; number of Chip Select Config regs to program
185 .endif
186 ; 0 to 2, where 0 is highest)
187
188 ;
189 ;/* End of low-level initialization constants. */
190 ;
191 ;
192 ;/* Define the initialization flag that indicates whether or not all of the
193 ; default vectors have been loaded during initialization. */
194 ;
195 ;INT INT_Loaded_Flag;
196
197 .def _INT_Loaded_Flag
198 .bss _INT_Loaded_Flag, 4, 4
199 ;
200 ;/* Define the vector table */
201 ;
202
203 .if CHIPSET = 12
204 .sect ".start"
205
206 .ref _INT_Bootloader_Start
207
208 _ResetVector:
209 B _INT_Bootloader_Start
210
211 .sect ".indint"
212
213 .def _IndirectVectorTable
214 _IndirectVectorTable:
215 LDR PC, [PC, #0x14]
216 LDR PC, [PC, #0x14]
217 LDR PC, [PC, #0x14]
218 LDR PC, [PC, #0x14]
219 LDR PC, [PC, #0x14]
220 LDR PC, [PC, #0x14]
221 LDR PC, [PC, #0x14]
222
223 .word INT_Undef_Inst
224 .word INT_Swi
225 .word INT_Abort_Prefetch
226 .word INT_Abort_Data
227 .word INT_Reserved
228 .word INT_IRQ
229 .word INT_FIQ
230
231 ; CALYPSO PLUS TEST MODE - TO BE ERASED
232 .sect ".intvecs"
233
234 _ResetVectorTestMode:
235 B _INT_Bootloader_Start
236 B INT_Undef_Inst
237 B INT_Swi
238 B INT_Abort_Prefetch
239 B INT_Abort_Data
240 B INT_Reserved
241 B INT_IRQ
242 B INT_FIQ
243
244 .else ; CHIPSET = 12
245
246 .sect ".intvecs"
247
248 .if BOARD = 34
249 B _INT_Initialize
250 .elseif BOARD = 35
251 B _INT_Initialize
252 .else
253 .ref _INT_Bootloader_Start
254
255 B _INT_Bootloader_Start
256 .endif
257 B INT_Undef_Inst
258 B INT_Swi
259 B INT_Abort_Prefetch
260 B INT_Abort_Data
261 B INT_Reserved
262 B Vect_IRQ
263 .if WCP_PROF = 1
264 .global _PR_StoreMonteCarloSample
265
266 ; Timing profiler using FIQ - Handle FIQ directly here
267
268 STMFD sp!,{R0-R4, LR} ; Save R0-R4 and LR on FIQ stack
269
270 MOV R0, LR ; Retrieve link register in R0
271 BL _PR_StoreMonteCarloSample ; Store into ring buffer
272 BL _IQ_FIQ_isr ; Ack FIQ
273
274 LDMFD sp!,{R0-R4, LR} ; Restore R0-R4 and LR from FIQ stack
275 SUBS PC, LR, #4 ; return from FIQ
276 .else
277 B Vect_FIQ
278 .endif
279 .endif ; CHIPSET = 12
280
281 ;
282 ; .text
283 ;
284 ; .ref cinit
285
286 .sect ".inttext"
287 .global cinit ; Linker symbol for C variable init.
288
289
290 ; Address definitions in the section where they are used.
291
292 ;
293 ;/* Define the global system stack variable. This is setup by the
294 ; initialization routine. */
295 ;
296 ;extern VOID *TCD_System_Stack;
297 ;
298 .ref _TCD_System_Stack
299 .ref _TCT_System_Limit
300 ;
301 ;
302 ;/* Define the global data structures that need to be initialized by this
303 ; routine. These structures are used to define the system timer management
304 ; HISR. */
305 ;
306 ;extern VOID *TMD_HISR_Stack_Ptr;
307 ;extern UNSIGNED TMD_HISR_Stack_Size;
308 ;extern INT TMD_HISR_Priority;
309 ;
310 .ref _TMD_HISR_Stack_Ptr
311 .ref _TMD_HISR_Stack_Size
312 .ref _TMD_HISR_Priority
313 ;
314 ;
315 ;/* Define extern function references. */
316 ;
317 ;VOID INC_Initialize(VOID *first_available_memory);
318 ;VOID TCT_Interrupt_Context_Save(VOID);
319 ;VOID TCT_Interrupt_Context_Restore(VOID);
320 ;VOID TCC_Dispatch_LISR(INT vector_number);
321 ;VOID TMT_Timer_Interrupt(void);
322 ;
323 .ref _INC_Initialize
324 .ref _TCT_Interrupt_Context_Save
325 .ref _TCT_Interrupt_Context_Restore
326 .ref _TCC_Dispatch_LISR
327 .ref _TMT_Timer_Interrupt
328
329 ;/* Application ISR */
330 .ref _IQ_IRQ_isr
331 .ref _IQ_FIQ_isr
332 ;
333 ; /* Reference pointers defined by the linker */
334 ;
335 .ref .bss
336 .ref end
337
338 .if C155_TARGET = 1
339 .def INT_C155_Boot_Entry
340 INT_C155_Boot_Entry
341 B _INT_Initialize
342 .endif
343
344 ;
345 ;/* Define indirect branching labels for the vector table */
346 ;
347
348 .def INT_Undef_Inst
349 INT_Undef_Inst
350 B arm_undefined ; Undefined
351 ;
352 .def INT_Swi
353 INT_Swi
354 B arm_swi ; Software Generated
355 ;
356 .def INT_Abort_Prefetch
357 INT_Abort_Prefetch
358 B arm_abort_prefetch ; Abort Prefetch
359 ;
360 .def INT_Abort_Data
361 INT_Abort_Data
362 B arm_abort_data ; Abort Data
363 ;
364 .def INT_Reserved
365 INT_Reserved
366 B arm_reserved ; Reserved
367 ;
368 .def Vect_IRQ
369 Vect_IRQ
370 .if TI_NUC_MONITOR = 1
371 B _INT_IRQ
372 .else
373 B INT_IRQ
374 .endif
375 ;
376 .def Vect_FIQ
377 Vect_FIQ
378 .if TI_PROFILER = 1
379 B _INT_FIQ
380 .else
381 B INT_FIQ
382 .endif
383 ;
384
385 ;
386 ;/*************************************************************************/
387 ;/* */
388 ;/* FUNCTION */
389 ;/* */
390 ;/* INT_Initialize */
391 ;/* */
392 ;/* DESCRIPTION */
393 ;/* */
394 ;/* This function sets up the global system stack variable and */
395 ;/* transfers control to the target independent initialization */
396 ;/* function INC_Initialize. Responsibilities of this function */
397 ;/* include the following: */
398 ;/* */
399 ;/* - Setup necessary processor/system control registers */
400 ;/* - Initialize the vector table */
401 ;/* - Setup the system stack pointers */
402 ;/* - Setup the timer interrupt */
403 ;/* - Calculate the timer HISR stack and priority */
404 ;/* - Calculate the first available memory address */
405 ;/* - Transfer control to INC_Initialize to initialize all of */
406 ;/* the system components. */
407 ;/* */
408 ;/* AUTHOR */
409 ;/* */
410 ;/* Barry Sellew, Accelerated Technology, Inc. */
411 ;/* */
412 ;/* CALLED BY */
413 ;/* */
414 ;/* none */
415 ;/* */
416 ;/* CALLS */
417 ;/* */
418 ;/* INC_Initialize Common initialization */
419 ;/* */
420 ;/* INPUTS */
421 ;/* */
422 ;/* None */
423 ;/* */
424 ;/* OUTPUTS */
425 ;/* */
426 ;/* None */
427 ;/* */
428 ;/* HISTORY */
429 ;/* */
430 ;/* NAME DATE REMARKS */
431 ;/* */
432 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
433 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
434 ;/* */
435 ;/*************************************************************************/
436 ;VOID INT_Initialize(void)
437 ;{
438 .def _c_int00
439 _c_int00
440
441 .include "init.asm"
442
443 addrCS0 .word 0xfffffb00 ; CS0 address space
444
445 .if BOARD = 34
446 CSConfigTable .long CS0_CONFIG
447 CS7_SIZE .equ 0x2000 ; 8 kB
448 CS7_ADDR .equ 0x03800000 ; initial address before toggling nIBOOT
449 SRAM_ADDR .equ 0x03000000 ; Internal SRAM start address
450 SRAM_SIZE .equ 0x00040000 ; 256kB
451 EXTRA_CONF .short 0x013E ; Boot configuration
452 DEF_EXTRA_CONF .short 0x063E ; Default configuration
453 addrCS7 .word 0xFFFFFB08 ; CS7 configuration
454 addrExtraConf .word 0xFFFFFB10 ; Extra configuration
455 armio_in .word 0xFFFE4800 ; ARMIO_IN register address
456 armio_out .word 0xFFFE4802 ; ARMIO_OUT register address
457 .endif
458
459 .if BOARD = 40 | 41
460 EX_MPU_CONF_REG .word 0xFFFEF006 ; Extended MPU configuration register address
461 EX_FLASH_VALUE .short 0x0008 ; set bit to enable A22
462 .endif
463
464 .if CHIPSET = 4
465 CNTL_ARM_CLK_REG .word 0xFFFFFD00 ; CNTL_ARM_CLK register address
466 DPLL_CNTRL_REG .word 0xFFFF9800 ; DPLL control register address
467 RHEA_CNTL_REG .word 0xFFFFF900 ; RHEA control register address
468
469
470 CNTL_ARM_CLK_RST .short 0x1081 ; Initialization of CNTL_ARM_CLK register
471 ; Use DPLL, Divide by 1
472 DPLL_CONTROL_RST .short 0x2002 ; Configure DPLL in default state
473 RHEA_CONTROL_RST .short 0xFF22 ; Set access factor in order to access the DPLL register
474 ; independently of the ARM clock
475 .elseif CHIPSET = 6
476 CNTL_ARM_CLK_REG .word 0xFFFFFD00 ; CNTL_ARM_CLK register address
477 CNTLCLK_26MHZ_SELECTOR .short 0x0040 ; VTCXO_26 selector
478
479 .elseif CHIPSET = 7
480 CNTL_ARM_CLK_REG .word 0xFFFFFD00 ; CNTL_ARM_CLK register address
481 DPLL_CNTRL_REG .word 0xFFFF9800 ; DPLL control register address
482 EXTRA_CONTROL_REG .word 0xFFFFFB10 ; Extra Control register CONF address
483 MPU_CTL_REG .word 0xFFFFFF08 ; MPU_CTL register address
484
485 CNTL_ARM_CLK_RST .short 0x1081 ; Initialization of CNTL_ARM_CLK register
486 ; Use DPLL, Divide by 1
487 DPLL_CONTROL_RST .short 0x2002 ; Configure DPLL in default state
488 DISABLE_DU_MASK .short 0x0800 ; Mask to Disable the DU module
489 ENABLE_DU_MASK .short 0xF7FF ; Mask to Enable the DU module
490 MPU_CTL_RST .short 0x0000 ; Reset value of MPU_CTL register - All protections disabled
491
492 .elseif CHIPSET = 8
493 CNTL_ARM_CLK_REG .word 0xFFFFFD00 ; CNTL_ARM_CLK register address
494 DPLL_CNTRL_REG .word 0xFFFF9800 ; DPLL control register address
495 EXTRA_CONTROL_REG .word 0xFFFFFB10 ; Extra Control register CONF address
496 MPU_CTL_REG .word 0xFFFFFF08 ; MPU_CTL register address
497
498 CNTL_ARM_CLK_RST .short 0x1081 ; Initialization of CNTL_ARM_CLK register
499 ; Use DPLL, Divide by 1
500 DPLL_CONTROL_RST .short 0x2002 ; Configure DPLL in default state
501 DISABLE_DU_MASK .short 0x0800 ; Mask to Disable the DU module
502 ENABLE_DU_MASK .short 0xF7FF ; Mask to Enable the DU module
503 MPU_CTL_RST .short 0x0000 ; Reset value of MPU_CTL register - All protections disabled
504
505 .elseif CHIPSET = 10
506 CNTL_ARM_CLK_REG .word 0xFFFFFD00 ; CNTL_ARM_CLK register address
507 DPLL_CNTRL_REG .word 0xFFFF9800 ; DPLL control register address
508 EXTRA_CONTROL_REG .word 0xFFFFFB10 ; Extra Control register CONF address
509 MPU_CTL_REG .word 0xFFFFFF08 ; MPU_CTL register address
510
511 CNTL_ARM_CLK_RST .short 0x1081 ; Initialization of CNTL_ARM_CLK register
512 ; Use DPLL, Divide by 1
513 DPLL_CONTROL_RST .short 0x2002 ; Configure DPLL in default state
514 DISABLE_DU_MASK .short 0x0800 ; Mask to Disable the DU module
515 ENABLE_DU_MASK .short 0xF7FF ; Mask to Enable the DU module
516 MPU_CTL_RST .short 0x0000 ; Reset value of MPU_CTL register - All protections disabled
517
518 .elseif CHIPSET = 11
519 CNTL_ARM_CLK_REG .word 0xFFFFFD00 ; CNTL_ARM_CLK register address
520 DPLL_CNTRL_REG .word 0xFFFF9800 ; DPLL control register address
521 EXTRA_CONTROL_REG .word 0xFFFFFB10 ; Extra Control register CONF address
522 MPU_CTL_REG .word 0xFFFFFF08 ; MPU_CTL register address
523
524 CNTL_ARM_CLK_RST .short 0x1081 ; Initialization of CNTL_ARM_CLK register
525 ; Use DPLL, Divide by 1
526 DPLL_CONTROL_RST .short 0x2002 ; Configure DPLL in default state
527 DISABLE_DU_MASK .short 0x0800 ; Mask to Disable the DU module
528 ENABLE_DU_MASK .short 0xF7FF ; Mask to Enable the DU module
529 MPU_CTL_RST .short 0x0000 ; Reset value of MPU_CTL register - All protections disabled
530
531 .elseif CHIPSET = 12
532 DBG_DMA_P2 .word 0xFFFEF02C ; DBG_DMA_P2 register address
533 CNTL_ARM_CLK_REG .word 0xFFFFFD00 ; CNTL_ARM_CLK register address
534 DPLL_CNTRL_REG .word 0xFFFF9800 ; DPLL control register address
535 EXTRA_CONTROL_REG .word 0xFFFFFB10 ; Extra Control register CONF address
536 MPU_CTL_REG .word 0xFFFFFF08 ; MPU_CTL register address
537
538 CNTL_ARM_CLK_RST .short 0x1081 ; Initialization of CNTL_ARM_CLK register
539 ; Use DPLL, Divide by 1
540 DPLL_CONTROL_RST .short 0x2006 ; Configure DPLL in default state
541 DISABLE_DU_MASK .short 0x0800 ; Mask to Disable the DU module
542 MPU_CTL_RST .short 0x0000 ; Reset value of MPU_CTL register - All protections disabled
543 DBG_DMA_P2_RST .short 0x0002 ; DBG_DMA_P2 register reset value
544 .endif ; CHIPSET = 4 or 6 or 7 or 8 or 10 or 11 or 12
545
546
547 c_cinit .long cinit
548
549 .def _INT_Initialize
550 _INT_Initialize
551
552 ;
553 ; Configuration of ARM clock and DPLL frequency
554 ;
555 .if CHIPSET = 4
556 ;
557 ; Configure RHEA access factor in order to allow the access of DPLL register
558 ;
559 ldr r1,RHEA_CNTL_REG ; Load address of RHEA control register in R1
560 ldrh r2,RHEA_CONTROL_RST ; Load RHEA configuration value in R2
561 strh r2,[r1] ; Store DPLL reset value in RHEA control register
562
563 ;
564 ; Configure DPLL register with reset value
565 ;
566 ldr r1,DPLL_CNTRL_REG ; Load address of DPLL register in R1
567 ldrh r2,DPLL_CONTROL_RST ; Load DPLL reset value in R2
568 strh r2,[r1] ; Store DPLL reset value in DPLL register
569
570 ;
571 ; Wait that DPLL goes in BYPASS mode
572 ;
573 Wait_DPLL_Bypass
574 ldr r2,[r1] ; Load DPLL register
575 and r2,r2,#1 ; Perform a mask on bit 0
576 cmp r2,#1 ; Compare DPLL lock bit
577 beq Wait_DPLL_Bypass ; Wait Bypass mode (i.e. bit[0]='0')
578
579 ;
580 ; Configure CNTL_ARM_CLK register with reset value: DPLL is used to
581 ; generate ARM clock with division factor of 1.
582 ;
583 ldr r1,CNTL_ARM_CLK_REG ; Load address of CNTL_ARM_CLK register in R1
584 ldrh r2,CNTL_ARM_CLK_RST ; Load CNTL_ARM_CLK reset value in R2
585 strh r2,[r1] ; Store CNTL_ARM_CLK reset value in CNTL_ARM_CLK register
586
587 .elseif CHIPSET = 6
588
589 ;
590 ; Set VTCXO_26MHZ bit to '1' in case of the VTCXO clock is 26MHz instead
591 ; of 13MHz.
592 ;
593 ldr r1, CNTL_ARM_CLK_REG ; Load CLKM base register address in R1
594 ldrh r2, [r1,#2] ; Load contents of CNTL_CLK register in R2
595 ldr r0, CNTLCLK_26MHZ_SELECTOR ; Load configuration of 26MHz selector
596 orr r0, r0, r2;
597 strh r0, [r1,#2];
598
599 ; Wait a while until clock is stable (required for AvengerII)
600 mov r0,#0x100
601 WaitAWhile1:
602 sub r0, r0, #1
603 cmp r0, #0
604 bne WaitAWhile1
605
606 .elseif CHIPSET = 7
607 ;
608 ; Configure DPLL register with reset value
609 ;
610 ldr r1,DPLL_CNTRL_REG ; Load address of DPLL register in R1
611 ldrh r2,DPLL_CONTROL_RST ; Load DPLL reset value in R2
612 strh r2,[r1] ; Store DPLL reset value in DPLL register
613
614 ;
615 ; Wait that DPLL goes in BYPASS mode
616 ;
617 Wait_DPLL_Bypass
618 ldr r2,[r1] ; Load DPLL register
619 and r2,r2,#1 ; Perform a mask on bit 0
620 cmp r2,#1 ; Compare DPLL lock bit
621 beq Wait_DPLL_Bypass ; Wait Bypass mode (i.e. bit[0]='0')
622
623 ;
624 ; Configure CNTL_ARM_CLK register with reset value: DPLL is used to
625 ; generate ARM clock with division factor of 1.
626 ;
627 ldr r1,CNTL_ARM_CLK_REG ; Load address of CNTL_ARM_CLK register in R1
628 ldrh r2,CNTL_ARM_CLK_RST ; Load CNTL_ARM_CLK reset value in R2
629 strh r2,[r1] ; Store CNTL_ARM_CLK reset value in CNTL_ARM_CLK register
630
631 ;
632 ; Disable/Enable the DU module by setting/resetting bit 11 to '1'/'0'
633 ;
634 ldr r1,EXTRA_CONTROL_REG ; Load address of Extra Control register CONF
635 ;ldrh r2,DISABLE_DU_MASK ; Load mask to write in Extra Control register CONF
636 ldrh r2,ENABLE_DU_MASK ; Load mask to write in Extra Control register CONF
637 ldrh r0,[r1] ; Load Extra Control register CONF in r0
638 ;orr r0,r0,r2 ; Disable DU module
639 and r0,r0,r2 ; Enable DU module
640 strh r0,[r1] ; Store configuration in Extra Control register CONF
641
642 ;
643 ; Disable all MPU protections
644 ;
645 ldr r1,MPU_CTL_REG ; Load address of MPU_CTL register
646 ldrh r2,MPU_CTL_RST ; Load reset value of MPU_CTL register
647 strh r2,[r1] ; Store reset value of MPU_CTL register
648
649 .elseif CHIPSET = 8
650 ;
651 ; Configure DPLL register with reset value
652 ;
653 ldr r1,DPLL_CNTRL_REG ; Load address of DPLL register in R1
654 ldrh r2,DPLL_CONTROL_RST ; Load DPLL reset value in R2
655 strh r2,[r1] ; Store DPLL reset value in DPLL register
656
657 ;
658 ; Wait that DPLL goes in BYPASS mode
659 ;
660 Wait_DPLL_Bypass
661 ldr r2,[r1] ; Load DPLL register
662 and r2,r2,#1 ; Perform a mask on bit 0
663 cmp r2,#1 ; Compare DPLL lock bit
664 beq Wait_DPLL_Bypass ; Wait Bypass mode (i.e. bit[0]='0')
665
666 ;
667 ; Configure CNTL_ARM_CLK register with reset value: DPLL is used to
668 ; generate ARM clock with division factor of 1.
669 ;
670 ldr r1,CNTL_ARM_CLK_REG ; Load address of CNTL_ARM_CLK register in R1
671 ldrh r2,CNTL_ARM_CLK_RST ; Load CNTL_ARM_CLK reset value in R2
672 strh r2,[r1] ; Store CNTL_ARM_CLK reset value in CNTL_ARM_CLK register
673
674 ;
675 ; Disable/Enable the DU module by setting/resetting bit 11 to '1'/'0'
676 ;
677 ldr r1,EXTRA_CONTROL_REG ; Load address of Extra Control register CONF
678 ;ldrh r2,DISABLE_DU_MASK ; Load mask to write in Extra Control register CONF
679 ldrh r2,ENABLE_DU_MASK ; Load mask to write in Extra Control register CONF
680 ldrh r0,[r1] ; Load Extra Control register CONF in r0
681 ;orr r0,r0,r2 ; Disable DU module
682 and r0,r0,r2 ; Enable DU module
683 strh r0,[r1] ; Store configuration in Extra Control register CONF
684
685 ;
686 ; Disable all MPU protections
687 ;
688 ldr r1,MPU_CTL_REG ; Load address of MPU_CTL register
689 ldrh r2,MPU_CTL_RST ; Load reset value of MPU_CTL register
690 strh r2,[r1] ; Store reset value of MPU_CTL register
691
692 .elseif CHIPSET = 10
693 ;
694 ; Configure DPLL register with reset value
695 ;
696 ldr r1,DPLL_CNTRL_REG ; Load address of DPLL register in R1
697 ldrh r2,DPLL_CONTROL_RST ; Load DPLL reset value in R2
698 strh r2,[r1] ; Store DPLL reset value in DPLL register
699
700 ;
701 ; Wait that DPLL goes in BYPASS mode
702 ;
703 Wait_DPLL_Bypass
704 ldr r2,[r1] ; Load DPLL register
705 and r2,r2,#1 ; Perform a mask on bit 0
706 cmp r2,#1 ; Compare DPLL lock bit
707 beq Wait_DPLL_Bypass ; Wait Bypass mode (i.e. bit[0]='0')
708
709 ;
710 ; Configure CNTL_ARM_CLK register with reset value: DPLL is used to
711 ; generate ARM clock with division factor of 1.
712 ;
713 ldr r1,CNTL_ARM_CLK_REG ; Load address of CNTL_ARM_CLK register in R1
714 ldrh r2,CNTL_ARM_CLK_RST ; Load CNTL_ARM_CLK reset value in R2
715 strh r2,[r1] ; Store CNTL_ARM_CLK reset value in CNTL_ARM_CLK register
716
717 ;
718 ; Disable/Enable the DU module by setting/resetting bit 11 to '1'/'0'
719 ;
720 ldr r1,EXTRA_CONTROL_REG ; Load address of Extra Control register CONF
721 ;ldrh r2,DISABLE_DU_MASK ; Load mask to write in Extra Control register CONF
722 ldrh r2,ENABLE_DU_MASK ; Load mask to write in Extra Control register CONF
723 ldrh r0,[r1] ; Load Extra Control register CONF in r0
724 ;orr r0,r0,r2 ; Disable DU module
725 and r0,r0,r2 ; Enable DU module
726 strh r0,[r1] ; Store configuration in Extra Control register CONF
727
728 ;
729 ; Disable all MPU protections
730 ;
731 ldr r1,MPU_CTL_REG ; Load address of MPU_CTL register
732 ldrh r2,MPU_CTL_RST ; Load reset value of MPU_CTL register
733 strh r2,[r1] ; Store reset value of MPU_CTL register
734
735 .elseif CHIPSET = 11
736 ;
737 ; Configure DPLL register with reset value
738 ;
739 ldr r1,DPLL_CNTRL_REG ; Load address of DPLL register in R1
740 ldrh r2,DPLL_CONTROL_RST ; Load DPLL reset value in R2
741 strh r2,[r1] ; Store DPLL reset value in DPLL register
742
743 ;
744 ; Wait that DPLL goes in BYPASS mode
745 ;
746 Wait_DPLL_Bypass
747 ldr r2,[r1] ; Load DPLL register
748 and r2,r2,#1 ; Perform a mask on bit 0
749 cmp r2,#1 ; Compare DPLL lock bit
750 beq Wait_DPLL_Bypass ; Wait Bypass mode (i.e. bit[0]='0')
751
752 ;
753 ; Configure CNTL_ARM_CLK register with reset value: DPLL is used to
754 ; generate ARM clock with division factor of 1.
755 ;
756 ldr r1,CNTL_ARM_CLK_REG ; Load address of CNTL_ARM_CLK register in R1
757 ldrh r2,CNTL_ARM_CLK_RST ; Load CNTL_ARM_CLK reset value in R2
758 strh r2,[r1] ; Store CNTL_ARM_CLK reset value in CNTL_ARM_CLK register
759
760 ;
761 ; Disable/Enable the DU module by setting/resetting bit 11 to '1'/'0'
762 ;
763 ldr r1,EXTRA_CONTROL_REG ; Load address of Extra Control register CONF
764 ;ldrh r2,DISABLE_DU_MASK ; Load mask to write in Extra Control register CONF
765 ldrh r2,ENABLE_DU_MASK ; Load mask to write in Extra Control register CONF
766 ldrh r0,[r1] ; Load Extra Control register CONF in r0
767 ;orr r0,r0,r2 ; Disable DU module
768 and r0,r0,r2 ; Enable DU module
769 strh r0,[r1] ; Store configuration in Extra Control register CONF
770
771 ;
772 ; Disable all MPU protections
773 ;
774 ldr r1,MPU_CTL_REG ; Load address of MPU_CTL register
775 ldrh r2,MPU_CTL_RST ; Load reset value of MPU_CTL register
776 strh r2,[r1] ; Store reset value of MPU_CTL register
777
778 .elseif CHIPSET = 12
779
780 .if BOARD = 6
781 ; Configure DBG_DMA_P2 reg => GPO_2 output pin for EVA4
782 ldr r1,DBG_DMA_P2 ; Load address of DBG_DMA_P2 register in R1
783 ldrh r2,DBG_DMA_P2_RST ; Load DBG_DMA_P2 reset value in R2
784 strh r2,[r1] ; Store reset value in register
785 ;
786 .endif ; BOARD = 6
787
788 ;
789 ; Configure DPLL register with reset value
790 ;
791 ldr r1,DPLL_CNTRL_REG ; Load address of DPLL register in R1
792 ldrh r2,DPLL_CONTROL_RST ; Load DPLL reset value in R2
793 strh r2,[r1] ; Store DPLL reset value in DPLL register
794
795 ;
796 ; Wait that DPLL goes in BYPASS mode
797 ;
798 Wait_DPLL_Bypass
799 ldr r2,[r1] ; Load DPLL register
800 and r2,r2,#1 ; Perform a mask on bit 0
801 cmp r2,#1 ; Compare DPLL lock bit
802 beq Wait_DPLL_Bypass ; Wait Bypass mode (i.e. bit[0]='0')
803
804 ;
805 ; Configure CNTL_ARM_CLK register with reset value: DPLL is used to
806 ; generate ARM clock with division factor of 1.
807 ;
808 ldr r1,CNTL_ARM_CLK_REG ; Load address of CNTL_ARM_CLK register in R1
809 ldrh r2,CNTL_ARM_CLK_RST ; Load CNTL_ARM_CLK reset value in R2
810 strh r2,[r1] ; Store CNTL_ARM_CLK reset value in CNTL_ARM_CLK register
811
812 ;
813 ; Disable the DU module by setting bit 11 to '1'
814 ;
815 ; ldr r1,EXTRA_CONTROL_REG ; Load address of Extra Control register CONF
816 ; ldrh r2,DISABLE_DU_MASK ; Load mask to write in Extra Control register CONF
817 ; ldrh r0,[r1] ; Load Extra Control register CONF in r0
818 ; orr r0,r0,r2 ; Disable DU module
819 ; strh r0,[r1] ; Store configuration in Extra Control register CONF
820
821 ;
822 ; Disable all MPU protections
823 ;
824 ldr r1,MPU_CTL_REG ; Load address of MPU_CTL register
825 ldrh r2,MPU_CTL_RST ; Load reset value of MPU_CTL register
826 strh r2,[r1] ; Store reset value of MPU_CTL register
827
828 .endif ; CHIPSET = 4 or 6 or 7 or 8 or 10 or 11 or 12
829
830 ;
831 ; Wait-state configuration of external and internal memories
832 ;
833 .if BOARD = 34
834 ;
835 ; Wait states for Perseus - see IQ_InitWaitStates for details
836 ;
837
838
839 mov r0, #NUM_CS_REGS ; number of chip selects to configure
840 ldr r1, addrCS0 ; first CS register
841 ldr r2, CSConfigTable ; table of values to program
842
843 ConfigCS:
844 ldrh r3,[r2]
845 strh r3,[r1]
846 add r1, r1, #2
847 add r2, r2, #2
848 sub r0, r0, #1
849 cmp r0, #0
850 bne ConfigCS
851
852 bl Ensure_external_access
853 bl Copy_code_into_CS7
854 bl Toggle_nIBoot
855
856 ; Wait a while - not quite sure why, but it is required for Avenger II
857 mov r0,#0x100
858 WaitAWhile2:
859 sub r0, r0, #1
860 cmp r0, #0
861 bne WaitAWhile2
862
863 bl Clear_Internal_SRAM ; This is required if the BSS is not in SRAM
864
865 .elseif BOARD = 35
866
867 ldr r1,addrCS0
868 ldrh r2,CS0_MEM_REG ; CS0 initialization
869 strh r2,[r1]
870 ldrh r2,CS1_MEM_REG ; CS1 initialization
871 strh r2,[r1,#0x2]
872 ldrh r2,CS2_MEM_REG ; CS2 initialization
873 strh r2,[r1,#0x4]
874 ldrh r2,CS7_MEM_REG ; CS7 initialization
875 strh r2,[r1,#0x8]
876 ldrh r2,CS6_MEM_REG ; CS6 initialization
877 strh r2,[r1,#0xC]
878 mov r2,#API_ADAPT ; API-RHEA configuration
879 strh r2,[r1,#0xE]
880
881 bl Ensure_external_access
882 bl Copy_code_into_CS7
883 bl Toggle_nIBoot
884 bl Clear_Internal_SRAM ; This is required if the BSS is not in SRAM
885
886 .else
887
888 ldr r1,addrCS0
889 .if CHIPSET != 12
890 ldrh r2,CS0_MEM_REG ; ROM initialization
891 strh r2,[r1] ; CS0
892
893 ldrh r2,CS1_MEM_REG ; RAM Initialization
894 strh r2,[r1,#2] ; CS1
895
896 ldrh r2,CS2_MEM_REG ; RAM Initialization
897 strh r2,[r1,#4] ; CS2
898
899 ldrh r2,CS3_MEM_REG ; Parallel I/O on B-Sample
900 strh r2,[r1,#6] ; CS3 (unused on EVA4?)
901
902 ldrh r2,CS4_MEM_REG ; Latch on B-Sample
903 strh r2,[r1,#0xa] ; CS4 (unused on EVA4)
904
905 .else
906
907 ldrh r2,CS0_MEM_REG ; CALYPSO PLUS TEST MODE - TO BE ERASED - FLASH Initialization
908 strh r2,[r1,#0x0] ; CS0
909
910 ldrh r2,CS5_MEM_REG ; FLASH Initialization
911 strh r2,[r1,#0xA] ; CS5
912
913 ldrh r2,CS4_MEM_REG ; RAM Initialization
914 strh r2,[r1,#0x8] ; CS4
915
916 .endif
917
918 .if CHIPSET = 3
919 ldrh r2,CS6_MEM_REG ; Internal SRAM initialization
920 strh r2,[r1,#0xc] ; CS6 Internal RAM
921
922 .elseif CHIPSET = 4
923 ldrh r2,CS6_MEM_REG ; Internal SRAM initialization
924 strh r2,[r1,#0xc] ; CS6 Internal RAM
925
926 ldrh r2,CS7_MEM_REG ; Internal SRAM initialization
927 strh r2,[r1,#0x8] ; CS7 Internal Boot RAM
928
929 .elseif CHIPSET = 5
930 ldrh r2,CS6_MEM_REG ; Internal SRAM initialization
931 strh r2,[r1,#0xc] ; CS6 Internal RAM
932
933 .elseif CHIPSET = 6
934 ldrh r2,CS6_MEM_REG ; Internal SRAM initialization
935 strh r2,[r1,#0xc] ; CS6 Internal RAM
936
937 .elseif CHIPSET = 7
938 ldrh r2,CS6_MEM_REG ; Internal SRAM initialization
939 strh r2,[r1,#0xc] ; CS6 Internal RAM
940
941 ldrh r2,CS7_MEM_REG ; Internal SRAM initialization
942 strh r2,[r1,#0x8] ; CS7 Internal Boot ROM
943
944 .elseif CHIPSET = 8
945 ldrh r2,CS6_MEM_REG ; Internal SRAM initialization
946 strh r2,[r1,#0xc] ; CS6 Internal RAM
947
948 ldrh r2,CS7_MEM_REG ; Internal SRAM initialization
949 strh r2,[r1,#0x8] ; CS7 Internal Boot ROM
950
951 .elseif CHIPSET = 10
952 ldrh r2,CS6_MEM_REG ; Internal SRAM initialization
953 strh r2,[r1,#0xc] ; CS6 Internal RAM
954
955 ldrh r2,CS7_MEM_REG ; Internal SRAM initialization
956 strh r2,[r1,#0x8] ; CS7 Internal Boot ROM
957
958 .elseif CHIPSET = 11
959 ldrh r2,CS6_MEM_REG ; Internal SRAM initialization
960 strh r2,[r1,#0xc] ; CS6 Internal RAM
961
962 ldrh r2,CS7_MEM_REG ; Internal SRAM initialization
963 strh r2,[r1,#0x8] ; CS7 Internal Boot ROM
964 .endif ; CHIPSET = 3 or 4 or 5 or 6 or 7 or 8 or 10 or 11
965
966 ldrh r2,CTL_MEM_REG ; API-RHEA configuration
967 strh r2,[r1,#0xe]
968
969 .endif ; BOARD = 34 | 35
970
971 .if BOARD = 40 | 41
972 ; /* On D-Sample Board, use A22 mode (ADD(22) instead of CS4) to be able to
973 ; address 8 Mbytes especially with CS0 (Flash) & CS3 (External Peripherals) */
974 ldr r1,EX_MPU_CONF_REG
975 ldrh r2,[r1]
976 ldr r0,EX_FLASH_VALUE
977 orr r0, r0, r2
978 strh r0,[r1]
979 .endif
980
981 ;
982 ; /* Insure that the processor is in supervisor mode. */
983 ;
984 MRS a1,CPSR ; Pickup current CPSR
985 BIC a1,a1,#MODE_MASK ; Clear the mode bits
986 ORR a1,a1,#SUP_MODE ; Set the supervisor mode bits
987 ORR a1,a1,#LOCKOUT ; Insure IRQ and FIQ interrupts are
988 ; locked out
989 MSR CPSR,a1 ; Setup the new CPSR
990 ;
991
992 ;
993 ;
994 ; REWORK OF .bss INITIALIZATION - start
995 ; Creation of INT_memset and INT_memcpy, respectively identical to memset and
996 ; memcpy from the rts library of compiler V2.51/2.54.
997 ; They are used to make the initialization of the .bss section and the load
998 ; of the internal ram code not dependent to the 32-bit alignment.
999 ; The old code used for the initialization and the load used a loop with
1000 ; 4-byte increment, assuming the 32-bit alignment of the .bss section.
1001 ; This alignment is not necessary true.
1002 ;
1003 ; /* Clear the un-initialized global and static C data areas. */
1004 ; Initialize the system stack pointer a first time to allow use of memset function
1005 ; which needs stack.
1006 ; The system stack pointers will be fully initialized after having cleared
1007 ; the BSS area. */
1008 ;
1009 LDR a1,StackSegment ; Pickup the begining address from .cmd file
1010 ; (is aligned on 8 byte boundary)
1011
1012 MOV a2,#SYSTEM_SIZE ; Pickup system stack size
1013 SUB a2,a2,#4 ; Subtract one word for first addr
1014 ADD a3,a1,a2 ; Build start of system stack area
1015
1016 MOV sp,a3 ; Setup initial stack pointer
1017
1018 STMFD sp!,{a1-a4} ; Save a1-a4 registers to stack
1019
1020 LDR a1,BSS_Start ; Pickup the start of the BSS area
1021 LDR a3,BSS_End ; Pickup the end of the BSS area
1022 SUB a3,a3,a1 ; Calculate size of the BSS area
1023 MOV a2,#0 ; Clear value in a2
1024
1025 BL _INT_memset ; Clear the BSS area using memset function
1026
1027 .if LONG_JUMP >= 3 ;
1028 LDR a1,BSS_IntMem_Start ; Pickup the start of the BSS area
1029 LDR a3,BSS_IntMem_End ; Pickup the end of the BSS area
1030 SUB a3,a3,a1 ; Calculate size of the BSS area
1031 MOV a2,#0 ; Clear value in a2
1032
1033 BL _INT_memset ; Clear the BSS area using memset function
1034
1035 .endif
1036
1037 LDMFD sp!,{a1-a4} ; Restore a1-a4 registers from stack
1038
1039 ; REWORK OF .bss INITIALIZATION - end
1040
1041 ;
1042 ; /* Setup the vectors loaded flag to indicate to other routines in the
1043 ; system whether or not all of the default vectors have been loaded.
1044 ; If INT_Loaded_Flag is 1, all of the default vectors have been loaded.
1045 ; Otherwise, if INT_Loaded_Flag is 0, registering an LISR cause the
1046 ; default vector to be loaded. In the THUMB this variable is always
1047 ; set to 1. All vectors must be setup by this function. */
1048 ; INT_Loaded_Flag = 0;
1049 ;
1050 MOV a1,#1 ; All vectors are assumed loaded
1051 LDR a2,Loaded_Flag ; Build address of loaded flag
1052 STR a1,[a2,#0] ; Initialize loaded flag
1053 ;
1054 ; /* Initialize the system stack pointers. This is done after the BSS is
1055 ; cleared because the TCD_System_Stack pointer is a BSS variable! It is
1056 ; assumed that the .cmd file is written to direct where these stacks should
1057 ; be allocated and to align them on double word boundaries.
1058 ;
1059 LDR a1,StackSegment ; Pickup the begining address from .cmd file
1060 ; (is aligned on 8 byte boundary)
1061 MOV a2,#SYSTEM_SIZE ; Pickup system stack size
1062 SUB a2,a2,#4 ; Subtract one word for first addr
1063 ADD a3,a1,a2 ; Build start of system stack area
1064 MOV v7,a1 ; Setup initial stack limit
1065 LDR a4,System_Limit ; Pickup system stack limit address
1066 STR v7,[a4, #0] ; Save stack limit
1067 MOV sp,a3 ; Setup initial stack pointer
1068 LDR a4,System_Stack ; Pickup system stack address
1069 STR sp,[a4, #0] ; Save stack pointer
1070 MOV a2,#IRQ_STACK_SIZE ; Pickup IRQ stack size in bytes
1071 ADD a3,a3,a2 ; Allocate IRQ stack area
1072 MRS a1,CPSR ; Pickup current CPSR
1073 BIC a1,a1,#MODE_MASK ; Clear the mode bits
1074 ORR a1,a1,#IRQ_MODE ; Set the IRQ mode bits
1075 MSR CPSR,a1 ; Move to IRQ mode
1076 MOV sp,a3 ; Setup IRQ stack pointer
1077 MOV a2,#FIQ_STACK_SIZE ; Pickup FIQ stack size in bytes
1078 ADD a3,a3,a2 ; Allocate FIQ stack area
1079 MRS a1,CPSR ; Pickup current CPSR
1080 BIC a1,a1,#MODE_MASK ; Clear the mode bits
1081 ORR a1,a1,#FIQ_MODE ; Set the FIQ mode bits
1082 MSR CPSR,a1 ; Move to the FIQ mode
1083 MOV sp,a3 ; Setup FIQ stack pointer
1084
1085 MRS a1,CPSR ; Pickup current CPSR
1086 BIC a1,a1,#MODE_MASK ; Clear the mode bits
1087 ORR a1,a1,#ABORT_MODE ; Set the Abort mode bits
1088 MSR CPSR,a1 ; Move to the Abort mode
1089 LDR sp,Exception_Stack ; Setup Abort stack pointer
1090
1091 MRS a1,CPSR ; Pickup current CPSR
1092 BIC a1,a1,#MODE_MASK ; Clear the mode bits
1093 ORR a1,a1,#UNDEF_MODE ; Set the Undefined mode bits
1094 MSR CPSR,a1 ; Move to the Undefined mode
1095 LDR sp,Exception_Stack ; Setup Undefined stack pointer
1096 ; (should never be used)
1097
1098 ; go to Supervisor Mode
1099 MRS a1,CPSR ; Pickup current CPSR
1100 BIC a1,a1,#MODE_MASK ; Clear mode bits
1101 ORR a1,a1,#SUP_MODE ; Set the supervisor mode bits
1102 MSR CPSR,a1 ; All interrupt stacks are setup,
1103 ; return to supervisor mode
1104 ;
1105 ; /* Define the global data structures that need to be initialized by this
1106 ; routine. These structures are used to define the system timer
1107 ; management HISR. */
1108 ; TMD_HISR_Stack_Ptr = (VOID *) a3;
1109 ; TMD_HISR_Stack_Size = TIMER_SIZE;
1110 ; TMD_HISR_Priority = TIMER_PRIORITY;
1111 ;
1112 ; TMD_HISR_Stack_Ptr points at the top (the lowest address) of the allocated
1113 ; area. The Timer HISR (called "SYSTEM H") and its related stack will be created
1114 ; in TMI_Initialize(). The current stack pointer will be set at the bottom (the
1115 ; lowest address) of the expected area.
1116
1117 LDR a4,HISR_Stack_Ptr ; Pickup variable's address
1118 ADD a3,a3,#4 ; Increment to next available word
1119 STR a3,[a4, #0] ; Setup timer HISR stack pointer
1120 MOV a2,#TIMER_SIZE ; Pickup the timer HISR stack size
1121 BIC a2,a2,#3 ; Insure word alignment
1122 ADD a3,a3,a2 ; Allocate the timer HISR stack
1123 ; from available memory
1124 LDR a4,HISR_Stack_Size ; Pickup variable's address
1125 STR a2,[a4, #0] ; Setup timer HISR stack size
1126 MOV a2,#TIMER_PRIORITY ; Pickup timer HISR priority (0-2)
1127 LDR a4,HISR_Priority ; Pickup variable's address
1128 STR a2,[a4, #0] ; Setup timer HISR priority
1129
1130 .if CHIPSET = 12
1131 ; This sequence must be always done in order to download the interrupt
1132 ; vector remapping
1133 MOV V1, a3 ; Save a3 register
1134 BL _f_load_int_mem ; Download FLASH to Internal RAM
1135 MOV a3, V1 ; Restore a3 register
1136 .else
1137
1138 .if LONG_JUMP >= 3
1139 MOV V1, a3 ; Save a3 register
1140 BL _f_load_int_mem ; Download FLASH to Internal RAM
1141 MOV a3, V1 ; Restore a3 register
1142 .endif
1143
1144 .endif ; CHIPSET != 12
1145
1146 ; We now fill up the System, IRQ, FIQ and System Timer HISR stacks with 0xFE for
1147 ; checking the status of the stacks later.
1148 ; inputs:
1149 ; a3 still has the bottom of all four stacks and is aligned.
1150 ; algorithm:
1151 ; We start from the top of all four stacks (*System_Limit), which is
1152 ; necessarily aligned. We store 0xFEFEFEFE until we have filled the
1153 ; bottom of the fourth stack
1154 ; outputs:
1155 ; memory has 0xFE on all four stacks: System, FIQ, IRQ and System Timer HISR
1156 ; a3 still has the bottom of all four stacks
1157
1158 LDR a2,System_Limit ; pickup system stack limit address
1159 LDR a1,[a2] ; a1 = StackSegment
1160 MOV a4,#0FEh ; use this and the next 7 instructons to set a4 = 0xFEFEFEFE
1161 STRB a4,[a1, #0]
1162 STRB a4,[a1, #1]
1163 STRB a4,[a1, #2]
1164 STRB a4,[a1, #3]
1165 LDR a4,[a1],#4 ; stored first word, move to second
1166
1167 fill_stack:
1168 STR a4,[a1],#4 ; store a word and increment by four
1169 CMP a1,a3 ; is this the last address?
1170 BLT fill_stack ; if not, loop back
1171
1172 ;
1173 ; Perform auto-initialization. if cinit is -1, then there is none.
1174 ;
1175 LDR r0, c_cinit
1176 CMN r0, #1
1177 BLNE _auto_init
1178 ;
1179 ; /* Call INC_Initialize with a pointer to the first available memory
1180 ; address after the compiler's global data. This memory may be used
1181 ; by the application. */
1182 ; INC_Initialize(first_available_memory);
1183 ;
1184 MOV a1,a3 ; Pass the first available memory
1185 B _INC_Initialize ; to high-level initialization
1186 ;}
1187 ;
1188
1189
1190 .if BOARD=35 | BOARD=34
1191
1192 ;/*
1193 ; * FUNCTION
1194 ; *
1195 ; * Ensure_external_access
1196 ; */
1197 Ensure_external_access:
1198 ;AI_ResetBit(4); // request shared mem clock
1199 ldr r1, armio_out
1200 ldrh r2, [r1]
1201 bic r2, r2, #0x10
1202 strh r2, [r1]
1203
1204 ;while(AI_ReadBit(5)!=1); // wait for acknowledge
1205 ack:
1206 ldr r1, armio_in
1207 ldrh r2, [r1]
1208 and r2, r2, #0x20
1209 cmp r2, #0x20
1210 bne ack
1211 bx lr ; Return to caller
1212
1213 ;/*
1214 ; * FUNCTION
1215 ; *
1216 ; * Copy_code_into_CS7
1217 ; */
1218 Copy_code_into_CS7:
1219 ldr r1, addrExtraConf
1220 ldr r3, DEF_EXTRA_CONF
1221 strh r3, [r1] ; ensure CS7 selects internal memory
1222
1223 mov r0, #CS7_SIZE ; size of CS7 memory in bytes
1224 mov r1, #CS7_ADDR ; destination
1225 mov r2, #0 ; source
1226 CopyIntCode:
1227 ldr r3,[r2]
1228 str r3,[r1]
1229 add r1, r1, #4
1230 add r2, r2, #4
1231 sub r0, r0, #4
1232 cmp r0, #0
1233 bne CopyIntCode
1234
1235 ldr r1, addrCS7
1236 ldr r2, [r1]
1237 bic r2, r2, #0x80 ; Write Enable OFF on CS7
1238 strh r2, [r1]
1239 bx lr ; Return to caller
1240
1241 ;/*
1242 ; * FUNCTION
1243 ; *
1244 ; * Toggle_nIBoot
1245 ; */
1246 Toggle_nIBoot:
1247 ldr r1, addrExtraConf ; Address of Extra Conf Register
1248 ldr r3, EXTRA_CONF ; set CS7 at address zero
1249 strh r3, [r1]
1250 bx lr ; Return to caller
1251
1252 ;/*
1253 ; * FUNCTION
1254 ; *
1255 ; * Clear_Internal_SRAM
1256 ; */
1257 Clear_Internal_SRAM:
1258 mov r0, #SRAM_ADDR ; r0 points to SRAM start
1259 mov r1, #SRAM_SIZE
1260 add r1, r0, r1 ; r1 points to SRAM end
1261 mov r2, #0
1262
1263 ClearSram:
1264 str r2,[r0], #4
1265 cmp r0, r1 ; done?
1266 bne ClearSram ; no - loop
1267 bx lr ; Return to caller
1268
1269 .endif ; BOARD=34 | BOARD=35
1270
1271 ;
1272 ;/*************************************************************************/
1273 ;/* */
1274 ;/* FUNCTION */
1275 ;/* */
1276 ;/* INT_Vectors_Loaded */
1277 ;/* */
1278 ;/* DESCRIPTION */
1279 ;/* */
1280 ;/* This function returns the flag that indicates whether or not */
1281 ;/* all the default vectors have been loaded. If it is false, */
1282 ;/* each LISR register also loads the ISR shell into the actual */
1283 ;/* vector table. */
1284 ;/* */
1285 ;/* AUTHOR */
1286 ;/* */
1287 ;/* Barry Sellew, Accelerated Technology, Inc. */
1288 ;/* */
1289 ;/* CALLED BY */
1290 ;/* */
1291 ;/* TCC_Register_LISR Register LISR for vector */
1292 ;/* */
1293 ;/* CALLS */
1294 ;/* */
1295 ;/* None */
1296 ;/* */
1297 ;/* INPUTS */
1298 ;/* */
1299 ;/* None */
1300 ;/* */
1301 ;/* OUTPUTS */
1302 ;/* */
1303 ;/* None */
1304 ;/* */
1305 ;/* HISTORY */
1306 ;/* */
1307 ;/* NAME DATE REMARKS */
1308 ;/* */
1309 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
1310 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
1311 ;/* */
1312 ;/*************************************************************************/
1313 ;INT INT_Vectors_Loaded(void)
1314 ;{
1315 .def $INT_Vectors_Loaded
1316 $INT_Vectors_Loaded ; Dual-state interworking veneer
1317 .state16
1318 BX pc
1319 NOP
1320 .state32
1321 B _INT_Vectors_Loaded
1322 ;
1323 .def _INT_Vectors_Loaded
1324 _INT_Vectors_Loaded
1325 ;
1326 ; /* Just return the loaded vectors flag. */
1327 ; return(INT_Loaded_Flag);
1328 ;
1329 MOV a1,#1 ; Always return TRUE since there
1330 ; are really only two normal
1331 ; vectors IRQ & FIQ
1332 BX lr ; Return to caller
1333 ;}
1334 ;
1335 ;
1336 ;/*************************************************************************/
1337 ;/* */
1338 ;/* FUNCTION */
1339 ;/* */
1340 ;/* INT_Setup_Vector */
1341 ;/* */
1342 ;/* DESCRIPTION */
1343 ;/* */
1344 ;/* This function sets up the specified vector with the new vector */
1345 ;/* value. The previous vector value is returned to the caller. */
1346 ;/* */
1347 ;/* AUTHOR */
1348 ;/* */
1349 ;/* Barry Sellew, Accelerated Technology, Inc. */
1350 ;/* */
1351 ;/* CALLED BY */
1352 ;/* */
1353 ;/* Application */
1354 ;/* TCC_Register_LISR Register LISR for vector */
1355 ;/* */
1356 ;/* CALLS */
1357 ;/* */
1358 ;/* None */
1359 ;/* */
1360 ;/* INPUTS */
1361 ;/* */
1362 ;/* vector Vector number to setup */
1363 ;/* new Pointer to new assembly */
1364 ;/* language ISR */
1365 ;/* */
1366 ;/* OUTPUTS */
1367 ;/* */
1368 ;/* old vector contents */
1369 ;/* */
1370 ;/* HISTORY */
1371 ;/* */
1372 ;/* NAME DATE REMARKS */
1373 ;/* */
1374 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
1375 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
1376 ;/* */
1377 ;/*************************************************************************/
1378 ;VOID *INT_Setup_Vector(INT vector, VOID *new)
1379 ;{
1380 .def $INT_Setup_Vector
1381 $INT_Setup_Vector ; Dual-state interworking veneer
1382 .state16
1383 BX pc
1384 NOP
1385 .state32
1386 B _INT_Setup_Vector
1387 ;
1388 .def _INT_Setup_Vector
1389 _INT_Setup_Vector
1390 ;
1391 ;VOID *old_vector; /* Old interrupt vector */
1392 ;VOID **vector_table; /* Pointer to vector table */
1393 ;
1394 ; /* Calculate the starting address of the actual vector table. */
1395 ; vector_table = (VOID **) 0;
1396 ;
1397 ; /* Pickup the old interrupt vector. */
1398 ; old_vector = vector_table[vector];
1399 ;
1400 ; /* Setup the new interrupt vector. */
1401 ; vector_table[vector] = new;
1402 ;
1403 ; /* Return the old interrupt vector. */
1404 ; return(old_vector);
1405 ;
1406 MOV a1,#0 ; This routine is not applicable to
1407 ; THUMB, return a NULL pointer
1408 BX lr ; Return to caller
1409 ;}
1410 ;
1411 ;
1412 ;
1413 ;
1414 ;/*************************************************************************/
1415 ;/* */
1416 ;/* FUNCTIONS */
1417 ;/* */
1418 ;/* INT_EnableIRQ, INT_DisableIRQ */
1419 ;/* */
1420 ;/* DESCRIPTION */
1421 ;/* */
1422 ;/* This function enable/disable IRQ/FIQ in current mode */
1423 ;/* */
1424 ;/*************************************************************************/
1425 ;
1426 .global $INT_EnableIRQ
1427 $INT_EnableIRQ:
1428 .state16
1429 BX pc
1430 nop
1431
1432 .state32
1433 MRS a1, CPSR ; read current PSR
1434 BIC a1,a1,#MODE_MASK ; remove all mode bits
1435 ORR a1,a1,#IRQ_MODE ; retrieve desired mode
1436 MSR CPSR,a1 ; IRQ mode
1437
1438 MRS a1, CPSR ; read current PSR
1439 BIC a1,a1,#LOCKOUT ; interrupt lockout value
1440 MSR CPSR,a1 ; Lockout interrupts
1441
1442 BIC a1,a1,#MODE_MASK ; remove all mode bits
1443 ORR a1,a1,#SUP_MODE
1444 MSR CPSR,a1 ; Lockout interrupts
1445
1446 add a1, pc, #1 ; back to Thumb mode
1447 bx a1
1448
1449 .state16
1450 BX lr ; Return to caller
1451
1452 ;
1453 ;
1454 .global $INT_DisableIRQ
1455 $INT_DisableIRQ:
1456 .state16
1457 BX pc
1458 nop
1459
1460 .state32
1461 MRS a1, CPSR ; read current PSR
1462 BIC a1,a1,#MODE_MASK ; remove all mode bits
1463 ORR a1,a1,#IRQ_MODE ; retrieve desired mode
1464 MSR CPSR,a1 ; IRQ mode
1465
1466 MRS a1, CPSR ; read current PSR
1467 ORR a1,a1,#LOCKOUT ; Build interrupt lockout value
1468 MSR CPSR,a1 ; Lockout interrupts
1469
1470 BIC a1,a1,#MODE_MASK ; remove all mode bits
1471 ORR a1,a1,#SUP_MODE
1472 MSR CPSR,a1 ; Lockout interrupts
1473
1474 add a1, pc, #1 ; back to Thumb mode
1475 bx a1
1476
1477 .state16
1478 BX lr ; Return to caller
1479 ;
1480 ;
1481 ;/*************************************************************************/
1482 ;/* */
1483 ;/* FUNCTION */
1484 ;/* */
1485 ;/* INT_Retrieve_Shell */
1486 ;/* */
1487 ;/* DESCRIPTION */
1488 ;/* */
1489 ;/* This function retrieves the pointer to the shell interrupt */
1490 ;/* service routine. The shell interrupt service routine calls */
1491 ;/* the LISR dispatch routine. */
1492 ;/* */
1493 ;/* AUTHOR */
1494 ;/* */
1495 ;/* Barry Sellew, Accelerated Technology, Inc. */
1496 ;/* */
1497 ;/* CALLED BY */
1498 ;/* */
1499 ;/* TCC_Register_LISR Register LISR for vector */
1500 ;/* */
1501 ;/* CALLS */
1502 ;/* */
1503 ;/* None */
1504 ;/* */
1505 ;/* INPUTS */
1506 ;/* */
1507 ;/* vector Vector number to setup */
1508 ;/* */
1509 ;/* OUTPUTS */
1510 ;/* */
1511 ;/* shell pointer */
1512 ;/* */
1513 ;/* HISTORY */
1514 ;/* */
1515 ;/* NAME DATE REMARKS */
1516 ;/* */
1517 ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
1518 ;/* B. Sellew 01-22-1996 Verified version 1.0 */
1519 ;/* */
1520 ;/*************************************************************************/
1521 ;VOID *INT_Retrieve_Shell(INT vector)
1522 ;{
1523 .def $INT_Retrieve_Shell
1524 $INT_Retrieve_Shell ; Dual-state interworking veneer
1525 .state16
1526 BX pc
1527 NOP
1528 .state32
1529 B _INT_Retrieve_Shell
1530 ;
1531 .def _INT_Retrieve_Shell
1532 _INT_Retrieve_Shell
1533 ;
1534 ; /* Return the LISR Shell interrupt routine. */
1535 ; return(INT_Vectors[vector]);
1536 ;
1537 MOV a1,#0 ; This routine is not applicable to
1538 ; THUMB, return a NULL pointer
1539 BX lr ; Return to caller
1540 ;}
1541 ;
1542 ;
1543 ;
1544 ;/* The following section contains default interrupt handlers. */
1545 ;
1546 .if TI_NUC_MONITOR = 1
1547 ; define a new section to be mapped independently
1548 ; .sect ".irqtext"
1549
1550 .def _INT_IRQ
1551 .global _INT_IRQ
1552 _INT_IRQ
1553 .else
1554 .def INT_IRQ
1555 INT_IRQ
1556 .endif
1557
1558 ;
1559 ; /* Call Prepare for IRQ interrupt processing by calling
1560 ; TCT_Interrupt_Context_Save. */
1561 STMDB sp!,{a1-a4} ; Save a1-a4 on temporary IRQ stack
1562
1563 ;BUG correction 1st part -------------------
1564 ;It looks like there is an issue with ARM7 IRQ masking in the CPSR register
1565 ;which leads to crashes in Nucleus+ scheduler.
1566 ;Basically the code below (correct as LOCKOUT = 0xC0) is used in many places by N+ but do not
1567 ;prevent from having an interrupt after the execution of the third line (I mean execution, not
1568 ;fetch).
1569 ; MRS a1,CPSR ; Pickup current CPSR
1570 ; ORR a1,a1,#LOCKOUT ; Build interrupt lockout value
1571 ; MSR CPSR,a1 ; Lockout interrupts
1572 ; * IRQ INTERRUPT ! *
1573 ; Next instructions...
1574 ;
1575 ;SW workaround:
1576 ;When a task is interrupted at this point an interrupted context is stored on its task and will
1577 ;be resumed later on at the next instruction but to make a long story short it leads to some
1578 ;problem as the OS does not expect to be interrupted there.
1579 ;Further testing tends to show that the CPSR *seems* to be loaded with the proper masking value
1580 ;but that the IRQ is still triggered (has been hardwarewise requested during the instruction
1581 ;exectution by the ARM7 core?)
1582 MRS a1,spsr ; check for the IRQ bug:
1583 TST a1,#080h ; if the I - flag is set,
1584 BNE IRQBUG ; then postpone execution of this IRQ
1585 ;Bug correction 1st part end ---------------
1586
1587 SUB a4,lr,#4 ; Save IRQ's lr (return address)
1588 BL _TCT_Interrupt_Context_Save ; Call context save routine
1589
1590 .if TI_NUC_MONITOR = 1
1591 ; Log the IRQ call entry
1592 .global _ti_nuc_monitor_LISR_log
1593 BL _ti_nuc_monitor_LISR_log ; Call the LISR Log function.
1594 .endif
1595
1596 ;
1597 ; /* On actuall hardware, a register must be examined to see what the
1598 ; IRQ interrupt was caused from. For default processing, the
1599 ; timer is the only IRQ interrupt source. It is assumed that further
1600 ; timer interrupts are disabled upon this call. */
1601 ;
1602 BL _IQ_IRQ_isr ; Call int. service routine
1603
1604 .if TI_NUC_MONITOR = 1
1605 ; Log the IRQ exit
1606 .global _ti_nuc_monitor_LISR_log_end
1607 BL _ti_nuc_monitor_LISR_log_end ; Call the LISR end function.
1608 .endif
1609
1610 ;
1611 ; /* IRQ interrupt processing is complete. Restore context- Never
1612 ; returns! */
1613 B _TCT_Interrupt_Context_Restore
1614
1615 ;BUG correction 2nd part ------------------
1616 IRQBUG: LDMFD sp!,{a1-a4} ; return from interrupt
1617 SUBS pc,r14,#4
1618 ;BUG correction 2nd part end --------------
1619
1620 ;
1621 .if TI_NUC_MONITOR = 1
1622 .sect ".inttext"
1623 .endif
1624 ;
1625 .if TI_PROFILER = 1
1626 ; define a new section to be mapped independently
1627 ; .sect ".fiqtext"
1628
1629 .def _INT_FIQ
1630 .global _INT_FIQ
1631 _INT_FIQ
1632 .else
1633 .def INT_FIQ
1634 INT_FIQ
1635 .endif
1636
1637 .if TI_PROFILER = 1
1638 ; Warning :
1639 ; This code has been added for profiliing purpose.
1640 ; It removes all other FIQ.
1641 .global _ti_profiler_handler
1642 ; Timing profiler using FIQ - Handle FIQ directly here
1643 STMFD sp!,{R0-R4, LR} ; Save R0-R4 and LR on FIQ stack
1644
1645 MOV R0, LR ; Retrieve link register in R0
1646 BL _ti_profiler_handler ; Store into buffer
1647 BL _IQ_FIQ_isr ; Call the FIQ ISR
1648 LDMFD sp!,{R0-R4, LR} ; Restore R0-R4 and LR from FIQ stack
1649 SUBS PC, LR, #4 ; return from FIQ
1650 .else
1651
1652 ;
1653 ; /* Call Prepare for FIQ interrupt processing by calling
1654 ; TCT_Interrupt_Context_Save. */
1655 STMDB sp!,{a1-a4} ; Save a1-a4 on temporary FIQ stack
1656 SUB a4,lr,#4 ; Save FIQ's lr (return address)
1657 BL _TCT_Interrupt_Context_Save ; Call context save routine
1658 ;
1659 ; /* On actuall hardware, a register must be examined to see what the
1660 ; FIQ interrupt was caused from. For default processing, the
1661 ; test is the only FIQ interrupt source. */
1662 ;
1663 ; /* Replace this with a call to your own ISR */
1664 BL _IQ_FIQ_isr ; Call the FIQ ISR
1665
1666 ;
1667 ; /* FIQ interrupt processing is complete. Restore context- Never
1668 ; returns! */
1669 B _TCT_Interrupt_Context_Restore
1670
1671 .endif
1672
1673 .if TI_PROFILER = 1
1674 .sect ".inttext"
1675 .endif
1676
1677 ;***************************************************************
1678 ;* CONSTANT TABLE *
1679 ;***************************************************************
1680
1681 ;
1682 ; /* Define all the global addresses used in this section */
1683 ;
1684
1685 ; internal/external RAM
1686 .if CHIPSET = 3 | CHIPSET = 5 | CHIPSET = 6
1687 RAM_SIZE .equ 0x40000 ; size (in bytes) of internal RAM
1688 RAM_LOW .equ 0x3000000 ; first address of internal RAM
1689 .elseif CHIPSET = 4
1690 RAM_SIZE .equ 0x40000 ; size (in bytes) of internal RAM
1691 RAM_LOW .equ 0x800000 ; first address of internal RAM
1692 .elseif CHIPSET = 7 | CHIPSET = 8 | CHIPSET = 10 | CHIPSET = 11 | CHIPSET = 12
1693 .if L1_GPRS = 1
1694 RAM_SIZE .equ 0x200000 ; size (in bytes) of external RAM
1695 RAM_LOW .equ 0x1000000 ; first address of external RAM
1696 .else ; GSM ONLY
1697 RAM_SIZE .equ 0x80000 ; size (in bytes) of internal RAM
1698 RAM_LOW .equ 0x800000 ; first address of internal RAM
1699 .endif
1700 .endif
1701
1702 RAM_HIGH .equ RAM_LOW + RAM_SIZE ; first address after internal/external RAM
1703
1704
1705 .global exception_stack ; top address of SVC mode stack
1706
1707 .global _xdump_buffer ; first address of state data
1708
1709 .global stack_segment ; address of the top of the system stack
1710
1711 ;
1712 ; /* Define exception functions */
1713 ;
1714 .ref _dar_exception
1715
1716 XDUMP_STACK_SIZE .equ 20
1717
1718 ; layout of xdump buffer:
1719 ; struct xdump_s {
1720 ; long registers[16] // svc mode registers
1721 ; long cpsr // svc mode CPSR
1722 ; long exception // magic word + index of vector taken
1723 ; long stack[20] // bottom 20 words of usr mode stack
1724 ; }
1725
1726 arm_undefined:
1727 stmfd r13!,{r11,r12} ; store r12 for Xdump_buffer pointer, r11 for index
1728 mov r11,#1
1729 b save_regs
1730
1731 arm_swi:
1732 stmfd r13!,{r11,r12} ; store r12 for Xdump_buffer pointer, r11 for index
1733 mov r11,#2
1734 b save_regs
1735
1736 arm_abort_prefetch:
1737 stmfd r13!,{r11,r12} ; store r12 for Xdump_buffer pointer, r11 for index
1738 mov r11,#3
1739 b save_regs
1740
1741
1742 arm_abort_data:
1743 stmfd r13!,{r11,r12} ; store r12 for Xdump_buffer pointer, r11 for index
1744 mov r11,#4
1745 b save_regs
1746
1747 arm_reserved:
1748 ldr r13,Exception_Stack ; should never happen, but mode is unknown at this point
1749 stmfd r13!,{r11,r12} ; store r12 for Xdump_buffer pointer, r11 for index
1750 mov r11,#5
1751 b save_regs
1752
1753 save_regs:
1754 ldr r12,Xdump_buffer
1755 str r14,[r12,#4*15] ; save r14_abt (original PC) into r15 slot
1756
1757 stmia r12,{r0-r10} ; save unbanked registers (except r11 and r12)
1758 ldmfd r13!,{r0,r1} ; get original r11 and r12
1759 str r0,[r12,#4*11] ; save original r11
1760 str r1,[r12,#4*12] ; save original r12
1761 mrs r0,spsr ; get original psr
1762 str r0,[r12,#4*16] ; save original cpsr
1763
1764 mrs r1,cpsr ; save mode psr
1765 bic r2,r1,#0x1f ; psr with mode bits cleared
1766 and r0,r0,#0x1f ; get original mode bits
1767 add r0,r0,r2
1768
1769 msr cpsr,r0 ; move to pre-exception mode
1770 str r13,[r12,#4*13] ; save original SP
1771 str r14,[r12,#4*14] ; save original LR
1772 msr cpsr,r1 ; restore mode psr
1773
1774 ; r11 has original index
1775 orr r10,r11,#0xDE<<24; r10 = 0xDEAD0000 + index of vector taken
1776 orr r10,r10,#0xAD<<16
1777 str r10,[r12,#4*17] ; save magic + index
1778
1779 mov r0,r11 ; put index into 1st argument
1780 b _dar_exception
1781
1782 .global $exception ; export function
1783
1784 $exception: ; Veneer function
1785 .ref _exception
1786 .state16
1787 adr r0,_exception
1788 bx r0
1789 .align
1790 .state32
1791 .def _exception
1792 _exception:
1793 ldr r12,Xdump_buffer ; redundant unless _exception is called
1794 ldr r11,[r12,#4*13] ; get svc mode r13
1795 add r12,r12,#4*18 ; base of stack buffer
1796
1797 ; check if svc r13(sp) is within internal/external RAM. It *could* be invalid.
1798 ; we boldly assume stack is only within internal RAM except for GPRS build on
1799 ; Calypso chipset : stack is within external RAM
1800 .if CHIPSET = 7 | CHIPSET = 8 | CHIPSET = 10 | CHIPSET = 11
1801 .if L1_GPRS = 1
1802 ; if GPRS, check for internal RAM as well as 2Mbytes of external RAM
1803 cmp r11,#0x800000 ; INTERNAL RAM_LOW
1804 blt nostack
1805 mov r0, #0x880000 ; INTERNAL RAM_HIGH
1806 sub r0,r0,#XDUMP_STACK_SIZE
1807 cmp r11,r0
1808 blt stack_range
1809 ; was not less than 0x880000, so check for external RAM
1810 cmp r11,#RAM_LOW
1811 blt nostack
1812 mov r0,#RAM_HIGH
1813 sub r0,r0,#XDUMP_STACK_SIZE
1814 cmp r11,r0
1815 bge nostack
1816 .else ; GSM ONLY
1817 cmp r11,#RAM_LOW
1818 blt nostack
1819 mov r0,#RAM_HIGH
1820 sub r0,r0,#XDUMP_STACK_SIZE
1821 cmp r11,r0
1822 bge nostack
1823 .endif
1824 .endif
1825
1826 stack_range:
1827 ldmfd r11!,{r0-r9} ; copy ten stack words..
1828 stmia r12!,{r0-r9}
1829 ldmfd r11!,{r0-r9} ; copy ten stack words..
1830 stmia r12!,{r0-r9}
1831
1832 nostack:
1833 STACKS .equ SYSTEM_SIZE + IRQ_STACK_SIZE + FIQ_STACK_SIZE + TIMER_SIZE
1834 .ref _dar_reset
1835 ; we're finished saving all state. Now execute C code for more flexibility.
1836 ; set up a stack for this C call
1837 LDR a1,StackSegment ; Pickup the begining address from .cmd file
1838 ; (is aligned on 8 byte boundary)
1839 MOV a2,#STACKS ; Pickup all stacks size
1840 ADD a2,a2,#0x80 ; Add 128 to get past all used data
1841 ADD a3,a1,a2
1842 MOV sp,a3 ; Setup exception stack pointer
1843 b _dar_reset
1844
1845
1846 BSS_Start
1847 .word .bss
1848 ;
1849 BSS_End
1850 .word end
1851 ;
1852 .if LONG_JUMP >= 3
1853 .align 4
1854 BSS_IntMem_Start: .field _S_D_Mem,32
1855 .align 4
1856 BSS_IntMem_End: .field _E_D_Mem,32
1857 .endif
1858
1859 StackSegment
1860 .word stack_segment
1861 ;
1862 Loaded_Flag
1863 .word _INT_Loaded_Flag
1864 ;
1865 System_Limit
1866 .word _TCT_System_Limit
1867 ;
1868 System_Stack
1869 .word _TCD_System_Stack
1870 ;
1871 HISR_Stack_Ptr
1872 .word _TMD_HISR_Stack_Ptr
1873 ;
1874 HISR_Stack_Size
1875 .word _TMD_HISR_Stack_Size
1876 ;
1877 HISR_Priority
1878 .word _TMD_HISR_Priority
1879 ;
1880 Exception_Stack
1881 .word exception_stack
1882 ;
1883 Xdump_buffer
1884 .word _xdump_buffer
1885 ;
1886 ; The following code is pulled from rts.src, which is part of the
1887 ; TI tools installation.
1888 ;
1889 ;***************************************************************************
1890 ;* PROCESS INITIALIZATION TABLE.
1891 ;*
1892 ;* THE TABLE CONSISTS OF A SEQUENCE OF RECORDS OF THE FOLLOWING FORMAT:
1893 ;*
1894 ;* .word <length of data (bytes)>
1895 ;* .word <address of variable to initialize>
1896 ;* .word <data>
1897 ;*
1898 ;* THE INITIALIZATION TABLE IS TERMINATED WITH A ZERO LENGTH RECORD.
1899 ;*
1900 ;***************************************************************************
1901 ;****auto_init(register int *table)
1902 ;****{
1903 ;**** register int length;
1904 ;**** register int *addr;
1905 ;****
1906 ;**** while (length = *table++)
1907 ;**** {
1908 ;**** addr = (int *)*table++;
1909 ;**** while (length)
1910 ;**** {
1911 ;**** if (length > 3)
1912 ;**** {
1913 ;**** *addr++ = *table++;
1914 ;**** length -= 4;
1915 ;**** }
1916 ;**** else
1917 ;**** {
1918 ;**** *(char *)addr++ = *(char *)table++;
1919 ;**** length--;
1920 ;**** }
1921 ;**** }
1922 ;**** }
1923 ;****}
1924
1925 tbl_addr: .set R0
1926 var_addr: .set R1
1927 length: .set R3
1928 data: .set R4
1929
1930 _auto_init:
1931 B rec_chk
1932
1933 record:
1934 ;*------------------------------------------------------
1935 ;* PROCESS AN INITIALIZATION RECORD
1936 ;*------------------------------------------------------
1937 LDR var_addr, [tbl_addr], #4
1938
1939 copy:
1940 ;*------------------------------------------------------
1941 ;* COPY THE INITIALIZATION DATA
1942 ;*------------------------------------------------------
1943 CMP length, #3
1944
1945 LDRHI data, [tbl_addr], #4
1946 STRHI data, [var_addr], #4 ; COPY A WORD OF DATA
1947 SUBHI length, length, #4 ; OR ...
1948 LDRLSB data, [tbl_addr], #1 ;
1949 STRLSB data, [var_addr], #1 ; COPY A BYTE OF DATA
1950 SUBLS length, length, #1
1951
1952 CMP length, #0 ; CONTINUE TO COPY IF
1953 BNE copy ; LENGTH IS NONZERO
1954
1955 ANDS length, tbl_addr, #0x3 ; MAKE SURE THE ADDRESS
1956 RSBNE length, length, #0x4 ; IS WORD ALIGNED
1957 ADDNE tbl_addr, tbl_addr, length ;
1958
1959 rec_chk:LDR length, [tbl_addr], #4 ; PROCESS NEXT
1960 CMP length, #0 ; RECORD IF LENGTH IS
1961 BNE record ; NONZERO
1962
1963 MOV PC, LR
1964 ;
1965
1966 ;
1967 ; Creation of INT_memset and INT_memcpy, respectively identical to memset and
1968 ; memcpy from the rts library of compiler 2.51/2.54.
1969 ; They are used to make the initialization of the .bss section and the load
1970 ; of the internal ram code not dependent to the 32-bit alignment.
1971 ; The old code used for the initialization and the load used a loop with
1972 ; 4-byte increment, assuming the 32-bit alignment of the .bss section.
1973 ; This alignment is not necessary true.
1974 ;
1975 ;******************************************************************************
1976 ;* INT_memset - INITIALIZE MEMORY WITH VALUE *
1977 ;******************************************************************************
1978 ;* MEMSET32.ASM - 32 BIT STATE - v2.51 *
1979 ;* Copyright (c) 1996-2003 Texas Instruments Incorporated *
1980 ;******************************************************************************
1981
1982 ;****************************************************************************
1983 ;* INT_memset - INITIALIZE MEMORY WITH VALUE.
1984 ;*
1985 ;* Same memset defined in rts.src.
1986 ;* Used in INT_Initialize to clear bss area.
1987 ;* Used in f_load_int_mem() function to clear internal memory space used
1988 ;* for data and code.
1989 ;* The memset function defined in rts library is loaded into internal memory,
1990 ;* then, it can not be used in either INT_Initialize, or f_load_int_mem().
1991 ;*
1992 ;* C Prototype : void *INT_memset(void *s, int c, size_t n);
1993 ;* C++ Prototype : void *std::INT_memset(void *s, int c, std::size_t n);
1994 ;*
1995 ;****************************************************************************
1996 ;*
1997 ;* o DESTINATION LOCATION IS IN r0
1998 ;* o INITIALIZATION VALUE IS IN r1
1999 ;* o NUMBER OF BYTES TO INITIALIZE IS IN r2
2000 ;*
2001 ;* o ORIGINAL DESTINATION LOCATION RETURNED IN r0
2002 ;****************************************************************************
2003 .state32
2004 .def _INT_memset
2005
2006 _INT_memset:
2007 STMFD SP!, {R0, LR} ; save R0 also since original dst
2008 ; address is returned.
2009
2010 TST R0, #3 ; check for word alignment
2011 BEQ _word_aligned
2012
2013 CMP R2, #0 ; set bytes until there are no more
2014 ; to set or until address is aligned
2015 _unaligned_loop:
2016 STRHIB R1, [R0], #1
2017 SUBHIS R2, R2, #1
2018 TSTHI R0, #3
2019 BNE _unaligned_loop
2020
2021 CMP R2, #0 ; return early if no more bytes
2022 LDMEQFD SP!, {R0, PC} ; to set.
2023
2024 _word_aligned:
2025 AND R1, R1, #255 ; be safe since prototype has value as
2026 ; as an int rather than unsigned char
2027
2028 ORR R1, R1, R1, LSL #8 ; replicate byte in 2nd byte of
2029 ; register
2030
2031 CMP R2,#4 ; are at least 4 bytes being set
2032 BCC _INT_memset3
2033
2034 ORR R1, R1, R1, LSL #16 ; replicate byte in upper 2 bytes
2035 ; of register. note that each of
2036 ; the bottom 2 bytes already contain
2037 ; the byte value from above.
2038
2039 CMP R2,#8 ; are at least 8 bytes being set
2040 BCC _INT_memset7
2041
2042 MOV LR,R1 ; copy bits into another register so
2043 ; 8 bytes at a time can be copied.
2044 ; use LR since it is already being
2045 ; saved/restored.
2046
2047 CMP R2,#16 ; are at least 16 bytes being set
2048 BCC _INT_memset15
2049
2050 STMFD SP!, {R4} ; save regs needed by 16 byte copies
2051
2052 MOV R4, R1 ; copy bits into 2 other registers so
2053 MOV R12, R1 ; 16 bytes at a time can be copied
2054
2055 SUB R3, R2, #15 ; set up loop count
2056 AND R2, R2, #15 ; determine number of bytes to set
2057 ; after setting 16 byte blocks
2058
2059 _INT_memset16_loop: ; set blocks of 16 bytes
2060 STMIA R0!, {R1, R4, R12, LR}
2061 SUBS R3, R3, #16
2062 BHI _INT_memset16_loop
2063
2064 LDMFD SP!, {R4} ; resotre regs used by 16 byte copies
2065
2066 _INT_memset15: ; may still be as many as 15 bytes to
2067 ; set. the address in R0 is guaranteed
2068 ; to be word aligned here.
2069
2070 TST R2, #8 ; are at least 8 bytes being set
2071 STMNEIA R0!, {R1, LR}
2072
2073
2074 _INT_memset7: ; may still be as many as 7 bytes to
2075 ; set. the address in R0 is guaranteed
2076 ; to be word aligned here.
2077
2078 TST R2, #4 ; are at least 4 bytes being set
2079 STRNE R1, [R0], #4
2080
2081 _INT_memset3: ; may still be as many as 3 bytes to
2082 ; set. the address in R0 is guaranteed
2083 ; to be word aligned here.
2084
2085 TST R2, #2 ; are there at least 2 more bytes to
2086 STRNEH R1, [R0], #2 ; set. the address in R0 is guaranteed
2087 ; to be half-word aligned here.
2088
2089 TST R2, #1 ; is there one remaining byte to set
2090 STRNEB R1, [R0]
2091
2092
2093 LDMFD SP!, {R0, PC} ; restore regs and return
2094
2095
2096 ;******************************************************************************
2097 ;* INT_memcpy - COPY CHARACTERS FROM SOURCE TO DEST *
2098 ;******************************************************************************
2099 ;* MEMCPY32.ASM - 32 BIT STATE - v2.51 *
2100 ;* Copyright (c) 1996-2003 Texas Instruments Incorporated *
2101 ;******************************************************************************
2102
2103 ;****************************************************************************
2104 ;* INT_memcpy - COPY CHARACTERS FROM SOURCE TO DEST
2105 ;*
2106 ;* Same as C_MEMCPY defined in rts.src.
2107 ;* Used in INT_Initialize to download code into internal memory space.
2108 ;* The memcpy function defined in rts library is loaded into internal memory.
2109 ;* then, it can not be used in f_load_int_mem().
2110 ;*
2111 ;****************************************************************************
2112 ;*
2113 ;* o DESTINATION LOCATION IS IN r0
2114 ;* o SOURCE LOCATION IS IN r1
2115 ;* o NUMBER OF CHARACTERS TO BE COPIED IS IN r2
2116 ;****************************************************************************
2117 .state32
2118 .def _INT_memcpy
2119
2120 _INT_memcpy:
2121 CMP r2, #0 ; CHECK FOR n == 0
2122 BXEQ lr ;
2123
2124 STMFD sp!, {r0, lr} ; SAVE RETURN VALUE AND ADDRESS
2125
2126 TST r1, #0x3 ; CHECK ADDRESS ALIGNMENT
2127 BNE _unaln ; IF NOT WORD ALIGNED, HANDLE SPECIALLY
2128 TST r0, #0x3 ;
2129 BNE _saln ;
2130
2131 _aln: CMP r2, #16 ; CHECK FOR n >= 16
2132 BCC _l16 ;
2133
2134 STMFD sp!, {r4} ;
2135 SUB r2, r2, #16 ;
2136 _c16: LDMIA r1!, {r3, r4, r12, lr} ; COPY 16 BYTES
2137 STMIA r0!, {r3, r4, r12, lr} ;
2138 SUBS r2, r2, #16 ;
2139 BCS _c16 ;
2140 LDMFD sp!, {r4} ;
2141 ADDS r2, r2, #16 ; RETURN IF DONE
2142 LDMEQFD sp!, {r0, pc} ;
2143
2144 _l16: ANDS r3, r2, #0xC ;
2145 BEQ _cp1 ;
2146 BICS r2, r2, #0xC ;
2147 ADR r12, _4line - 16 ;
2148 ADD pc, r12, r3, LSL #2 ;
2149
2150 _4line: LDR r3, [r1], #4 ; COPY 4 BYTES
2151 STR r3, [r0], #4 ;
2152 LDMEQFD sp!, {r0, pc} ; CHECK FOR n == 0
2153 B _cp1 ;
2154
2155 LDMIA r1!, {r3, r12} ; COPY 8 BYTES
2156 STMIA r0!, {r3, r12} ;
2157 LDMEQFD sp!, {r0, pc} ; CHECK FOR n == 0
2158 B _cp1 ;
2159
2160 LDMIA r1!, {r3, r12, lr} ; COPY 12 BYTES
2161 STMIA r0!, {r3, r12, lr} ;
2162 LDMEQFD sp!, {r0, pc} ; CHECK FOR n == 0
2163
2164 _cp1: SUBS r2, r2, #1 ;
2165 ADRNE r3, _1line - 4 ; SETUP TO COPY 1 - 3 BYTES...
2166 ADDNE pc, r3, r2, LSL #4 ;
2167
2168 _1line: LDRB r3, [r1], #1 ; COPY 1 BYTE
2169 STRB r3, [r0], #1 ;
2170 LDMFD sp!, {r0, pc} ;
2171
2172 LDRH r3, [r1], #2 ; COPY 2 BYTES
2173 STRH r3, [r0], #2 ;
2174 LDMFD sp!, {r0, pc} ;
2175 NOP ;
2176
2177 LDRH r3, [r1], #2 ; COPY 3 BYTES
2178 STRH r3, [r0], #2 ;
2179 LDRB r3, [r1], #1 ;
2180 STRB r3, [r0], #1 ;
2181 LDMFD sp!, {r0, pc} ;
2182
2183 _unaln: LDRB r3, [r1], #1 ; THE ADDRESSES ARE NOT WORD ALIGNED.
2184 STRB r3, [r0], #1 ; COPY BYTES UNTIL THE SOURCE IS
2185 SUBS r2, r2, #1 ; WORD ALIGNED OR THE COPY SIZE
2186 LDMEQFD sp!, {r0, pc} ; BECOMES ZERO
2187 TST r1, #0x3 ;
2188 BNE _unaln ;
2189
2190 _saln: TST r0, #0x1 ; IF THE ADDRESSES ARE OFF BY 1 BYTE
2191 BNE _off1 ; JUST BYTE COPY
2192
2193 TST r0, #0x2 ; IF THE ADDRESSES ARE NOW WORD ALIGNED
2194 BEQ _aln ; GO COPY. ELSE THEY ARE OFF BY 2, SO
2195 ; GO SHORT WORD COPY
2196
2197 _off2: SUBS r2, r2, #4 ; COPY 2 BYTES AT A TIME...
2198 BCC _c1h ;
2199 _c2: LDR r3, [r1], #4 ; START BY COPYING CHUNKS OF 4,
2200 .if .TMS470_BIG
2201 STRH r3, [r0, #2] ;
2202 MOV r3, r3, LSR #16 ;
2203 STRH r3, [r0], #4 ;
2204 .else
2205 STRH r3, [r0], #4 ;
2206 MOV r3, r3, LSR #16 ;
2207 STRH r3, [r0, #-2] ;
2208 .endif
2209 SUBS r2, r2, #4 ;
2210 BCS _c2 ;
2211 CMN r2, #4 ;
2212 LDMEQFD sp!, {r0, pc} ;
2213
2214 _c1h: ADDS r2, r2, #2 ; THEN COPY THE ODD BYTES.
2215 LDRCSH r3, [r1], #2 ;
2216 STRCSH r3, [r0], #2 ;
2217 SUBCS r2, r2, #2 ;
2218 ADDS r2, r2, #1 ;
2219 LDRCSB r3, [r1], #1 ;
2220 STRCSB r3, [r0], #1 ;
2221 LDMFD sp!, {r0, pc} ;
2222
2223 _off1: SUBS r2, r2, #4 ; COPY 1 BYTE AT A TIME...
2224 BCC _c1b ;
2225 _c1: LDR r3, [r1], #4 ; START BY COPYING CHUNKS OF 4,
2226 .if .TMS470_BIG
2227 STRB r3, [r0, #3] ;
2228 MOV r3, r3, LSR #8 ;
2229 STRB r3, [r0, #2] ;
2230 MOV r3, r3, LSR #8 ;
2231 STRB r3, [r0, #1] ;
2232 MOV r3, r3, LSR #8 ;
2233 STRB r3, [r0], #4 ;
2234 .else
2235 STRB r3, [r0], #4 ;
2236 MOV r3, r3, LSR #8 ;
2237 STRB r3, [r0, #-3] ;
2238 MOV r3, r3, LSR #8 ;
2239 STRB r3, [r0, #-2] ;
2240 MOV r3, r3, LSR #8 ;
2241 STRB r3, [r0, #-1] ;
2242 .endif
2243 SUBS r2, r2, #4 ;
2244 BCS _c1 ;
2245
2246 _c1b: ADDS r2, r2, #4 ; THEN COPY THE ODD BYTES.
2247 LDMEQFD sp!, {r0, pc} ;
2248 _lp1: LDRB r3, [r1], #1 ;
2249 STRB r3, [r0], #1 ;
2250 SUBS r2, r2, #1 ;
2251 BNE _lp1 ;
2252 LDMFD sp!, {r0, pc} ;
2253
2254 .end
2255