Skip to content
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

Support for new CHERI128 trace format from hardware. #3

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Tests/cheri128.trace
Binary file not shown.
10 changes: 10 additions & 0 deletions Tests/cheri128.trace.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Time= 19985 : 9800000040000c9c: 48041800 DestReg <- 0x000000000007ffff {0}
Time= 19986 : 9800000040000ca0: 49a51802 DestReg <- 0x0000000000001234 {0}
Time= 19987 : 9800000040000ca4: 48061802 DestReg <- 0x9800000040000000 {0}
Time= 19988 : 9800000040000ca8: 48071803 DestReg <- 0x0000000012347000 {0}
Time= 19989 : 9800000040000cac: 48081805 DestReg <- 0x0000000000000001 {0}
Time= 19990 : 9800000040000cb0: 08000324 j 0x9800000040000c90 branch to 0x9800000040000c90 {0}
Time= 19991 : 9800000040000cb4: 00000000 nop {0}
Time= 19992 : 9800000040001234: f8406000 sdc2 r0,24576(v0) [] Address 0x9800000040000d60 <- tag: 1 u:0 perms:0x3fff type:0x0000000000000000 offset:0x0000000000001234 base:0x9800000040000000 length:0x0000000012347000 {0}
Time= 19993 : 9800000040001234: d8606000 ldc2 r0,24576(v1) [] CapReg <- tag: 1 u:0 perms:0x3fff type:0x0000000000000000 offset:0x0000000000001234 base:0x9800000040000000 length:0x0000000012347000 from Address 0x9800000040000d60 {0}
Time= 19996 : 9800000040000c98: 49a31800 CapReg <- tag: 1 u:0 perms:0x3fff type:0x0000000000000000 offset:0x0000000000001234 base:0x9800000040000000 length:0x0000000012347000 {0}
83 changes: 83 additions & 0 deletions streamtrace.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1695,6 +1695,68 @@ void decode_cap(capability_register &cap, uint64_t val2, uint64_t val3,
cap.length = val5;
cap.offset = val3 - cap.base;
}
/**
* Decode a 128-bit capability register from streamtrace values. `val2` is always
* `val2` from the streamtrace, but `val1` is either `val1` or `pc` depending
* on the trace format. val1/pc is the 1st half of the capability containing the
* pointer and val2 is the 2nd half of the compressed capability containing the
* bounds and permissions.
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first half of this comment is confusing, as it's talking about where these values come from long before they get to this function.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. This is brought forward from the older variations of this function. If we want to change the comment, we should change it everywhere.

void decode_cap128(capability_register &cap, uint64_t val2, uint64_t val1)
{
// extract the tag from the reserved bits where it has been stashed for tracing.
cap.valid = extract_bits<47>(val2);
// unsealed flag is at the top of the pair of 20-bit top and bottom fields.
cap.unsealed = extract_bits<40>(val2);
// The type, if there was one, would be the bottom 10 bits of the top
// and bottom fields appended together.
cap.type = 0; // TODO extract type from typed capabilities
// The permissions are in the top of the 2nd word.
cap.permissions = extract_bits<63,49>(val2);
// The exponent for the top and bottom values.
uint64_t exp = extract_bits<46,41>(val2);
// Generate a mask for grabbing the bits of the pointer
// that we will reuse for the bounds.
uint64_t mask = ((uint64_t) ~0)<<20ULL;
mask <<= exp;
// The pointer is simply the 1st 64-bit value.
uint64_t ptr = val1;
// The 20-bit field holding 20-bits of the bottom bound.
uint64_t botbits = extract_bits<39,20>(val2);//(half2>>20) & 0xFFFFFULL;
// Shift if up, zeros at the bottom, and bits borrowed from the
// pointer at the top.
uint64_t bot = (ptr&mask)|(botbits<<exp);
// The 20-bit field holding 20-bits of the top bound.
uint64_t topbits = (half2) & 0xFFFFFULL;
// Shift them up, zeros at the bottom, bits borrowed from the
// pointer at the top.
uint64_t top = (ptr&mask)|(topbits<<exp);

// Procedure described in the cheri architecture document for determining
// if the upper bits of the pointer should be adjusted by one for
// either of the bounds.
uint64_t edgbits = (botbits-0x100ULL)&0xFFFFFULL;
uint64_t ptrbits = (ptr>>exp)&0xFFFFFULL;
uint8_t ptrHi = (ptrbits < edgbits);
uint8_t botHi = (botbits < edgbits);
uint8_t topHi = (topbits < edgbits);

uint64_t bigOne = 1ULL<<(exp+20ULL);
// Calculate potential upper-bits fixup for the top.
uint64_t topfix = 0;
if (topHi && !ptrHi) topfix = bigOne;
if (!topHi && ptrHi) topfix = -bigOne;
top = top + topfix;
// Calculate potential upper-bits fixup for the bottom.
uint64_t botfix = 0;
if (botHi && !ptrHi) botfix = bigOne;
if (!botHi && ptrHi) botfix = -bigOne;
bot = bot + botfix;
// Fill the full address fields.
cap.offset = ptr - bot;
cap.base = bot;
cap.length = top - bot;
}


/**
Expand Down Expand Up @@ -1728,6 +1790,27 @@ void decode_entry(debug_trace_entry &e, uint8_t version, uint64_t val1, uint64_t
e.memory_address = val1;
break;
}
case 8:
{
decode_cap128(e.reg_value.cap, val2, val1);
break;
}
case 9:
{
e.is_load = true;
e.memory_address = val1;
decode_cap128(e.reg_value.cap, val2, e.pc);
e.pc = 0;
break;
}
case 10:
{
e.is_store = true;
decode_cap128(e.reg_value.cap, val2, e.pc);
e.memory_address = val1;
e.pc = 0;
break;
}
case 11:
{
decode_cap(e.reg_value.cap, val2, val1);
Expand Down