mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-21 14:23:01 +00:00
Add support for different boot-args revisions.
Boot-args version 1 (iOS 12), and version 3 (iOS 18, macOS 15). Signed-off-by: Nick Chan <towinchenmi@gmail.com>
This commit is contained in:
parent
869d2ae35c
commit
f4ca3a19fd
6 changed files with 109 additions and 23 deletions
|
@ -58,7 +58,7 @@ int firmware_set_fdt(void *fdt, int node, const char *prop, const struct fw_vers
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void parse_version(const char *s, u32 *out)
|
||||
void firmware_parse_version(const char *s, u32 *out)
|
||||
{
|
||||
memset(out, 0, sizeof(*out) * IBOOT_VER_COMP);
|
||||
|
||||
|
@ -86,21 +86,9 @@ static void detect_firmware(struct fw_version_info *info, const char *ver)
|
|||
info->iboot = ver;
|
||||
}
|
||||
|
||||
// Note: semi-open range
|
||||
bool firmware_sfw_in_range(enum fw_version lower_bound, enum fw_version upper_bound)
|
||||
bool firmware_iboot_in_range(u32 min[IBOOT_VER_COMP], u32 max[IBOOT_VER_COMP],
|
||||
u32 this[IBOOT_VER_COMP])
|
||||
{
|
||||
u32 min[IBOOT_VER_COMP] = {0};
|
||||
u32 max[IBOOT_VER_COMP] = {UINT32_MAX};
|
||||
u32 this[IBOOT_VER_COMP] = {0};
|
||||
|
||||
if (lower_bound > V_UNKNOWN && lower_bound < NUM_FW_VERSIONS)
|
||||
parse_version(fw_versions[lower_bound].iboot, min);
|
||||
|
||||
if (upper_bound > V_UNKNOWN && upper_bound < NUM_FW_VERSIONS)
|
||||
parse_version(fw_versions[upper_bound].iboot, max);
|
||||
|
||||
parse_version(system_firmware.iboot, this);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < IBOOT_VER_COMP; i++)
|
||||
if (this[i] != min[i])
|
||||
|
@ -116,6 +104,24 @@ bool firmware_sfw_in_range(enum fw_version lower_bound, enum fw_version upper_bo
|
|||
return this[i] < max[i];
|
||||
}
|
||||
|
||||
// Note: semi-open range
|
||||
bool firmware_sfw_in_range(enum fw_version lower_bound, enum fw_version upper_bound)
|
||||
{
|
||||
u32 min[IBOOT_VER_COMP] = {0};
|
||||
u32 max[IBOOT_VER_COMP] = {UINT32_MAX};
|
||||
u32 this[IBOOT_VER_COMP] = {0};
|
||||
|
||||
if (lower_bound > V_UNKNOWN && lower_bound < NUM_FW_VERSIONS)
|
||||
firmware_parse_version(fw_versions[lower_bound].iboot, min);
|
||||
|
||||
if (upper_bound > V_UNKNOWN && upper_bound < NUM_FW_VERSIONS)
|
||||
firmware_parse_version(fw_versions[upper_bound].iboot, max);
|
||||
|
||||
firmware_parse_version(system_firmware.iboot, this);
|
||||
|
||||
return firmware_iboot_in_range(min, max, this);
|
||||
}
|
||||
|
||||
int firmware_init(void)
|
||||
{
|
||||
int node = adt_path_offset(adt, "/chosen");
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "types.h"
|
||||
|
||||
/* macOS */
|
||||
enum fw_version {
|
||||
V_UNKNOWN = 0,
|
||||
V12_1,
|
||||
|
@ -48,6 +49,9 @@ extern const struct fw_version_info fw_versions[NUM_FW_VERSIONS];
|
|||
|
||||
int firmware_init(void);
|
||||
int firmware_set_fdt(void *fdt, int node, const char *prop, const struct fw_version_info *ver);
|
||||
bool firmware_iboot_in_range(u32 min[IBOOT_VER_COMP], u32 max[IBOOT_VER_COMP],
|
||||
u32 this[IBOOT_VER_COMP]);
|
||||
bool firmware_sfw_in_range(enum fw_version lower_bound, enum fw_version upper_bound);
|
||||
void firmware_parse_version(const char *s, u32 *out);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -411,7 +411,7 @@ static void mmu_add_default_mappings(void)
|
|||
* With SPRR enabled, this becomes RW.
|
||||
* This range includes all real RAM, including carveouts
|
||||
*/
|
||||
mmu_add_mapping(ram_base, ram_base, cur_boot_args.mem_size_actual, MAIR_IDX_NORMAL, PERM_RWX);
|
||||
mmu_add_mapping(ram_base, ram_base, mem_size_actual, MAIR_IDX_NORMAL, PERM_RWX);
|
||||
|
||||
/* Unmap carveout regions */
|
||||
mcc_unmap_carveouts();
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#include "adt.h"
|
||||
#include "chickens.h"
|
||||
#include "exception.h"
|
||||
#include "firmware.h"
|
||||
#include "smp.h"
|
||||
#include "string.h"
|
||||
#include "types.h"
|
||||
|
@ -59,8 +61,13 @@ void pan_fixup(void)
|
|||
sysop("isb");
|
||||
}
|
||||
|
||||
u64 boot_flags, mem_size_actual;
|
||||
void dump_boot_args(struct boot_args *ba)
|
||||
{
|
||||
if (ba->revision > 3) {
|
||||
printf("Unsupported boot_args revision %hu\n!", ba->revision);
|
||||
}
|
||||
|
||||
printf(" revision: %d\n", ba->revision);
|
||||
printf(" version: %d\n", ba->version);
|
||||
printf(" virt_base: 0x%lx\n", ba->virt_base);
|
||||
|
@ -78,11 +85,61 @@ void dump_boot_args(struct boot_args *ba)
|
|||
printf(" machine_type: %d\n", ba->machine_type);
|
||||
printf(" devtree: %p\n", ba->devtree);
|
||||
printf(" devtree_size: 0x%x\n", ba->devtree_size);
|
||||
printf(" cmdline: %s\n", ba->cmdline);
|
||||
printf(" boot_flags: 0x%lx\n", ba->boot_flags);
|
||||
printf(" mem_size_act: 0x%lx\n", ba->mem_size_actual);
|
||||
int node = adt_path_offset(adt, "/chosen");
|
||||
|
||||
if (node < 0) {
|
||||
printf("ADT: no /chosen found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is called very early - before firmware information is initialized */
|
||||
u32 len;
|
||||
const char *p = adt_getprop(adt, node, "firmware-version", &len);
|
||||
if (!p) {
|
||||
printf("ADT: failed to find firmware-version\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t version = ba->revision;
|
||||
u32 iboot_min[IBOOT_VER_COMP] = {0};
|
||||
u32 iboot_version[IBOOT_VER_COMP] = {0};
|
||||
u32 iboot_ba_v1_max[IBOOT_VER_COMP] = {5539}; /* iOS 13 = 5540 */
|
||||
|
||||
firmware_parse_version(p, iboot_version);
|
||||
if (firmware_iboot_in_range(iboot_min, iboot_ba_v1_max, iboot_version))
|
||||
version = 1;
|
||||
|
||||
switch (version) {
|
||||
case 1:
|
||||
printf(" cmdline: %s\n", ba->rv1.cmdline);
|
||||
printf(" boot_flags: 0x%lx\n", ba->rv1.boot_flags);
|
||||
printf(" mem_size_act: 0x%lx\n", ba->rv1.mem_size_actual);
|
||||
boot_flags = ba->rv1.boot_flags;
|
||||
mem_size_actual = ba->rv1.mem_size_actual;
|
||||
break;
|
||||
case 2:
|
||||
printf(" cmdline: %s\n", ba->rv2.cmdline);
|
||||
printf(" boot_flags: 0x%lx\n", ba->rv2.boot_flags);
|
||||
printf(" mem_size_act: 0x%lx\n", ba->rv2.mem_size_actual);
|
||||
boot_flags = ba->rv2.boot_flags;
|
||||
mem_size_actual = ba->rv2.mem_size_actual;
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
printf(" cmdline: %s\n", ba->rv3.cmdline);
|
||||
printf(" boot_flags: 0x%lx\n", ba->rv3.boot_flags);
|
||||
printf(" mem_size_act: 0x%lx\n", ba->rv3.mem_size_actual);
|
||||
boot_flags = ba->rv3.boot_flags;
|
||||
mem_size_actual = ba->rv3.mem_size_actual;
|
||||
break;
|
||||
}
|
||||
if (!mem_size_actual) {
|
||||
mem_size_actual = ALIGN_UP(ba->phys_base + ba->mem_size - 0x800000000, BIT(30));
|
||||
printf("Correcting mem_size_actual to 0x%lx\n", mem_size_actual);
|
||||
}
|
||||
}
|
||||
|
||||
extern void get_device_info(void);
|
||||
void _start_c(void *boot_args, void *base)
|
||||
{
|
||||
UNUSED(base);
|
||||
|
@ -105,6 +162,8 @@ void _start_c(void *boot_args, void *base)
|
|||
}
|
||||
|
||||
uart_puts("Initializing");
|
||||
get_device_info();
|
||||
|
||||
printf("CPU init (MIDR: 0x%lx)...\n", mrs(MIDR_EL1));
|
||||
const char *type = init_cpu();
|
||||
printf(" CPU: %s\n\n", type);
|
||||
|
|
|
@ -452,6 +452,7 @@ extern bool is_mac, has_dcp;
|
|||
extern bool cpufeat_actlr_el2, cpufeat_fast_ipi, cpufeat_mmu_sprr;
|
||||
|
||||
extern struct vector_args next_stage;
|
||||
extern u64 boot_flags, mem_size_actual;
|
||||
|
||||
void cpu_sleep(bool deep) __attribute__((noreturn));
|
||||
void deep_wfi(void);
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
#ifndef XNUBOOT_H
|
||||
#define XNUBOOT_H
|
||||
|
||||
#define CMDLINE_LENGTH 608
|
||||
#define CMDLINE_LENGTH_RV1 256
|
||||
#define CMDLINE_LENGTH_RV2 608
|
||||
#define CMDLINE_LENGTH_RV3 1024
|
||||
|
||||
struct boot_video {
|
||||
u64 base;
|
||||
|
@ -25,9 +27,23 @@ struct boot_args {
|
|||
u32 machine_type;
|
||||
void *devtree;
|
||||
u32 devtree_size;
|
||||
char cmdline[CMDLINE_LENGTH];
|
||||
u64 boot_flags;
|
||||
u64 mem_size_actual;
|
||||
union {
|
||||
struct {
|
||||
char cmdline[CMDLINE_LENGTH_RV1];
|
||||
u64 boot_flags;
|
||||
u64 mem_size_actual;
|
||||
} rv1;
|
||||
struct {
|
||||
char cmdline[CMDLINE_LENGTH_RV2];
|
||||
u64 boot_flags;
|
||||
u64 mem_size_actual;
|
||||
} rv2;
|
||||
struct {
|
||||
char cmdline[CMDLINE_LENGTH_RV3];
|
||||
u64 boot_flags;
|
||||
u64 mem_size_actual;
|
||||
} rv3;
|
||||
};
|
||||
};
|
||||
|
||||
extern u64 boot_args_addr;
|
||||
|
|
Loading…
Reference in a new issue