www.pudn.com > vxworks0108.rar > sysALib.s
/* sysALib.s - SBS Technologies VG4 system-dependent assembly routines */
/*
DESCRIPTION
This module contains the entry code, sysInit(), for VxWorks images that start
running from RAM, such as 'vxWorks'. These images are loaded into memory
by some external program (e.g., a boot ROM) and then started.
The routine sysInit() must come first in the text segment. Its job is to perform
the minimal setup needed to call the generic C
routine usrInit() with parameter BOOT_COLD.
The routine sysInit() typically masks interrupts in the processor, sets the
initial stack pointer to _sysInit then jumps to usrInit.
Most other hardware and device initialization is performed later by
sysHwInit().
*/
#define _ASMLANGUAGE
#include "config.h"
#include "reg.h"
#include "ppc750.h"
#include "vg4.h"
/* globals */
.globl _sysInit /* start of system code */
.globl sysTbInit /* Initialize the time base */
.globl sysTimeBaseUGet /* Get upper 32 bit of time base */
.globl sysTimeBaseLGet /* Get lower 32 bit of time base */
.globl sysMsrGet
.globl sysMsrSet
.globl sysL2crSet
.globl sysL2crGet
.globl sysHid1Get
.globl sysThrm1Get
.globl sysThrm1Set
.globl sysThrm2Get
.globl sysThrm2Set
.globl sysThrm3Get
.globl sysThrm3Set
.globl sysInByte
.globl sysOutByte
.globl sysIn16
.globl sysOut16
.globl sysIn32
.globl sysOut32
.globl sysInWord
.globl sysOutWord
.globl sysInLong
.globl sysOutLong
.globl sysPciRead32
.globl sysPciWrite32
.globl sysPciInByte
.globl sysPciOutByte
.globl sysPciInWord
.globl sysPciOutWord
.globl sysPciInLong
.globl sysPciOutLong
.globl sysPVRReadSys
.globl sysMemProbeSup
.globl sysProbeExc
/* externals */
.extern kernelInit
.text
/*******************************************************************************
*
* sysInit - start after boot
*
* This is the system start-up entry point for VxWorks in RAM, the
* first code executed after booting. It disables interrupts, sets up
* the stack, and jumps to the C routine usrInit() in usrConfig.c.
*
* The initial stack is set to grow down from the address of sysInit(). This
* stack is used only by usrInit() and is never used again. Memory for the
* stack must be accounted for when determining the system load address.
*
* NOTE: This routine should not be called by the user.
*
* RETURNS: N/A
* sysInit (void) /@ THIS IS NOT A CALLABLE ROUTINE @/
*/
_sysInit:
/* disable interrupts */
xor p0, p0, p0
mtmsr p0 /* clear the MSR register */
/* Zero-out registers: r0 & SPRGs */
xor r0,r0,r0
mtspr 272,r0
mtspr 273,r0
mtspr 274,r0
mtspr 275,r0
/*
* Set MPU/MSR to a known state
* Turn on FP
*/
andi. r3, r3, 0
ori r3, r3, 0x2000
sync
mtmsr r3
isync
/* Init the floating point control/status register */
mtfsfi 7,0x0
mtfsfi 6,0x0
mtfsfi 5,0x0
mtfsfi 4,0x0
mtfsfi 3,0x0
mtfsfi 2,0x0
mtfsfi 1,0x0
mtfsfi 0,0x0
isync
/* Initialize the floating point data registers to a known state */
bl ifpdrValue
.long 0x3f800000 /* 1.0 */
ifpdrValue:
mfspr r3,8
lfs f0,0(r3)
lfs f1,0(r3)
lfs f2,0(r3)
lfs f3,0(r3)
lfs f4,0(r3)
lfs f5,0(r3)
lfs f6,0(r3)
lfs f7,0(r3)
lfs f8,0(r3)
lfs f9,0(r3)
lfs f10,0(r3)
lfs f11,0(r3)
lfs f12,0(r3)
lfs f13,0(r3)
lfs f14,0(r3)
lfs f15,0(r3)
lfs f16,0(r3)
lfs f17,0(r3)
lfs f18,0(r3)
lfs f19,0(r3)
lfs f20,0(r3)
lfs f21,0(r3)
lfs f22,0(r3)
lfs f23,0(r3)
lfs f24,0(r3)
lfs f25,0(r3)
lfs f26,0(r3)
lfs f27,0(r3)
lfs f28,0(r3)
lfs f29,0(r3)
lfs f30,0(r3)
lfs f31,0(r3)
sync
/*
* Set MPU/MSR to a known state
* Turn off FP
*/
andi. r3, r3, 0
sync
mtmsr r3
isync
/* Init the Segment registers */
andi. r3, r3, 0
isync
mtsr 0,r3
isync
mtsr 1,r3
isync
mtsr 2,r3
isync
mtsr 3,r3
isync
mtsr 4,r3
isync
mtsr 5,r3
isync
mtsr 6,r3
isync
mtsr 7,r3
isync
mtsr 8,r3
isync
mtsr 9,r3
isync
mtsr 10,r3
isync
mtsr 11,r3
isync
mtsr 12,r3
isync
mtsr 13,r3
isync
mtsr 14,r3
isync
mtsr 15,r3
isync
/* disable L2 caches */
sync
mfspr r3, L2CR_REG /* Read L2 control register */
andis. r3, r3, L2CR_DISABLE_MASK_U /* Disable L2 backside */
mtspr L2CR_REG, r3
sync
/* insert protection from decrementer exceptions */
addis p1, r0, 0x4c00
addi p1, p1, 0x0064 /* load rfi (0x4c000064) to p1 */
stw p1, 0x900(r0) /* store rfi at 0x00000900 */
/* initialize the stack pointer */
lis sp, HIADJ(_sysInit)
addi sp, sp, LO(_sysInit)
/* Turn off data and instruction cache control bits */
mfspr r3, HID0
isync
rlwinm r4, r3, 0, 18, 15 /* r4 has ICE and DCE bits cleared */
sync
isync
mtspr HID0, r4 /* HID0 = r4 */
isync
/* Get cpu type */
mfspr r28, PVR
rlwinm r28, r28, 16, 16, 31
/* invalidate the MPU's data/instruction caches */
#ifdef USER_I_CACHE_ENABLE
mfspr r3,HID0
addis r4,r0,0x0000 /* Clear r4 */
ori r4,r4,0x8800 /* Setup bit pattern for ICE/ICFI */
or r3,r4,r3
isync
mtspr HID0,r3 /* set ICE/ICFI */
addis r4,r0,0x0000 /* Clear r4 */
ori r4,r4,0x0800 /* Setup bit pattern for ICFI */
andc r3,r3,r4
isync
mtspr HID0,r3 /* clear IFCI (bit 16) */
addis r4,r0,0x0000 /* Clear r4 */
ori r4,r4,0x2000 /* Setup bit pattern for ILOCK */
andc r3,r3,r4
isync
mtspr HID0,r3 /* clear ILOCK (bit 18) */
sync
#endif
/* disable instruction and data translations in the MMU */
sync
mfmsr r3 /* get the value in msr *
/* clear bits IR and DR */
rlwinm r4, r3, 0, _PPC_MSR_BIT_DR+1, _PPC_MSR_BIT_IR - 1
mtmsr r4 /* set the msr */
sync /* SYNC */
/* initialize the BAT register */
li p3,0 /* clear p0 */
isync
mtspr IBAT0U,p3 /* SPR 528 (IBAT0U) */
isync
mtspr IBAT0L,p3 /* SPR 529 (IBAT0L) */
isync
mtspr IBAT1U,p3 /* SPR 530 (IBAT1U) */
isync
mtspr IBAT1L,p3 /* SPR 531 (IBAT1L) */
isync
mtspr IBAT2U,p3 /* SPR 532 (IBAT2U) */
isync
mtspr IBAT2L,p3 /* SPR 533 (IBAT2L) */
isync
mtspr IBAT3U,p3 /* SPR 534 (IBAT3U) */
isync
mtspr IBAT3L,p3 /* SPR 535 (IBAT3L) */
isync
mtspr DBAT0U,p3 /* SPR 536 (DBAT0U) */
isync
mtspr DBAT0L,p3 /* SPR 537 (DBAT0L) */
isync
mtspr DBAT1U,p3 /* SPR 538 (DBAT1U) */
isync
mtspr DBAT1L,p3 /* SPR 539 (DBAT1L) */
isync
mtspr DBAT2U,p3 /* SPR 540 (DBAT2U) */
isync
mtspr DBAT2L,p3 /* SPR 541 (DBAT2L) */
isync
mtspr DBAT3U,p3 /* SPR 542 (DBAT3U) */
isync
mtspr DBAT3L,p3 /* SPR 543 (DBAT3L) */
isync
/* Check CPU type resp. revision */
cmplwi r28, CPU_TYPE_750
bne INVAL_TLB
cmplwi r27, CPU_REV_750_IBM
bnl INVAL_TLB
cmpli cr0, r27, CPU_REV_755
blt INVAL_TLB
/* Disable additional BATs for 755 processor */
mtspr IBAT4U, r3
isync
mtspr IBAT5U, r3
isync
mtspr IBAT6U, r3
isync
mtspr IBAT7U, r3
isync
mtspr DBAT4U, r3
isync
mtspr DBAT5U, r3
isync
mtspr DBAT6U, r3
isync
mtspr DBAT7U, r3
isync
/* Set HID2 to known state (755 processors) */
andi. r3, r3, 0
mtspr HID2, r3
/* invalidate entries within both TLBs */
INVAL_TLB:
li p1, 128
xor p0, p0, p0 /* p0 = 0 */
mtctr p1 /* CTR = 128 */
isync /* context sync req'd before tlbie */
sysALoop:
tlbie p0
addi p0, p0, 0x1000 /* increment bits 15-19 */
bdnz sysALoop /* decrement CTR, branch if CTR != 0 */
sync /* sync instr req'd after tlbie */
/* initialize Small Data Area (SDA) start address */
#if FALSE /* XXX TPR NO SDA for now */
lis r2, HIADJ(_SDA2_BASE_)
addi r2, r2, LO(_SDA2_BASE_)
lis r13, HIADJ(_SDA_BASE_)
addi r13, r13, LO(_SDA_BASE_)
#endif
addi sp, sp, -FRAMEBASESZ /* get frame stack */
li p0, 0 /* set start type arg = WARM_BOOT */
b kernelInit /* never returns - starts up kernel */
/*******************************************************************************
*
* sysL2crSet - write to L2CR register of Arthur CPU
*
* This routine will write the contents of r3 to the L2CR
* register.
*
* From a C point of view, the routine is defined as follows:
*
* void sysL2crSet
* (
* ULONG value to write
* )
*
* RETURNS: NA
*/
sysL2crSet:
mtspr 1017,r3
blr
/*******************************************************************************
*
* sysL2crGet - read from L2CR register of Arthur CPU
*
* This routine will read the contents the L2CR register.
*
* From a C point of view, the routine is defined as follows:
*
* UINT sysL2crGet()
*
* RETURNS: value of SPR1017 (in r3)
*/
sysL2crGet:
mfspr r3,1017
blr
/******************************************************************************
*
* sysHid1Get - read from HID1 register SPR1009.
*
* This routine will read the contents the HID1 (SPR1009)
*
* From a C point of view, the routine is defined as follows:
*
* UINT sysHid1Get()
*
* RETURNS: value of SPR1009 (in r3)
*/
sysHid1Get:
mfspr p0,1009 /* HID1 */
blr
/******************************************************************************
*
* sysIabrGet - read from HID1 register SPR1009.
*
* This routine will read the contents the HID1 (SPR1009)
*
* From a C point of view, the routine is defined as follows:
*
* UINT sysIabrGet()
*
* RETURNS: value of SPR1009 (in r3)
*/
sysIabrGet:
mfspr p0,1009 /* HID1 */
blr
/******************************************************************************
*
* sysThrm1Get - read from THRM1 register SPR1020.
*
* This routine will read the contents the THRM1 (SPR1020)
*
* From a C point of view, the routine is defined as follows:
*
* UINT sysThrm1Get()
*
* RETURNS: value of SPR1020 (in r3)
*/
sysThrm1Get:
mfspr p0,1020 /* THRM1 */
blr
/*******************************************************************************
*
* sysThrm1Set - write to THRM1 register of Arthur CPU
*
* This routine will write the contents of r3 to the THRM1
* register.
*
* From a C point of view, the routine is defined as follows:
*
* void sysThrm1Set
* (
* ULONG value to write
* )
*
* RETURNS: NA
*/
sysThrm1Set:
mtspr 1020,r3
blr
/******************************************************************************
*
* sysThrm2Get - read from THRM2 register SPR1021.
*
* This routine will read the contents the THRM2 (SPR1020)
*
* From a C point of view, the routine is defined as follows:
*
* UINT sysThrm2Get()
*
* RETURNS: value of SPR1021 (in r3)
*/
sysThrm2Get:
mfspr p0,1021 /* THRM2 */
blr
/*******************************************************************************
*
* sysThrm2Set - write to THRM2 register of Arthur CPU
*
* This routine will write the contents of r3 to the THRM2
* register.
*
* From a C point of view, the routine is defined as follows:
*
* void sysThrm2Set
* (
* ULONG value to write
* )
*
* RETURNS: NA
*/
sysThrm2Set:
mtspr 1021,r3
blr
/******************************************************************************
*
* sysThrm3Get - read from THRM3 register SPR1022.
*
* This routine will read the contents the THRM3 (SPR1022)
*
* From a C point of view, the routine is defined as follows:
*
* UINT sysThrm3Get()
*
* RETURNS: value of SPR1022 (in r3)
*/
sysThrm3Get:
mfspr p0,1022 /* THRM3 */
blr
/*******************************************************************************
*
* sysThrm3Set - write to THRM3 register of Arthur CPU
*
* This routine will write the contents of r3 to the THRM3
* register.
*
* From a C point of view, the routine is defined as follows:
*
* void sysThrm3Set
* (
* ULONG value to write
* )
*
* RETURNS: NA
*/
sysThrm3Set:
mtspr 1022,r3
blr
/******************************************************************************
*
* sysTimeBaseUGet - Get upper half of Time Base Register
*
* This routine will read the contents the upper half of the Time
* Base Register (TBL - TBR 269).
*
* This is not a standard routine. The library call vxTimeBaseGet returns a
* 64-bit quantity. This is a special fix to get access to just the upper
* 32-bits of the timebase.
*
* From a C point of view, the routine is defined as follows:
*
* UINT32 sysTimeBaseUGet(void)
*
* RETURNS: value of TBR 269 (in r3)
*/
sysTimeBaseUGet:
mftbu 3
bclr 20,0
/******************************************************************************
*
* sysTimeBaseLGet - Get lower half of Time Base Register
*
* This routine will read the contents the lower half of the Time
* Base Register (TBL - TBR 268).
*
* This is not a standard routine. The library call vxTimeBaseGet returns a
* 64-bit quantity. This is a special fix to get access to just the lower
* 32-bits of the timebase.
*
* From a C point of view, the routine is defined as follows:
*
* UINT32 sysTimeBaseLGet(void)
*
* RETURNS: value of TBR 268 (in r3)
*/
sysTimeBaseLGet:
mftb 3
bclr 20,0
/******************************************************************************
*
* sysTbInit - Initialize to timebase to 0
*
* This routine will set the contents the timebase (SPR284/285) to 0
*
* From a C point of view, the routine is defined as follows:
*
* VOID sysTbInit()
*
* RETURNS: NA
*/
sysTbInit:
li 3,0
mtspr 284,3 /* Set TBL to zero (prevents carry during init) */
mtspr 285,3 /* Init TBU to zero */
mtspr 284,3 /* Init TBL to zero */
blr
/******************************************************************************
*
* sysMsrGet - Get the MSR register
*
* This routine will read the contents of the MSR
*
* From a C point of view, the routine is defined as follows:
*
* UINT sysMsrGet()
*
* RETURNS: value of MSR (in r3)
*/
sysMsrGet:
mfmsr p0 /* MSR */
blr
/******************************************************************************
*
* sysMsrSet - Set the MSR register
*
* This routine will set the contents of the MSR
*
* From a C point of view, the routine is defined as follows:
*
* void sysMsrSet(UINT value to write)
*
* RETURNS: NA
*/
sysMsrSet:
sync
isync
mtmsr p0 /* MSR */
sync
isync
blr
/*****************************************************************************
*
* sysInByte - reads a byte from an address.
*
* This function reads a byte from a specified address.
*
* From a C programmers point of view, the routine is defined as follows:
*
* sysInByte
* (
* ULONG *addr; - address of data
* )
*
* INPUTS:
* r3 = address to read data from
*
* OUTPUTS:
* r3 = data
*
* RETURNS: byte from address.
*/
sysInByte:
lbzx p0,r0,p0 /* Read byte from I/O space */
eieio /* Sync I/O operation */
sync
bclr 20,0 /* Return to caller */
/******************************************************************************
*
* sysOutByte - writes a byte to an address.
*
* This function writes a byte to a specified address.
*
* From a C point of view, the routine is defined as follows:
*
* sysOutByte
* (
* ULONG *addr - address to write data to
* UCHAR data - 8-bit data
* )
*
* INPUTS:
* r3 = address to write to
* r4 = data to be written
*
* RETURNS: N/A
*/
sysOutByte:
stbx p1,r0,p0 /* Write a byte to given address */
eieio /* Sync I/O operation */
sync
bclr 20,0 /* Return to caller */
/*****************************************************************************
*
* sysIn16 - reads a 16-bit unsigned value from an address.
*
* This function reads a 16-bit unsigned value from a specified address.
*
* From a C programmers point of view, the routine is defined as follows:
*
* sysIn16
* (
* UINT16 *addr; - address of data
* )
*
* INPUTS:
* r3 = address to read data from
*
* OUTPUTS:
* r3 = data
*
* RETURNS: 16-bit unsigned value from address.
*/
sysIn16:
lhz p0, 0(p0)
eieio /* Sync I/O operation */
sync
bclr 20,0
/******************************************************************************
*
* sysOut16 - writes a 16-bit unsigned value to an address.
*
* This function writes a 16-bit unsigned value to a specified address.
*
* From a C point of view, the routine is defined as follows:
*
* sysOut16
* (
* UINT16 *addr - address to write data to
* UINT16 data - 8-bit data
* )
*
* INPUTS:
* r3 = address to write to
* r4 = data to be written
*
* RETURNS: N/A
*/
sysOut16:
sth p1,0(p0)
eieio /* Sync I/O operation */
sync
bclr 20,0
/*****************************************************************************
*
* sysIn32 - reads a 32-bit unsigned value from an address.
*
* This function reads a 32-bit unsigned value from a specified address.
*
* From a C programmers point of view, the routine is defined as follows:
*
* sysIn32
* (
* UINT32 *addr; - address of data
* )
*
* INPUTS:
* r3 = address to read data from
*
* OUTPUTS:
* r3 = data
*
* RETURNS: 32-bit unsigned value from address.
*/
sysIn32:
lwz p0,0(p0)
eieio /* Sync I/O operation */
sync
bclr 20,0
/******************************************************************************
*
* sysOut32 - writes a 32-bit unsigned value to an address.
*
* This function writes a 32-bit unsigned value to a specified address.
*
* From a C point of view, the routine is defined as follows:
*
* sysOut32
* (
* UINT32 *addr - address to write data to
* UINT32 data - 32-bit data
* )
*
* INPUTS:
* r3 = address to write to
* r4 = data to be written
*
* RETURNS: N/A
*/
sysOut32:
stw p1,0(p3)
eieio /* Sync I/O operation */
sync
bclr 20,0
/******************************************************************************
*
* sysPciRead32 - read 32 bit PCI data
*
* This routine will read a 32-bit data item from PCI (I/O or
* memory) space.
*
* RETURNS: N/A
* VOID sysPciRead32
* (
* ULONG * pAddr, /@ Virtual addr to read from @/
* ULONG * pResult /@ location to receive data @/
* )
*/
sysPciRead32:
lwbrx p0,r0,p0 /* get the data and swap the bytes */
eieio /* Sync I/O operation */
sync
stw p0,0(p1) /* store into address ptd. to by p1 */
bclr 20,0
/******************************************************************************
*
* sysPciWrite32 - write a 32 bit data item to PCI space
*
* This routine will store a 32-bit data item (input as big-endian)
* into PCI (I/O or memory) space in little-endian mode.
*
* RETURNS: N/A
* VOID sysPciWrite32
* (
* ULONG * pAddr, /@ Virtual addr to write to @/
* ULONG data /@ Data to be written @/
* )
*/
sysPciWrite32:
stwbrx p1,r0,p0 /* store data as little-endian */
eieio /* Sync I/O operation */
sync
bclr 20,0
/*****************************************************************************
*
* sysPciInByte - reads a byte from PCI Config Space.
*
* This function reads a byte from a specified PCI Config Space address.
*
* RETURNS:
* Returns 8 bit data from the specified register. Note that for PCI systems
* if no target responds, the data returned to the CPU will be 0xff.
* UINT8 sysPciInByte
* (
* UINT8 * pAddr, /@ Virtual addr to read from @/
* )
*/
sysPciInByte:
lbzx p0,r0,p0 /* Read byte from PCI space */
eieio /* Sync I/O operation */
sync
bclr 20,0 /* Return to caller */
/*****************************************************************************
*
* sysPciInWord - reads a word (16-bit big-endian) from PCI Config Space.
*
* This function reads a word from a specified PCI Config Space (little-endian)
* address.
*
* RETURNS:
* Returns 16 bit data from the specified register. Note that for PCI systems
* if no target responds, the data returned to the CPU will be 0xffff.
* USHORT sysPciInWord
* (
* USHORT * pAddr, /@ Virtual addr to read from @/
* )
*/
sysPciInWord:
sysInWord:
lhbrx p0,r0,p0 /* Read and swap from PCI space */
eieio /* Sync I/O operation */
sync
bclr 20,0 /* Return to caller */
/*****************************************************************************
*
* sysPciInLong - reads a long (32-bit big-endian) from PCI Config Space.
*
* This function reads a long from a specified PCI Config Space (little-endian)
* address.
*
* RETURNS:
* Returns 32 bit data from the specified register. Note that for PCI systems
* if no target responds, the data returned to the CPU will be 0xffffffff.
* ULONG sysPciInLong
* (
* ULONG * pAddr, /@ Virtual addr to read from @/
* )
*/
sysPciInLong:
sysInLong:
lwbrx p0,r0,p0 /* Read and swap from PCI space */
eieio /* Sync I/O operation */
sync
bclr 20,0 /* Return to caller */
/******************************************************************************
*
* sysPciOutByte - writes a byte to PCI Config Space.
*
* This function writes a byte to a specified PCI Config Space address.
*
* RETURNS: N/A
* VOID sysPciOutByte
* (
* UINT8 * pAddr, /@ Virtual addr to write to @/
* UINT8 data /@ Data to be written @/
* )
*/
sysPciOutByte:
stbx p1,r0,p0 /* Write a byte to PCI space */
eieio /* Sync I/O operation */
sync
bclr 20,0 /* Return to caller */
/******************************************************************************
*
* sysPciOutWord - writes a word (16-bit big-endian) to PCI Config Space.
*
* This function writes a word to a specified PCI Config Space (little-endian)
* address.
*
* RETURNS: N/A
* VOID sysPciOutWord
* (
* USHORT * pAddr, /@ Virtual addr to write to @/
* USHORT data /@ Data to be written @/
* )
*/
sysPciOutWord:
sysOutWord:
sthbrx p1,r0,p0 /* Write with swap to PCI space */
eieio /* Sync I/O operation */
sync
bclr 20,0 /* Return to caller */
/******************************************************************************
*
* sysPciOutLong - writes a long (32-bit big-endian) to PCI Config Space.
*
* This function writes a long to a specified PCI Config Space (little-endian)
* address.
*
* RETURNS: N/A
* VOID sysPciOutLong
* (
* ULONG * pAddr, /@ Virtual addr to write to @/
* ULONG data /@ Data to be written @/
* )
*/
sysPciOutLong:
sysOutLong:
stwbrx p1,r0,p0 /* Write big-endian long to little-endian */
mr p0,p1 /* PCI space */
eieio /* Sync I/O operation */
sync
bclr 20,0 /* Return to caller */
/**********************************************************************
* sysPVRReadSys - Read the content of the PVR register
* Once the PVR is read, the 16 least significant bits are shifted
* off.
* Input - None
* Return - upper 16 bits of PVR stored in r3
*/
sysPVRReadSys:
mfspr r4, PVR_REG /* read PVR */
srawi r3, r4, 16 /* shift off the least 16 bits */
blr
#ifdef INCLUDE_CACHE_L2
#include "sysMaxL2Disable.s"
#endif
/*******************************************************************************
*
* sysMemProbeSup - sysBusProbe support routine
*
* This routine is called to try to read byte, word, or long, as specified
* by length, from the specified source to the specified destination.
*
* RETURNS: OK if successful probe, else ERROR
*
* STATUS sysMemProbeSup (length, src, dest)
* (
* int length, // length of cell to test (1, 2, 4)
* char * src, // address to read
* char * dest // address to write
* )
*/
sysMemProbeSup:
addi r10, r3, 0 /* save length to p7 */
xor r3, r3, r3 /* set return status */
cmpwi r10, 1 /* check for byte access */
bne sbpShort /* no, go check for short word access */
lbz r9, 0(r4) /* load byte from source */
eieio
sync
stb r9, 0(r5) /* store byte to destination */
eieio
sync
isync /* flush instruction pipe */
blr
sbpShort:
cmpwi r10, 2 /* check for short word access */
bne sbpWord /* no, check for word access */
lhz r9, 0(r4) /* load half word from source */
eieio
sync
sth r9, 0(r5) /* store half word to destination */
eieio
sync
isync /* flush instruction pipe */
blr
sbpWord:
cmpwi r10, 4 /* check for word access */
bne sysProbeExc /* no, error return */
lwz r9, 0(r4) /* load half word from source */
eieio
sync
stw r9, 0(r5) /* store half word to destination */
eieio
sync
isync /* flush instruction pipe */
blr
sysProbeExc:
li r3, -1 /* shouldn't ever get here, but... */
blr /* Return to caller */