📄 vectors.s
字号:
subi sp,_TS_size,sp // Space for scratch saves
save_GDB_exception_regs sp,gr6
save_state sp
#else
save_exception_regs sp
save_state sp
#endif
LED 0x0FF2
mov sp,gr8
call exception_handler
bra _exception_return
//
// Handle an interrupt
// Separated from exception handling to support eCos multi-level
// (ISR/DSR) interrupt structure.
//
_interrupt:
save_exception_regs sp
save_state sp
mov gr4,gr30 // save vector #
// Set the global offset register (gr16)
call .Lexp1
.Lexp1: movsg lr,gr16
sethi #gprelhi(.Lexp1),gr5
setlo #gprello(.Lexp1),gr5
sub gr16,gr5,gr16
LED 0x0700
lda hal_vsr_table,gr8
slli gr30,#2,gr4 // Vector in GR30
ld @(gr8,gr4),gr8 // Handler (VSR) defined?
cmpi gr8,0,icc0
beq icc0,0,10f // No - use default
LED 0x0702
callil @(gr8,0) // Yes - call it
bra _exception_return
//
// Default interrupt processing
//
10:
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
|| defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
// If we are supporting Ctrl-C interrupts from GDB, we must squirrel
// away a pointer to the save interrupt state here so that we can
// plant a breakpoint at some later time.
.extern hal_saved_interrupt_state
lda hal_saved_interrupt_state,gr5
sti sp,@(gr5,0)
#endif
lda hal_interrupt_data,gr5
lda hal_interrupt_handlers,gr6
mov gr30,gr8 // Interrupt vector #
slli gr30,#2,gr4
ld @(gr5,gr4),gr9 // data pointer
ld @(gr6,gr4),gr6 // function
callil @(gr6,0)
LED 0x0701
// FIXME - no DSR processing
//
// Return from an exception/interrupt
//
_exception_return:
LED 0x0000
restore_state sp,pcsr,0
#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
.global reset_vector
reset_vector:
#if 1
// I'm not sure why this is necessary, but power on reset
// of CB70/VDK appears very unreliable without it.
setlos #1000,gr4
99: subicc gr4,#1,gr4,icc0
bne icc0,0,99b
#endif
// Make sure the CPU is in the proper mode (system), interrupts disabled
movsg psr,gr4
li ~(_PSR_ET|_PSR_PS|_PSR_PIVL_MASK),gr5
and gr4,gr5,gr4
li (_PSR_S|_PSR_ET|_PSR_CM|(0x0F<<_PSR_PIVL_SHIFT)),gr5
or gr4,gr5,gr4
movgs gr4,psr
movsg hsr0,gr4
// Make sure caches, MMUs, sleep states are disabled
li ~(_HSR0_ICE|_HSR0_DCE|_HSR0_IMMU|_HSR0_DMMU|7),gr5
and gr4,gr5,gr5
movgs gr5,hsr0
#ifdef __CB70_DEBUG
membar
sethi #0xffc0,gr11
setlo #0x0000,gr11
setlo #0x5555,gr6
sthi gr6,@(gr11,0x100) // leds
membar
#endif
#ifdef CYGSEM_REDBOOT_FRV_LINUX_BOOT
andicc gr4,#7,gr0,icc0 // Were we in a sleep state?
beq icc0,0,3f // No... normal startup
#ifdef __CB70_DEBUG
setlo #1,gr6
sthi gr6,@(gr11,0x100) // leds
membar
#endif
not gr14,gr5 // If gr14 = ~gr13 then gr14 is return address
cmp gr5,gr13,icc0 // ... else normal startup
bne icc0,0,3f
#ifdef __CB70_DEBUG
setlo #2,gr6
sthi gr6,@(gr11,0x100) // leds
membar
#endif
// Assume FR400 since FR5xx doesn't run Linux (yet)
li _FRV400_SDRAM_STS, gr4
sti gr0,@(gr4,8) // DRCN. Turn off self-refresh.
2:
ldi @(gr4,0),gr5 // Wait for it to come back...
andicc gr5,#1,gr0,icc0
bne icc0,0,2b
#ifdef __CB70_DEBUG
setlo #4,gr6
sthi gr6,@(gr11,0x100) // leds
membar
#endif
jmpil @(gr14,#0)
3:
#endif
// Initialize hardware platform - this macro only contains
// code which must be run before any "normal" accesses are
// allowed, such as enabling DRAM controllers, etc.
platform_init
#if defined(CYG_HAL_STARTUP_ROMRAM)
// Relocate code from ROM to static RAM
call 10f // Actual address loaded at
5: .long _vectors
.long 20f
.long 5b-_vectors
.long __rom_data_end
10: movsg lr,gr4
ldi @(gr4,0),gr6
ldi @(gr4,4),gr10
ldi @(gr4,8),gr7
ldi @(gr4,12),gr8
sub gr4,gr7,gr4 // GR4 - absolute base address
subi gr4,#4,gr4
subi gr6,#4,gr6
setlos #4,gr7
15: ldu @(gr4,gr7),gr5
stu gr5,@(gr6,gr7)
cmp gr6,gr8,icc0
bne icc0,0,15b
LED 0x5001
jmpl @(gr10,gr0)
20: nop
#endif // ROMRAM
// Fall through to normal program startup
#endif // ROM || ROMRAM
#endif // !CYGSEM_HAL_USE_ROM_MONITOR
.text
.global _start
_start:
LED 0x5002
// Set the global offset register (gr16) call
call .Lcall
.Lcall:
movsg lr,gr4
sethi #gprelhi(.Lcall),gr5
setlo #gprello(.Lcall),gr5
sub gr4,gr5,gr16
LED 0x0000
#ifndef CYGSEM_HAL_USE_ROM_MONITOR
// Set up trap base register
lda _vectors,gr4
movgs gr4,tbr
LED 0x0001
#endif
#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
// Relocate [copy] data from ROM to RAM
lda __rom_data_start,gr4
lda __ram_data_start,gr5
lda __ram_data_end,gr6
cmp gr5,gr6,icc0
beq icc0,0,2f
setlos #4,gr7
sub gr4,gr7,gr4
sub gr5,gr7,gr5
1: ldu @(gr4,gr7),gr8
stu gr8,@(gr5,gr7)
cmp gr5,gr6,icc0
bne icc0,0,1b
2:
#endif
// Set up stack, initial environment
lda __startup_stack,gr4
mov gr4,sp
// Enable caches early, based on configuration
#ifdef CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP
icei @(gr4,gr0),1 // purges current contents
movsg hsr0,gr4
li _HSR0_ICE,gr5 // enable instruction cache
or gr4,gr5,gr4
movgs gr4,hsr0
#endif
#ifdef CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP
dcef @(gr4,gr0),1 // flush contents to memory
dcei @(gr4,gr0),1 // purges current contents
movsg hsr0,gr4
li _HSR0_DCE,gr5 // enable data cache
or gr4,gr5,gr4
movgs gr4,hsr0
#endif
LED 0x0002
// Clear BSS space
lda __bss_start,gr4
lda __bss_end,gr5
1: sti gr0,@(gr4,0)
addi gr4,#4,gr4
cmp gr4,gr5,icc0
bne icc0,0,1b
// Initialize interrupt handlers, etc
li CYGNUM_HAL_ISR_COUNT,gr4
lda hal_interrupt_handlers,gr5
subi gr5,4,gr5
lda hal_default_isr,gr6
lda hal_vsr_table,gr8
subi gr8,4,gr8
// Note: this should be controlled by a CDL option
lda _handle_interrupt,gr9
setlos #4,gr7
10: stu gr6,@(gr5,gr7)
stu gr9,@(gr8,gr7)
subi gr4,1,gr4
cmp gr4,gr0,icc0
bne icc0,0,10b
LED 0x0003
// Initialize hardware
call hal_hardware_init
LED 0x0004
// Run any C++ initializations
call cyg_hal_invoke_constructors
LED 0x0005
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
call initialize_stub
#endif
LED 0x0006
// Start eCos application
call cyg_start
0: LED 0x0999 // Should never get here
bra 0b
//
// Interrupt processing
//
_handle_interrupt:
mov sp,gr31 // Save pointer to state frame
movsg lr,gr29
// Set the global offset register (gr16)
call 10f
10: movsg lr,gr4
sethi #gprelhi(10b),gr5
setlo #gprello(10b),gr5
sub gr4,gr5,gr16
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
// Switch to interrupt stack
#endif
// The entire CPU state is now stashed on the stack,
// increment the scheduler lock and handle the interrupt
#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
.extern cyg_scheduler_sched_lock
lda cyg_scheduler_sched_lock,gr8
ldi @(gr8,0),gr9
addi gr9,1,gr9
sti gr9,@(gr8,0)
#endif
#if defined(CYGPKG_KERNEL_INSTRUMENT) && \
defined(CYGDBG_KERNEL_INSTRUMENT_INTR)
setlos #RAISE_INTR,gr8 // arg0 = type = INTR,RAISE
ldi @(gr31,_TS_VECTOR),gr9 // arg1 = vector
mov gr0,gr10 // arg2 = 0
call cyg_instrument // call instrument function
#endif
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
|| defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
// If we are supporting Ctrl-C interrupts from GDB, we must squirrel
// away a pointer to the save interrupt state here so that we can
// plant a breakpoint at some later time.
.extern hal_saved_interrupt_state
lda hal_saved_interrupt_state,gr5
sti sp,@(gr5,0)
#endif
lda hal_interrupt_data,gr5
lda hal_interrupt_handlers,gr7
mov gr30,gr8 // Interrupt vector #
slli gr30,#2,gr4
ld @(gr5,gr4),gr9 // data pointer
ld @(gr7,gr4),gr6 // function
callil @(gr6,0)
LED 0x0701
#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
// The return value from the handler (in gr8) will indicate whether a
// DSR is to be posted. Pass this together with a pointer to the
// interrupt object we have just used to the interrupt tidy up routine.
lda hal_interrupt_objects,gr5
slli gr30,#2,gr4
ld @(gr5,gr4),gr9
mov gr31,gr10 // register frame
call interrupt_end // post any bottom layer handler
// threads and call scheduler
#endif
movgs gr29,lr
ret
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
// Execute pending DSRs the interrupt stack
// Note: this can only be called from code running on a thread stack
.globl hal_interrupt_stack_call_pending_DSRs
hal_interrupt_stack_call_pending_DSRs:
subi sp,32,sp // Save important registers
movsg lr,gr8
sti gr8,@(sp,0)
// Turn on interrupts, switch to interrupt stack
call cyg_interrupt_call_pending_DSRs
// Turn off interrupts, switch back to thread stack
ldi @(sp,0),gr8
movgs gr8,lr
addi sp,32,sp
ret
#endif // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
//
// Restore interrupt state
// GR8 has state
//
.global hal_restore_interrupts
hal_restore_interrupts:
movsg psr,gr4
setlos _PSR_PIVL_MASK,gr5
and gr8,gr5,gr8 // Save level being restored
not gr5,gr5
and gr4,gr5,gr4 // Clear out current level
or gr8,gr4,gr4 // Insert new level
movgs gr4,psr
ret
.global hal_query_interrupts
hal_query_interrupts:
movsg psr,gr8
setlos _PSR_PIVL_MASK,gr5
and gr8,gr5,gr8
ret
//
// "Vectors" - fixed location data items
// This section contains any data which might be shared between
// an eCos application and any other environment, e.g. the debug
// ROM.
//
.section ".fixed_vectors"
// Space for the virtual vectors
.balign 16
// Vectors used to communicate between eCos and ROM environments
.globl hal_virtual_vector_table
hal_virtual_vector_table:
.rept CYGNUM_CALL_IF_TABLE_SIZE
.long 0
.endr
.globl hal_vsr_table
hal_vsr_table:
.rept CYGNUM_HAL_ISR_COUNT // exceptions & interrupts
.long 0
.endr
.section ".data"
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
.balign 16
__GDB_stack_base:
.rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE // rather than 1k
.byte 0
.endr
__GDB_stack:
#endif
.balign 16
__startup_stack_base:
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
.rept 512
#else
.rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
#endif
.byte 0
.endr
.balign 16
.global __startup_stack
__startup_stack:
.globl hal_interrupt_handlers
hal_interrupt_handlers:
.rept CYGNUM_HAL_ISR_COUNT
.long 0
.endr
.globl hal_interrupt_data
hal_interrupt_data:
.rept CYGNUM_HAL_ISR_COUNT
.long 0
.endr
.globl hal_interrupt_objects
hal_interrupt_objects:
.rept CYGNUM_HAL_ISR_COUNT
.long 0
.endr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -