Merge pull request #238 from qookei/fix-aa64-fbs

limine: Fix caching mode detection for multiple framebuffers on AArch64
This commit is contained in:
mint 2022-11-25 03:21:51 +01:00 committed by GitHub
commit 32d7aa1815
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -852,18 +852,21 @@ FEAT_END
#endif #endif
#if defined (__aarch64__) #if defined (__aarch64__)
uint64_t fb_attr = 0x00; // Find the most restrictive caching mode from all framebuffers to use
if (fb.framebuffer_addr) { uint64_t fb_attr = (uint64_t)-1;
for (size_t i = 0; i < fbs_count; i++) {
int el = current_el(); int el = current_el();
uint64_t res; uint64_t res;
// Figure out the caching mode used for this particular framebuffer
if (el == 1) { if (el == 1) {
asm volatile ( asm volatile (
"at s1e1w, %1\n\t" "at s1e1w, %1\n\t"
"isb\n\t" "isb\n\t"
"mrs %0, par_el1" "mrs %0, par_el1"
: "=r"(res) : "=r"(res)
: "r"(fb.framebuffer_addr) : "r"(fbs[i].framebuffer_addr)
: "memory"); : "memory");
} else if (el == 2) { } else if (el == 2) {
asm volatile ( asm volatile (
@ -871,7 +874,7 @@ FEAT_END
"isb\n\t" "isb\n\t"
"mrs %0, par_el1" "mrs %0, par_el1"
: "=r"(res) : "=r"(res)
: "r"(fb.framebuffer_addr) : "r"(fbs[i].framebuffer_addr)
: "memory"); : "memory");
} else { } else {
panic(false, "Unexpected EL in limine_load"); panic(false, "Unexpected EL in limine_load");
@ -880,8 +883,26 @@ FEAT_END
if (res & 1) if (res & 1)
panic(false, "Address translation for framebuffer failed"); panic(false, "Address translation for framebuffer failed");
fb_attr = res >> 56; uint64_t new_attr = res >> 56;
// Use whatever we find first
if (fb_attr == (uint64_t)-1)
fb_attr = new_attr;
// Prefer Device memory over Normal memory
else if ((fb_attr & 0b11110000) && !(new_attr & 0b11110000))
fb_attr = new_attr;
// Prefer tighter Device memory (lower values)
else if (!(fb_attr & 0b11110000) && !(new_attr & 0b11110000) && fb_attr > new_attr)
fb_attr = new_attr;
// Use Normal non-cacheable otherwise (avoid trying to figure out how to downgrade inner vs outer).
else if ((fb_attr & 0b11110000) && (new_attr & 0b11110000))
fb_attr = 0b01000100; // Inner&outer Non-cacheable
// Otherwise do nothing (fb_attr is already more restrictive than new_attr).
} }
// If no framebuffers are found, just zero out the MAIR entry
if (fb_attr == (uint64_t)-1)
fb_attr = 0;
#endif #endif
void *stack = ext_mem_alloc(stack_size) + stack_size; void *stack = ext_mem_alloc(stack_size) + stack_size;