Skip to content

Commit c19303d

Browse files
committed
firmware: New module to detect firmware version
Signed-off-by: Hector Martin <[email protected]>
1 parent 7782944 commit c19303d

4 files changed

Lines changed: 120 additions & 0 deletions

File tree

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ OBJECTS := \
9696
display.o \
9797
exception.o exception_asm.o \
9898
fb.o font.o font_retina.o \
99+
firmware.o \
99100
gxf.o gxf_asm.o \
100101
heapblock.o \
101102
hv.o hv_vm.o hv_exc.o hv_vuart.o hv_wdt.o hv_asm.o hv_aic.o \

src/firmware.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/* SPDX-License-Identifier: MIT */
2+
3+
#include "firmware.h"
4+
#include "adt.h"
5+
#include "string.h"
6+
#include "types.h"
7+
#include "utils.h"
8+
9+
#include "libfdt/libfdt.h"
10+
#include "libfdt/libfdt_env.h"
11+
12+
struct fw_version_info os_firmware;
13+
struct fw_version_info system_firmware;
14+
15+
const struct fw_version_info fw_versions[NUM_FW_VERSIONS] = {
16+
[V_UNKNOWN] = {V_UNKNOWN, "unknown", {0}, 1, "unknown"},
17+
[V12_1] = {V12_1, "12.1", {12, 1, 0}, 3, "iBoot-7429.61.2"},
18+
[V12_2] = {V12_2, "12.2", {12, 2, 0}, 3, "iBoot-7429.81.3"},
19+
[V12_3] = {V12_3, "12.3", {12, 3, 0}, 3, "iBoot-7459.101.2"},
20+
[V12_4] = {V12_4, "12.4", {12, 4, 0}, 3, "iBoot-7459.121.3"},
21+
[V12_5] = {V12_5, "12.5", {12, 4, 0}, 3, "iBoot-7459.141.1"},
22+
// Same as 12.5
23+
// {V12_6, "12.6", {12, 4, 0}, 3, "iBoot-7459.141.1"},
24+
[V13_0B4] = {V13_0B4, "13.0 beta4", {12, 99, 4}, 3, "iBoot-8419.0.151.0.1"},
25+
[V13_0] = {V13_0, "13.0", {13, 0, 0}, 3, "iBoot-8419.41.10"},
26+
};
27+
28+
int firmware_set_fdt(void *fdt, int node, const char *prop, const struct fw_version_info *ver)
29+
{
30+
fdt32_t data[ARRAY_SIZE(ver->num)];
31+
32+
for (size_t i = 0; i < ver->num_length; i++) {
33+
data[i] = cpu_to_fdt32(ver->num[i]);
34+
}
35+
36+
return fdt_setprop(fdt, node, prop, data, ver->num_length * sizeof(u32));
37+
}
38+
39+
static void detect_firmware(struct fw_version_info *info, const char *ver)
40+
{
41+
for (size_t i = 0; i < ARRAY_SIZE(fw_versions); i++) {
42+
if (!strcmp(fw_versions[i].iboot, ver)) {
43+
*info = fw_versions[i];
44+
return;
45+
}
46+
}
47+
48+
*info = fw_versions[V_UNKNOWN];
49+
info->iboot = ver;
50+
}
51+
52+
int firmware_init(void)
53+
{
54+
int node = adt_path_offset(adt, "/chosen");
55+
56+
if (node < 0) {
57+
printf("ADT: no /chosen found\n");
58+
return -1;
59+
}
60+
61+
u32 len;
62+
const char *p = adt_getprop(adt, node, "firmware-version", &len);
63+
if (p && len && p[len - 1] == 0) {
64+
detect_firmware(&os_firmware, p);
65+
printf("OS FW version: %s (%s)\n", os_firmware.string, os_firmware.iboot);
66+
} else {
67+
printf("ADT: failed to find firmware-version\n");
68+
return -1;
69+
}
70+
71+
p = adt_getprop(adt, node, "system-firmware-version", &len);
72+
if (p && len && p[len - 1] == 0) {
73+
detect_firmware(&system_firmware, p);
74+
printf("System FW version: %s (%s)\n", system_firmware.string, system_firmware.iboot);
75+
} else {
76+
printf("ADT: failed to find system-firmware-version\n");
77+
return -1;
78+
}
79+
80+
return 0;
81+
}

src/firmware.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/* SPDX-License-Identifier: MIT */
2+
3+
#ifndef __FIRMWARE_H__
4+
#define __FIRMWARE_H__
5+
6+
#include "types.h"
7+
8+
enum fw_version {
9+
V_UNKNOWN,
10+
V12_1,
11+
V12_2,
12+
V12_3,
13+
V12_4,
14+
V12_5,
15+
// V12_6,
16+
V13_0B4,
17+
V13_0,
18+
NUM_FW_VERSIONS,
19+
};
20+
21+
struct fw_version_info {
22+
enum fw_version version;
23+
const char *string;
24+
u32 num[4];
25+
size_t num_length;
26+
const char *iboot;
27+
};
28+
29+
extern struct fw_version_info os_firmware;
30+
extern struct fw_version_info system_firmware;
31+
extern const struct fw_version_info fw_versions[NUM_FW_VERSIONS];
32+
33+
int firmware_init(void);
34+
int firmware_set_fdt(void *fdt, int node, const char *prop, const struct fw_version_info *ver);
35+
36+
#endif

src/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "display.h"
1313
#include "exception.h"
1414
#include "fb.h"
15+
#include "firmware.h"
1516
#include "gxf.h"
1617
#include "heapblock.h"
1718
#include "mcc.h"
@@ -140,6 +141,7 @@ void m1n1_main(void)
140141
printf("Running in EL%lu\n\n", mrs(CurrentEL) >> 2);
141142

142143
get_device_info();
144+
firmware_init();
143145

144146
heapblock_init();
145147

0 commit comments

Comments
 (0)