FreeCalypso > hg > fc-tourmaline
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 |