URL
https://opencores.org/ocsvn/ion/ion/trunk
Subversion Repositories ion
Compare Revisions
- This comparison shows the changes necessary to convert path
/ion/trunk/src/common
- from Rev 172 to Rev 173
- ↔ Reverse comparison
Rev 172 → Rev 173
/c_startup.s
0,0 → 1,70
#------------------------------------------------------------------------------- |
# startup.s -- C startup code common to all C programs. |
# |
# This code does the following: |
# 1.- Initialize the stack at the end of the bss area |
# 2.- Clear the bss area |
# 3.- Move the data section from FLASH to RAM (if applicable) |
# 4.- Call main() |
# 5.- Freeze in endless loop after main() returns, if it does |
# |
# The code does not initialize the caches or the hardware and does not include |
# the reset or trap vectors. |
# |
# This code was inherited from OpenCores' Plasma project. |
#------------------------------------------------------------------------------- |
|
# The stack size can be defined from the assembler command line |
# FIXME should use info from the link script |
.ifndef STACK_SIZE |
.set STACK_SIZE, 1024 # by default, reserve 1KB |
.endif |
|
# Reserve space for regular stack (BSS segment) |
.comm init_stack, STACK_SIZE |
|
.text |
.align 2 |
.global entry |
.ent entry |
entry: |
.set noreorder |
|
# (The linker script defined these symbols) |
la $gp, _gp # initialize global pointer |
la $5, __bss_start # $5 = .sbss_start |
la $4, _end # $2 = .bss_end |
la $sp, init_stack+STACK_SIZE-24 #initialize stack pointer |
|
# Clear BSS area |
$BSS_CLEAR: |
sw $0, 0($5) |
slt $3, $5, $4 |
bnez $3, $BSS_CLEAR |
addiu $5, $5, 4 |
|
# Move data section image from flash to RAM, if necessary. |
la $a0,data_start |
la $a1,data_load_start |
beq $a1,$a0,move_data_section_done |
nop |
la $s0,data_size |
beqz $s0,move_data_section_done |
nop |
move_data_section_loop: |
lw $t0,0($a1) |
addiu $a1,$a1,4 |
sw $t0,0($a0) |
addiu $a0,$a0,4 |
bnez $s0,move_data_section_loop |
addiu $s0,$s0,-4 |
move_data_section_done: |
|
jal main # init done; call main() |
nop |
$L1: |
j $L1 |
nop |
|
.end entry |
|
/bootstrap.s
0,0 → 1,156
################################################################################ |
# bootstrap.s -- Reset code and trap handlers. |
# |
# This is the boot code for all applications, includes reset code and basic trap |
# handler with calls for all the trap causes. |
# |
# Initializes the caches and jumps to 'entry' in kernel mode and with interrupts |
# disabled. |
# |
# This code is meant to be placed at the reset vector address (0xbfc00000). |
#------------------------------------------------------------------------------- |
# FIXME: exception handling is incomplete (nothing is done on exception). |
################################################################################ |
|
#---- Cache parameters ----------------------------------------------------- |
.set ICACHE_NUM_LINES, 256 # no. of lines in the I-Cache |
.set DCACHE_NUM_LINES, 256 # no. of lines in the D-Cache |
.set DCACHE_LINE_SIZE, 4 # D-Cache line size in words |
|
#--------------------------------------------------------------------------- |
|
.text |
.align 2 |
.global reset |
.ent reset |
reset: |
.set noreorder |
|
b start_boot |
nop |
|
#--- Trap handler ---------------------------------------------------------- |
|
# We have three trap sources: syscall, break and unimplemented opcode |
# Plus we have to account for a faulty cause code; that's 4 causes. |
# Besides, we have to look out for the branch delay flag (BD). |
.org 0x0180 |
interrupt_vector: |
mfc0 $k0,$13 # Get trap cause code |
srl $k0,$k0,2 |
andi $k0,$k0,0x01f |
ori $k1,$zero,0x8 # was it a syscall? |
beq $k0,$k1,trap_syscall |
addi $k1,$k1,0x1 # was it a break? |
beq $k0,$k1,trap_break |
addi $k1,$k1,0x1 # was it a bad opcode? |
bne $k0,$k1,trap_invalid |
nop |
|
# Unimplemented instruction |
trap_unimplemented: |
.ifdef NO_EMU_MIPS32 |
j trap_return # FIXME should flag the bad opcode? |
nop |
.else |
j opcode_emu |
nop |
.endif |
|
# Break instruction |
trap_break: |
j trap_return # FIXME no support for break opcode |
nop |
|
# Syscall instruction |
trap_syscall: |
j trap_return # FIXME no support for syscall opcode |
nop |
|
# Invalid trap cause code, most likely hardware bug |
trap_invalid: |
j trap_return # FIXME should do something about this |
nop |
|
trap_return: |
mfc0 $k1,$14 # C0_EPC=14 (Exception PC) |
mfc0 $k0,$13 # Get bit 31 (BD) from C0 cause register |
srl $k0,31 |
andi $k0,$k0,1 |
bnez $k0,trap_return_delay_slot |
addi $k1,$k1,4 # skip trap instruction |
jr $k1 |
nop |
trap_return_delay_slot: |
addi $k1,$k1,4 # skip jump instruction too |
jr $k1 # (we just added 8 to epc) |
rfe |
|
|
#------------------------------------------------------------------------------- |
|
start_boot: |
mfc0 $a0,$12 |
andi $a0,$a0,0xfffe |
mtc0 $a0,$12 # disable interrupts, disable cache |
|
jal setup_cache # Initialize the caches |
nop |
|
# Hardware initialization done. Now we should jump to the main program. |
# Note that if this file was linked separately from the main program (for |
# example to be loaded in different memory areas) then the makefile will |
# have to provide a suitable value for symbol 'entry'. |
la $a0,entry |
jr $a0 |
nop |
# We won't be coming back... |
|
|
#---- Functions ---------------------------------------------------------------- |
|
# void setup_cache(void) -- invalidates all I-Cache lines (uses no RAM) |
setup_cache: |
lui $a1,0x0001 # Disable cache, enable I-cache line invalidation |
mfc0 $a0,$12 |
andi $a0,$a0,0xffff |
or $a1,$a0,$a1 |
mtc0 $a1,$12 |
|
# In order to invalidate a I-Cache line we have to write its tag number to |
# any address while bits CP0[12].17:16=01. The write will be executed as a |
# regular write too, as a side effect, so we need to choose a harmless |
# target address. |
|
li $a0,XRAM_BASE |
li $a2,0 |
li $a1,ICACHE_NUM_LINES-1 |
|
inv_i_cache_loop: |
sw $a2,0($a0) |
blt $a2,$a1,inv_i_cache_loop |
addi $a2,1 |
|
# Now, the D-Cache is different. To invalidate a D-Cache line you just |
# read from it (by proper selection of a dummy target address) while bits |
# CP0[12].17:16=01. The data read is undefined and should be discarded. |
|
li $a0,0 # Use any base address that is mapped |
li $a2,0 |
li $a1,DCACHE_NUM_LINES-1 |
|
inv_d_cache_loop: |
lw $zero,0($a0) |
addi $a0,DCACHE_LINE_SIZE*4 |
blt $a2,$a1,inv_d_cache_loop |
addi $a2,1 |
|
lui $a1,0x0002 # Leave with cache enabled |
mfc0 $a0,$12 |
andi $a0,$a0,0xffff |
or $a1,$a0,$a1 |
jr $ra |
mtc0 $a1,$12 |
|
.set reorder |
.end reset |