mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-24 23:53:04 +00:00
Skip over features unsupported in A7-A11 SoCs.
This includes - GXF - SPRR - PAN (A7-A9) - Atomics (A7-A10) - FIPI (A7-A10) - DCP SPRR on T8030 seems to be quite different from M1 (at least according to qemu-t8030), so keep it disabled for those CPU parts. Signed-off-by: Nick Chan <towinchenmi@gmail.com>
This commit is contained in:
parent
accb393510
commit
869d2ae35c
10 changed files with 77 additions and 29 deletions
|
@ -69,7 +69,7 @@ void init_t6021_avalanche(int rev);
|
|||
void init_t6031_sawtooth(void);
|
||||
void init_t6031_everest(int rev);
|
||||
|
||||
bool cpufeat_actlr_el2, cpufeat_fast_ipi;
|
||||
bool cpufeat_actlr_el2, cpufeat_fast_ipi, cpufeat_mmu_sprr;
|
||||
|
||||
const char *init_cpu(void)
|
||||
{
|
||||
|
@ -230,11 +230,17 @@ const char *init_cpu(void)
|
|||
sysop("isb");
|
||||
|
||||
msr(SYS_IMP_APL_AMX_CTX_EL1, core);
|
||||
|
||||
/* T8030 SPRR is different */
|
||||
cpufeat_mmu_sprr = true;
|
||||
}
|
||||
|
||||
if (part >= MIDR_PART_T8030_LIGHTNING)
|
||||
msr(SYS_IMP_APL_AMX_CTL_EL1, 0x100);
|
||||
|
||||
if (part >= MIDR_PART_T8015_MONSOON)
|
||||
cpufeat_fast_ipi = true;
|
||||
|
||||
/* Unmask external IRQs, set WFI mode to up (2) */
|
||||
reg_mask(SYS_IMP_APL_CYC_OVRD,
|
||||
CYC_OVRD_FIQ_MODE_MASK | CYC_OVRD_IRQ_MODE_MASK | CYC_OVRD_WFI_MODE_MASK,
|
||||
|
|
|
@ -264,6 +264,11 @@ int display_start_dcp(void)
|
|||
return 0;
|
||||
#endif
|
||||
|
||||
if (!has_dcp) {
|
||||
printf("display: DCP not present\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
const display_config_t *disp_cfg = display_get_config();
|
||||
|
||||
display_is_dptx = !!disp_cfg->dptx_phy[0];
|
||||
|
@ -622,13 +627,14 @@ int display_init(void)
|
|||
else
|
||||
printf("display: Display is internal\n");
|
||||
|
||||
if (cur_boot_args.video.width == 640 && cur_boot_args.video.height == 1136) {
|
||||
if ((cur_boot_args.video.width == 640 && cur_boot_args.video.height == 1136) &&
|
||||
chip_id != S5L8960X) {
|
||||
printf("display: Dummy framebuffer found, initializing display\n");
|
||||
return display_configure(NULL);
|
||||
} else if (display_is_external) {
|
||||
} else if (display_is_external && is_mac) {
|
||||
printf("display: External display found, reconfiguring\n");
|
||||
return display_configure(NULL);
|
||||
} else if (!(cur_boot_args.video.depth & FB_DEPTH_FLAG_RETINA)) {
|
||||
} else if ((!(cur_boot_args.video.depth & FB_DEPTH_FLAG_RETINA)) && is_mac) {
|
||||
printf("display: Internal display with non-retina flag, assuming Sonoma bug and "
|
||||
"reconfiguring\n");
|
||||
fb_clear_direct(); // Old m1n1 stage1 ends up with an ugly logo situation, clear it.
|
||||
|
|
|
@ -137,7 +137,6 @@ void exception_initialize(void)
|
|||
msr(CNTP_CTL_EL02, 7L);
|
||||
msr(CNTV_CTL_EL02, 7L);
|
||||
}
|
||||
|
||||
if (cpufeat_fast_ipi) {
|
||||
reg_clr(SYS_IMP_APL_PMCR0, PMCR0_IACT | PMCR0_IMODE_MASK);
|
||||
reg_clr(SYS_IMP_APL_UPMCR0, UPMCR0_IMODE_MASK);
|
||||
|
@ -223,11 +222,13 @@ void print_regs(u64 *regs, int el12)
|
|||
if (is_ecore()) {
|
||||
printf("E_LSU_ERR_STS: 0x%lx\n", mrs(SYS_IMP_APL_E_LSU_ERR_STS));
|
||||
printf("E_FED_ERR_STS: 0x%lx\n", mrs(SYS_IMP_APL_E_FED_ERR_STS));
|
||||
printf("E_MMU_ERR_STS: 0x%lx\n", mrs(SYS_IMP_APL_E_MMU_ERR_STS));
|
||||
if (cpufeat_fast_ipi)
|
||||
printf("E_MMU_ERR_STS: 0x%lx\n", mrs(SYS_IMP_APL_E_MMU_ERR_STS));
|
||||
} else {
|
||||
printf("LSU_ERR_STS: 0x%lx\n", mrs(SYS_IMP_APL_LSU_ERR_STS));
|
||||
printf("FED_ERR_STS: 0x%lx\n", mrs(SYS_IMP_APL_FED_ERR_STS));
|
||||
printf("MMU_ERR_STS: 0x%lx\n", mrs(SYS_IMP_APL_MMU_ERR_STS));
|
||||
if (cpufeat_fast_ipi)
|
||||
printf("MMU_ERR_STS: 0x%lx\n", mrs(SYS_IMP_APL_MMU_ERR_STS));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -383,15 +384,19 @@ void exc_fiq(u64 *regs)
|
|||
printf(" PMC IRQ, masking\n");
|
||||
reg_clr(SYS_IMP_APL_PMCR0, PMCR0_IACT | PMCR0_IMODE_MASK);
|
||||
}
|
||||
reg = mrs(SYS_IMP_APL_UPMCR0);
|
||||
if ((reg & UPMCR0_IMODE_MASK) == UPMCR0_IMODE_FIQ && (mrs(SYS_IMP_APL_UPMSR) & UPMSR_IACT)) {
|
||||
printf(" UPMC IRQ, masking\n");
|
||||
reg_clr(SYS_IMP_APL_UPMCR0, UPMCR0_IMODE_MASK);
|
||||
}
|
||||
|
||||
if (mrs(SYS_IMP_APL_IPI_SR_EL1) & IPI_SR_PENDING) {
|
||||
printf(" Fast IPI IRQ, clearing\n");
|
||||
msr(SYS_IMP_APL_IPI_SR_EL1, IPI_SR_PENDING);
|
||||
if (cpufeat_fast_ipi) {
|
||||
reg = mrs(SYS_IMP_APL_UPMCR0);
|
||||
if ((reg & UPMCR0_IMODE_MASK) == UPMCR0_IMODE_FIQ &&
|
||||
(mrs(SYS_IMP_APL_UPMSR) & UPMSR_IACT)) {
|
||||
printf(" UPMC IRQ, masking\n");
|
||||
reg_clr(SYS_IMP_APL_UPMCR0, UPMCR0_IMODE_MASK);
|
||||
}
|
||||
|
||||
if (mrs(SYS_IMP_APL_IPI_SR_EL1) & IPI_SR_PENDING) {
|
||||
printf(" Fast IPI IRQ, clearing\n");
|
||||
msr(SYS_IMP_APL_IPI_SR_EL1, IPI_SR_PENDING);
|
||||
}
|
||||
}
|
||||
|
||||
UNUSED(regs);
|
||||
|
|
|
@ -30,6 +30,9 @@ void gxf_init(void)
|
|||
|
||||
bool gxf_enabled(void)
|
||||
{
|
||||
if (!supports_gxf())
|
||||
return false;
|
||||
|
||||
if (!(mrs(SYS_IMP_APL_SPRR_CONFIG_EL1) & SPRR_CONFIG_EN))
|
||||
return false;
|
||||
|
||||
|
|
12
src/main.c
12
src/main.c
|
@ -51,6 +51,7 @@ void get_device_info(void)
|
|||
printf(" Target: %s\n", target);
|
||||
|
||||
is_mac = !!strstr(model, "Mac");
|
||||
has_dcp = adt_path_offset(adt, "/arm-io/dcp") > 0;
|
||||
|
||||
int chosen = adt_path_offset(adt, "/chosen");
|
||||
if (chosen > 0) {
|
||||
|
@ -146,13 +147,13 @@ void m1n1_main(void)
|
|||
|
||||
printf("Running in EL%lu\n\n", mrs(CurrentEL) >> 2);
|
||||
|
||||
get_device_info();
|
||||
firmware_init();
|
||||
|
||||
heapblock_init();
|
||||
|
||||
#ifndef BRINGUP
|
||||
gxf_init();
|
||||
if (supports_gxf())
|
||||
gxf_init();
|
||||
mcc_init();
|
||||
mmu_init();
|
||||
aic_init();
|
||||
|
@ -160,13 +161,14 @@ void m1n1_main(void)
|
|||
wdt_disable();
|
||||
#ifndef BRINGUP
|
||||
pmgr_init();
|
||||
|
||||
#ifdef USE_FB
|
||||
display_init();
|
||||
// Kick DCP to sleep, so dodgy monitors which cause reconnect cycles don't cause us to lose the
|
||||
// framebuffer.
|
||||
display_shutdown(DCP_SLEEP_IF_EXTERNAL);
|
||||
fb_init(false);
|
||||
if (has_dcp)
|
||||
display_shutdown(DCP_SLEEP_IF_EXTERNAL);
|
||||
// On idevice we need to always clear, because otherwise it looks scuffed on white devices
|
||||
fb_init(!is_mac);
|
||||
fb_display_logo();
|
||||
#ifdef FB_SILENT_MODE
|
||||
fb_set_active(!cur_boot_args.video.display);
|
||||
|
|
12
src/memory.c
12
src/memory.c
|
@ -503,10 +503,12 @@ void mmu_init(void)
|
|||
mmu_init_pagetables();
|
||||
mmu_add_default_mappings();
|
||||
mmu_configure();
|
||||
mmu_init_sprr();
|
||||
if (cpufeat_mmu_sprr)
|
||||
mmu_init_sprr();
|
||||
|
||||
// Enable EL0 memory access by EL1
|
||||
msr(PAN, 0);
|
||||
if (supports_pan())
|
||||
msr(PAN, 0);
|
||||
|
||||
// RES1 bits
|
||||
u64 sctlr = SCTLR_LSMAOE | SCTLR_nTLSMD | SCTLR_TSCXT | SCTLR_ITD;
|
||||
|
@ -521,10 +523,12 @@ void mmu_init(void)
|
|||
static void mmu_secondary_setup(void)
|
||||
{
|
||||
mmu_configure();
|
||||
mmu_init_sprr();
|
||||
if (cpufeat_mmu_sprr)
|
||||
mmu_init_sprr();
|
||||
|
||||
// Enable EL0 memory access by EL1
|
||||
msr(PAN, 0);
|
||||
if (supports_pan())
|
||||
msr(PAN, 0);
|
||||
|
||||
// RES1 bits
|
||||
u64 sctlr = SCTLR_LSMAOE | SCTLR_nTLSMD | SCTLR_TSCXT | SCTLR_ITD;
|
||||
|
|
|
@ -95,6 +95,7 @@ _start:
|
|||
bl debug_putc
|
||||
mov w0, '\n'
|
||||
bl debug_putc
|
||||
bl pan_fixup
|
||||
|
||||
mrs x8, CurrentEL
|
||||
cmp x8, #0xc
|
||||
|
@ -105,7 +106,6 @@ _start:
|
|||
bl _start_c
|
||||
b .
|
||||
|
||||
.globl exception_initialize
|
||||
start_el3:
|
||||
bl exception_initialize
|
||||
adrp x8, _stack_bot_el3
|
||||
|
@ -197,6 +197,9 @@ debug_putc:
|
|||
.globl reboot
|
||||
.type reboot, @function
|
||||
reboot:
|
||||
mrs x8, id_aa64pfr0_el1
|
||||
tst w8, 0xf00
|
||||
beq 1f
|
||||
mrs x0, CurrentEL
|
||||
cmp x0, #8
|
||||
beq 1f
|
||||
|
|
|
@ -44,6 +44,21 @@ void apply_rela(uint64_t base, struct rela_entry *rela_start, struct rela_entry
|
|||
}
|
||||
}
|
||||
|
||||
extern uint32_t _v_sp0_sync[], _v_sp0_irq[], _v_sp0_fiq[], _v_sp0_serr[];
|
||||
void pan_fixup(void)
|
||||
{
|
||||
if (supports_pan())
|
||||
return;
|
||||
|
||||
/* Patch msr pan, #0 to nop */
|
||||
_v_sp0_sync[0] = 0xd503201f;
|
||||
_v_sp0_irq[0] = 0xd503201f;
|
||||
_v_sp0_fiq[0] = 0xd503201f;
|
||||
_v_sp0_serr[0] = 0xd503201f;
|
||||
|
||||
sysop("isb");
|
||||
}
|
||||
|
||||
void dump_boot_args(struct boot_args *ba)
|
||||
{
|
||||
printf(" revision: %d\n", ba->revision);
|
||||
|
|
|
@ -8,10 +8,11 @@
|
|||
#include "iodev.h"
|
||||
#include "smp.h"
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
#include "vsprintf.h"
|
||||
#include "xnuboot.h"
|
||||
|
||||
bool is_mac = false;
|
||||
bool is_mac, has_dcp;
|
||||
|
||||
static char ascii(char s)
|
||||
{
|
||||
|
@ -149,7 +150,7 @@ void spin_lock(spinlock_t *lock)
|
|||
__asm__ volatile("1:\n"
|
||||
"mov\t%0, -1\n"
|
||||
"2:\n"
|
||||
"\tcasa\t%0, %2, %1\n"
|
||||
"\tldaxr\t%0, %1\n"
|
||||
"\tcmn\t%0, 1\n"
|
||||
"\tbeq\t3f\n"
|
||||
"\tldxr\t%0, %1\n"
|
||||
|
@ -158,6 +159,8 @@ void spin_lock(spinlock_t *lock)
|
|||
"\twfe\n"
|
||||
"\tb\t1b\n"
|
||||
"3:"
|
||||
"\tstxr\t%w0, %2, %1\n"
|
||||
"\tcbnz\t%w0, 2b\n"
|
||||
: "=&r"(tmp), "+m"(lock->lock)
|
||||
: "r"(me)
|
||||
: "cc", "memory");
|
||||
|
|
|
@ -447,8 +447,9 @@ struct vector_args {
|
|||
};
|
||||
|
||||
extern u32 board_id, chip_id;
|
||||
extern bool is_mac;
|
||||
extern bool cpufeat_actlr_el2, cpufeat_fast_ipi;
|
||||
|
||||
extern bool is_mac, has_dcp;
|
||||
extern bool cpufeat_actlr_el2, cpufeat_fast_ipi, cpufeat_mmu_sprr;
|
||||
|
||||
extern struct vector_args next_stage;
|
||||
|
||||
|
|
Loading…
Reference in a new issue