📄 startup.s
字号:
#-----------------------------------------------------------------------------
#
# FILE: startup.s
#
# DESCRIPTION:
#
# This file defines the external interrupt vector and the interrupt handler
# for this vector. It also includes code that sets up the stack and branches
# to main(). This is where code execution starts.
#
#
# REFERENCES:
#
# 1. MPC8260 PowerQUICC Users Manual
# 2. PowerPC Microprocessor Family: The Programming Environments for 32-Bit
# Microprocessors
# 3. MPC603e & EC603e RISC Microprocessors Users Manual -
# MPC603EUM/AD Rev. 1
#
# HISTORY:
#
# 1/25/99 jay Initial Release
# 2/05/99 pdw Updated stack pointer
#-----------------------------------------------------------------------------
.text
.align 2
.globl _start
.extern main, __SP_INIT
_start:
####################
# Establish a stack
####################
#---------------------------------------------------
# SP_INIT is defined in the linker file ethernet.lnx
#---------------------------------------------------
addis r1,r0,__SP_INIT@h
ori r1,r1,__SP_INIT@l
#****************
# jump to main()
#****************
bl main
########################################################
# External Interrupt Definitions, Declarations and Code
########################################################
.extern ExtIntHandler
.globl ExtIntTable # Make table available to InterruptInit() in
# ethernet.c
#-------------------------------------------------
# PowerPC Defined Vector for External Interrupt
#-------------------------------------------------
EXTERNAL_INTERRUPT_VECTOR: .equ 0x500
#-------------------------------------------------
# ABI Compliant Interrupt StackFrame Space
#-------------------------------------------------
R0_OFFSET: .equ (0*4) # R0 Stack Offset
R1_OFFSET: .equ (1*4) # R1 Stack Offset
R2_OFFSET: .equ (2*4) # R2 Stack Offset
R3_OFFSET: .equ (3*4) # R3 Stack Offset
R4_OFFSET: .equ (4*4) # R4 Stack Offset
R5_OFFSET: .equ (5*4) # R5 Stack Offset
R6_OFFSET: .equ (6*4) # R6 Stack Offset
R7_OFFSET: .equ (7*4) # R7 Stack Offset
R8_OFFSET: .equ (8*4) # R8 Stack Offset
R9_OFFSET: .equ (9*4) # R9 Stack Offset
R10_OFFSET: .equ (10*4) # R10 Stack Offset
R11_OFFSET: .equ (11*4) # R11 Stack Offset
R12_OFFSET: .equ (12*4) # R12 Stack Offset
SRR0_OFFSET: .equ (13*4) # SRR0 Stack Offset
SRR1_OFFSET: .equ (14*4) # SRR1 Stack Offset
LR_OFFSET: .equ (15*4) # LR Stack Offset
CTR_OFFSET: .equ (16*4) # CTR Stack Offset
XER_OFFSET: .equ (17*4) # XER Stack Offset
CR_OFFSET: .equ (18*4) # CR Stack Offset
STACK_SZ: .equ (20*4) # Quad-Word Aligned Interrupt Stack Frame
#-------------------------------------------------
# Special Purpose Register Indices for SRR0, SRR1
#-------------------------------------------------
SRR0: .equ 26 # Save/Restore Register 0
SRR1: .equ 27 # Save/Restore Register 1
#*****************************************************************************
# This is the external interrupts vector table entry for the MPC8260.
# This code is setup for handling non-reentrant external interrupts.
#
# The following are the steps, in order, taken by the External Interrupt
# Table Code:
# 1) Save following Registers: gpr0, gpr3-gpr12, CR, XER, LR, CTR
# on stack as necessary to preserve user state across the interrupt
# handler. Save SRR0, SRR1 to provide breakpoint/debug support for
# Interrupt Code.
# 2) The exception vector (0x500) is saved in register r3.
# 3) Absolute Branch and Link to C routine to complete interrupt processing.
# 4) Restore Registers in (1) from stack.
# 5) Execute rfi instruction to return from supervisor-state interrupt handler.
#*****************************************************************************
.text
ExtIntTable:
##################
# Save USER State
##################
#----------------------------------------------------------
# Move stack pointer to beginning of Interrupt stack frame
#----------------------------------------------------------
subi r1,r1,STACK_SZ
#-----------------------------------------------------
# Save r0 -- Volatile Register
#-----------------------------------------------------
stw r0,R0_OFFSET(r1)
#---------------------------------------------------------------
# Save SRR0, SRR1
# NOTE: DO NOT Trace or Set Breakpoint Before SRR0, SRR1 Saved
#---------------------------------------------------------------
mfspr r0, SRR0
stw r0, SRR0_OFFSET(r1)
mfspr r0, SRR1
stw r0, SRR1_OFFSET(r1)
#-----------------------------------
# Save r3-r12 -- Volatile Registers
#-----------------------------------
stw r3, R3_OFFSET(r1) # Store r3
stw r4, R4_OFFSET(r1) # Store r4
stw r5, R5_OFFSET(r1) # Store r5
stw r6, R6_OFFSET(r1) # Store r6
stw r7, R7_OFFSET(r1) # Store r7
stw r8, R8_OFFSET(r1) # Store r8
stw r9, R9_OFFSET(r1) # Store r9
stw r10, R10_OFFSET(r1) # Store r10
stw r11, R11_OFFSET(r1) # Store r11
stw r12, R12_OFFSET(r1) # Store r12
#----------
# Store LR
#----------
mflr r0
stw r0, LR_OFFSET(r1)
#----------
# Save CTR
#----------
mfctr r0
stw r0, CTR_OFFSET(r1)
#----------
# Save XER
#----------
mfxer r0
stw r0, XER_OFFSET(r1)
#---------
# Save CR
#---------
mfcr r0
stw r0, CR_OFFSET(r1)
#---------------------------------------
# Place External Interrupt Vector in r3
#---------------------------------------
addi r3,r0,EXTERNAL_INTERRUPT_VECTOR
#------------------------------------
# Execute external interrupt handler
#------------------------------------
bla ExtIntHandler
#####################
# Restore USER State
#####################
#------------
# Restore CR
#------------
lwz r0, CR_OFFSET(r1)
mtcrf 0xff,r0
#-------------
# Restore XER
#-------------
lwz r0, XER_OFFSET(r1)
mtxer r0
#-------------
# Restore CTR
#-------------
lwz r0, CTR_OFFSET(r1)
mtctr r0
#------------
# Restore LR
#------------
lwz r0, LR_OFFSET(r1)
mtlr r0
#--------------------------------------
# Restore r12-r3 -- Volatile Registers
#--------------------------------------
lwz r12, R12_OFFSET(r1) # Store r12
lwz r11, R11_OFFSET(r1) # Store r11
lwz r10, R10_OFFSET(r1) # Store r10
lwz r9, R9_OFFSET(r1) # Store r9
lwz r8, R8_OFFSET(r1) # Store r8
lwz r7, R7_OFFSET(r1) # Store r7
lwz r6, R6_OFFSET(r1) # Store r6
lwz r5, R5_OFFSET(r1) # Store r5
lwz r4, R4_OFFSET(r1) # Store r4
lwz r3, R3_OFFSET(r1) # Store r3
#-----------------------------------------------------------------
# Save SRR1, SRR0
# NOTE: DO NOT Trace or Set Breakpoints until after SRR1 and SRR0
# is restored.
#-----------------------------------------------------------------
lwz r0, SRR1_OFFSET(r1)
mtspr SRR1, r0
lwz r0, SRR0_OFFSET(r1)
mtspr SRR0, r0
#---------------------------------
# Restore r0 -- Volatile Register
#---------------------------------
lwz r0, R0_OFFSET(r1)
#-----------------------------------------------------------------------
# Restore r1 back to its original value before entering this interrupt
#-----------------------------------------------------------------------
addi r1, r1, STACK_SZ
#----------------------------------------------------------------
# Return from interrupt handler in supervisor state to user code
#----------------------------------------------------------------
rfi
.end # end of text section
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -