📄 mpc8xx_lo.s
字号:
mfspr r15,spr_8xx_md_twc
mfspr r16,spr_8xx_md_rpn
mfspr r17,spr_8xx_m_tw
mfspr r18,spr_8xx_md_dbcam
mfspr r19,spr_8xx_md_dbram0
mfspr r20,spr_8xx_md_dbram1
stw r10,o_8xx_md_ctr(r31)
stw r11,o_8xx_m_casid(r31)
stw r12,o_8xx_md_ap(r31)
stw r13,o_8xx_md_epn(r31)
stw r14,o_8xx_m_twb(r31)
stw r15,o_8xx_md_twc(r31)
stw r16,o_8xx_md_rpn(r31)
stw r17,o_8xx_m_tw(r31)
stw r18,o_8xx_md_dbcam(r31)
stw r19,o_8xx_md_dbram0(r31)
stw r20,o_8xx_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
# Make memory coherent
#
bl cpu_cache_flush
# 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 to 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.
#
mpc8xx_wr_msr:
isync
mtmsr r3
isync
blr
mpc8xx_rd_msr:
mfmsr r3
isync
blr
#
# These routines read and write the value of the Lower TimeBase
#
mpc8xx_rd_tbl:
mftb r3,268
blr
mpc8xx_wr_tbl:
mtspr 284,r3
isync
blr
#
# These routines read and write the value of the Upper TimeBase
#
mpc8xx_rd_tbu:
mftb r3,269
blr
mpc8xx_wr_tbu:
mtspr 285,r3
isync
blr
#
# Debug Port Interrupt Cause Register, ICR
#
mpc8xx_rd_icr:
mfspr r3,spr_8xx_icr
blr
#
# These routines read and write the value of the DECrementer
#
mpc8xx_wr_dec:
mtspr spr_dec,r3
isync
blr
mpc8xx_rd_dec:
isync
mfspr r3,spr_dec
blr
#
# These routines are used to read and write the value of the IMMR, the
# MPC8XX Internal Memory Map Register. This register provides an
# address base and 64K "wide" space for accessing the on-board
# peripherals.
#
mpc8xx_wr_immr:
rlwinm r3,r3,0,0,15 # mask out lower 16 bits
mtspr spr_8xx_immr,r3
blr
mpc8xx_rd_immr:
mfspr r3,spr_8xx_immr
blr
mpc8xx_get_immp:
mfspr r3,spr_8xx_immr
rlwinm r3,r3,0,0,15 # mask out lower 16 bits
blr
#
# The following routines are meant to be called from C routines
# and manipulate the Instruction Cache, IC, special purpose registers.
#
# 'C' prototypes
#
# uint32 mpc8xx_rd_ic_dat (void);
# void mpc8xx_wr_ic_adr (uint32);
# uint32 mpc8xx_rd_ic_adr (void);
# void mpc8xx_wr_ic_cst (uint32);
# uint32 mpc8xx_rd_ic_cst (void);
#
mpc8xx_rd_ic_dat:
mfspr r3,spr_8xx_ic_dat
isync
blr
mpc8xx_wr_ic_adr:
mtspr spr_8xx_ic_adr,r3
isync
blr
mpc8xx_rd_ic_adr:
mfspr r3,spr_8xx_ic_adr
isync
blr
mpc8xx_wr_ic_cst:
mtspr spr_8xx_ic_cst,r3
isync
blr
mpc8xx_rd_ic_cst:
mfspr r3,spr_8xx_ic_cst
isync
blr
mpc8xx_rd_dc_dat:
mfspr r3,spr_8xx_dc_dat
isync
blr
mpc8xx_wr_dc_adr:
mtspr spr_8xx_dc_adr,r3
isync
blr
mpc8xx_rd_dc_adr:
mfspr r3,spr_8xx_dc_adr
isync
blr
mpc8xx_wr_dc_cst:
sync
mtspr spr_8xx_dc_cst,r3
isync
blr
mpc8xx_rd_dc_cst:
mfspr r3,spr_8xx_dc_cst
isync
blr
mpc8xx_wr_ictrl:
sync
mtspr spr_8xx_ictrl,r3
isync
blr
mpc8xx_rd_ictrl:
mfspr r3,spr_8xx_ictrl
isync
blr
.end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -