mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-21 22:23:05 +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;
|
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);
|
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;
|
info->iboot = ver;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: semi-open range
|
bool firmware_iboot_in_range(u32 min[IBOOT_VER_COMP], u32 max[IBOOT_VER_COMP],
|
||||||
bool firmware_sfw_in_range(enum fw_version lower_bound, enum fw_version upper_bound)
|
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;
|
int i;
|
||||||
for (i = 0; i < IBOOT_VER_COMP; i++)
|
for (i = 0; i < IBOOT_VER_COMP; i++)
|
||||||
if (this[i] != min[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];
|
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 firmware_init(void)
|
||||||
{
|
{
|
||||||
int node = adt_path_offset(adt, "/chosen");
|
int node = adt_path_offset(adt, "/chosen");
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
|
/* macOS */
|
||||||
enum fw_version {
|
enum fw_version {
|
||||||
V_UNKNOWN = 0,
|
V_UNKNOWN = 0,
|
||||||
V12_1,
|
V12_1,
|
||||||
|
@ -48,6 +49,9 @@ extern const struct fw_version_info fw_versions[NUM_FW_VERSIONS];
|
||||||
|
|
||||||
int firmware_init(void);
|
int firmware_init(void);
|
||||||
int firmware_set_fdt(void *fdt, int node, const char *prop, const struct fw_version_info *ver);
|
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);
|
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
|
#endif
|
||||||
|
|
|
@ -411,7 +411,7 @@ static void mmu_add_default_mappings(void)
|
||||||
* With SPRR enabled, this becomes RW.
|
* With SPRR enabled, this becomes RW.
|
||||||
* This range includes all real RAM, including carveouts
|
* 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 */
|
/* Unmap carveout regions */
|
||||||
mcc_unmap_carveouts();
|
mcc_unmap_carveouts();
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
/* SPDX-License-Identifier: MIT */
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
|
||||||
|
#include "adt.h"
|
||||||
#include "chickens.h"
|
#include "chickens.h"
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
|
#include "firmware.h"
|
||||||
#include "smp.h"
|
#include "smp.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
@ -59,8 +61,13 @@ void pan_fixup(void)
|
||||||
sysop("isb");
|
sysop("isb");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 boot_flags, mem_size_actual;
|
||||||
void dump_boot_args(struct boot_args *ba)
|
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(" revision: %d\n", ba->revision);
|
||||||
printf(" version: %d\n", ba->version);
|
printf(" version: %d\n", ba->version);
|
||||||
printf(" virt_base: 0x%lx\n", ba->virt_base);
|
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(" machine_type: %d\n", ba->machine_type);
|
||||||
printf(" devtree: %p\n", ba->devtree);
|
printf(" devtree: %p\n", ba->devtree);
|
||||||
printf(" devtree_size: 0x%x\n", ba->devtree_size);
|
printf(" devtree_size: 0x%x\n", ba->devtree_size);
|
||||||
printf(" cmdline: %s\n", ba->cmdline);
|
int node = adt_path_offset(adt, "/chosen");
|
||||||
printf(" boot_flags: 0x%lx\n", ba->boot_flags);
|
|
||||||
printf(" mem_size_act: 0x%lx\n", ba->mem_size_actual);
|
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)
|
void _start_c(void *boot_args, void *base)
|
||||||
{
|
{
|
||||||
UNUSED(base);
|
UNUSED(base);
|
||||||
|
@ -105,6 +162,8 @@ void _start_c(void *boot_args, void *base)
|
||||||
}
|
}
|
||||||
|
|
||||||
uart_puts("Initializing");
|
uart_puts("Initializing");
|
||||||
|
get_device_info();
|
||||||
|
|
||||||
printf("CPU init (MIDR: 0x%lx)...\n", mrs(MIDR_EL1));
|
printf("CPU init (MIDR: 0x%lx)...\n", mrs(MIDR_EL1));
|
||||||
const char *type = init_cpu();
|
const char *type = init_cpu();
|
||||||
printf(" CPU: %s\n\n", type);
|
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 bool cpufeat_actlr_el2, cpufeat_fast_ipi, cpufeat_mmu_sprr;
|
||||||
|
|
||||||
extern struct vector_args next_stage;
|
extern struct vector_args next_stage;
|
||||||
|
extern u64 boot_flags, mem_size_actual;
|
||||||
|
|
||||||
void cpu_sleep(bool deep) __attribute__((noreturn));
|
void cpu_sleep(bool deep) __attribute__((noreturn));
|
||||||
void deep_wfi(void);
|
void deep_wfi(void);
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
#ifndef XNUBOOT_H
|
#ifndef XNUBOOT_H
|
||||||
#define 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 {
|
struct boot_video {
|
||||||
u64 base;
|
u64 base;
|
||||||
|
@ -25,9 +27,23 @@ struct boot_args {
|
||||||
u32 machine_type;
|
u32 machine_type;
|
||||||
void *devtree;
|
void *devtree;
|
||||||
u32 devtree_size;
|
u32 devtree_size;
|
||||||
char cmdline[CMDLINE_LENGTH];
|
union {
|
||||||
u64 boot_flags;
|
struct {
|
||||||
u64 mem_size_actual;
|
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;
|
extern u64 boot_args_addr;
|
||||||
|
|
Loading…
Reference in a new issue