📄 boot_gnu.s
字号:
// CONFIG_CONTROL to make sure the PLD configuration logic is not locked.
// If it is locked, we branch to an error vector (PLD_LOCKED).
//
// At this point, the boot code, including the contents of the SBI file are
// located in both SRAM0 and in flash at EBI0. However, SRAM0 is not large
// enought to hold all of the PLD image. We only copied as much of the flash
// to SRAM0 as would fit. Because of this, we have to load the SBI file into
// the PLD from flash. Here we load the address of sbi_start, which will be
// the SRAM0 copy. Adding the EBI0 offset to this address will yield the
// address of the flash copy of the SBI file.
//
// The PLD is configured by reading words from the SBI file and writing them
// to to the CONFIG_DATA register. When the busy bit is cleared, the next
// word of SBI data can be written to CONFIG_DATA. When the last word of
// data is written, we wait for the CO bit of CONFIG_CONTROL to be cleared,
// indicating that configuration is compete. We also check the E bit of
// CONFIG_CONTROL to assure there were no errors.
//
//***************************************************************************
CONFIGURE_PLD:
ldr r0, =(EXC_REGISTERS_BASE + 0x144) //-Set config_clock period
ldr r1, =0x4 // to 7.8125MHz with
str r1, [r0] // CONFIG_CLOCK reg (AHB2/8)
ldr r0, =(EXC_REGISTERS_BASE + 0x140) //-Check Lock bit of
ldr r1, [r0] // CONFIG_CONTROL
and r2, r1, #0x1
cmp r2, #0x1
beq PLD_LOCKED
orr r2, r1, #0x2 //-Set CO bit of
str r2, [r0] // CONFIG_CONTROL
ldr r0,=sbi_start //-Set address of sbi_start
add r0, r0, #0x20000000
ldr r1, =(EXC_REGISTERS_BASE + 0x8) //-Load address of IDCODE reg
ldr r2, [r1] //-Load IDCODE from device
ldr r3, [r0, #4] //-Load IDCODE from SBI file
cmp r2, r3 //-Compare two IDCODE's
bne SBI_IDCODE_ERROR //-Take error vector if two
// IDCODE's dont match
ldr r0,=sbi_start //-Now look at flash copy of SBI
add r0, r0, #0x40000000
ldmia r0,{r1-r4} //-Load the first 4 words
add r3, r3, r0 //-Add coffset to get address of
// first word of config data
add r0, r3, r4 //-Add csize to get address of
// last word of config data
ldr r2, =(EXC_REGISTERS_BASE + 0x148) //-Load address of CONFIG_DATA
// register
ldr r4, =(EXC_REGISTERS_BASE + 0x140) //-Load address of CONFIG_CONTROL
// register
ldr r5, =0x04 //-Load Busy Bit mask
CONFIGURE_LOOP:
ldr r1, [r3], #4 //-Load a word of data
str r1, [r2] //-Write data to CONFIG_DATA
BUSY_BIT_LOOP:
ldr r6, [r4] //-Load CONFIG_CONTROL
and r7, r6, r5 //-Mask Busy Bit
cmp r7, #0x4 //-Check if Busy Bit is set
beq BUSY_BIT_LOOP //-If not, load more data
cmp r3, r0 //-Loop until end of SBI file
bne CONFIGURE_LOOP
WAIT_FOR_CO_TO_BE_CLEARED: //-Wait for CO bit to be cleared
ldr r6, [r4] //-Load CONFIG_CONTROL reg
and r6, r6, #0x2 //-Mask CO bit
cmp r6, #0x2 //-Loop until CO is '0'
beq WAIT_FOR_CO_TO_BE_CLEARED
CHECK_ERROR_BIT: //-Check E bit
ldr r6, [r4] //-Load CONFIG_CONTROL reg
and r7, r6, #0x010 //-Mask E Bit
cmp r7, #0x010 //-Take error vector if '1'
beq CONFIG_ERROR
//-PLD should now be in
// user mode.
PLD_CONFIG_DONE:
//***************************************************************************
// RESET_WATCHDOG_TIMER
//
// This section initializes and resets the watchdog timer by writing the
// trigger value to the register WDOG_CR, then writing the magic value
// 0xA5A5A5A5 to the register WDOG_RELOAD
//
//***************************************************************************
RESET_WATCHDOG_TIMER:
ldr r0, =(EXC_REGISTERS_BASE + 0xA00) //-Load register
ldr r1, =0x3FFFFFF0 // WDOG_CR
str r1, [r0] // Trigger value
// = 0x3FFFFFF0
ldr r0, =(EXC_REGISTERS_BASE + 0xA08) //-Load register
ldr r1, =0xA5A5A5A5 // WDOG_RELOAD
str r1, [r0] // Reset WD timer
RESET_WATCHDOG_TIMER_DONE:
END_LOOP:
//***************************************************************************
//*********************** BRANCH TO USER CODE HERE **************************
//***************************************************************************
b END_LOOP
//***************************************************************************
// WAIT_FUNCTION
//
// This function waits for a specified number of AHB1 cycles by reading the
// register AHB1_COUNT.
//
// r9 - Parameter that contains number of AHB1 cycles to wait
//
//***************************************************************************
CACHE_THIS_CODE2_START:
WAIT_FUNCTION:
ldr r7, [r6] //-Load value of AHB1_COUNT
add r7, r7, r9 //-r9 contains cycles to wait
// Load r7 with terminal count
WAIT_LOOP:
ldr r8, [r6] //-Load value of AHB1_COUNT
cmp r7, r8 //-Compare to terminal count
bhi WAIT_LOOP //-Loop until we get there
mov pc, lr //-Return from function
CACHE_THIS_CODE2_END:
//***************************************************************************
// Error Vectors
//
// These are the error vectors taken when errors are encountered in the boot
// process. These handlers simply trap the execution of code with an
// infinite loop. It is the users responsibility to design meaningful error
// handlers.
//
//***************************************************************************
PLD_LOCKED: //-Error vector if PLD is locked
b PLD_LOCKED
CONFIG_ERROR: //-Error vector if PLD config
b CONFIG_ERROR // sets error flag
ID_Error: //-Error vector if IDCODE does
b ID_Error // not match expected value
SBI_IDCODE_ERROR: //-Error vector if IDCODE does
b SBI_IDCODE_ERROR // not match SBI file
//***************************************************************************
// Interrupt Handlers
//
// These are the interrupt handlers that are run when interrupts are
// encountered. These handlers simply trap the execution of code with an
// infinite loop. It is the users responsibility to design meaningful
// interrupt handlers.
//
//***************************************************************************
UDEFHND:
b UDEFHND
SWIHND:
b SWIHND
PABTHND:
b PABTHND
DABTHND:
b DABTHND
UNEXPECTED:
b UNEXPECTED
IRQHND:
b IRQHND
FIQHND:
b FIQHND
//***************************************************************************
// Include SBI file
//
// In this section, a new data section named sbi_data is declared. The
// INCBIN directive tells the assembler to insert the file boot_example.sbi
// in pure binary form. The file is not interpreted in any way. During
// the PLD configuration portion of the boot process, this file is read
// using the sbi_start label. The SBI file is written to the PLD
// configuration peripheral to configure the PLD portion of the device.
//
//***************************************************************************
// AREA sbi_data, DATA, READONLY
//sbi_start
// INCBIN boot_example.sbi
//sbi_end
//***************************************************************************
// End of assembly source file
//***************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -