mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-10 01:34:12 +00:00
firmware: New module to detect firmware version
Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
parent
7782944808
commit
c19303dc87
4 changed files with 120 additions and 0 deletions
1
Makefile
1
Makefile
|
@ -96,6 +96,7 @@ OBJECTS := \
|
|||
display.o \
|
||||
exception.o exception_asm.o \
|
||||
fb.o font.o font_retina.o \
|
||||
firmware.o \
|
||||
gxf.o gxf_asm.o \
|
||||
heapblock.o \
|
||||
hv.o hv_vm.o hv_exc.o hv_vuart.o hv_wdt.o hv_asm.o hv_aic.o \
|
||||
|
|
81
src/firmware.c
Normal file
81
src/firmware.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#include "firmware.h"
|
||||
#include "adt.h"
|
||||
#include "string.h"
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "libfdt/libfdt.h"
|
||||
#include "libfdt/libfdt_env.h"
|
||||
|
||||
struct fw_version_info os_firmware;
|
||||
struct fw_version_info system_firmware;
|
||||
|
||||
const struct fw_version_info fw_versions[NUM_FW_VERSIONS] = {
|
||||
[V_UNKNOWN] = {V_UNKNOWN, "unknown", {0}, 1, "unknown"},
|
||||
[V12_1] = {V12_1, "12.1", {12, 1, 0}, 3, "iBoot-7429.61.2"},
|
||||
[V12_2] = {V12_2, "12.2", {12, 2, 0}, 3, "iBoot-7429.81.3"},
|
||||
[V12_3] = {V12_3, "12.3", {12, 3, 0}, 3, "iBoot-7459.101.2"},
|
||||
[V12_4] = {V12_4, "12.4", {12, 4, 0}, 3, "iBoot-7459.121.3"},
|
||||
[V12_5] = {V12_5, "12.5", {12, 4, 0}, 3, "iBoot-7459.141.1"},
|
||||
// Same as 12.5
|
||||
// {V12_6, "12.6", {12, 4, 0}, 3, "iBoot-7459.141.1"},
|
||||
[V13_0B4] = {V13_0B4, "13.0 beta4", {12, 99, 4}, 3, "iBoot-8419.0.151.0.1"},
|
||||
[V13_0] = {V13_0, "13.0", {13, 0, 0}, 3, "iBoot-8419.41.10"},
|
||||
};
|
||||
|
||||
int firmware_set_fdt(void *fdt, int node, const char *prop, const struct fw_version_info *ver)
|
||||
{
|
||||
fdt32_t data[ARRAY_SIZE(ver->num)];
|
||||
|
||||
for (size_t i = 0; i < ver->num_length; i++) {
|
||||
data[i] = cpu_to_fdt32(ver->num[i]);
|
||||
}
|
||||
|
||||
return fdt_setprop(fdt, node, prop, data, ver->num_length * sizeof(u32));
|
||||
}
|
||||
|
||||
static void detect_firmware(struct fw_version_info *info, const char *ver)
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_SIZE(fw_versions); i++) {
|
||||
if (!strcmp(fw_versions[i].iboot, ver)) {
|
||||
*info = fw_versions[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*info = fw_versions[V_UNKNOWN];
|
||||
info->iboot = ver;
|
||||
}
|
||||
|
||||
int firmware_init(void)
|
||||
{
|
||||
int node = adt_path_offset(adt, "/chosen");
|
||||
|
||||
if (node < 0) {
|
||||
printf("ADT: no /chosen found\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
u32 len;
|
||||
const char *p = adt_getprop(adt, node, "firmware-version", &len);
|
||||
if (p && len && p[len - 1] == 0) {
|
||||
detect_firmware(&os_firmware, p);
|
||||
printf("OS FW version: %s (%s)\n", os_firmware.string, os_firmware.iboot);
|
||||
} else {
|
||||
printf("ADT: failed to find firmware-version\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = adt_getprop(adt, node, "system-firmware-version", &len);
|
||||
if (p && len && p[len - 1] == 0) {
|
||||
detect_firmware(&system_firmware, p);
|
||||
printf("System FW version: %s (%s)\n", system_firmware.string, system_firmware.iboot);
|
||||
} else {
|
||||
printf("ADT: failed to find system-firmware-version\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
36
src/firmware.h
Normal file
36
src/firmware.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#ifndef __FIRMWARE_H__
|
||||
#define __FIRMWARE_H__
|
||||
|
||||
#include "types.h"
|
||||
|
||||
enum fw_version {
|
||||
V_UNKNOWN,
|
||||
V12_1,
|
||||
V12_2,
|
||||
V12_3,
|
||||
V12_4,
|
||||
V12_5,
|
||||
// V12_6,
|
||||
V13_0B4,
|
||||
V13_0,
|
||||
NUM_FW_VERSIONS,
|
||||
};
|
||||
|
||||
struct fw_version_info {
|
||||
enum fw_version version;
|
||||
const char *string;
|
||||
u32 num[4];
|
||||
size_t num_length;
|
||||
const char *iboot;
|
||||
};
|
||||
|
||||
extern struct fw_version_info os_firmware;
|
||||
extern struct fw_version_info system_firmware;
|
||||
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);
|
||||
|
||||
#endif
|
|
@ -12,6 +12,7 @@
|
|||
#include "display.h"
|
||||
#include "exception.h"
|
||||
#include "fb.h"
|
||||
#include "firmware.h"
|
||||
#include "gxf.h"
|
||||
#include "heapblock.h"
|
||||
#include "mcc.h"
|
||||
|
@ -140,6 +141,7 @@ void m1n1_main(void)
|
|||
printf("Running in EL%lu\n\n", mrs(CurrentEL) >> 2);
|
||||
|
||||
get_device_info();
|
||||
firmware_init();
|
||||
|
||||
heapblock_init();
|
||||
|
||||
|
|
Loading…
Reference in a new issue