Files
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

524 lines
11 KiB
ArmAsm

# @(#)26 1.9 src/bos/kernel/ml/POWER/debug.s, sysml, bos411, 9428A410j 6/10/94 12:23:51
#*****************************************************************************
#
# COMPONENT_NAME: (SYSML) Kernel Assembler Code
#
# FUNCTIONS: debugger assembler functions
#
# ORIGINS: 27
#
# IBM CONFIDENTIAL -- (IBM Confidential Restricted when
# combined with the aggregated modules for this product)
# SOURCE MATERIALS
# (C) COPYRIGHT International Business Machines Corp. 1989, 1994
# All Rights Reserved
#
# US Government Users Restricted Rights - Use, duplication or
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
#
#****************************************************************************
.file "debug.s"
.machine "com"
.using low,r0
#*******************************************************************************
#
# NAME: realbyt, read_align
#
# FUNCTION:
# read 1, 2, or 4 bytes of data from memory, both functions flush
# and invalidate cache lines touched
#
# realbyt does read in real mode
# read_align read xlate on
# NOTE: real mode reads do *not* ignore seg regs with T=1, so this routine
# now saves the current sr and sets it unused before reading
#
# input: r3 = address of the data
# r4 = number of bytes(1,2,or 4) to read
# output: r3 = the data that was read
#
# EXECUTION ENVIRONMENT:
# Only called from debugger
#
#*******************************************************************************
S_PROLOG(realbyt)
#
.machine "com"
.set DRBIT, 0x10
mr r9, r3 # Save addr for segreg calculations
mfmsr r6 # get current msr
rlinm r7, r6, 0, ~DRBIT # unset data relocate bit
mtmsr r7 # put it back in msr
isync
# Figure out which architecture we're using, because the segreg instructions are
# different between POWER and PPC.
l r12, syscfg_arch # get architecture value
cmpi cr1, r12, POWER_PC # check for PPC, save comp in cr1
beq cr1, rb_ppcsavesr # Do PPC save and set of segreg
.machine "pwr"
mfsri r8, 0, r9 # Save segment register for addr
rlinm r5, r8, 0, 0x7fffffff # Mask off T bit
mtsri r5, 0, r9 # Mark segreg for addr unused
b read_com # Ready to start reading
rb_ppcsavesr:
.machine "ppc"
mfsrin r8, r9 # Save segment register for addr
rlwinm r5, r8, 0, 0x7fffffff # Mask off T bit
mtsrin r5, r9 # Mark segreg for addr unused
isync
b read_com
.machine "com"
ENTRY(read_align):
.globl ENTRY(read_align)
mr r9, r3 # copy address to r9 for segreg use
mfmsr r6
# Figure out which architecture we're using, because the segreg instructions are
# different between POWER and PPC.
l r12, syscfg_arch # get architecture value
cmpi cr1, r12, POWER_PC # check for PPC, save comp in cr1
beq cr1, ra_ppcsavesr # Do PPC save of segreg
.machine "pwr"
mfsri r8, 0, r9 # Save seg reg for addr
b read_com
ra_ppcsavesr:
.machine "ppc"
mfsrin r8, r9 # Save seg reg for addr
.machine "com"
read_com:
# # check the length of data to read
cmpli 0,r4,2 # compare r4 with 2 and put results
# in bit field (BF) 0
ai r5,r3,0 # Move address to r5 for clf later
bge rb02 # branch if 2 or 4 bytes to read
lbz r3,0(r3) # load byte into r3
b rbfini
rb02:
bgt rb04 # branch if 4 bytes to read
lhz r3,0(r3) # load half word into r3
b rbfini
rb04:
l r3,0(r3) # load word into r3
rbfini:
beq cr1, rb_ppcflush # branch if PPC
.machine "pwr"
clf 0,r5 # flush/invalidate cache
dcs
mtsri r8, 0, r9 # Restore seg reg for addr
b rb_fldone
rb_ppcflush:
.machine "ppc"
dcbf 0, r5 # flush/invalidate cche
sync
icbi 0, r5
mtsrin r8, r9 # Restore seg reg for addr
rb_fldone:
.machine "com"
isync
mtmsr r6 # reset msr to the way it was
isync
br
#*******************************************************************************
#
# NAME: writebyt, write_align
#
# FUNCTION:
# write 1, 2, or 4 bytes of data to memory. Both functions also flush
# and invalidate cache blocks written
#
# input: r3=address of the data
# r4=the data to write.
# r5=N of bytes to store, 1, 2, or 4
#
# output: the memory is changed.
#
# EXECUTION ENVIRONMENT:
# called only from the debugger
#
#*******************************************************************************
S_PROLOG(writbyt)
#
.machine "com"
# DRBIT, 0x10
mr r9, r3 # copy address to r9 for segreg use
mfmsr r6 # get current msr
rlinm r7, r6, 0, ~DRBIT # unset data relocate bit
mtmsr r7 # put it back in msr
isync
# Figure out which architecture we're using, because the segreg instructions are
# different between POWER and PPC.
l r12, syscfg_arch # get architecture value
cmpi cr1, r12, POWER_PC # check for PPC, save comp in cr1
beq cr1, wb_ppcsavesr # Do PPC save and set of segreg
.machine "pwr"
mfsri r8, 0, r9 # Save segment register for addr
rlinm r10, r8, 0, 0x7fffffff # Mask off T bit
mtsri r10, 0, r9 # Mark segreg for addr unused
b write_com # Ready to write
wb_ppcsavesr:
.machine "ppc"
mfsrin r8, r9 # Save segment register for addr
rlwinm r10, r8, 0, 0x7fffffff # Mask off T bit
mtsrin r10, r9 # Mark segreg for addr unused
isync
b write_com
.machine "com"
ENTRY(write_align):
.globl ENTRY(write_align)
mr r9, r3 # copy address to r9 for segreg use
mfmsr r6
# Figure out which architecture we're using, because the segreg instructions are
# different between POWER and PPC.
l r12, syscfg_arch # get architecture value
cmpi cr1, r12, POWER_PC # check for PPC, save comp in cr1
beq cr1, wa_ppcsavesr # Do PPC save of segreg
.machine "pwr"
mfsri r8, 0, r9 # Save seg reg for addr
b write_com
wa_ppcsavesr:
.machine "ppc"
mfsrin r8, r9 # Save seg reg for addr
.machine "com"
write_com:
# # check the length of data to write
cmpli 0,r5,2 # compare r5 with 2 and put results
# in bit field (BF) 0
bge wb02 # branch if 2 or 4 bytes to write
stb r4,0(r3) # store the byte
b wbfini
wb02:
bgt wb04 # branch if 4 bytes to write
sth r4,0(r3) # store half word
b wbfini
wb04:
st r4,0(r3) # store word
wbfini:
beq cr1, wb_ppcflush # branch if PPC
.machine "pwr"
clf 0,r3 # flush/invalidate cache
dcs
mtsri r8, 0, r9 # Restore seg reg for addr
b wb_fdone
wb_ppcflush:
.machine "ppc"
dcbf 0, r3 # flush/invalidate cache
sync
icbi 0, r3
mtsrin r8, r9 # Restore seg reg for addr
wb_fdone:
.machine "com"
isync
mtmsr r6 # reset msr to the way it was
isync
br
.machine "any"
S_PROLOG(cache_sync)
dcs
ics
S_EPILOG
#*******************************************************************************
#
# NAME: Move to bpr - breakpoint register
#
# FUNCTION:
# input: r3 = address to put in breakpoint register
# output: bpr updated
#
# EXECUTION ENVIRONMENT:
# Only called from debugger
#
S_PROLOG(mtbpr)
mtspr 0x10,r3
S_EPILOG
ifdef(`_POWER_PC',`
#******************************************************************************
#
# NAME: Move from time base upper
#
# CALL: unsigned int db_mftbu
#
# FUNCTION: Reads time base upper on PowerPC
#
# RETURNS: raw contents of register
# output: R3 = contents of time base upper
#
# EXECUTION ENVIRONMENT:
# Only called from debugger
#
S_PROLOG(db_mftbu)
.machine "ppc"
mftbu r3 # read high part of time base register
.machine "com"
br
#******************************************************************************
#
# NAME: Move from time base upper
#
# CALL: unsigned int db_mftbl
#
# FUNCTION: Reads time base lower on PowerPC
#
# RETURNS: raw contents of register
# output: R3 = contents of time base lower
#
# EXECUTION ENVIRONMENT:
# Only called from debugger
#
S_PROLOG(db_mftbl)
.machine "ppc"
mftb r3 # read low part of time base register
.machine "com"
br
#******************************************************************************
#
# NAME: Move to time base upper
#
# CALL: void db_mttbu(unsigned int)
#
# FUNCTION: Writes time base upper on PowerPC
# input: R3 = contents to put in time base upper
#
# RETURNS: nothing (void)
#
# EXECUTION ENVIRONMENT:
# Only called from debugger
#
S_PROLOG(db_mttbu)
.machine "ppc"
mttbu r3
.machine "com"
br
#******************************************************************************
#
# NAME: Move to time base lower
#
# CALL: void db_mttbl(unsigned int)
#
# FUNCTION: Writes time base lower on PowerPC
# input: R3 = contents to put in time base lower
#
# RETURNS: nothing (void)
#
# EXECUTION ENVIRONMENT:
# Only called from debugger
#
S_PROLOG(db_mttbl)
.machine "ppc"
mttb r3 # documentation says should be mttbl
.machine "com"
br
',)
ifdef(`_POWER_RS2',`
#
#
# FUNCTION: read peis registers
#
# CALL: void db_mfpeis(peis0, peis1)
# int *peis0; /* return value of peis0 here */
# int *peis1; /* reture value of peis1 here */
#
# EXECUTION ENVIORNMET:
# Interrupt level, and process level
#
# RETURNS: None
#
#
S_PROLOG(db_mfpeis)
cau r6, 0, BUID0 # value for i/o seg reg
mfsr r5, sr15 # save seg reg 15
mtsr sr15, r6 # to seg reg 15 for i/o
cau r6, 0, 0xf000 # set r6 to access i/o segment
cal r6, PEIS0(r6) # add offset to PEISs
lsi r7, r6, 8 # load PEIS0 and PEIS1
mtsr sr15, r5 # restore seg reg 15
st r7, 0(r3) # set PEIS0
st r8, 0(r4) # set PEIS1
br
FCNDES(db_mfpeis)
#
#
# FUNCTION: Set bit in PEIS0/1 for RS2
#
# CALL: void db_rs2peis_set(level)
# int level; /* 0 - 63. Bit to set in PEIS0/1 */
#
# RETURNS:
# None
#
#
S_PROLOG(db_rs2peis_set)
cau r3, r3, ICO_SLI # add in ICO cmd to set level
mtspr ILCR, r3 # set the level
br
#
#
# FUNCTION: Clear level in PEIS0/1 for RS2
#
# CALL: void db_rs2peis_reset(level)
# int level; /* 0-63. level to clear */
#
# RETURNS:
# None
#
#
S_PROLOG(db_rs2peis_reset)
cau r3, r3, ICO_CLI # add in ICO cmd to clear level
mtspr ILCR, r3 # clear the level
br
#
#
# FUNCTION: Get contents of ILCR without any side effects
#
# CALL: void db_mfilcr()
#
# RETURNS:
# contents of ILCR
#
#
S_PROLOG(db_mfilcr)
mfspr r3, ILCR # get ILCR
rlinm r4, r3, 0, 0xFF # get PIL
cmpi cr0, r4, 0x3F # if PIL <= 64 set the PEIS bit
bgt cr0, ilcr_rd1 # that was cleared by the read of ILCR
cau r4, r4, ICO_SLI # add in ICO cmd to set level
mtspr ILCR, r4 # set the level
ilcr_rd1:
br
#
# Move to dabr
#
# input: r3 = value to write to dabr
#
# output: dabr updated
#
S_PROLOG(mtdabr)
MTSPR(DABR) # get the dar
br
FCNDES(mtdabr)
#
# Move from dabr
#
# input: none
#
# output: r3=dabr value
#
S_PROLOG(mfdabr)
MFSPR(DABR) # get the dar
br
FCNDES(mfdabr)
.machine "601"
.set HID1, 1009 #
.set HID2, 1010 #
.set HID5, 1013 #DABR
#
# Move to dabr - 601
#
# input: r3 = value to write to dabr
#
# output: dabr (hid5) updated
#
S_PROLOG(mtdabr601)
mtspr HID5,r3
br
FCNDES(mtdabr601)
# Move to hid1 - 601
#
# input: r3 = value to write to hid1
#
# output: hid1 updated
#
S_PROLOG(mthid1)
mtspr HID1,r3
br
FCNDES(mthid1)
# Move to hid2 - 601
#
# input: r3 = value to write to hid2
#
# output: hid2 updated
#
S_PROLOG(mthid2)
mtspr HID2,r3
br
FCNDES(mthid2)
# Move from hid1 - 601
#
# input: none
#
# output: r3 = value of hid1
#
S_PROLOG(mfhid1)
mfspr r3,HID1
br
FCNDES(mfhid1)
',)
include(low_dsect.m4)
include(systemcfg.m4)
include(scrs.m4)