DMASequencer.cc (6433:0f0f0fbef977) DMASequencer.cc (6467:5670eee2a866)
1
2#include "mem/ruby/system/DMASequencer.hh"
3#include "mem/ruby/buffers/MessageBuffer.hh"
4#include "mem/ruby/slicc_interface/AbstractController.hh"
5
6/* SLICC generated types */
1
2#include "mem/ruby/system/DMASequencer.hh"
3#include "mem/ruby/buffers/MessageBuffer.hh"
4#include "mem/ruby/slicc_interface/AbstractController.hh"
5
6/* SLICC generated types */
7#include "mem/protocol/DMARequestMsg.hh"
8#include "mem/protocol/DMARequestType.hh"
9#include "mem/protocol/DMAResponseMsg.hh"
7#include "mem/protocol/SequencerMsg.hh"
8#include "mem/protocol/SequencerRequestType.hh"
10#include "mem/ruby/system/System.hh"
11
12DMASequencer::DMASequencer(const string & name)
13 : RubyPort(name)
14{
15}
16
17void DMASequencer::init(const vector<string> & argv)
18{
19 m_version = -1;
20 m_controller = NULL;
21 for (size_t i=0;i<argv.size();i+=2) {
22 if (argv[i] == "controller")
23 m_controller = RubySystem::getController(argv[i+1]);
24 else if (argv[i] == "version")
25 m_version = atoi(argv[i+1].c_str());
26 }
27 assert(m_controller != NULL);
28 assert(m_version != -1);
29
30 m_mandatory_q_ptr = m_controller->getMandatoryQueue();
31 m_is_busy = false;
32 m_data_block_mask = ~ (~0 << RubySystem::getBlockSizeBits());
33}
34
35int64_t DMASequencer::makeRequest(const RubyRequest & request)
36{
37 uint64_t paddr = request.paddr;
38 uint8_t* data = request.data;
39 int len = request.len;
40 bool write = false;
41 switch(request.type) {
42 case RubyRequestType_LD:
43 write = false;
44 break;
45 case RubyRequestType_ST:
46 write = true;
47 break;
48 case RubyRequestType_NULL:
49 case RubyRequestType_IFETCH:
50 case RubyRequestType_Locked_Read:
51 case RubyRequestType_Locked_Write:
52 case RubyRequestType_RMW_Read:
53 case RubyRequestType_RMW_Write:
54 case RubyRequestType_NUM:
55 assert(0);
56 }
57
58 assert(!m_is_busy); // only support one outstanding DMA request
59 m_is_busy = true;
60
61 active_request.start_paddr = paddr;
62 active_request.write = write;
63 active_request.data = data;
64 active_request.len = len;
65 active_request.bytes_completed = 0;
66 active_request.bytes_issued = 0;
67 active_request.id = makeUniqueRequestID();
68
9#include "mem/ruby/system/System.hh"
10
11DMASequencer::DMASequencer(const string & name)
12 : RubyPort(name)
13{
14}
15
16void DMASequencer::init(const vector<string> & argv)
17{
18 m_version = -1;
19 m_controller = NULL;
20 for (size_t i=0;i<argv.size();i+=2) {
21 if (argv[i] == "controller")
22 m_controller = RubySystem::getController(argv[i+1]);
23 else if (argv[i] == "version")
24 m_version = atoi(argv[i+1].c_str());
25 }
26 assert(m_controller != NULL);
27 assert(m_version != -1);
28
29 m_mandatory_q_ptr = m_controller->getMandatoryQueue();
30 m_is_busy = false;
31 m_data_block_mask = ~ (~0 << RubySystem::getBlockSizeBits());
32}
33
34int64_t DMASequencer::makeRequest(const RubyRequest & request)
35{
36 uint64_t paddr = request.paddr;
37 uint8_t* data = request.data;
38 int len = request.len;
39 bool write = false;
40 switch(request.type) {
41 case RubyRequestType_LD:
42 write = false;
43 break;
44 case RubyRequestType_ST:
45 write = true;
46 break;
47 case RubyRequestType_NULL:
48 case RubyRequestType_IFETCH:
49 case RubyRequestType_Locked_Read:
50 case RubyRequestType_Locked_Write:
51 case RubyRequestType_RMW_Read:
52 case RubyRequestType_RMW_Write:
53 case RubyRequestType_NUM:
54 assert(0);
55 }
56
57 assert(!m_is_busy); // only support one outstanding DMA request
58 m_is_busy = true;
59
60 active_request.start_paddr = paddr;
61 active_request.write = write;
62 active_request.data = data;
63 active_request.len = len;
64 active_request.bytes_completed = 0;
65 active_request.bytes_issued = 0;
66 active_request.id = makeUniqueRequestID();
67
69 DMARequestMsg msg;
68 SequencerMsg msg;
70 msg.getPhysicalAddress() = Address(paddr);
71 msg.getLineAddress() = line_address(msg.getPhysicalAddress());
69 msg.getPhysicalAddress() = Address(paddr);
70 msg.getLineAddress() = line_address(msg.getPhysicalAddress());
72 msg.getType() = write ? DMARequestType_WRITE : DMARequestType_READ;
73 msg.getOffset() = paddr & m_data_block_mask;
74 msg.getLen() = (msg.getOffset() + len) <= RubySystem::getBlockSizeBytes() ?
71 msg.getType() = write ? SequencerRequestType_ST : SequencerRequestType_LD;
72 int offset = paddr & m_data_block_mask;
73 msg.getLen() = (offset + len) <= RubySystem::getBlockSizeBytes() ?
75 len :
74 len :
76 RubySystem::getBlockSizeBytes() - msg.getOffset();
77 if (write) {
78 msg.getType() = DMARequestType_WRITE;
79 msg.getDataBlk().setData(data, msg.getOffset(), msg.getLen());
80 } else {
81 msg.getType() = DMARequestType_READ;
82 }
75 RubySystem::getBlockSizeBytes() - offset;
76 if (write)
77 msg.getDataBlk().setData(data, offset, msg.getLen());
83 m_mandatory_q_ptr->enqueue(msg);
84 active_request.bytes_issued += msg.getLen();
85
86 return active_request.id;
87}
88
89void DMASequencer::issueNext()
90{
91 assert(m_is_busy == true);
92 active_request.bytes_completed = active_request.bytes_issued;
93 if (active_request.len == active_request.bytes_completed) {
94 m_hit_callback(active_request.id);
95 m_is_busy = false;
96 return;
97 }
98
78 m_mandatory_q_ptr->enqueue(msg);
79 active_request.bytes_issued += msg.getLen();
80
81 return active_request.id;
82}
83
84void DMASequencer::issueNext()
85{
86 assert(m_is_busy == true);
87 active_request.bytes_completed = active_request.bytes_issued;
88 if (active_request.len == active_request.bytes_completed) {
89 m_hit_callback(active_request.id);
90 m_is_busy = false;
91 return;
92 }
93
99 DMARequestMsg msg;
94 SequencerMsg msg;
100 msg.getPhysicalAddress() = Address(active_request.start_paddr +
101 active_request.bytes_completed);
102 assert((msg.getPhysicalAddress().getAddress() & m_data_block_mask) == 0);
103 msg.getLineAddress() = line_address(msg.getPhysicalAddress());
95 msg.getPhysicalAddress() = Address(active_request.start_paddr +
96 active_request.bytes_completed);
97 assert((msg.getPhysicalAddress().getAddress() & m_data_block_mask) == 0);
98 msg.getLineAddress() = line_address(msg.getPhysicalAddress());
104 msg.getOffset() = 0;
105 msg.getType() = (active_request.write ? DMARequestType_WRITE :
106 DMARequestType_READ);
99 msg.getType() = (active_request.write ? SequencerRequestType_ST :
100 SequencerRequestType_LD);
107 msg.getLen() = (active_request.len -
108 active_request.bytes_completed < RubySystem::getBlockSizeBytes() ?
109 active_request.len - active_request.bytes_completed :
110 RubySystem::getBlockSizeBytes());
111 if (active_request.write) {
112 msg.getDataBlk().setData(&active_request.data[active_request.bytes_completed],
113 0, msg.getLen());
101 msg.getLen() = (active_request.len -
102 active_request.bytes_completed < RubySystem::getBlockSizeBytes() ?
103 active_request.len - active_request.bytes_completed :
104 RubySystem::getBlockSizeBytes());
105 if (active_request.write) {
106 msg.getDataBlk().setData(&active_request.data[active_request.bytes_completed],
107 0, msg.getLen());
114 msg.getType() = DMARequestType_WRITE;
108 msg.getType() = SequencerRequestType_ST;
115 } else {
109 } else {
116 msg.getType() = DMARequestType_READ;
110 msg.getType() = SequencerRequestType_LD;
117 }
118 m_mandatory_q_ptr->enqueue(msg);
119 active_request.bytes_issued += msg.getLen();
120}
121
122void DMASequencer::dataCallback(const DataBlock & dblk)
123{
124 assert(m_is_busy == true);
125 int len = active_request.bytes_issued - active_request.bytes_completed;
126 int offset = 0;
127 if (active_request.bytes_completed == 0)
128 offset = active_request.start_paddr & m_data_block_mask;
129 assert( active_request.write == false );
130 memcpy(&active_request.data[active_request.bytes_completed],
131 dblk.getData(offset, len), len);
132 issueNext();
133}
134
135void DMASequencer::ackCallback()
136{
137 issueNext();
138}
139
140void DMASequencer::printConfig(ostream & out)
141{
142
143}
111 }
112 m_mandatory_q_ptr->enqueue(msg);
113 active_request.bytes_issued += msg.getLen();
114}
115
116void DMASequencer::dataCallback(const DataBlock & dblk)
117{
118 assert(m_is_busy == true);
119 int len = active_request.bytes_issued - active_request.bytes_completed;
120 int offset = 0;
121 if (active_request.bytes_completed == 0)
122 offset = active_request.start_paddr & m_data_block_mask;
123 assert( active_request.write == false );
124 memcpy(&active_request.data[active_request.bytes_completed],
125 dblk.getData(offset, len), len);
126 issueNext();
127}
128
129void DMASequencer::ackCallback()
130{
131 issueNext();
132}
133
134void DMASequencer::printConfig(ostream & out)
135{
136
137}