Skip to content

Instantly share code, notes, and snippets.

@shlomopongratz
Last active January 18, 2024 18:33
Show Gist options
  • Save shlomopongratz/f82466b6044f3a1653890b43b046c443 to your computer and use it in GitHub Desktop.
Save shlomopongratz/f82466b6044f3a1653890b43b046c443 to your computer and use it in GitHub Desktop.
Viewport calculation.
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
typedef union {
uint64_t ll;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
struct {
uint32_t lo;
uint32_t hi;
};
#else
struct {
uint32_t hi;
uint32_t lo;
};
#endif
} u_t;
// From include/qemu/bitops.h
static inline uint64_t deposit64(uint64_t value, int start, int length,
uint64_t fieldval)
{
uint64_t mask;
assert(start >= 0 && length > 0 && length <= 64 - start);
mask = (~0ULL >> (64 - length)) << start;
return (value & ~mask) | ((fieldval << start) & mask);
}
static inline uint64_t extract64(uint64_t value, int start, int length)
{
assert(start >= 0 && length > 0 && length <= 64 - start);
return (value >> start) & (~0ULL >> (64 - length));
}
void original(uint64_t base, uint32_t limit, uint64_t truelimit)
{
uint64_t tlimit;
uint64_t size;
printf("Original\n");
size = (uint64_t)limit - base + 1;
tlimit = base + size - 1;
printf("Base 0x%lx inferd limit 0x%lx size 0x%lx %s\n",
base, tlimit, size,
tlimit == truelimit ? "Good" : "Bad");
}
void truncated(uint64_t base, uint32_t limit, uint64_t truelimit)
{
uint32_t tbase;
uint32_t tsize;
uint64_t size;
uint64_t tlimit;
printf("Trucated\n");
// Use 32 bit calculation
tbase = base; // Truncate
tsize = limit - tbase;
// Return to 64 bit
size = tsize;
size++;
tlimit = base + size - 1;
printf("Base 0x%lx inferd limit 0x%lx size 0x%lx %s\n",
base, tlimit, size,
tlimit == truelimit ? "Good" : "Bad");
}
void peters(uint64_t base, uint32_t limit, uint64_t truelimit)
{
uint64_t size;
uint64_t tlimit;
printf("Peter's\n");
tlimit = deposit64(limit, 32, 32, extract64(base, 32, 32));
size = tlimit - base + 1;
tlimit = base + size - 1;
printf("Base 0x%lx inferd limit 0x%lx size 0x%lx %s\n",
base, tlimit, size,
tlimit == truelimit ? "Good" : "Bad");
}
void my_patch(uint64_t base, uint32_t limit, uint64_t truelimit)
{
uint64_t tbase;
uint64_t tlimit;
uint64_t size;
printf("My patch\n");
tbase = base & 0xffffffff;
tlimit = 0x100000000 + (uint64_t)limit;
size = ((tlimit - tbase) & 0xffffffff) + 1;
tlimit = base + size - 1;
printf("Base 0x%lx inferd limit 0x%lx size 0x%lx %s\n",
base, tlimit, size,
tlimit == truelimit ? "Good" : "Bad");
}
void do_math(uint64_t base, uint32_t limit, uint64_t truelimit)
{
uint64_t tlimit;
uint64_t size;
uint32_t tsize;
uint32_t tbase;
original(base, limit, truelimit);
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
truncated(base, limit, truelimit);
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
peters(base, limit, truelimit);
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
my_patch(base, limit, truelimit);
}
void nxp_example_init(u_t *base, u_t *limit)
{
base->lo = 0xd0000000;
base->hi = 0x80000000;
limit->lo = 0xd000ffff;
limit->hi = 0x80000000;
}
void peter_example_init(u_t *base, u_t *limit)
{
base->lo = 0xd0000000;
base->hi = 0x80000000;
limit->lo = 0xffffffff;
limit->hi = 0x80000000;
}
int main(int arc, char *argv[])
{
u_t base;
u_t limit;
printf("=======================================================\n");
nxp_example_init(&base, &limit);
printf("-> NXP example: Base 0x%lx Limit 0x%lx\n", base.ll, limit.ll);
do_math(base.ll, limit.lo, limit.ll);
printf("-------------------------------------------------------\n");
nxp_example_init(&base, &limit);
base.ll += 0x200000000;
limit.ll += 0x200000000;
printf("-> NXP example shifted by 0x200000000 Base 0x%lx Limit 0x%lx\n", base.ll, limit.ll);
do_math(base.ll, limit.lo, limit.ll);
printf("-------------------------------------------------------\n");
nxp_example_init(&base, &limit);
base.ll += 0x2ffff000;
limit.ll += 0x2ffff000;
printf("-> NXP example shifted by 0x2ffff000 Base 0x%lx Limit 0x%lx\n", base.ll, limit.ll);
do_math(base.ll, limit.lo, limit.ll);
printf("=======================================================\n");
peter_example_init(&base, &limit);
printf("Peter's: Base 0x%lx Limit 0x%lx\n", base.ll, limit.ll);
do_math(base.ll, limit.lo, limit.ll);
printf("-------------------------------------------------------\n");
peter_example_init(&base, &limit);
base.ll += 0x200000000;
limit.ll += 0x200000000;
printf("-> Peter's shifted by 0x200000000 Base 0x%lx Limit 0x%lx\n", base.ll, limit.ll);
do_math(base.ll, limit.lo, limit.ll);
printf("-------------------------------------------------------\n");
peter_example_init(&base, &limit);
base.ll += 0x2ffff000;
limit.ll += 0x2ffff000;
printf("-> Peter's shifted by 0x2ffff000 Base 0x%lx Limit 0x%lx\n", base.ll, limit.ll);
do_math(base.ll, limit.lo, limit.ll);
printf("=======================================================\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment