1/* 2 * Copyright (c) 2009 Advanced Micro Devices, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 37 unchanged lines hidden (view full) --- 46 m_controller = NULL; 47 m_mandatory_q_ptr = NULL; 48 49 m_request_cnt = 0; 50 pio_port = NULL; 51 physMemPort = NULL; 52 53 m_usingRubyTester = p->using_ruby_tester; |
54 access_phys_mem = p->access_phys_mem; |
55} 56 57void 58RubyPort::init() 59{ 60 assert(m_controller != NULL); 61 m_mandatory_q_ptr = m_controller->getMandatoryQueue(); 62} 63 64Port * 65RubyPort::getPort(const std::string &if_name, int idx) 66{ 67 if (if_name == "port") { |
68 return new M5Port(csprintf("%s-port%d", name(), idx), this, 69 access_phys_mem); |
70 } 71 72 if (if_name == "pio_port") { 73 // ensure there is only one pio port 74 assert(pio_port == NULL); 75 76 pio_port = new PioPort(csprintf("%s-pio-port%d", name(), idx), this); 77 78 return pio_port; 79 } 80 81 if (if_name == "physMemPort") { 82 // RubyPort should only have one port to physical memory 83 assert (physMemPort == NULL); 84 |
85 physMemPort = new M5Port(csprintf("%s-physMemPort", name()), this, 86 access_phys_mem); |
87 88 return physMemPort; 89 } 90 91 if (if_name == "functional") { 92 // Calls for the functional port only want to access 93 // functional memory. Therefore, directly pass these calls 94 // ports to physmem. --- 8 unchanged lines hidden (view full) --- 103 RubyPort *_port) 104 : SimpleTimingPort(_name, _port) 105{ 106 DPRINTF(Ruby, "creating port to ruby sequencer to cpu %s\n", _name); 107 ruby_port = _port; 108} 109 110RubyPort::M5Port::M5Port(const std::string &_name, |
111 RubyPort *_port, bool _access_phys_mem) |
112 : SimpleTimingPort(_name, _port) 113{ 114 DPRINTF(Ruby, "creating port from ruby sequcner to cpu %s\n", _name); 115 ruby_port = _port; 116 _onRetryList = false; |
117 access_phys_mem = _access_phys_mem; |
118} 119 120Tick 121RubyPort::PioPort::recvAtomic(PacketPtr pkt) 122{ 123 panic("RubyPort::PioPort::recvAtomic() not implemented!\n"); 124 return 0; 125} --- 118 unchanged lines hidden (view full) --- 244 // Note: M5 packets do not differentiate ST from RMW_Write 245 // 246 type = RubyRequestType_ST; 247 } else { 248 panic("Unsupported ruby packet type\n"); 249 } 250 } 251 |
252 RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(true), |
253 pkt->getSize(), pc, type, 254 RubyAccessMode_Supervisor, pkt); 255 256 assert(Address(ruby_request.paddr).getOffset() + ruby_request.len <= 257 RubySystem::getBlockSizeBytes()); 258 259 // Submit the ruby request 260 RequestStatus requestStatus = ruby_port->makeRequest(ruby_request); --- 58 unchanged lines hidden (view full) --- 319} 320 321void 322RubyPort::M5Port::hitCallback(PacketPtr pkt) 323{ 324 bool needsResponse = pkt->needsResponse(); 325 326 // |
327 // Unless specified at configuraiton, all responses except failed SC 328 // operations access M5 physical memory. |
329 // |
330 bool accessPhysMem = access_phys_mem; |
331 332 if (pkt->isLLSC()) { 333 if (pkt->isWrite()) { 334 if (pkt->req->getExtraData() != 0) { 335 // 336 // Successful SC packets convert to normal writes 337 // 338 pkt->convertScToWrite(); --- 12 unchanged lines hidden (view full) --- 351 // 352 pkt->convertLlToRead(); 353 } 354 } 355 DPRINTF(MemoryAccess, "Hit callback needs response %d\n", needsResponse); 356 357 if (accessPhysMem) { 358 ruby_port->physMemPort->sendAtomic(pkt); |
359 } else { 360 pkt->makeResponse(); |
361 } 362 363 // turn packet around to go back to requester if response expected 364 if (needsResponse) { |
365 DPRINTF(MemoryAccess, "Sending packet back over port\n"); 366 sendTiming(pkt); 367 } else { 368 delete pkt; 369 } 370 DPRINTF(MemoryAccess, "Hit callback done!\n"); 371} 372 --- 39 unchanged lines hidden --- |