osEPiWriteIo osEPiWriteIo (function)

osEPiStartDma, osEPiWriteIo, osEPiReadIo

Functions as Expanded Peripheral Interface (EPI) using PI manager


#include <ultra64.h>     /* ultra64.h */    
s32 osEPiStartDma(OSPiHandle *pihandle, OSIoMesg *mb, s32 direction)
s32 osEPiWriteIo(OSPiHandle *pihandle, u32 devAddr, u32 data);
s32 osEPiReadIo(OSPiHandle *pihandle, u32 devAddr, u32 *data);


The expanded peripheral interface (EPI) transfers data between RDRAM and a bulk storage device (BSD) such as ROM, Drive ROM, and the N64 Disk Drive. EPI supports many devices sharing the PI domain, and it can switch among these devices dynamically.

These functions manage the PI bus by using the PI manager, and they support synchronization and independence when the PI is shared byperipheral IO utilities such as debug, print, logging, and profiling. You need to initialize the PI manager's system thread before using these EPIroutines. See osPiStartDma for more information on how to do it.

The OSPiHandle data structure acts as a handler so the EPI routines can reference each PI device.The OSPiHandle structure is allocated and initialized by each device's initialization routine. It is also used for saving each PI device attributes.

The osEPiStartDma routine sets up a DMA transfer between RDRAM and the PI device address space (devAddr), by sending an IO message block request (mb) to the PI manager, based on the value of direction (OS_READ or OS_WRITE). The calling side specifies the following parameters in the request block (the device address devAddr, the RDRAM address dramAddr, transfer volume, and the message queue hdr.retQueue that is to receive the message from the PI manager that the IO operation has finished). If the priority request (hdr.pri) is OS_MESG_PRI_HIGH (the default is OS_MESG_PRI_NORMAL), the osEPiStartDma function pushes the message in front of the PI manager's command queue. If it is not OS_MESG_PRI_HIGH, the message is added to the end of the command queue. If the PI manager is not started, osEPiStartDma returns -1. Otherwise, the status is returned to either the osSendMesg or the osJamMesg function. The transfer volume is a maximum of 16 megabytes, and it must be a multiple of two. Two-byte alignment is required for the PI device address (devAddr), and eight-byte alignment is required for the RDRAM's virtual address (dramAddr). Nintendo recommends that you use a 16-byte alignment if the DMA operation is done with OS_READ. See OS_DCACHE_ROUNDUP_ADDR for information about the problems that can occur when the address and the transfer volume are not multiples of the cache line.

The osEPiWriteIo routine performs a 32-bit IO Write operation from devAddr. Similarly, the osEPiReadIo routine performs a 32-bit IO Read operation from devAddr and stores the value to data.


To gain access to the PI, Nintendo strongly recommends that you use these high-level, managed functions (osEPiWriteIo, osEPiReadIo, or osEPiStartDma). Caution is especially required when high-and low-level functions are mixed. The PI can support only one IO at a time, so an out of synchronization condition may cause an error to occur in the PI. osEPiStartDma, osEPiWriteIo, and osEPiReadIo reset the PI bus if there is a discrepancy between the given PI bus setting specified by pihandle and the actual PI bus setting when the function is called. It is not necessary to call osCartRomInit each time.


void romCopy(const char *src, const char *dest, const int len)
        OSIoMesg dmaIoMesgBuf; OSMesgQueue dmaMessageQ; OSMesg dummyMesg;
                osInvalDCache((void *)dest, (s32) len); 
                dmaIoMesgBuf.hdr.pri = OS_MESG_PRI_NORMAL;
                dmaIoMesgBuf.hdr.retQueue = &dmaMessageQ;
                dmaIoMesgBuf.dramAddr = dest;
                dmaIoMesgBuf.devAddr = (u32)src;
                dmaIoMesgBuf.size = len;
                &dmaIoMesgBuf, OS_READ);
                (void) osRecvMesg(&dmaMessageQ, &dummyMesg, OS_MESG_BLOCK);

See Also

osPiRawStartDma , osPiStartDma , osEPiRawStartDma , osCartRomInit , osSendMesg , and osJamMesg

Revision History

1999/04/30 Changed Format