?? nios2_germs_monitor.s
字號:
# Contents: Nios II monitor, (modified from nios_germs_monitor.s)
# this one with S-Record, I-Hex
# records, and Flash Programming
# for the Nios development board.
#
# ex:tabstop=4:
# ex:shiftwidth=4:
# ex:expandtab:
#
# +-------------------------------------------
# | A Note About Caching
# |
# | To eliminate issues with caching, this Germs
# | monitor uses the following strategy:
# |
# | 1. Init the i- and d-caches at startup.
# | So the caches are EMPTY when we begin.
# | 2. Use only IO reads and writes.
# | So the d-cache stays empty, and the
# | i-cache contains only parts of
# | Germs itself.
# |
# | therefore
# |
# | 3. When you execute a G (go) command,
# | or the s-record equivalent, there
# | CANNOT be any stale i-cache data
# | associated with that address. Only
# | parts of Germs itself will be found
# | in the i-cache.
# |
# | dvb2004.04.02
# +--------------------------------------------
#
# GermsMon is build-time configurable to
# support various Nios configurations.
# The following variables control
# how it's built:
#
# GM_UARTBase -- base of the uart for output, presumed
# to be Nios compatible registers
#
# GM_FlashBase,
# GM_FlashTop --
# The flash to support, unless FlashTop is zero,
# which means "no flash". The flash is presumed
# to be AMD 29LV800, as on the Nios reference design.
# Other AMD flashes might be compatible.
#
# GM_Flash --
# The address in flash to check for the Nios 2
# signature "N2". The boot loader generated by
# nios2-srec2flash contains the signature at
# offset 4.
# If the signature is found, execution
# is transferred to GM_Flash. If
# GM_Flash is zero, the feature is disabled.
# GM_PIO --
# The pio to check bit zero of before executing
# from flash.
#
# GM_VectorTable --
# Interrupt vector table base
#
# To set a variable, include the directive
#
# --defsym GM_whatever=value
#
# on the assembler's command line. With nios-build, include
# the directive
#
# -as "--defsym GM_whatever=value"
#
#
.include "excalibur.s"
.ifndef GM_UARTBase
.ifdef nasys_printf_uart
.equ GM_UARTBase,nasys_printf_uart
.else
#
# If there's no UART defined, we'll compile
# as IF the uart address is 0x0000.
# This, of course, won't be a functioning
# monitor, but, hey, there's no UART. What
# were you expecting?
# At least it puts some bytes in your
# ROM, and you can see what code looks like.
#
#.equ GM_UARTBase,0
# !!!
# The above comment is obsolete, but is preserved here
# for future generations to look upon, and marvel.
# See the bottom of this file for the code that's generated
# when no UART exists.
# !!!
.endif
.endif
.ifndef GM_FlashBase
.ifdef nasys_main_flash
.equ GM_FlashBase,nasys_main_flash
.endif
.endif
.ifdef GM_FlashBase
.ifndef GM_FlashTop
.ifdef nasys_main_flash_end
.equ GM_FlashTop,nasys_main_flash_end
.else
.equ GM_FlashTop,GM_FlashBase+0x100000
.endif
.endif
.ifndef GM_Flash
.equ GM_Flash,GM_FlashBase+0x40000
.endif
.endif
.ifndef GM_StackTop
.equ GM_StackTop,nasys_stack_top
.endif
.ifndef GM_VectorTable
.equ GM_VectorTable,nasys_vector_table
.endif
.ifndef GM_PIO
.ifdef na_button_pio
.equ GM_PIO,na_button_pio
.endif
.endif
.ifndef GM_WIDTHS
.equ GM_WIDTHS,1
.endif
# Constants used by nj germs monitor
.equ CR,13 # carriage return
.equ WORD, 4 # default word size, for 32-bit NJ, 4 bytes in a word
.equ LOW_NIBBLE_MASK, 0x00000000f # to mask out low nibble of a word
#.equ ADDR_MASK, 0xFFFFFFFC # for masking out low two bits of addresses
.equ ADDR_LOBITS,2 # how many low bits to zap for rounding
# Useful Macros!
#
# A simple macro to branch if register bit is 0
#
.macro BR0 rB, rA, bit, dest
ANDI \rB, \rA, (1<<\bit)
BEQ r0, \rB, \dest
.endm
# +----------------------------
# | _CLRLOBITS reg,bits
.macro _CLRLOBITS _dst,_src,_bits
SRLI \_dst,\_src,\_bits
SLLI \_dst,\_dst,\_bits
.endm
#--------------------------------------------------
#
# A simple macro to branch if register bit is 1
.macro BR1 rB, rA, bit, dest
ANDI \rB, \rA, (1<<\bit)
BNE r0, \rB, \dest
.endm
# Mostly, this is one big goto-tangle.
#
# No RAM used
#
# LOW_NIBBLE_MASK : the value 0x0000000F
#
# Global Register Usage:
#
# r3 : number of bytes read by getHex routine
# r8 : UART Base Address
# r9 : return address temp for flash routines
# r11 : residual byte for writing to Flash in words
# rl2 : Upper bytes (or segment) for I-Hex records
# r13 : Force-to address for S-Records/I-Hex records
# r14 : Address to read next from <CR>
# This gets set by an R command
# r15,r16 : Any routine's scratch
# r17,r18 : Any routine's scratch
# r19 : record type for S-record
# r20 : record length in bytes for S-record
# r21 : address we're reading bytes into for S-record
#
# r22 : How many words to display on CR
# r23 : stashed return address
#
# r24 : stashed value-end during doMWrite
#
#
#
#
# --------------
#
#
# -------------------------------
# Commands:
# G<address> Go at address
# E<address> Erase flash at address
# R<address>-<address> Relocate S-Records from-to
# M<address> Display at address
# M<address>-<address> Display range
# M<address>:val val... Write at address
# M<address>-<address>:val Fill range with val
# S... S-record, no error checking
# :... Intel-Hex record, no error checking
.text
GFUNC _start
# +------------------------------------------------------
# | Cache flushing code
# |
# | Initialize caches if present.
# | All contents will be cleared without writing back dirty data to memory.
# | This is required since the caches start from an unknown state on reset.
.if nasys_has_icache
_start_icache_init:
mov r4, r0
MOVIK32 r5, nasys_icache_size
_start_icache_loop:
# This looped is unrolled by a factor of 2 to speed it up.
# Further unrolling is not done because the end of the loop won't
# fit in one icache line.
initi r4
addi r4, r4, nasys_icache_line_size
initi r4
addi r4, r4, nasys_icache_line_size
bltu r4, r5, _start_icache_loop
flushp
.endif
.if nasys_has_dcache
_start_dcache_init:
mov r4, r0
MOVIK32 r5, nasys_dcache_size
_start_dcache_loop:
# This looped is unrolled by a factor of 8 to speed it up.
# Further unrolling could be done as desired.
initd 0*nasys_dcache_line_size(r4)
initd 1*nasys_dcache_line_size(r4)
initd 2*nasys_dcache_line_size(r4)
initd 3*nasys_dcache_line_size(r4)
initd 4*nasys_dcache_line_size(r4)
initd 5*nasys_dcache_line_size(r4)
initd 6*nasys_dcache_line_size(r4)
initd 7*nasys_dcache_line_size(r4)
addi r4, r4, nasys_dcache_line_size * 8
bltu r4, r5, _start_dcache_loop
.endif
# | the caches are now flushed
# |
# +--------------------------------------------------
_start_post_cache_flush:
WRCTL status, r0 # Disabling interrupts
.ifdef GM_UARTBase
# (previous germs monitors cleared the vector table
# here, but it's more useful to be able to still
# see it after you finish. Also, every byte is
# precious, to keep it under 1k bytes! so its gone.)
#
# Reset UART, SwitchPIO, and Timers
#
MOVIK32 r8, GM_UARTBase
STWIO r0, WORD*np_uartcontrol(r8) # control all 0's: no irq's
.ifdef GM_PIO
MOVIK32 r16, GM_PIO
STWIO r0, WORD*np_piointerruptmask(r16)
.endif
#
# set the stack pointer
#
.ifdef GM_StackTop
MOVIK32 sp, GM_StackTop
.endif
#
# Look for Signature in flash, & jump there.
#
.ifdef GM_PIO
LDWIO r15, WORD*np_piodata(r16) # Unless the button is pressed
BR0 r16, r15, 0, postFlash_start
.endif
.ifdef GM_FlashTop
MOVIK32 r16, GM_Flash
LDHIO r15, 4(r16)
CMPNEI r15, r15, 'N'+(256*'2')
BNE r0, r15, postFlash_start
CALLR r16 # (if it wants to return, no problem!)
.endif
GFUNC postFlash_start
## We end up here upon exit of a user-program run with the 'G'
## command. User-programs can do -anything-, including exitng
## with interrupts left running. This is inconvenient when
## using the monitor. Disable CPU interrupts as a defensive measure.
WRCTL status, r0
#
# Registers which need certain
# values for the rest of the monitor
# to work.
# (Other registers are used as
# needed, although their reservations
# for certain uses must be respected
# while running.)
MOVIK32 r8, GM_UARTBase
CALL PutHash
MOV r12, r0
MOV r13, r0
MOV r14, r0 # address to show on <CR>
MOVUI r22, 16 # words to show on <CR>
.ifndef __timeStamp__
.equ __timeStamp__,0
.endif
MOVIK32 r5, __timeStamp__
CALL PutHex
# RDCTL r5, cpuid # uncomment once cpu id control register is defined
MOVIK32 r5, 0x12171981 # for now put this, guess who's b-day?
CALL PutHex
MOVUI r4, CR
CALL PutChar
#
# Print the system name GM_SystemName, if defined
#
MOVI32 r21, systemNameString
printSystemNameLoop:
LDBIO r4, 0(r21)
BEQ r0, r4, donePrintSystemNameLoop
CALL PutChar
ADDI r21, r21, 1
BR printSystemNameLoop
donePrintSystemNameLoop:
# |
# | print address of monitor
# |
MOVUI r4, ' '
CALL PutChar
MOVUI r4, '@'
CALL PutChar
MOVUI r4, ' '
CALL PutChar
MOVI32 r5,_start
CALL PutHex
MOVUI r4, CR
CALL PutChar
ReceiveCommand:
MOVUI r4, '+'
CALL PutChar
CALL GetChar
CMPGEUI r15, r4, 0x0060 # character from [60,7f]
BEQ r0, r15, RespondToInput
LowercaseChar:
ANDI r4, r4, 0xffdf
#BR RespondToInput
RespondToInput:
ADDI r4, r4, -CR
BEQ r0, r4, doCR
ADDI r4, r4, CR-'#' # '#' (hash) is for comments: ignore to EOL
BEQ r0, r4, happyWaitForEOL
ADDI r4, r4, '#'-':'
BEQ r0, r4, doColon
ADDI r4, r4, ':'-'E'
BEQ r0, r4, doE
ADDI r4, r4, 'E'-'G'
BEQ r0, r4, doG
ADDI r4, r4, 'G'-'M'
BEQ r0, r4, doM
ADDI r4, r4, 'M'-'R'
BEQ r0, r4, doR
ADDI r4, r4, 'R'-'S'
BEQ r0, r4, doS
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -