Skip to content

Commit

Permalink
Change loadWord(), storeWord() etc. to take untranslated addresses.
Browse files Browse the repository at this point in the history
  • Loading branch information
Richard Osborne committed Apr 5, 2012
1 parent fc3156e commit 0680598
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 53 deletions.
20 changes: 12 additions & 8 deletions Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ Core::Core(uint32_t RamSize, uint32_t RamBase) :
syscallAddress(~0),
exceptionAddress(~0)
{
memoryOffset = memory - (RamBase / 4);
invalidationInfoOffset = invalidationInfo - (RamBase / 2);

resource[RES_TYPE_PORT] = 0;
resourceNum[RES_TYPE_PORT] = 0;

Expand Down Expand Up @@ -182,7 +185,7 @@ Resource *Core::allocResource(Thread &current, ResourceType type)

void Core::writeMemory(uint32_t address, void *src, size_t size)
{
std::memcpy(&mem()[address], src, size);
std::memcpy(&memOffset()[address], src, size);
}

const Port *Core::getPortByID(ResourceID ID) const
Expand Down Expand Up @@ -327,23 +330,24 @@ std::string Core::getCoreName() const

void Core::invalidateWordSlowPath(uint32_t shiftedAddress)
{
if (invalidationInfo[shiftedAddress + 1] == INVALIDATE_NONE) {
if (invalidationInfoOffset[shiftedAddress + 1] == INVALIDATE_NONE) {
invalidateSlowPath(shiftedAddress);
return;
}
invalidationInfo[shiftedAddress + 1] = INVALIDATE_CURRENT_AND_PREVIOUS;
invalidationInfoOffset[shiftedAddress + 1] = INVALIDATE_CURRENT_AND_PREVIOUS;
invalidateSlowPath(shiftedAddress + 1);
}

void Core::invalidateSlowPath(uint32_t shiftedAddress)
{
unsigned char info;
do {
info = invalidationInfo[shiftedAddress];
if (!JIT::invalidate(*this, shiftedAddress))
opcode[shiftedAddress] = decodeOpcode;
executionFrequency[shiftedAddress] = 0;
invalidationInfo[shiftedAddress--] = INVALIDATE_NONE;
info = invalidationInfoOffset[shiftedAddress];
uint32_t pc = shiftedAddress - (ram_base/2);
if (!JIT::invalidate(*this, pc))
opcode[pc] = decodeOpcode;
executionFrequency[pc] = 0;
invalidationInfoOffset[shiftedAddress--] = INVALIDATE_NONE;
} while (info == INVALIDATE_CURRENT_AND_PREVIOUS);
}

Expand Down
35 changes: 23 additions & 12 deletions Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class Core {
unsigned *resourceNum;
static bool allocatable[LAST_STD_RES_TYPE + 1];
uint32_t * const memory;
uint32_t * memoryOffset;
unsigned coreNumber;
Node *parent;
std::string codeReference;
Expand All @@ -72,22 +73,22 @@ class Core {

bool invalidateWord(uint32_t address) {
uint16_t info;
std::memcpy(&info, &invalidationInfo[address >> 1], sizeof(info));
std::memcpy(&info, &invalidationInfoOffset[address >> 1], sizeof(info));
if (info == (INVALIDATE_NONE | (INVALIDATE_NONE << 8)))
return false;
invalidateWordSlowPath(address);
return true;
}

bool invalidateShort(uint32_t address) {
if (invalidationInfo[address >> 1] == INVALIDATE_NONE)
if (invalidationInfoOffset[address >> 1] == INVALIDATE_NONE)
return false;
invalidateSlowPath(address >> 1);
return true;
}

bool invalidateByte(uint32_t address) {
if (invalidationInfo[address >> 1] == INVALIDATE_NONE)
if (invalidationInfoOffset[address >> 1] == INVALIDATE_NONE)
return false;
invalidateSlowPath(address >> 1);
return true;
Expand All @@ -101,6 +102,7 @@ class Core {
OPCODE_TYPE *opcode;
Operands *operands;
unsigned char *invalidationInfo;
unsigned char *invalidationInfoOffset;
executionFrequency_t *executionFrequency;
uint32_t getRamSizeShorts() const { return 1 << (ramSizeLog2 - 1); }

Expand Down Expand Up @@ -187,13 +189,22 @@ class Core {
return reinterpret_cast<uint8_t*>(memory);
}

uint8_t *memOffset() {
return reinterpret_cast<uint8_t*>(memoryOffset);
}

const uint8_t *memOffset() const {
return reinterpret_cast<uint8_t*>(memoryOffset);
}

public:
uint32_t loadWord(uint32_t address) const
{
if (HOST_LITTLE_ENDIAN) {
return *reinterpret_cast<const uint32_t*>((mem() + address));
return *reinterpret_cast<const uint32_t*>((memOffset() + address));
} else {
return bswap32(*reinterpret_cast<const uint32_t*>((mem() + address)));
return
bswap32(*reinterpret_cast<const uint32_t*>((memOffset() + address)));
}
}

Expand All @@ -204,34 +215,34 @@ class Core {

uint8_t loadByte(uint32_t address) const
{
return mem()[address];
return memOffset()[address];
}

uint8_t &byte(uint32_t address)
{
return mem()[address];
return memOffset()[address];
}

bool storeWord(uint32_t value, uint32_t address)
{
if (HOST_LITTLE_ENDIAN) {
*reinterpret_cast<uint32_t*>((mem() + address)) = value;
*reinterpret_cast<uint32_t*>((memOffset() + address)) = value;
} else {
*reinterpret_cast<uint32_t*>((mem() + address)) = bswap32(value);
*reinterpret_cast<uint32_t*>((memOffset() + address)) = bswap32(value);
}
return invalidateWord(address);
}

bool storeShort(int16_t value, uint32_t address)
{
mem()[address] = static_cast<uint8_t>(value);
mem()[address + 1] = static_cast<uint8_t>(value >> 8);
memOffset()[address] = static_cast<uint8_t>(value);
memOffset()[address + 1] = static_cast<uint8_t>(value >> 8);
return invalidateShort(address);
}

bool storeByte(uint8_t value, uint32_t address)
{
mem()[address] = value;
memOffset()[address] = value;
return invalidateByte(address);
}

Expand Down
7 changes: 4 additions & 3 deletions Instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,11 +356,12 @@ void instructionDecode(Core &core, uint32_t pc, InstructionOpcode &opcode,
opcode = EXCEPTION;
return;
}
uint16_t low = core.loadShort(pc << 1);
uint32_t address = core.fromPc(pc);
uint16_t low = core.loadShort(address);
uint16_t high = 0;
bool highValid;
if (core.isValidAddress(core.fromPc(pc + 1))) {
high = core.loadShort((pc + 1) << 1);
if (core.isValidAddress(address + 2)) {
high = core.loadShort(address + 2);
highValid = true;
} else {
highValid = false;
Expand Down
7 changes: 2 additions & 5 deletions InstructionGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -860,11 +860,10 @@ emitStore(const std::string &argString, LoadStoreType type)
emitException("ET_LOAD_STORE, StoreAddr");
std::cout << " }\n";

std::cout << " uint32_t StorePhyAddr = PHYSICAL_ADDR(StoreAddr);\n";
std::cout << " if (STORE_" << getLoadStoreTypeName(type);
std::cout << "(";
emitNested(value);
std::cout << ", StorePhyAddr)) {\n";
std::cout << ", StoreAddr)) {\n";
std::cout << " retval = JIT_RETURN_END_TRACE;\n";
std::cout << " }\n";

Expand All @@ -889,11 +888,9 @@ emitLoad(const std::string &argString, LoadStoreType type)
std::cout << "(LoadAddr)) {\n";
emitException("ET_LOAD_STORE, LoadAddr");
std::cout << " }\n";

std::cout << " uint32_t LoadPhyAddr = PHYSICAL_ADDR(LoadAddr);\n";
emitNested(dest);
std::cout << " = LOAD_" << getLoadStoreTypeName(type);
std::cout << "(LoadPhyAddr)\n;";
std::cout << "(LoadAddr)\n;";

std::cout << "}\n";
}
Expand Down
36 changes: 15 additions & 21 deletions SyscallHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,35 +115,30 @@ SyscallHandlerImpl::SyscallHandlerImpl() :

/// Returns a pointer to a string in memory at the given address.
/// Returns 0 if the address is invalid or the string is not null terminated.
char *SyscallHandlerImpl::getString(Thread &thread, uint32_t address)
char *SyscallHandlerImpl::getString(Thread &thread, uint32_t startAddress)
{
Core &state = thread.getParent();
// Perform address translation
address = state.physicalAddress(address);
Core &core = thread.getParent();
if (!core.isValidAddress(startAddress))
return 0;
// Check the string is null terminated
uint32_t end = address;
for (; end < state.getRamSize() && state.loadByte(end); end++) {}
if (end >= state.getRamSize()) {
uint32_t address = startAddress;
uint32_t end = core.getRamSize() + core.ram_base;
for (; address < end && core.loadByte(address); address++) {}
if (address >= end) {
return 0;
}
return (char *)&state.byte(address);
return (char *)&core.byte(address);
}

/// Returns a pointer to a buffer in memory of the given size.
/// Returns 0 if the buffer address is invalid.
void *SyscallHandlerImpl::
getBuffer(Thread &thread, uint32_t address, uint32_t size)
{
Core &state = thread.getParent();
// Perform address translation
address = state.physicalAddress(address);
if (address > state.getRamSize()) {
return 0;
}
if (address + size > state.getRamSize()) {
Core &core = thread.getParent();
if (!core.isValidAddress(address) || !core.isValidAddress(address + size))
return 0;
}
return (void *)&state.byte(address);
return (void *)&core.byte(address);
}

/// Either returns an unused number for a file descriptor or -1 if there are no
Expand Down Expand Up @@ -382,15 +377,14 @@ doSyscall(Thread &thread, int &retval)
{
uint32_t TimeAddr = thread.regs[R1];
uint32_t Time = (uint32_t)std::time(0);
Core &state = thread.getParent();
Core &core = thread.getParent();
if (TimeAddr != 0) {
TimeAddr = state.physicalAddress(TimeAddr);
if (TimeAddr > state.getRamSize() || (TimeAddr & 3)) {
if (!core.isValidAddress(TimeAddr) || (TimeAddr & 3)) {
// Invalid address
thread.regs[R0] = (uint32_t)-1;
return SyscallHandler::CONTINUE;
}
state.storeWord(Time, TimeAddr);
core.storeWord(Time, TimeAddr);
}
thread.regs[R0] = Time;
return SyscallHandler::CONTINUE;
Expand Down
9 changes: 5 additions & 4 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,13 @@ static void readElf(const char *filename, const XEElfSector *elfSector,
std::cerr << "Invalid offet in ELF program header" << i << std::endl;
std::exit(1);
}
uint32_t offset = phdr.p_paddr - core.ram_base;
if (offset > ram_size || offset + phdr.p_filesz > ram_size || offset + phdr.p_memsz > ram_size) {
std::cerr << "Error data from ELF program header " << i << " does not fit in memory" << std::endl;
if (!core.isValidAddress(phdr.p_paddr) ||
!core.isValidAddress(phdr.p_paddr + phdr.p_memsz)) {
std::cerr << "Error data from ELF program header " << i;
std::cerr << " does not fit in memory" << std::endl;
std::exit(1);
}
core.writeMemory(offset, &buf[phdr.p_offset], phdr.p_filesz);
core.writeMemory(phdr.p_paddr, &buf[phdr.p_offset], phdr.p_filesz);
}

readSymbols(e, ram_base, ram_base + ram_size, SI);
Expand Down

0 comments on commit 0680598

Please sign in to comment.