dma.h 3.28 KB
/*
 * Copyright (C) 1996-1998 by the Board of Trustees
 *    of Leland Stanford Junior University.
 * 
 * This file is part of the SimOS distribution. 
 * See LICENSE file for terms of the license. 
 *
 */

/*****************************************************************
 * dma.h
 * 
 * Author: $author$
 * Date: $date$
 *****************************************************************
 * Simple implementation of DMA transfer:
 *
 * During the DMA transfer, each line generates a call to the memory system,
 * either a GET (DMARead) or a GETX (DMAWrite). The line will then be owned
 * owned by the requesting processor (the one that initiated the IO operation.
 * Unlike calls to the memory system initiated by the CPU, the line does not 
 * end up in the cache hierarchy.
 *
 * Revision history:
 *  Dan Teodosiu, 07/96  Changed to use a data source function instead
 *                       of as pre-provided data buffer.
 * *******************************************************************/

#ifndef DMA_H
#define DMA_H


typedef enum {DMA_OK, DMA_NAK, DMA_BAD} DMAStatus;

extern void DMAInit(void);
extern void DMACmdDone(int transId, DMAStatus result);

/*
 * transId are negative numbers that uniquely map to
 * DMA channels. At most one DMA request per DMA channel
 * is outstanding at the same time.
 * 
 * For a given transId, TRANSID2DMACHANNEL(transId) is 
 * guarranteed to be smaller than NUM_DMA_CHANNELS
 */

#define NUM_DMA_CHANNELS 36
#define DMACHANNEL2TRANSID(_chnum) (-((_chnum)+1))
#define TRANSID2DMACHANNEL(_transid) ((-(_transid))-1)

/* 
 * The DMARequest structure is initialized by the 
 * caller for a set of DMA requests and is subsequently
 * updated by the dma model.  (simhd is THE example)
 */
typedef struct DMARequest {
   int    execCpu;       /* CPU to execute on */

   int    isDMAWrite;    /* type of transfer */
   PA    *pAddrs;        /* physical addresses */
   int    offset;        /* current offset */
   int    remainingLen;  /* remaining transfer length (set by DMA) */
   int    amountMoved;   /* amount moved so far */

   int    dmaLen;        /* current transfer size (set by DMA) */
   byte  *data;          /* current data buffer (changed by handler) */
   void (*handler)(struct DMARequest* req); /* data handler */
   uint  arg;           /* argument for handler */
} DMARequest;

/* Notes on DMA data handling:
 *  - for DMA write requests, the handler is called before the call
 *    into the memsystem. The handler must update the data field to
 *    point to the data buffer from which the transfer to memory will
 *    take place.
 *  - for DMA read requests, the handler is called after the transfer
 *    from memory to the data buffer has occurred. After it has saved
 *    the data, the handler is free to change the data field in
 *    preparation for the next request.
 * In both cases, the transfer size is indicated by the dmaLen field.
 */

extern void DMAdoTransfer (int cpuNum,                     /* initiator CPU */
                           DMARequest *req,                /* request */
                           SimTime finishTime,             /* DMA end time */
                           void (*done)(int), int doneArg, /* done cb */
                           int execCpuNum);                /* executor CPU */

                                
#endif /* DMA_H */