📄 bootsys.s
字号:
; if the application code transfers control back to the boot block to
; download a new application image.
;----------------------------------------------------------------------------
LEAF_NODE dload_entry
; Restore supervisor mode stack for use by boot image in the event
; that the boot image has been entered from the application. Also
; disable IRQ and FIQ interrupts in the event that the boot image
; has been entered from the application with interrupts enabled.
msr CPSR_c, #PSR_Supervisor:OR:PSR_Irq_Mask:OR:PSR_Fiq_Mask
ldr r13, =svc_stack+SVC_Stack_Size
; Enter the boot kernel, upon return from the boot kernel the only
; action left to take is to powerdown.
ldr r4, =boot_downloader
blatox r4
LEAF_NODE_END
;----------------------------------------------------------------------------
; BOOT POWERDOWN ENTRY POINT
;
; DESCRIPTION
; The boot powerdown routine is entered in the event of a return from the
; boot kernel.
;----------------------------------------------------------------------------
LEAF_NODE boot_powerdown_entry
; Disable IRQ and FIQ interrupts in the event that the boot image
; has been entered from the application with interrupts enabled.
msr CPSR_c, #PSR_Supervisor:OR:PSR_Irq_Mask:OR:PSR_Fiq_Mask
#if defined FEATURE_STACK_CHECK
eor sl, sl, sl
#endif
; Enter the boot powerdown routine. There is no return from this
; routine.
ldr r4, =boot_hw_powerdown
bx r4
LEAF_NODE_END
;----------------------------------------------------------------------------
; BOOT ISR MESSAGE TABLE
;
; The boot ISR message table contains the messages to be displayed on the
; LCD in the event of an unexpected interrupt.
;----------------------------------------------------------------------------
isr_msg_table_base
DCD undef_inst_msg
DCD swi_msg
DCD pref_abort_msg
DCD data_abort_msg
DCD reserved_msg
undef_inst_msg
DCB " Undef Inst Exception ",0
;;; 123456789AB+123456789AB+
swi_msg
DCB " SWI Exception ",0
;;; 123456789AB+123456789AB+
pref_abort_msg
DCB " Pref Abort Exception ",0
;;; 123456789AB+123456789AB+
data_abort_msg
DCB " Data Abort Exception ",0
;;; 123456789AB+123456789AB+
reserved_msg
DCB " Reserved Exception ",0
;;; 123456789AB+123456789AB+
ram_error_msg
DCB " RAM test Failure ",0
;;; 123456789AB+123456789AB+
re_entrant_abort_msg
DCB " Re-entrant Data Abort ",0
;;; 123456789AB+123456789AB+
;============================================================================
; BOOT BLOCK DATA LOCATIONS
;
; Locations and sizes of data areas in ROM and RAM are imported from the
; linker and stored as data items that are used at runtime by the boot
; kernel routines.
;============================================================================
AREA BOOTSYS_DATA, DATA, READONLY
; The $$ convention used by the linker is replaced to avoid the need
; for the -pcc option required by the ARM compiler when symbols that
; include $$ are used in 'C' code.
Load__BB_RAM__Base
DCD |Load$$BB_RAM$$Base|
Image__BB_RAM__Base
DCD |Image$$BB_RAM$$Base|
Image__BB_RAM__Length
DCD |Image$$BB_RAM$$Length|
Image__BB_RAM__ZI__Base
DCD |Image$$BB_RAM$$ZI$$Base|
Image__BB_RAM__ZI__Length
DCD |Image$$BB_RAM$$ZI$$Length|
;============================================================================
; BOOT BLOCK COPYRIGHT SEGMENT
;
; This segment contains the copyright notice which is contained in the
; Boot Block.
;============================================================================
AREA BOOTSYS_COPYRIGHT, DATA, READONLY
DCB "Copyright (c) 1998"
DCB "by QUALCOMM, Incorporated."
DCB "All rights reserved."
;============================================================================
; BOOT_RAM_TEST
;
; NOTE: All variables are in registers to avoid using RAM. Also, no
; instructions which use the stack are used.
;
; This function tests the RAM with a method which is designed to catch
; a variety of problems, including:
;
; data pins shorted high, low, or to each other
; address pins shorted high, low, or to each other
; improper selection of byte/halfword/word on reading or writting
; stuck/shorted chip selects
; disconnected address or data pins
;
; This is accomplished by testing with a series of selected patterns
; (both for addresses and data) which are designed to bring such faults
; to light. The basic algorithm is as follows:
;
; First, the data pins are checked. The memory locations 0x0 and
; ram_test_offset are used (this must be added to ram_base to form the correct
; MSM3000 address). A number is written to location 0x0 of the form
; 0x1 << n where n is a number from 0 to 15. This is designed to test
; each individual pin. After that number is written, a zero is written to
; ram_test_offset to clear the data pins and their buffers (in the case
; where the pins are disconnected). The number is read back, and checked
; for correctness. If the data pins are shorted, stuck, or floating, an
; incorrect value will be fetched.
;
; Next, address pins are tested. Address of the form 0x1 << n where n is a
; number from 0 to some limit (defined by the size of RAM) are used. This
; tests every address pin individually. The data written to those locations
; are the logical negation of the address (except for locations 0x0-0x2,
; which are too close together to store a 32 bit address). Once all written,
; these memory locations are checked in turn for the correct values. If the
; address pins are shorted, stuck, or floating, then two writes will select
; the same location, causing the read/test on one of them to fail.
;
; The final test performed tests the selection of byte/word/halfword on reads
; and writes. Storing individual bytes has allready been accomplished in the
; setup for the address pin test. Therefore, we simply must read from
; addresses 0x0-0x3 in bytes and halfwords to verify the correct results.
;
; NOTE: The constants coded here are designed for a little-endian processor.
; They will have to be changed for a big-endian processor.
;
; In the event a test fails, the address of the error string is placed in r0.
; In the event all the tests pass, the value 0x0 is loaded into r0. In
; either case, program execution returns to the calling function.
;
;============================================================================
AREA BOOT_RAM_TEST, CODE, READONLY
CODE32
;; Needed Constants
;; ----------------
;; These need to be in the flash for us to use since they are too
;; big to be encoded into the instruction
;;(or could grow to be too big)
ram_base
DCD RAM_BASE
ram_size
DCD RAM_SIZE
ram_test_offset
DCD 0x10
val_0055aa0f
DCD 0x0055AA0F
val_aa0f
DCD 0xAA0F
val_0055
DCD 0x0055
; watchdog register
watch_dog
DCD SLEEP_CTL_WB
ENTRY_NODE boot_ram_test
;; Check for data bus failures
;; ---------------------------
;; loop over all the data pins, testing each one
ldr r0, =ram_base ; the base address of RAM
ldr r0, [r0]
mov r1, #1 ; the test value (a single 1 bit)
mov r2, #0 ; a zero (used to clear data pins)
ldr r3, =ram_test_offset
ldr r3, [r3] ; a RAM location to test with
add r4, r3, r0 ; offset by the base addr of RAM
data_test_loop
str r1, [r0] ; store the test value
str r2, [r4] ; store a zero to clear data pins
ldr r3, [r0] ; retrieve the test value
cmp r3, r1 ; check test value for correctness
bne ram_error ; if incorrect, go to error routine
mov r1, r1, LSL #1 ; shift test bit left one position
cmp r1, #0x8000 ; check that we are still in the test range
ble data_test_loop ; if we are, continue tests
;; Kick the watchdog timer
;; -----------------------
mov r2, #SLEEP_CTL_WB__WATCH_DOG_MASK
ldr r3, =watch_dog ; get offset for SLEEP_CTL
ldr r3, [r3]
strb r2, [r3] ; write to port
mov r2, #0 ; clear out R2
strb r2, [r3] ; write to port
;; Check for address bus failures
;; ------------------------------
;; first we store data into RAM -- later we will test it all
;; treat addresses 0x0-0x2 specially
;; at this point, r0 = base ram address
mov r1, #0x0F ; store 0x0f in location 0
strb r1, [r0]
mov r1, #0xAA ; store 0xaa in location 1
strb r1, [r0, #1]
mov r1, #0x55 ; store 0x55 in location 2
strb r1, [r0, #2]
;; store the highest address in the last location in ram
ldr r1, =ram_size ; fetch the size of ram
ldr r1, [r1]
add r1, r1, r0 ; calculate where the last location is
str r1, [r1, #-3] ; store the last ram address there
;; loop over all the address pins, storing with each one
;; at this point, r0 = base ram address and r1 = last ram address
mov r2, #0x4 ; start with testing the 3rd pin
ldr r3, =ram_size ; fetch the size of ram
ldr r3, [r3]
address_test_write_loop
mvn r4, r2 ; r4 = bit inversion of address
str r4, [r2, r0] ; store the data into the test location
mov r2, r2, LSL #1 ; shift test bit left one position
cmp r2, r3 ; check that we are in the test range
blt address_test_write_loop ; if we are, continue tests
;; start checking the stored data for correctness
;; treat addresses 0x0-0x2 specially
;; at this point,
;; r0 = base ram address
;; r1 = last ram address
;; r3 = size of ram
ldrb r2, [r0] ; compare location 0 to 0x0F
cmp r2, #0x0F
bne ram_error ; if they do not match, error
ldrb r2, [r0, #1] ; compare location 1 to 0xAA
cmp r2, #0xAA
bne ram_error ; if they do not match, error
ldrb r2, [r0, #2] ; compare location 2 to 0x55
cmp r2, #0x55
bne ram_error ; if they do not match, error
;; now we loop over our previously stored data and check it all
;; at this point,
;; r0 = base ram address
;; r1 = last ram address
;; r3 = size of ram
mov r2, #0x4 ; start with testing the 3rd pin
address_test_read_loop
mvn r4, r2 ; r4 = bit inversion of address
ldr r5, [r2, r0] ; store the data into the test location
cmp r5, r4 ; compare retrieved data with correct data
bne ram_error ; if they do not match, error
mov r2, r2, LSL #1 ; shift test bit left one position
cmp r2, r3 ; check that we are in the test range
blt address_test_read_loop ; if we are, continue tests
;; now we check the last address
ldr r2, [r1, #-3] ; load from the last address
cmp r2, r1 ; if the value there != the last address
bne ram_error ; the we have an error
;; Check for byte/word/halfword access failures
;; --------------------------------------------
;; at this point,
;; r0 = base ram address
;; r1 = last ram address
;; r3 = size of ram
;; store a 0 in the 3rd byte of RAM (so we know what the
;; entire first word should be
mov r3, #0
strb r3, [r0, #3]
;; check that the word at 0x0 is 0x0FAA5500
ldr r2, =val_0055aa0f
ldr r2, [r2]
ldr r4, [r0]
cmp r2, r4
bne ram_error
;; check that the halfword at 0x0 is 0xAA0f
ldr r2, =val_aa0f
ldr r2, [r2]
ldrh r4, [r0]
cmp r2, r4
bne ram_error
;; check that the halfword at 0x2 is 0x0055
ldr r2, =val_0055
ldr r2, [r2]
ldrh r4, [r0, #2]
cmp r2, r4
bne ram_error
;; check that the byte at 0x1 is 0xAA
mov r2, #0xAA
ldrb r4, [r0, #1]
cmp r2, r4
bne ram_error
; nothing more to do -- we must have passed all tests
mov r0, #0 ; no errors - return 0
mov pc, r14 ; continue with boot sequence
ram_error
ldr r0, =ram_error_msg ; load up RAM error message
mov pc, r14 ; jump to error handler
ENTRY_NODE_END
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -