1 2/* 3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright --- 599 unchanged lines hidden (view full) --- 608 g_system_ptr->getProfiler()->swPrefetchLatency(miss_latency, type, respondingMach); 609 return; // Ignore the software prefetch, don't callback the driver 610 } 611 612 // Profile the miss latency for all non-zero demand misses 613 if (miss_latency != 0) { 614 g_system_ptr->getProfiler()->missLatency(miss_latency, type, respondingMach); 615 |
616#if 0 617 uinteger_t tick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick")); 618 uinteger_t tick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick_cmpr")); 619 uinteger_t stick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick")); 620 uinteger_t stick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick_cmpr")); 621 cout << "END PROC " << m_version << hex << " tick = " << tick << " tick_cmpr = " << tick_cmpr << " stick = " << stick << " stick_cmpr = " << stick_cmpr << " cycle = "<< g_eventQueue_ptr->getTime() << dec << endl; 622#endif |
623 624 } 625 626 bool write = 627 (type == CacheRequestType_ST) || 628 (type == CacheRequestType_ST_XACT) || 629 (type == CacheRequestType_LDX_XACT) || 630 (type == CacheRequestType_ATOMIC); --- 148 unchanged lines hidden (view full) --- 779} 780 781void Sequencer::printDebug(){ 782 //notify driver of debug 783 g_system_ptr->getDriver()->printDebug(); 784} 785 786// Returns true if the sequencer already has a load or store outstanding |
787bool 788Sequencer::isReady(const Packet* pkt) const 789{ |
790 |
791 int cpu_number = pkt->req->contextId(); 792 la_t logical_addr = pkt->req->getVaddr(); 793 pa_t physical_addr = pkt->req->getPaddr(); 794 CacheRequestType type_of_request; 795 if ( pkt->req->isInstFetch() ) { 796 type_of_request = CacheRequestType_IFETCH; 797 } else if ( pkt->req->isLocked() || pkt->req->isSwap() ) { 798 type_of_request = CacheRequestType_ATOMIC; 799 } else if ( pkt->isRead() ) { 800 type_of_request = CacheRequestType_LD; 801 } else if ( pkt->isWrite() ) { 802 type_of_request = CacheRequestType_ST; 803 } else { 804 assert(false); 805 } 806 int thread = pkt->req->threadId(); 807 808 CacheMsg request(Address( physical_addr ), 809 Address( physical_addr ), 810 type_of_request, 811 Address(0), 812 AccessModeType_UserMode, // User/supervisor mode 813 0, // Size in bytes of request 814 PrefetchBit_No, // Not a prefetch 815 0, // Version number 816 Address(logical_addr), // Virtual Address 817 thread, // SMT thread 818 0, // TM specific - timestamp of memory request 819 false // TM specific - whether request is part of escape action 820 ); 821 isReady(request); 822} 823 824bool 825Sequencer::isReady(const CacheMsg& request) const 826{ |
827 if (m_outstanding_count >= g_SEQUENCER_OUTSTANDING_REQUESTS) { 828 //cout << "TOO MANY OUTSTANDING: " << m_outstanding_count << " " << g_SEQUENCER_OUTSTANDING_REQUESTS << " VER " << m_version << endl; 829 //printProgress(cout); 830 return false; 831 } |
832 833 // This code allows reads to be performed even when we have a write 834 // request outstanding for the line 835 bool write = 836 (request.getType() == CacheRequestType_ST) || 837 (request.getType() == CacheRequestType_ST_XACT) || 838 (request.getType() == CacheRequestType_LDX_XACT) || 839 (request.getType() == CacheRequestType_ATOMIC); --- 12 unchanged lines hidden (view full) --- 852 853 if (TSO) { 854 return m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->isReady(); 855 } 856 return true; 857} 858 859// Called by Driver (Simics or Tester). |
860void 861Sequencer::makeRequest(const Packet* pkt, void* data) 862{ 863 int cpu_number = pkt->req->contextId(); 864 la_t logical_addr = pkt->req->getVaddr(); 865 pa_t physical_addr = pkt->req->getPaddr(); 866 int request_size = pkt->getSize(); 867 CacheRequestType type_of_request; 868 if ( pkt->req->isInstFetch() ) { 869 type_of_request = CacheRequestType_IFETCH; 870 } else if ( pkt->req->isLocked() || pkt->req->isSwap() ) { 871 type_of_request = CacheRequestType_ATOMIC; 872 } else if ( pkt->isRead() ) { 873 type_of_request = CacheRequestType_LD; 874 } else if ( pkt->isWrite() ) { 875 type_of_request = CacheRequestType_ST; 876 } else { 877 assert(false); 878 } 879 la_t virtual_pc = pkt->req->getPC(); 880 int isPriv = false; // TODO: get permission data 881 int thread = pkt->req->threadId(); 882 883 AccessModeType access_mode = AccessModeType_UserMode; // TODO: get actual permission 884 885 CacheMsg request(Address( physical_addr ), 886 Address( physical_addr ), 887 type_of_request, 888 Address(virtual_pc), 889 access_mode, // User/supervisor mode 890 request_size, // Size in bytes of request 891 PrefetchBit_No, // Not a prefetch 892 0, // Version number 893 Address(logical_addr), // Virtual Address 894 thread, // SMT thread 895 0, // TM specific - timestamp of memory request 896 false // TM specific - whether request is part of escape action 897 ); 898 makeRequest(request); 899} 900 901void 902Sequencer::makeRequest(const CacheMsg& request) 903{ |
904 bool write = (request.getType() == CacheRequestType_ST) || 905 (request.getType() == CacheRequestType_ST_XACT) || 906 (request.getType() == CacheRequestType_LDX_XACT) || 907 (request.getType() == CacheRequestType_ATOMIC); 908 909 if (TSO && (request.getPrefetch() == PrefetchBit_No) && write) { 910 assert(m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->isReady()); 911 m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->insertStore(request); --- 19 unchanged lines hidden (view full) --- 931 data_ptr); 932 933 if (hit && (request.getType() == CacheRequestType_IFETCH || !REMOVE_SINGLE_CYCLE_DCACHE_FAST_PATH) ) { 934 DEBUG_MSG(SEQUENCER_COMP, MedPrio, "Fast path hit"); 935 hitCallback(request, *data_ptr, GenericMachineType_L1Cache, thread); 936 return true; 937 } 938 |
939#if 0 |
940 uinteger_t tick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick")); 941 uinteger_t tick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick_cmpr")); 942 uinteger_t stick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick")); 943 uinteger_t stick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick_cmpr")); 944 cout << "START PROC " << m_version << hex << " tick = " << tick << " tick_cmpr = " << tick_cmpr << " stick = " << stick << " stick_cmpr = " << stick_cmpr << " cycle = "<< g_eventQueue_ptr->getTime() << dec << endl;; |
945#endif |
946 947 if (TSO && (request.getType() == CacheRequestType_LD || request.getType() == CacheRequestType_IFETCH)) { 948 949 // See if we can satisfy the load entirely from the store buffer 950 SubBlock subblock(line_address(request.getAddress()), request.getSize()); 951 if (m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->trySubBlock(subblock)) { 952 DataBlock dummy; 953 hitCallback(request, dummy, GenericMachineType_NULL, thread); // Call with an 'empty' datablock, since the data is in the store buffer --- 165 unchanged lines hidden (view full) --- 1119 n->m_L1Cache_L1IcacheMemory_vec[m_version]->getMemoryValue(addr, value, size_in_bytes); 1120 found = true; 1121 } else if (n->m_L1Cache_L1DcacheMemory_vec[m_version]->tryCacheAccess(lineAddr, CacheRequestType_LD, dataPtr)){ 1122 n->m_L1Cache_L1DcacheMemory_vec[m_version]->getMemoryValue(addr, value, size_in_bytes); 1123 found = true; 1124 } else if (Protocol::m_CMP && n->m_L2Cache_L2cacheMemory_vec[l2_ver]->tryCacheAccess(lineAddr, CacheRequestType_LD, dataPtr)){ 1125 n->m_L2Cache_L2cacheMemory_vec[l2_ver]->getMemoryValue(addr, value, size_in_bytes); 1126 found = true; |
1127 // } else if (n->TBE_TABLE_MEMBER_VARIABLE->isPresent(lineAddr)){ 1128 // ASSERT(n->TBE_TABLE_MEMBER_VARIABLE->isPresent(lineAddr)); 1129 // L1Cache_TBE tbeEntry = n->TBE_TABLE_MEMBER_VARIABLE->lookup(lineAddr); |
1130 |
1131 // int offset = addr.getOffset(); 1132 // for(int i=0; i<size_in_bytes; ++i){ 1133 // value[i] = tbeEntry.getDataBlk().getByte(offset + i); 1134 // } |
1135 |
1136 // found = true; |
1137 } else { 1138 // Address not found 1139 //cout << " " << m_chip_ptr->getID() << " NOT IN CACHE, Value at Directory is: " << (int) value[0] << endl; 1140 n = dynamic_cast<Chip*>(g_system_ptr->getChip(map_Address_to_DirectoryNode(addr)/RubyConfig::numberOfDirectoryPerChip())); 1141 int dir_version = map_Address_to_DirectoryNode(addr)%RubyConfig::numberOfDirectoryPerChip(); 1142 for(unsigned int i=0; i<size_in_bytes; ++i){ 1143 int offset = addr.getOffset(); 1144 value[i] = n->m_Directory_directory_vec[dir_version]->lookup(lineAddr).m_DataBlk.getByte(offset + i); --- 27 unchanged lines hidden (view full) --- 1172 int l2_ver = l2_mach.num%RubyConfig::numberOfL2CachePerChip(); 1173 // LUKE - use variable names instead of macros 1174 //cout << "number of L2caches per chip = " << RubyConfig::numberOfL2CachePerChip(m_version) << endl; 1175 //cout << "L1I cache vec size = " << n->m_L1Cache_L1IcacheMemory_vec.size() << endl; 1176 //cout << "L1D cache vec size = " << n->m_L1Cache_L1DcacheMemory_vec.size() << endl; 1177 //cout << "L1cache_cachememory size = " << n->m_L1Cache_cacheMemory_vec.size() << endl; 1178 //cout << "L1cache_l2cachememory size = " << n->m_L1Cache_L2cacheMemory_vec.size() << endl; 1179 // if (Protocol::m_TwoLevelCache) { |
1180 // if(Protocol::m_CMP){ 1181 // cout << "CMP L2 cache vec size = " << n->m_L2Cache_L2cacheMemory_vec.size() << endl; 1182 // } 1183 // else{ 1184 // cout << "L2 cache vec size = " << n->m_L1Cache_cacheMemory_vec.size() << endl; 1185 // } 1186 // } |
1187 1188 assert(n->m_L1Cache_L1IcacheMemory_vec[m_version] != NULL); 1189 assert(n->m_L1Cache_L1DcacheMemory_vec[m_version] != NULL); 1190 if (Protocol::m_TwoLevelCache) { 1191 if(Protocol::m_CMP){ 1192 assert(n->m_L2Cache_L2cacheMemory_vec[l2_ver] != NULL); 1193 } 1194 else{ --- 5 unchanged lines hidden (view full) --- 1200 n->m_L1Cache_L1IcacheMemory_vec[m_version]->setMemoryValue(addr, value, size_in_bytes); 1201 found = true; 1202 } else if (n->m_L1Cache_L1DcacheMemory_vec[m_version]->tryCacheAccess(lineAddr, CacheRequestType_LD, dataPtr)){ 1203 n->m_L1Cache_L1DcacheMemory_vec[m_version]->setMemoryValue(addr, value, size_in_bytes); 1204 found = true; 1205 } else if (Protocol::m_CMP && n->m_L2Cache_L2cacheMemory_vec[l2_ver]->tryCacheAccess(lineAddr, CacheRequestType_LD, dataPtr)){ 1206 n->m_L2Cache_L2cacheMemory_vec[l2_ver]->setMemoryValue(addr, value, size_in_bytes); 1207 found = true; |
1208 // } else if (n->TBE_TABLE_MEMBER_VARIABLE->isTagPresent(lineAddr)){ 1209 // L1Cache_TBE& tbeEntry = n->TBE_TABLE_MEMBER_VARIABLE->lookup(lineAddr); 1210 // DataBlock tmpData; 1211 // int offset = addr.getOffset(); 1212 // for(int i=0; i<size_in_bytes; ++i){ 1213 // tmpData.setByte(offset + i, value[i]); 1214 // } 1215 // tbeEntry.setDataBlk(tmpData); 1216 // tbeEntry.setDirty(true); |
1217 } else { 1218 // Address not found 1219 n = dynamic_cast<Chip*>(g_system_ptr->getChip(map_Address_to_DirectoryNode(addr)/RubyConfig::numberOfDirectoryPerChip())); 1220 int dir_version = map_Address_to_DirectoryNode(addr)%RubyConfig::numberOfDirectoryPerChip(); 1221 for(unsigned int i=0; i<size_in_bytes; ++i){ 1222 int offset = addr.getOffset(); 1223 n->m_Directory_directory_vec[dir_version]->lookup(lineAddr).m_DataBlk.setByte(offset + i, value[i]); 1224 } --- 16 unchanged lines hidden --- |