📄 mpc5xx_lo.s
字号:
#mfspr r19,spr_5xx_md_dbram0
#mfspr r20,spr_5xx_md_dbram1
#stw r10,o_5xx_md_ctr(r31)
#stw r11,o_5xx_m_casid(r31)
#stw r12,o_5xx_md_ap(r31)
#stw r13,o_5xx_md_epn(r31)
#stw r14,o_5xx_m_twb(r31)
#stw r15,o_5xx_md_twc(r31)
#stw r16,o_5xx_md_rpn(r31)
#stw r17,o_5xx_m_tw(r31)
#stw r18,o_5xx_md_dbcam(r31)
#stw r19,o_5xx_md_dbram0(r31)
#stw r20,o_5xx_md_dbram1(r31)
sync
#
# Context save complete!
#
# Change to the monitor stack.
#
addis r1,r0,(__SP_INIT-20)@h
ori r1,r1,(__SP_INIT-20)@l
# Invoke the C exception handler.
#
# int cpu_handler (int exception);
#
mfspr r3,spr_sprg1 # the address in LR indicates exception
bl cpu_handler
# Code to determine if we go back to monitor or user code
# r3 == 1 if we go back to monitor, 0 for RFI
cmpi cr0,0,r3,0x0001
beq cr0,backtomonitor
# restore state and execute rfi.
# Point r3 to the user register data structure
addis r3,r0,(context)@h
ori r3,r3,(context)@l
b asm_switch_context
# The RFI is performed in asm_switch_context
backtomonitor:
# mask exceptions -- FIX
b mainloop
######################################################################
# This routine accepts a pointer to the data structure containing
# the user register set, and restores its context.
# Call from C:
#
# asm_switch_context(&context);
#
# NOTE: This routine only restores SPRs 1, 8, 9, 275, and 1010
#
asm_switch_context:
# Point r31 to the user register data structure
addi r31,r3,0 # arg in r3
# Special Purpose Registers
lwz r10,o_xer(r31)
lwz r11,o_lr(r31)
lwz r12,o_ctr(r31)
lwz r13,o_dsisr(r31)
lwz r14,o_dar(r31)
lwz r15,o_dec(r31)
mtspr spr_xer,r10
mtspr spr_lr,r11
mtspr spr_ctr,r12
# mtspr spr_dsisr,r13
# mtspr spr_dar,r14
# mtspr spr_dec,r15
sync
# Some of the MMU registers could be done here! FIX !!!
# Restore CR, and setup MSR, IP for the RFI
lwz r10,o_cr(r31)
lwz r11,o_msr(r31)
lwz r12,o_srr0(r31)
mtcrf 0xFF,r10
mtspr spr_srr1,r11
mtspr spr_srr0,r12
sync
# Restore all GPRs.
lwz r0,o_r0(r31)
lwz r1,o_r1(r31)
lwz r2,o_r2(r31)
lwz r3,o_r3(r31)
lwz r4,o_r4(r31)
lwz r5,o_r5(r31)
lwz r6,o_r6(r31)
lwz r7,o_r7(r31)
lwz r8,o_r8(r31)
lwz r9,o_r9(r31)
lwz r10,o_r10(r31)
lwz r11,o_r11(r31)
lwz r12,o_r12(r31)
lwz r13,o_r13(r31)
lwz r14,o_r14(r31)
lwz r15,o_r15(r31)
lwz r16,o_r16(r31)
lwz r17,o_r17(r31)
lwz r18,o_r18(r31)
lwz r19,o_r19(r31)
lwz r20,o_r20(r31)
lwz r21,o_r21(r31)
lwz r22,o_r22(r31)
lwz r23,o_r23(r31)
lwz r24,o_r24(r31)
lwz r25,o_r25(r31)
lwz r26,o_r26(r31)
lwz r27,o_r27(r31)
lwz r28,o_r28(r31)
lwz r29,o_r29(r31)
lwz r30,o_r30(r31)
lwz r31,o_r31(r31) # must be done last
sync
isync
# Here we go!
rfi
######################################################################
#
# This routine is used to return from a 'call' command. It uses
# asm_sc_exit_to_dbug as well. Since a return from a call has no
# real IP, we dummy it up.
#
asm_return_from_call:
mtspr spr_sprg1,r31
mfmsr r31
mtspr spr_srr1,r31
mfspr r31,spr_lr
mtspr spr_srr0,r31
mfspr r31,spr_sprg1
# we now let the following routine finish it off
######################################################################
#
# This routine is called from a system call to save the context and
# return to the dBUG prompt. This routine is used in conjuction with
# asm_exception_body() and cpu_handler() to avoid rewriting/copying
# the context save code. It passes exception #0xFF00 to cpu_handler(),
# which will then dump out to the dBUG prompt.
#
# Prior to invoking this routine, the caller must have ensured that
# the entry conditions for asm_exception_body have already been met,
# with the exception that LR is set here to indicate bogus exception.
#
asm_sc_exit_to_dbug:
addi r31,0,-1
mtspr spr_lr,r31
b asm_exception_body
######################################################################
#
# This is the Interrupt Service Routine for External Interrupts. This
# routine saves off a few registers that may be modified ala EABI, and
# then calls the higher level C routine to determine and dispatch the
# correct interrupt handler.
#
.equ ISRSZ,128
.equ EMASK,0x0000FF00
asm_isr_handler:
# Save volatile registers, as per EABI
#
stwu r1,-ISRSZ(r1)
stw r0,40(r1) # Save R0
stw r2,44(r1) # Save R2
stw r3,48(r1) # Save R3
stw r4,52(r1) # Save R4
stw r5,56(r1) # Save R5
stw r6,60(r1) # Save R6
stw r7,64(r1) # Save R7
stw r8,68(r1) # Save R8
stw r9,72(r1) # Save R9
stw r10,76(r1) # Save R10
stw r11,80(r1) # Save R11
stw r12,84(r1) # Save R12
stw r13,88(r1) # Save R13
mfspr r0,spr_sprg1
stw r0,92(r1) # Save LR - Exception header
mfcr r0
stw r0,96(r1) # Save CR
mfspr r0,spr_xer
stw r0,100(r1) # Save XER
mfspr r0,spr_ctr
stw r0,104(r1) # Save CTR
mfspr r0,spr_sprg0
stw r0,108(r1) # Save R31 - Exception header
mfspr r0,spr_srr0
stw r0,112(r1) # Save IP
mfspr r0,spr_srr1
stw r0,116(r1) # Save MSR
sync
isync
# Call the higher level interrupt handler
#
mfspr r4,8 # LR contains exception number
addis r5,r0,(EMASK)@h # Get exception number
ori r5,r5,(EMASK)@l
and r3,r4,r5
bl isr_execute_handler
# Code to determine if we go back to monitor or user code
# r3 == 0 if IRQ not handled, r3 == 1 if IRQ handled
cmpi cr0,0,r3,0x0000
beq cr0,nothandled
handled:
# Restore registers
#
lwz r2,44(r1) # Restore R2
lwz r3,48(r1) # Restore R3
lwz r4,52(r1) # Restore R4
lwz r5,56(r1) # Restore R5
lwz r6,60(r1) # Restore R6
lwz r7,64(r1) # Restore R7
lwz r8,68(r1) # Restore R8
lwz r9,72(r1) # Restore R9
lwz r10,76(r1) # Restore R10
lwz r11,80(r1) # Restore R11
lwz r12,84(r1) # Restore R12
lwz r13,88(r1) # Restore R13
lwz r0,92(r1) #
mtspr spr_lr,r0 # Restore LR
lwz r0,96(r1) #
mtcrf 0xFF,r0 # Restore CR
lwz r0,100(r1) #
mtspr spr_xer,r0 # Restore XER
lwz r0,104(r1) #
mtspr spr_ctr,r0 # Restore CTR
lwz r31,108(r1) # Restore R31
lwz r0,112(r1)
mtspr spr_srr0,r0 # Restore IP
lwz r0,116(r1)
mtspr spr_srr1,r0 # Restore MSR
lwz r0,40(r1) # Restore R0 - Must be done last!
addi r1,r1,ISRSZ
sync
isync
# All done!
rfi
nothandled:
# Restore registers
#
lwz r2,44(r1) # Restore R2
lwz r3,48(r1) # Restore R3
lwz r4,52(r1) # Restore R4
lwz r5,56(r1) # Restore R5
lwz r6,60(r1) # Restore R6
lwz r7,64(r1) # Restore R7
lwz r8,68(r1) # Restore R8
lwz r9,72(r1) # Restore R9
lwz r10,76(r1) # Restore R10
lwz r11,80(r1) # Restore R11
lwz r12,84(r1) # Restore R12
lwz r13,88(r1) # Restore R13
lwz r0,92(r1) #
mtspr spr_sprg1,r0 # Restore LR (for exception body)
lwz r0,96(r1) #
mtcrf 0xFF,r0 # Restore CR
lwz r0,100(r1) #
mtspr spr_xer,r0 # Restore XER
lwz r0,104(r1) #
mtspr spr_ctr,r0 # Restore CTR
lwz r31,108(r1) # Restore R31
mtspr spr_sprg0,r31 # Restore r31 (for exception body)
lwz r0,112(r1)
mtspr spr_srr0,r0 # Restore IP
lwz r0,116(r1)
mtspr spr_srr1,r0 # Restore MSR
lwz r0,40(r1) # Restore R0 - Must be done last!
addi r1,r1,ISRSZ
sync
isync
# Jump to generic exception handler
addi r31,r0,0x0500
mtspr spr_lr,r31
b asm_exception_body
######################################################################
#
# These routines perform I/O to memory mapped I/O peripherals.
#
# uint32 cpu_iord_8 (void *addr);
# uint32 cpu_iord_16(void *addr);
# uint32 cpu_iord_32(void *addr);
# void cpu_iowr_8 (void *addr, uint32 data);
# void cpu_iowr_16(void *addr, uint32 data);
# void cpu_iowr_32(void *addr, uint32 data);
#
# Under EABI, addr is in r3, and data is in r4. Return value also in r3
#
cpu_iord_8:
eieio
lbz r3,0(r3)
eieio
blr
cpu_iord_16:
eieio
lhz r3,0(r3)
eieio
blr
cpu_iord_32:
eieio
lwz r3,0(r3)
eieio
blr
cpu_iowr_8:
eieio
stb r4,0(r3)
eieio
blr
cpu_iowr_16:
eieio
sth r4,0(r3)
eieio
blr
cpu_iowr_32:
eieio
stw r4,0(r3)
eieio
blr
######################################################################
#
# These routines read and write the value of the Machine State Register
# MSR.
#
mpc5xx_wr_msr:
isync
mtmsr r3
isync
blr
mpc5xx_rd_msr:
mfmsr r3
isync
blr
#
# These routines read and write the value of the Special Purpose Register
# 144, CMPA.
#
mpc5xx_wr_cmpa:
isync
mtspr 144,r3
isync
blr
mpc5xx_rd_cmpa:
mfspr r3,144
isync
blr
#
# These routines read and write the value of the Special Purpose Register
# 145, CMPB.
#
mpc5xx_wr_cmpb:
isync
mtspr 145,r3
isync
blr
mpc5xx_rd_cmpb:
mfspr r3,145
isync
blr
#
# These routines read and write the value of the Special Purpose Register
# 146, CMPC.
#
mpc5xx_wr_cmpc:
isync
mtspr 146,r3
isync
blr
mpc5xx_rd_cmpc:
mfspr r3,146
isync
blr
#
# These routines read and write the value of the Special Purpose Register
# 147, CMPD.
#
mpc5xx_wr_cmpd:
isync
mtspr 147,r3
isync
blr
mpc5xx_rd_cmpd:
mfspr r3,147
isync
blr
#
# These routines read and write the value of the Debug Enable Register
# .
#
mpc5xx_wr_der:
isync
mtspr 149,r3
isync
blr
mpc5xx_rd_der:
mfspr r3,149
isync
blr
#
# These routines read and write the value of the I-bus Control Register
# ICTRL.
#
mpc5xx_wr_ictrl:
isync
mtspr 158,r3
isync
blr
mpc5xx_rd_ictrl:
mfspr r3,158
isync
blr
#
# These routines read and write the value of the Lower TimeBase
#
mpc5xx_rd_tbl:
mftb r3,268
blr
mpc5xx_wr_tbl:
mtspr 284,r3
isync
blr
#
# These routines read and write the value of the Upper TimeBase
#
mpc5xx_rd_tbu:
mftb r3,269
blr
mpc5xx_wr_tbu:
mtspr 285,r3
isync
blr
#
# Debug Port Interrupt Cause Register, ICR
#
mpc5xx_rd_ecr:
mfspr r3,spr_5xx_ecr
blr
#
# These routines read and write the value of the DECrementer
#
mpc5xx_wr_dec:
mtspr spr_dec,r3
isync
blr
mpc5xx_rd_dec:
isync
mfspr r3,spr_dec
blr
#
# These routines are used to read and write the value of the IMMR, the
# MPC5xx Internal Memory Map Register. This register provides an
# address base and 64K "wide" space for accessing the on-board
# peripherals.
#
mpc5xx_wr_immr:
###rlwinm r3,r3,0,0,15 # mask out lower 16 bits
rlwinm r3,r3,0,16,31 #mask out upper 16 bits
mtspr spr_5xx_immr,r3
blr
mpc5xx_rd_immr:
mfspr r3,spr_5xx_immr
blr
mpc5xx_get_immp:
mfspr r3,spr_5xx_immr
rlwinm r3,r3,21,6,10 # mask out the upper 27 bits and mask out bit 31. then shift left 21 bits to go with table on pg.6-23 of 565 manual.
rlwinm r3,r3,0,0,30 #mask out bit 31 (LSB)
###rlwinm r3,r3,0,0,15 # mask out lower 16 bits
blr
.end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -