add basic mmu tests

Some simple tests for diffrent mmu.
Basicly add some tlb entries, enable the mmu try to read from virtual address

The aarm64 test was provided by imre-kis-arm in #1718
This commit is contained in:
Takacs, Philipp
2022-10-06 15:53:25 +02:00
parent f2eb1f4711
commit 7f1eb4532d
3 changed files with 298 additions and 0 deletions

View File

@@ -372,6 +372,106 @@ static void test_arm64_block_invalid_mem_read_write_sync(void)
OK(uc_close(uc));
}
static void test_arm64_mmu(void)
{
uc_engine *uc;
char *data;
char tlbe[8];
uint64_t x0, x1, x2;
/*
* Not exact the binary, but aarch64-linux-gnu-as generate this code and reference sometimes data after ttb0_base.
* // Read data from physical address
* ldr X0, =0x40000000
* ldr X1, [X0]
* // Initialize translation table control registers
* ldr X0, =0x180803F20
* msr TCR_EL1, X0
* ldr X0, =0xFFFFFFFF
* msr MAIR_EL1, X0
* // Set translation table
* adr X0, ttb0_base
* msr TTBR0_EL1, X0
* // Enable caches and the MMU
* mrs X0, SCTLR_EL1
* orr X0, X0, #(0x1 << 2) // The C bit (data cache).
* orr X0, X0, #(0x1 << 12) // The I bit (instruction cache)
* orr X0, X0, #0x1 // The M bit (MMU).
* msr SCTLR_EL1, X0
* dsb SY
* isb
* // Read the same memory area through virtual address
* ldr X0, =0x80000000
* ldr X2, [X0]
*
* // Stop
* b .
*/
char code[] = "\x00\x81\x00\x58\x01\x00\x40\xf9\x00\x81\x00\x58\x40\x20\x18\xd5\x00\x81\x00\x58\x00\xa2\x18\xd5\x40\x7f\x00\x10\x00\x20\x18\xd5\x00\x10\x38\xd5\x00\x00\x7e\xb2\x00\x00\x74\xb2\x00\x00\x40\xb2\x00\x10\x18\xd5\x9f\x3f\x03\xd5\xdf\x3f\x03\xd5\xe0\x7f\x00\x58\x02\x00\x40\xf9\x00\x00\x00\x14\x1f\x20\x03\xd5\x1f\x20\x03\xd5\x1F\x20\x03\xD5\x1F\x20\x03\xD5";
data = malloc(0x1000);
TEST_CHECK(data != NULL);
OK(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc));
OK(uc_mem_map(uc, 0, 0x2000, UC_PROT_ALL));
OK(uc_mem_write(uc, 0, code, sizeof(code) - 1));
// generate tlb entries
tlbe[0] = 0x41;
tlbe[1] = 0x07;
tlbe[2] = 0;
tlbe[3] = 0;
tlbe[4] = 0;
tlbe[5] = 0;
tlbe[6] = 0;
tlbe[7] = 0;
OK(uc_mem_write(uc, 0x1000, tlbe, sizeof(tlbe)));
tlbe[3] = 0x40;
OK(uc_mem_write(uc, 0x1008, tlbe, sizeof(tlbe)));
OK(uc_mem_write(uc, 0x1010, tlbe, sizeof(tlbe)));
OK(uc_mem_write(uc, 0x1018, tlbe, sizeof(tlbe)));
//mentioned data referenced by the asm generated my aarch64-linux-gnu-as
tlbe[0] = 0;
tlbe[1] = 0;
OK(uc_mem_write(uc, 0x1020, tlbe, sizeof(tlbe)));
tlbe[0] = 0x20;
tlbe[1] = 0x3f;
tlbe[2] = 0x80;
tlbe[3] = 0x80;
tlbe[4] = 0x1;
OK(uc_mem_write(uc, 0x1028, tlbe, sizeof(tlbe)));
tlbe[0] = 0xff;
tlbe[1] = 0xff;
tlbe[2] = 0xff;
tlbe[3] = 0xff;
tlbe[4] = 0x00;
OK(uc_mem_write(uc, 0x1030, tlbe, sizeof(tlbe)));
tlbe[0] = 0x00;
tlbe[1] = 0x00;
tlbe[2] = 0x00;
tlbe[3] = 0x80;
OK(uc_mem_write(uc, 0x1038, tlbe, sizeof(tlbe)));
for (size_t i = 0; i < 0x1000; i++) {
data[i] = 0x44;
}
OK(uc_mem_map_ptr(uc, 0x40000000, 0x1000, UC_PROT_READ, data));
OK(uc_emu_start(uc, 0, 0x44, 0, 0));
OK(uc_reg_read(uc, UC_ARM64_REG_X0, &x0));
OK(uc_reg_read(uc, UC_ARM64_REG_X1, &x1));
OK(uc_reg_read(uc, UC_ARM64_REG_X2, &x2));
TEST_CHECK(x0 == 0x80000000);
TEST_CHECK(x1 == 0x4444444444444444);
TEST_CHECK(x2 == 0x4444444444444444);
free(data);
}
TEST_LIST = {{"test_arm64_until", test_arm64_until},
{"test_arm64_code_patching", test_arm64_code_patching},
{"test_arm64_code_patching_count", test_arm64_code_patching_count},
@@ -385,4 +485,5 @@ TEST_LIST = {{"test_arm64_until", test_arm64_until},
{"test_arm64_block_sync_pc", test_arm64_block_sync_pc},
{"test_arm64_block_invalid_mem_read_write_sync",
test_arm64_block_invalid_mem_read_write_sync},
{"test_arm64_mmu", test_arm64_mmu},
{NULL, NULL}};