Files
Acelogic 1510d8c6ce Snapintosh public release
An EL2 monitor/hypervisor and toolchain that boots macOS 27 on the ASUS A16
(Snapdragon X2 Elite), with an Adreno Metal plug-in and IOGPU kext, and
air2ir3, an AIR to Mesa ir3 shader compiler.

MIT, with GPL-2.0 components listed in LICENSE and THIRD_PARTY_NOTICES.md.
No Apple, Qualcomm, ASUS or Microsoft binaries are included.
2026-10-21 21:26:36 -04:00

86 lines
3.1 KiB
C

/* SPDX-License-Identifier: MIT */
#include "cpu.h"
int guest_cpu_root_busy(const struct guest_cpu_address_space spaces[GUEST_CPU_COUNT],
uint64_t root)
{
const uint64_t mask = UINT64_C(0x0000ffffffffc000);
if (!spaces || !root || (root & ~mask)) return 1;
for (unsigned cpu = 0; cpu < GUEST_CPU_COUNT; cpu++)
if ((spaces[cpu].ttbr0 & mask) == root || (spaces[cpu].ttbr1 & mask) == root)
return 1;
return 0;
}
static int valid(const struct guest_cpu_registry *cpus)
{
return cpus && !(cpus->registered & ~UINT64_C(0x3f)) &&
cpus->active_slot < GUEST_CPU_COUNT && !cpus->reserved;
}
static uint64_t count(uint64_t value) { return value == UINT64_MAX ? value : value+1; }
static int affinity_slot(uint64_t affinity)
{
if (affinity < 4) return (int)affinity;
if (affinity >= 0x100 && affinity < 0x102) return (int)(affinity-0x100+4);
return -1;
}
enum guest_cpu_result guest_cpu_register(struct guest_cpu_registry *cpus, uint64_t affinity)
{
if (!valid(cpus)) return CPU_BAD_STATE;
int slot = affinity_slot(affinity);
if (slot < 0) return CPU_BAD_AFFINITY;
cpus->registered |= UINT64_C(1) << slot;
cpus->registrations = count(cpus->registrations);
cpus->last_affinity = affinity;
cpus->last_slot = (uint64_t)slot;
return CPU_OK;
}
enum guest_cpu_result guest_cpu_id(struct guest_cpu_registry *cpus, uint64_t affinity,
uint64_t *out)
{
if (!valid(cpus) || !out) return CPU_BAD_STATE;
int slot = affinity_slot(affinity);
if (slot < 0) return CPU_BAD_AFFINITY;
if (!(cpus->registered & (UINT64_C(1) << slot))) return CPU_NOT_REGISTERED;
cpus->id_queries = count(cpus->id_queries);
cpus->last_affinity = affinity;
cpus->last_slot = (uint64_t)slot;
*out = (uint64_t)slot;
return CPU_OK;
}
int guest_cpu_buffers_valid(uint64_t pa, uint64_t va, uint64_t low, uint64_t high)
{
return low < high && pa >= low && pa <= high &&
GUEST_CPU_SCRATCH_SPAN <= high-pa &&
!(pa & (GUEST_CPU_SCRATCH_STRIDE-1)) &&
!(va & (GUEST_CPU_SCRATCH_STRIDE-1)) &&
va <= UINT64_MAX-GUEST_CPU_SCRATCH_SPAN && (va >> 47) == 0x1ffff;
}
enum guest_cpu_result guest_cpu_buffer(const struct guest_cpu_registry *cpus,
uint64_t slot, uint64_t pa, uint64_t va, uint64_t low, uint64_t high,
struct guest_cpu_buffer *out)
{
if (!valid(cpus) || !out) return CPU_BAD_STATE;
if (slot >= GUEST_CPU_COUNT) return CPU_BAD_SLOT;
if (!(cpus->registered & (UINT64_C(1) << slot))) return CPU_NOT_REGISTERED;
if (!guest_cpu_buffers_valid(pa, va, low, high)) return CPU_BAD_BUFFER;
out->pa = pa+slot*GUEST_CPU_SCRATCH_STRIDE;
out->va = va+slot*GUEST_CPU_SCRATCH_STRIDE;
return CPU_OK;
}
enum guest_cpu_result guest_cpu_output(struct guest_cpu_registry *cpus,
uint64_t slot, uint64_t pa, uint64_t va, uint64_t low, uint64_t high,
struct guest_cpu_buffer *out)
{
enum guest_cpu_result result = guest_cpu_buffer(cpus, slot, pa, va, low, high, out);
if (result != CPU_OK) return result;
cpus->output_queries = count(cpus->output_queries);
cpus->last_slot = slot;
return CPU_OK;
}