-
Notifications
You must be signed in to change notification settings - Fork 216
Big endianness Support added #751
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this! I left some initial comments below.
One other thing that I don't see here is the necessary modification to the reset function. Reset should set endianness back to little-endian if supported.
model/prelude.sail
Outdated
@@ -236,3 +236,6 @@ type max_mem_access : Int = 4096 | |||
|
|||
// Type used for memory access widths. Zero byte accesses are not allowed. | |||
type mem_access_width = range(1, max_mem_access) | |||
|
|||
// Function to reverse endianness. | |||
val reverse_endianness = pure {c: " reverse_endianness"} : forall 'n . (bits('n * 8)) -> bits('n * 8) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason not to just use the existing sail reverse_endianness
library? https://github.com/rems-project/sail/blob/6a8d444e41a3e04798e874325bf4ec0f813e3a3a/lib/reverse_endianness.sail#L47
Just put a $include <reverse_endianness.sail>
at the top of the prelude.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually tried this but was getting the following error:
This is because of the difference of types being passed by the function (bits(8 * 'n)) and type taken by the function bits('n).
Actually, this solution was suggested by @Timmmm and this method made the function accept values forall 'n instead of using contrained values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Alasdair I know you're planning on a new version of Sail soon. Any chance the reverse_endianness
library could be updated so that it can be used here?
I just noticed that |
The readme can also be updated to mention this support. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking pretty close to me. I think we will need some kind of testing for this... It feels like the sort of thing that is easy to screw up without knowing. How do you compile a big endian ELF though?
Ah never mind, I saw your test. |
@MuhammadHammad001 Seems like this is pretty close. Would be good to get merged before conflicts start to build. Any chance you can finish it off soon? |
I just merged support for first-party tests so we could add this as part of this PR now! |
Hi Jordan and Tim, sorry for the late response. I will commit the requested changes today. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks very close at this point! One more small comment.
Okayy, I will add this in the next commit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM once the test is added. Down the road we should add a configuration option to enable or disable big endianness support. Feel free to add a TODO comment in the code where the value of MBE is set to remind us of this.
model/riscv_mem.sail
Outdated
@@ -63,8 +63,16 @@ function write_kind_of_flags (aq : bool, rl : bool, con : bool) -> write_kind = | |||
(true, false, true) => throw(Error_not_implemented("sc.aq")) | |||
} | |||
|
|||
function is_big_endian(typ : AccessType(ext_access_type)) -> bool = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not have this be something like get_endianness
that returns a type from the Endianness enum and push the check for an Execute
access into it? So it becomes something like:
function get_endianness(typ : AccessType(ext_access_type)) -> Endianness = {
match (typ, effectivePrivilege(typ, mstatus, cur_privilege)) {
(Execute(), _) => LittleEndian
(_, Machine) => if bits_to_bool(mstatus[MBE]) then BigEndian else LittleEndian,
(_, Supervisor) => if bits_to_bool(mstatus[SBE]) then BigEndian else LittleEndian,
(_, User) => if bits_to_bool(mstatus[UBE]) then BigEndian else LittleEndian,
}
}
Then you can replace all of the uses of let current_endianness: Endianness = if is_big_endian(typ) & typ != Execute() then BigEndian else LittleEndian
with just get_endianness(typ)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea! I will implement this
Signed-off-by: Muhammad Hammad Bashir <[email protected]>
I wonder if we should try to get #467 merged before this, since I don't think they will work together currently, and I think the endianness conversion should actually go in |
Signed-off-by: Muhammad Hammad Bashir <[email protected]>
@MuhammadHammad001 Thanks for your patience with this one. #861 (which replaced #467) is merged, so it should be possible to update this PR now to move the endianness conversion into the new functions that it introduced. |
Sure, I will update this accordingly. |
Hi, @jordancarlin @pmundkur @Timmmm , can you please review this and let me know if I need to change anything? Also, I have removed the testcase for the |
Signed-off-by: Muhammad Hammad Bashir <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I'm missing something, but I though the whole point of waiting for #861 was to move the endianness handling into vmem_read
/vmem_write
so that it didn't need to be duplicated everywhere. Right now it looks like it's still being handled in mem_write_value_priv_meta
and the individual mmio functions.
I may be mis-understanding but as I mentioned earlier, I can surely do this for
As you can see, the
is printing the data here instead in the Note: I am referring reversed == Big endian Can you please help me in clearing the doubt? |
I'm not sure what to do about printing: it would be confusing to see endianness-adjusted writes but unadjusted reads in the logs. Also, |
But, I am converting the data to be written inside the |
AMO instructions are not using |
Sorry @pmundkur, I may be mis-understanding, I am currently looking at the file Can you please give a pointer to exact function you want me to change? |
There is a |
Hi @jordancarlin and @Timmmm
This PR adds the support for the big endianness in Sail RISC-V.
The test for the verification of this support is also added in this PR.