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 */