dma.h
3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/*
* 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 */