Proper misalignment for AllocatePool, add guest object table
This commit is contained in:
committed by
Radosław Gliński
parent
ee424ae14a
commit
6a08208dc8
@@ -432,9 +432,11 @@ typedef struct alignas(64) PPCContext_s {
|
||||
|
||||
template <typename T = uint8_t*>
|
||||
inline T TranslateVirtual(uint32_t guest_address) XE_RESTRICT const {
|
||||
static_assert(std::is_pointer_v<T>);
|
||||
#if XE_PLATFORM_WIN32 == 1
|
||||
uint8_t* host_address = virtual_membase + guest_address;
|
||||
if (guest_address >= static_cast<uint32_t>(reinterpret_cast<uintptr_t>(this))) {
|
||||
if (guest_address >=
|
||||
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(this))) {
|
||||
host_address += 0x1000;
|
||||
}
|
||||
return reinterpret_cast<T>(host_address);
|
||||
@@ -443,11 +445,17 @@ typedef struct alignas(64) PPCContext_s {
|
||||
|
||||
#endif
|
||||
}
|
||||
//for convenience in kernel functions, version that auto narrows to uint32
|
||||
template <typename T>
|
||||
inline xe::be<T>* TranslateVirtualBE(uint32_t guest_address)
|
||||
XE_RESTRICT const {
|
||||
static_assert(!std::is_pointer_v<T> &&
|
||||
sizeof(T) > 1); // maybe assert is_integral?
|
||||
return TranslateVirtual<xe::be<T>*>(guest_address);
|
||||
}
|
||||
// for convenience in kernel functions, version that auto narrows to uint32
|
||||
template <typename T = uint8_t*>
|
||||
inline T TranslateVirtualGPR(uint64_t guest_address) XE_RESTRICT const {
|
||||
return TranslateVirtual<T>(static_cast<uint32_t>(guest_address));
|
||||
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
||||
@@ -1291,6 +1291,62 @@ uint32_t Processor::CalculateNextGuestInstruction(ThreadDebugInfo* thread_info,
|
||||
return current_pc + 4;
|
||||
}
|
||||
}
|
||||
uint32_t Processor::GuestAtomicIncrement32(ppc::PPCContext* context,
|
||||
uint32_t guest_address) {
|
||||
uint32_t* host_address = context->TranslateVirtual<uint32_t*>(guest_address);
|
||||
|
||||
uint32_t result;
|
||||
while (true) {
|
||||
result = *host_address;
|
||||
// todo: should call a processor->backend function that acquires a
|
||||
// reservation instead of using host atomics
|
||||
if (xe::atomic_cas(xe::byte_swap(result), xe::byte_swap(result + 1),
|
||||
host_address)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
uint32_t Processor::GuestAtomicDecrement32(ppc::PPCContext* context,
|
||||
uint32_t guest_address) {
|
||||
uint32_t* host_address = context->TranslateVirtual<uint32_t*>(guest_address);
|
||||
|
||||
uint32_t result;
|
||||
while (true) {
|
||||
result = *host_address;
|
||||
// todo: should call a processor->backend function that acquires a
|
||||
// reservation instead of using host atomics
|
||||
if (xe::atomic_cas(xe::byte_swap(result), xe::byte_swap(result - 1),
|
||||
host_address)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t Processor::GuestAtomicOr32(ppc::PPCContext* context,
|
||||
uint32_t guest_address, uint32_t mask) {
|
||||
return xe::atomic_or(
|
||||
context->TranslateVirtual<volatile int32_t*>(guest_address),
|
||||
xe::byte_swap(mask));
|
||||
}
|
||||
uint32_t Processor::GuestAtomicXor32(ppc::PPCContext* context,
|
||||
uint32_t guest_address, uint32_t mask) {
|
||||
return xe::atomic_xor(
|
||||
context->TranslateVirtual<volatile int32_t*>(guest_address),
|
||||
xe::byte_swap(mask));
|
||||
}
|
||||
uint32_t Processor::GuestAtomicAnd32(ppc::PPCContext* context,
|
||||
uint32_t guest_address, uint32_t mask) {
|
||||
return xe::atomic_and(
|
||||
context->TranslateVirtual<volatile int32_t*>(guest_address),
|
||||
xe::byte_swap(mask));
|
||||
}
|
||||
|
||||
bool Processor::GuestAtomicCAS32(ppc::PPCContext* context, uint32_t old_value,
|
||||
uint32_t new_value, uint32_t guest_address) {
|
||||
return xe::atomic_cas(xe::byte_swap(old_value), xe::byte_swap(new_value),
|
||||
context->TranslateVirtual<uint32_t*>(guest_address));
|
||||
}
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
|
||||
@@ -184,6 +184,19 @@ class Processor {
|
||||
// Returns the new PC guest address.
|
||||
uint32_t StepToGuestSafePoint(uint32_t thread_id, bool ignore_host = false);
|
||||
|
||||
uint32_t GuestAtomicIncrement32(ppc::PPCContext* context,
|
||||
uint32_t guest_address);
|
||||
uint32_t GuestAtomicDecrement32(ppc::PPCContext* context,
|
||||
uint32_t guest_address);
|
||||
uint32_t GuestAtomicOr32(ppc::PPCContext* context, uint32_t guest_address,
|
||||
uint32_t mask);
|
||||
uint32_t GuestAtomicXor32(ppc::PPCContext* context, uint32_t guest_address,
|
||||
uint32_t mask);
|
||||
uint32_t GuestAtomicAnd32(ppc::PPCContext* context, uint32_t guest_address,
|
||||
uint32_t mask);
|
||||
bool GuestAtomicCAS32(ppc::PPCContext* context, uint32_t old_value,
|
||||
uint32_t new_value, uint32_t guest_address);
|
||||
|
||||
public:
|
||||
// TODO(benvanik): hide.
|
||||
void OnThreadCreated(uint32_t handle, ThreadState* thread_state,
|
||||
|
||||
Reference in New Issue
Block a user