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

454 lines
12 KiB
Plaintext

# @(#)05 1.3 src/bos/kernel/ml/POWER/pioutil.m4, sysml, bos411, 9428A410j 7/27/93 20:54:17
#
# COMPONENT_NAME: (SYSIOS) IO Subsystem
#
# FUNCTIONS: buscpy, busgetlr, busputlr, busgetc, busputc
# busgets, busputs, busgetl, busputl
#
# ORIGINS: 27, 83
#
# IBM CONFIDENTIAL -- (IBM Confidential Restricted when
# combined with the aggregated modules for this product)
# SOURCE MATERIALS
# (C) COPYRIGHT International Business Machines Corp. 1990,1992,1993
# All Rights Reserved
#
# US Government Users Restricted Rights - Use, duplication or
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
#
#
# LEVEL 1, 5 Years Bull Confidential Information
#
# NOTES:
# These are the UP system overlays for pio services. These routines
# should be callable from a kernel extension with a branch absolute, or
# through the glink interface.
#
#-----------------------------------------------------------------------------
#------------------------------------------------------------------------------
#
# NAME: busgetc
#
# FUNCTION: set up a exception handler and get a byte from IO space
#
# CALL: int busgetc(ioaddr, data)
# char *ioaddr; /* effective address to load from */
# char *data; /* byte value returned here */
#
# EXECUTION ENVIORNMENT:
# can be called from process or interrupt level
#
#
# RETURNS:
# 0 if load was successful
# exception code if an exception occured
#
#------------------------------------------------------------------------------
.org busgetc_addr+real0
ENTRY(busgetc):
.globl ENTRY(busgetc)
GET_CSA(cr0, r6, r5) # get mst pointer
mflr r6 # return address
st r6, excbranch(r5) # set exception handler
lbz r8, 0(r3) # do load
lil r3, 0 # clear exception handler
st r3, excbranch(r5)
stb r8, 0(r4) # set return value
br
_DF(_DF_NOFRAME)
#------------------------------------------------------------------------------
#
# NAME: busgets
#
# FUNCTION: set up a exception handler and read a short form IO space
#
# CALL: int busgets(ioaddr, data)
# short *ioaddr; /* effective address to load from */
# short *data; /* short value returned here */
#
# EXECUTION ENVIORNMENT:
# can be called from process or interrupt level
#
# RETURNS:
# 0 if load was successful
# exception code if an exception occured
#
#------------------------------------------------------------------------------
.org busgets_addr+real0
ENTRY(busgets):
.globl ENTRY(busgets)
GET_CSA(cr0, r6, r5) # get pointer to mst
mflr r6 # get return address
st r6, excbranch(r5) # set up exception handler
lhz r8, 0(r3) # do load
lil r3, 0 # clear exception handler
st r3, excbranch(r5)
sth r8, 0(r4) # store return data
br
_DF(_DF_NOFRAME)
#------------------------------------------------------------------------------
#
# NAME: busgetsr
#
# FUNCTION: set up a exception handler, and read a little-endian short
#
#
# CALL: int busgetsr(ioaddr, data)
# short *ioaddr; /* effective address to load from */
# short *data; /* short value returned here */
#
# EXECUTION ENVIORNMENT:
# can be called from process or interrupt level
#
# RETURNS:
# 0 if load was successful
# exception code if an exception occured
#
#------------------------------------------------------------------------------
.org busgetsr_addr+real0
ENTRY(busgetsr):
.globl ENTRY(busgetsr)
GET_CSA(cr0, r6, r5) # get mst pointer
mflr r6 # get return address
st r6, excbranch(r5) # set excption handler
lhz r12,0(r3) # Get the two byte value
lil r3, 0
st r3, excbranch(r5) # clear exception handler
rlimi r7, r12, 24, 0xff # move high byte to low
rlimi r7, r12, 8, 0xff00 # move low byte to high
sth r7, 0(r4) # store result
br
_DF(_DF_NOFRAME)
#------------------------------------------------------------------------------
#
# NAME: busgetl
#
# FUNCTION: set up a exception handler and read a long form IO space
#
# CALL: int busgetl(ioaddr, data)
# long *ioaddr; /* effective address to load from */
# long *data; /* long value returned here */
#
# EXECUTION ENVIORNMENT:
# can be called from process or interrupt level
#
# RETURNS:
# 0 if load was successful
# exception code if an exception occured
#
#------------------------------------------------------------------------------
.org busgetl_addr+real0
ENTRY(busgetl):
.globl ENTRY(busgetl)
GET_CSA(cr0, r6, r5) # get mst pointer
mflr r6 # get return value
st r6, excbranch(r5) # set exception handler
l r8, 0(r3) # do load
lil r3, 0 # clear exception handler
st r3, excbranch(r5)
st r8, 0(r4) # store result
br
_DF(_DF_NOFRAME)
#------------------------------------------------------------------------------
#
# NAME: busgetlr
#
# FUNCTION: set up a exception handler, and read a little-endian long
#
#
# CALL: int busgetlr(ioaddr, data)
# long *ioaddr; /* effective address to store to */
# long *data; /* long value returned here */
#
# EXECUTION ENVIORNMENT:
# can be called from process or interrupt level
#
# RETURNS:
# 0 if load was successful
# exception code if an exception occured
#
#------------------------------------------------------------------------------
.org busgetlr_addr+real0
ENTRY(busgetlr):
.globl ENTRY(busgetlr)
GET_CSA(cr0, r6, r5) # get mst pointer
mflr r6 # get return address
st r6, excbranch(r5) # set exception handler
l r12,0(r3) # do load
lil r3, 0 # clear exception handler
st r3, excbranch(r5)
rlimi r7, r12, 24, 0xff000000 # do byte swapping, lo to high
rlimi r7, 12, 8, 0x00ff0000 # swap middle byte
rlimi r7, r12, 24, 0x0000ff00 # swap middle byte
rlimi r7, r12, 8, 0x000000ff # high byte to low byte
st r7, 0(r4) # store result
br
_DF(_DF_NOFRAME)
#------------------------------------------------------------------------------
#
# NAME: busputc
#
# FUNCTION: set up a exception handler, and store a byte to IO space
#
# CALL: int busputc(ioaddr, data)
# char *ioaddr; /* effective address to store to */
# char data; /* byte to store */
#
# EXECUTION ENVIORNMENT:
# can be called from process or interrupt level
#
# RETURNS:
# 0 if load was successful
# exception code if an exception occured
#
#------------------------------------------------------------------------------
.org busputc_addr+real0
ENTRY(busputc):
.globl ENTRY(busputc)
GET_CSA(cr0, r6, r5) # get mst address
mflr r6 # get return address
st r6, excbranch(r5) # set exception handler
stb r4, 0(r3) # do store
lil r3, 0 # clear exception hander
st r3, excbranch(r5)
br
_DF(_DF_NOFRAME)
#------------------------------------------------------------------------------
#
# NAME: busputs
#
# FUNCTION: set up a exception handler, and store a short to IO space
#
# CALL: int busputs(ioaddr, data)
# short *ioaddr; /* effective address to store to */
# short data; /* short to store */
#
# EXECUTION ENVIORNMENT:
# can be called from process or interrupt level
#
# RETURNS:
# 0 if load was successful
# exception code if an exception occured
#
#------------------------------------------------------------------------------
.org busputs_addr+real0
ENTRY(busputs):
.globl ENTRY(busputs)
GET_CSA(cr0, r6, r5) # get mst address
mflr r6 # get return address
st r6, excbranch(r5) # set exception hander
sth r4, 0(r3) # do store
lil r3, 0 # clear exception hander
st r3, excbranch(r5)
br
_DF(_DF_NOFRAME)
#------------------------------------------------------------------------------
#
# NAME: busputl
#
# FUNCTION: set up a exception handler, and store a long to IO space
#
# CALL: int busputl(ioaddr, data)
# long *ioaddr; /* effective address to store to */
# long data; /* long to store */
#
# EXECUTION ENVIORNMENT:
# can be called from process or interrupt level
#
# RETURNS:
# 0 if load was successful
# exception code if an exception occured
#
#------------------------------------------------------------------------------
.org busputl_addr+real0
ENTRY(busputl):
.globl ENTRY(busputl)
GET_CSA(cr0, r6, r5) # get mst pointer
mflr r6 # get return addresse
st r6, excbranch(r5) # set exception hander
st r4, 0(r3) # do store
lil r3, 0 # clear exception hander
st r3, excbranch(r5)
br
_DF(_DF_NOFRAME)
#------------------------------------------------------------------------------
#
# NAME: busputsr
#
# FUNCTION: set up a exception handler, and store a short to IO space in
# littel endian format
#
# CALL: int busputsr(ioaddr, data)
# short *ioaddr; /* effective address to store to */
# short data; /* short to store */
#
# EXECUTION ENVIORNMENT:
# can be called from process or interrupt level
#
# RETURNS:
# 0 if load was successful
# exception code if an exception occured
#
#------------------------------------------------------------------------------
.org busputsr_addr+real0
ENTRY(busputsr):
.globl ENTRY(busputsr)
GET_CSA(cr0, r6, r5) # get mst pointer
mflr r6 # get return address
rlimi r12, r4, 24, 0x000000ff # high byte to low
rlimi r12, r4, 8, 0x0000ff00 # low byte to high
st r6, excbranch(r5) # set up exception hander
sth r12, 0(r3) # Store the two byte value
lil r3, 0 # clear exception handler
st r3, excbranch(r5)
br
_DF(_DF_NOFRAME)
#------------------------------------------------------------------------------
#
# NAME: busputlr
#
# FUNCTION: set up a exception handler, and store a long to IO space in
# littel endian format
#
# CALL: int busputlr(ioaddr, data)
# long *ioaddr; /* effective address to store to */
# long data; /* long to store */
#
# EXECUTION ENVIORNMENT:
# can be called from process or interrupt level
#
# RETURNS:
# 0 if load was successful
# exception code if an exception occured
#
#------------------------------------------------------------------------------
.org busputlr_addr+real0
ENTRY(busputlr):
.globl ENTRY(busputlr)
GET_CSA(cr0, r6, r5) # get mst pointer
mflr r6 # get return address
rlimi r12, r4, 24, 0xff000000 # low to high byte
rlimi r12, r4, 8, 0x00ff0000 # switch middle byte
st r6, excbranch(r5) # set up exception hander
rlimi r12, r4, 24, 0x0000ff00 # switch middle byte
rlimi r12, r4, 8, 0x000000ff # high byte to low
st r12, 0(r3) # Store the four byte value
lil r3, 0
st r3, excbranch(r5) # clear exception hander
br
_DF(_DF_NOFRAME)
#------------------------------------------------------------------------------
#
# NAME: buscpy
#
#
# FUNCTION: Indexed string movement to and from Bus I/O and Memory, with
# exception handler
#
# CALL: int buscpy(source, dest, cnt)
# void *source; /* source address */
# void *dest; /* dest address */
# int cnt; /* count in bytes */
#
# EXECUTION ENVIORNMENT:
# can be called from process or interrupt level
#
# RETURNS:
# 0 if successful
# Exception Code if an exception occured
#
#------------------------------------------------------------------------------
.set CHUNK, 32 # bytes to move per chunk
.set L2CHUNK, 5 # log base 2 of CHUNK
.org real0+buscpy_addr
ENTRY(buscpy):
.globl ENTRY(buscpy)
GET_CSA(cr0, r7, r6) # get pointer to current mst
lil r8, CHUNK # number of bytes to move
# per chunk
st r13, -8(r1) # save nonvolatile gprs
st r14, -4(r1)
l r11, DATA(g_toc) # get kernel TOC pointer
sri. r7, r5, L2CHUNK # number of chunks to move
LTOCR(r11, busexcpt, data, r11) # get address out of TOC
rlinm r0, r5, 0, CHUNK-1 # remainder to move
lil r5, 0 # move index
st r11, excbranch(r6) # set up exception hander
beq cr0, small_copy # branch if less then CHUNK
# bytes to move
mtxer r8 # set for string move
mtctr r7 # loop counter
cp_loop:
lsx r7, r5, r3 # load CHUNK bytes
stsx r7, r5, r4 # store CHUNK bytes
ai r5, r5, CHUNK # move to next chunk
bdn cp_loop # banch if more CHUNKs
small_copy:
mtxer r0 # remaining bytes to move
lsx r7, r5, r3
stsx r7, r5, r4
lil r3, 0 # clear exception handler
st r3, excbranch(r6)
busexcpt:
l r13, -8(r1) # restore nonvolatile gprs
l r14, -4(r1)
br
_DF(_DF_NOFRAME)
.toc
TOCL(busexcpt, data)
FCNDES(busgetc, label)
FCNDES(busgets, label)
FCNDES(busgetsr, label)
FCNDES(busgetl, label)
FCNDES(busgetlr, label)
FCNDES(busputc, label)
FCNDES(busputs, label)
FCNDES(busputl, label)
FCNDES(busputsr, label)
FCNDES(busputlr, label)
FCNDES(buscpy, label)
.csect ENTRY(low[PR])