Re: [Gems-users] Contiguous Address Translation Issues


Date: Sat, 5 Nov 2011 21:20:18 -0400 (EDT)
From: Hamza Bin Sohail <hsohail@xxxxxxxxxx>
Subject: Re: [Gems-users] Contiguous Address Translation Issues
It can. Look at the CONTIGUOUS_ADDRESSES flag in the ruby Makefile. You have to uncomment it and compile ruby. You'll probably have to add a few lines in one of the C++ files to get it to run.
The patch is on the gems-users list. 

This link should be helpful

https://www-auth.cs.wisc.edu/lists/gems-users/2009-July/msg00002.shtml

----- Original Message -----
From: abhisekpan@xxxxxxxxx
To: "gems-users" <gems-users@xxxxxxxxxxx>
Sent: Saturday, November 5, 2011 9:13:13 PM
Subject: [Gems-users] Contiguous Address Translation Issues


Hi All! 

The simics physical memory configuration I am using has a non-contiguous address space. So my question is what are the specific reasons why ruby can not handle the non-contiguous address space . 

The question arises because I have a specific memory space configuration for which the non-contiguous to contiguous translation mechanism leads to creation of physical addresses greater than the memory size. 
Here is my configuration: 

base object fn offset length 
0x0000000000000000 dram0 0 0x0 0x a0,000 
0x0000000000,100,000 dram0 0 0x100,000 0xf0,000,000 
0x0000000,100,000,000 dram0 0 0xf0,000,000 0x10,000,000 

This creates an interesting problem because if you add up all the lengths, it adds up to more than 2^32(100,000,000 in hex) bytes which is what the dram size is. This happens because there is an overlap of addresses in the dram. The offset field gives the starting address in the dram for each segment. We can see the second chunk starts at 0x100,000 of dram0 and should end at 0xf0,100,000 (start + length). However the start address for the third segment starts at 0xf0,000,000 and ends at 0x100,000,000 (0xf0,000,000 + 0x10,000,000). Hence although the final address is within the limits of the dram size - 0x100,000,000 (4GB) the total size of the 3 segments is actually 0x100,0a0,000. 

The translator in ruby ignores the device offset and considers only the base addresses and size, and compresses the address space into a contiguous space, which in this case means that some of the addresses exceed the dram size. 

Now in SimicsDriver::isUnhandledTransaction(): there is a filter like this: 
if (IS_DEV_MEM_OP(mem_trans->s.ini_type) || 
IS_OTH_MEM_OP(mem_trans->s.ini_type) || 
mem_trans->s.physical_address > uinteger_t(RubyConfig::memorySizeBytes()) 
) { 
return true; 
} 

Hence all the address which are greater than the memory size(4GB here) are ignored silently. I set up a counter inside the 'if' condition and found out that there are a lot of addresses like that. 

So I was thinking a straight-forward way to bring all addresses inside the memory size would be to subtract the difference between the base and dram start offset in the translation for each segment. That creates chunks which are inside the limit, but still not contiguous. 

So my question is is this okay to do, as in are there things in ruby which will break if I use this non-contiguous arrangement? 

-- 
Abhisek 
Live Long and Prosper 

PS. If you look at the translator code (TranslateSimicsToRuby()), you would find that the last segment is not considered, "since it appears to be some kind of seldom-used ROM." That will prevent these out-of-limit translated values. But it does not work in this case because I found out that most of the addresses come from the last segment, and the translator silently translates all these out-of bounds addresses to zero, as you can see below. I mention this is PS because it is kind of a separate issue, but might be important for people to know. I had changed that previously to include all the segments. Normally this would be hard to see because it won't create any error as such, but I was trying to measure the number of distinct memory addresses accessed by the program and in the process saw that most of the translated addresses are zero. 

uint64 translated = 0; 
for(int i=0;i<m_nNumMaps-1;i++) { 
if(m_startAddrs[i+1] > addr) { 
translated = addr - m_translations[i]; 
break; 
} 
} 
/* 
* If the loop falls through, then addr is part of an untranslated region anyway, 
* like that silly little ROM that sits at the end of memory 
*/ 
return translated; 



_______________________________________________
Gems-users mailing list
Gems-users@xxxxxxxxxxx
https://lists.cs.wisc.edu/mailman/listinfo/gems-users
Use Google to search the GEMS Users mailing list by adding "site:https://lists.cs.wisc.edu/archive/gems-users/"; to your search.

[← Prev in Thread] Current Thread [Next in Thread→]