Created
May 17, 2019 05:22
-
-
Save bazad/07f6d748246b6a16fb77ff938fcd4fb3 to your computer and use it in GitHub Desktop.
A C implementation of a simple page table walk on A12 devices (iOS 12.1.2).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
uint64_t | |
aarch64_page_table_lookup(uint64_t ttbr, uint64_t vaddr, | |
uint64_t *l1_tte_, uint64_t *l2_tte_, uint64_t *l3_tte_) { | |
const uint64_t pg_bits = 14; | |
const uint64_t l1_size = 3; | |
const uint64_t l2_size = 11; | |
const uint64_t l3_size = 11; | |
const uint64_t tte_physaddr_mask = ((1uLL << 40) - 1) & ~((1 << pg_bits) - 1); | |
uint64_t l1_index = (vaddr >> (l2_size + l3_size + pg_bits)) & ((1 << l1_size) - 1); | |
uint64_t l2_index = (vaddr >> (l3_size + pg_bits)) & ((1 << l2_size) - 1); | |
uint64_t l3_index = (vaddr >> pg_bits) & ((1 << l3_size) - 1); | |
uint64_t pg_offset = vaddr & ((1 << pg_bits) - 1); | |
uint64_t l1_table = ttbr; | |
uint64_t l1_tte = phys_read64(l1_table + 8 * l1_index); | |
if (l1_tte_ != NULL) { | |
*l1_tte_ = l1_tte; | |
} | |
if ((l1_tte & 3) != 3) { | |
return -1; | |
} | |
uint64_t l2_table = l1_tte & tte_physaddr_mask; | |
uint64_t l2_tte = phys_read64(l2_table + 8 * l2_index); | |
if (l2_tte_ != NULL) { | |
*l2_tte_ = l2_tte; | |
} | |
if ((l2_tte & 3) != 3) { | |
return -1; | |
} | |
uint64_t l3_table = l2_tte & tte_physaddr_mask; | |
uint64_t l3_tte = phys_read64(l3_table + 8 * l3_index); | |
if (l3_tte_ != NULL) { | |
*l3_tte_ = l3_tte; | |
} | |
if ((l3_tte & 3) != 3) { | |
return -1; | |
} | |
uint64_t frame = l3_tte & tte_physaddr_mask; | |
return frame | pg_offset; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment