Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions proxyclient/m1n1/hv/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1786,6 +1786,15 @@ def remove_oslog(node):
continue
addr, size = cpu.cpu_impl_reg
print(f" {cpu.name}: [0x{addr:x}] = 0x{rvbar:x}")
# On some platforms (M4) iBoot already sets this
# to the m1n1 entrypoint and locks the register.
# Skip the write if the value is already correct.
val = self.p.read64(addr)
if val & 0xfffffffff000 == rvbar:
continue
if val & 1:
print(f"{hex(val & 0xfffffffff000)} != {hex(rvbar)}")
print("The cpu_impl_reg is already locked, this might fail...")
self.p.write64(addr, rvbar)

def _load_macho_symbols(self):
Expand Down
11 changes: 10 additions & 1 deletion proxyclient/tools/chainload.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,16 @@ def remove_oslog(node):
continue
addr, size = cpu.cpu_impl_reg
print(f" {cpu.name}: [0x{addr:x}] = 0x{rvbar:x}")
p.write64(addr, rvbar)

val = p.read64(addr)
locked = val & 1
do_write = val & 0xfffffffff000 != rvbar

if locked and do_write:
raise Exception("RVBAR is locked and does not already contain start address")

if do_write:
p.write64(addr, rvbar)

u.push_adt()

Expand Down
14 changes: 13 additions & 1 deletion src/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,15 @@ static void smp_start_cpu(int index, int die, int cluster, int core, u64 impl, u

printf("Starting CPU %d (%d:%d:%d)... ", index, die, cluster, core);

u64 rvbar_value = read64(impl);
bool rvbar_locked = rvbar_value & 1;
bool write_rvbar = (rvbar_value & 0xfffffffff000) != (u64)_vectors_start;
if (rvbar_locked && write_rvbar) {
printf("RVBAR is locked and does not already contain start address:\n 0x%lx != 0x%lx\n",
rvbar_value, (u64)_vectors_start);
return;
}

memset(&spin_table[index], 0, sizeof(struct spin_table));

target_cpu = index;
Expand All @@ -140,7 +149,9 @@ static void smp_start_cpu(int index, int die, int cluster, int core, u64 impl, u

sysop("dsb sy");

write64(impl, (u64)_vectors_start);
if (write_rvbar) {
write64(impl, (u64)_vectors_start);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, if the register is locked and doesn't contain the right address just fail earlier

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

cpu_start_base += die * PMGR_DIE_OFFSET;

Expand Down Expand Up @@ -267,6 +278,7 @@ void smp_start_secondaries(void)
break;
case T8112:
case T8122:
case T8132:
cpu_start_off = CPU_START_OFF_T8112;
break;
case T6020:
Expand Down