diff --git a/cputest/unaligned_stores.cpp b/cputest/unaligned_stores.cpp index 25fdd23..06f8d55 100644 --- a/cputest/unaligned_stores.cpp +++ b/cputest/unaligned_stores.cpp @@ -24,18 +24,24 @@ static u32 Read(volatile u8* ptr) return *reinterpret_cast(ptr); } -static void Write(volatile u8* ptr, u32 value, u32 size) +static void Write(volatile u8* ptr, u32 value, u32 size, bool swap) { switch (size) { case 4: - asm volatile("stw %0, 0(%1)" :: "r"(value), "r"(ptr)); + if (swap) + asm volatile("stwbrx %0, 0, %1" :: "r"(value), "r"(ptr)); + else + asm volatile("stwx %0, 0, %1" :: "r"(value), "r"(ptr)); break; case 2: - asm volatile("sth %0, 0(%1)" :: "r"(value), "r"(ptr)); + if (swap) + asm volatile("sthbrx %0, 0, %1" :: "r"(value), "r"(ptr)); + else + asm volatile("sthx %0, 0, %1" :: "r"(value), "r"(ptr)); break; case 1: - asm volatile("stb %0, 0(%1)" :: "r"(value), "r"(ptr)); + asm volatile("stbx %0, 0, %1" :: "r"(value), "r"(ptr)); break; } } @@ -53,23 +59,24 @@ static void WriteWithSimulatedQuirks(uintptr_t alignment, volatile u8* ptr, u32 for (uintptr_t i = 0; i < count; i += 8) { - Write(ptr - misalignment_64 + i, value, sizeof(u32)); - Write(ptr - misalignment_64 + i + 4, value, sizeof(u32)); + Write(ptr - misalignment_64 + i, value, sizeof(u32), false); + Write(ptr - misalignment_64 + i + 4, value, sizeof(u32), false); } } else { - Write(ptr, value, size); + Write(ptr, value, size, false); } } -static void UnalignedStoresTest(volatile u8* ptr, u32 size, bool cached_memory) +static void UnalignedStoresTest(volatile u8* ptr, u32 size, bool cached_memory, bool swap) { - network_printf("Starting test using ptr 0x%" PRIxPTR ", size %u\n", - reinterpret_cast(ptr), size); + network_printf("Starting test using ptr 0x%" PRIxPTR ", size %u, swap %u\n", + reinterpret_cast(ptr), size, swap); volatile u8 reference_buffer[32]; const u32 word = 0x12345678; + const u32 swapped_word = swap ? (size == 2 ? 0x12347856 : 0x78563412) : word; for (size_t i = 0; i <= 28; ++i) { @@ -80,12 +87,12 @@ static void UnalignedStoresTest(volatile u8* ptr, u32 size, bool cached_memory) s_pi_error_occurred = false; // The actual write that we are testing the behavior of - Write(ptr + i, word, size); + Write(ptr + i, word, size, swap); if (cached_memory) - Write(reference_buffer + i, word, size); + Write(reference_buffer + i, swapped_word, size, false); else - WriteWithSimulatedQuirks(i, reference_buffer + i, word, size); + WriteWithSimulatedQuirks(i, reference_buffer + i, swapped_word, size); DO_TEST(std::equal(ptr, ptr + 32, reference_buffer), "{}-byte write to {} failed\n" @@ -181,9 +188,11 @@ int main() volatile u8* cached_ptr = reinterpret_cast(memory_allocation + 16); - UnalignedStoresTest(cached_ptr, 1, true); - UnalignedStoresTest(cached_ptr, 2, true); - UnalignedStoresTest(cached_ptr, 4, true); + UnalignedStoresTest(cached_ptr, 1, true, false); + UnalignedStoresTest(cached_ptr, 2, true, false); + UnalignedStoresTest(cached_ptr, 4, true, false); + UnalignedStoresTest(cached_ptr, 2, true, true); + UnalignedStoresTest(cached_ptr, 4, true, true); network_printf("Invalidating cache...\n"); asm volatile("dcbi %0, %1" :: "r"(memory_allocation), "r"(0)); @@ -191,9 +200,11 @@ int main() volatile u8* uncached_ptr = reinterpret_cast(MEM_K0_TO_K1(cached_ptr)); - UnalignedStoresTest(uncached_ptr, 1, false); - UnalignedStoresTest(uncached_ptr, 2, false); - UnalignedStoresTest(uncached_ptr, 4, false); + UnalignedStoresTest(uncached_ptr, 1, false, false); + UnalignedStoresTest(uncached_ptr, 2, false, false); + UnalignedStoresTest(uncached_ptr, 4, false, false); + UnalignedStoresTest(uncached_ptr, 2, false, true); + UnalignedStoresTest(uncached_ptr, 4, false, true); network_printf("Shutting down...\n"); network_shutdown();