Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bootloader/frontend/fe_info.c
1471 views
1
/*
2
* Copyright (c) 2018 naehrwert
3
* Copyright (c) 2018-2022 CTCaer
4
*
5
* This program is free software; you can redistribute it and/or modify it
6
* under the terms and conditions of the GNU General Public License,
7
* version 2, as published by the Free Software Foundation.
8
*
9
* This program is distributed in the hope it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
* more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
*/
17
18
#include <string.h>
19
20
#include <bdk.h>
21
22
#include "fe_info.h"
23
#include "../config.h"
24
#include "../hos/hos.h"
25
#include "../hos/pkg1.h"
26
#include <libs/fatfs/ff.h>
27
28
extern hekate_config h_cfg;
29
30
#pragma GCC push_options
31
#pragma GCC optimize ("Os")
32
33
void print_fuseinfo()
34
{
35
u32 fuse_size = h_cfg.t210b01 ? 0x368 : 0x300;
36
u32 fuse_address = h_cfg.t210b01 ? 0x7000F898 : 0x7000F900;
37
38
gfx_clear_partial_grey(0x1B, 0, 1256);
39
gfx_con_setpos(0, 0);
40
41
gfx_printf("\nSKU: %X - ", FUSE(FUSE_SKU_INFO));
42
switch (fuse_read_hw_state())
43
{
44
case FUSE_NX_HW_STATE_PROD:
45
gfx_printf("Retail\n");
46
break;
47
case FUSE_NX_HW_STATE_DEV:
48
gfx_printf("Dev\n");
49
break;
50
}
51
gfx_printf("Sdram ID: %d\n", fuse_read_dramid(true));
52
gfx_printf("Burnt fuses: %d / 64\n", bit_count(fuse_read_odm(7)));
53
gfx_printf("Secure key: %08X%08X%08X%08X\n\n\n",
54
byte_swap_32(FUSE(FUSE_PRIVATE_KEY0)), byte_swap_32(FUSE(FUSE_PRIVATE_KEY1)),
55
byte_swap_32(FUSE(FUSE_PRIVATE_KEY2)), byte_swap_32(FUSE(FUSE_PRIVATE_KEY3)));
56
57
gfx_printf("%kFuse cache:\n\n%k", TXT_CLR_CYAN_L, TXT_CLR_DEFAULT);
58
gfx_hexdump(fuse_address, (u8 *)fuse_address, fuse_size);
59
60
btn_wait();
61
}
62
63
void print_mmc_info()
64
{
65
gfx_clear_partial_grey(0x1B, 0, 1256);
66
gfx_con_setpos(0, 0);
67
68
static const u32 SECTORS_TO_MIB_COEFF = 11;
69
70
if (!emmc_initialize(false))
71
{
72
EPRINTF("Failed to init eMMC.");
73
goto out;
74
}
75
else
76
{
77
u16 card_type;
78
u32 speed = 0;
79
80
gfx_printf("%kCID:%k\n", TXT_CLR_CYAN_L, TXT_CLR_DEFAULT);
81
switch (emmc_storage.csd.mmca_vsn)
82
{
83
case 2: /* MMC v2.0 - v2.2 */
84
case 3: /* MMC v3.1 - v3.3 */
85
case 4: /* MMC v4 */
86
gfx_printf(
87
" Vendor ID: %X\n"
88
" OEM ID: %02X\n"
89
" Model: %c%c%c%c%c%c\n"
90
" Prd Rev: %X\n"
91
" S/N: %04X\n"
92
" Month/Year: %02d/%04d\n\n",
93
emmc_storage.cid.manfid, emmc_storage.cid.oemid,
94
emmc_storage.cid.prod_name[0], emmc_storage.cid.prod_name[1], emmc_storage.cid.prod_name[2],
95
emmc_storage.cid.prod_name[3], emmc_storage.cid.prod_name[4], emmc_storage.cid.prod_name[5],
96
emmc_storage.cid.prv, emmc_storage.cid.serial, emmc_storage.cid.month, emmc_storage.cid.year);
97
break;
98
default:
99
break;
100
}
101
102
if (emmc_storage.csd.structure == 0)
103
EPRINTF("Unknown CSD structure.");
104
else
105
{
106
gfx_printf("%kExtended CSD V1.%d:%k\n",
107
TXT_CLR_CYAN_L, emmc_storage.ext_csd.ext_struct, TXT_CLR_DEFAULT);
108
card_type = emmc_storage.ext_csd.card_type;
109
char card_type_support[96];
110
card_type_support[0] = 0;
111
if (card_type & EXT_CSD_CARD_TYPE_HS_26)
112
{
113
strcat(card_type_support, "HS26");
114
speed = (26 << 16) | 26;
115
}
116
if (card_type & EXT_CSD_CARD_TYPE_HS_52)
117
{
118
strcat(card_type_support, ", HS52");
119
speed = (52 << 16) | 52;
120
}
121
if (card_type & EXT_CSD_CARD_TYPE_DDR_1_8V)
122
{
123
strcat(card_type_support, ", DDR52_1.8V");
124
speed = (52 << 16) | 104;
125
}
126
if (card_type & EXT_CSD_CARD_TYPE_HS200_1_8V)
127
{
128
strcat(card_type_support, ", HS200_1.8V");
129
speed = (200 << 16) | 200;
130
}
131
if (card_type & EXT_CSD_CARD_TYPE_HS400_1_8V)
132
{
133
strcat(card_type_support, ", HS400_1.8V");
134
speed = (200 << 16) | 400;
135
}
136
137
gfx_printf(
138
" Spec Version: %02X\n"
139
" Extended Rev: 1.%d\n"
140
" Dev Version: %d\n"
141
" Cmd Classes: %02X\n"
142
" Capacity: %s\n"
143
" Max Rate: %d MB/s (%d MHz)\n"
144
" Current Rate: %d MB/s\n"
145
" Type Support: ",
146
emmc_storage.csd.mmca_vsn, emmc_storage.ext_csd.rev, emmc_storage.ext_csd.dev_version, emmc_storage.csd.cmdclass,
147
emmc_storage.csd.capacity == (4096 * EMMC_BLOCKSIZE) ? "High" : "Low", speed & 0xFFFF, (speed >> 16) & 0xFFFF,
148
emmc_storage.csd.busspeed);
149
gfx_con.fntsz = 8;
150
gfx_printf("%s", card_type_support);
151
gfx_con.fntsz = 16;
152
gfx_printf("\n\n", card_type_support);
153
154
u32 boot_size = emmc_storage.ext_csd.boot_mult << 17;
155
u32 rpmb_size = emmc_storage.ext_csd.rpmb_mult << 17;
156
gfx_printf("%keMMC Partitions:%k\n", TXT_CLR_CYAN_L, TXT_CLR_DEFAULT);
157
gfx_printf(" 1: %kBOOT0 %k\n Size: %5d KiB (LBA Sectors: 0x%07X)\n", TXT_CLR_GREENISH, TXT_CLR_DEFAULT,
158
boot_size / 1024, boot_size / EMMC_BLOCKSIZE);
159
gfx_put_small_sep();
160
gfx_printf(" 2: %kBOOT1 %k\n Size: %5d KiB (LBA Sectors: 0x%07X)\n", TXT_CLR_GREENISH, TXT_CLR_DEFAULT,
161
boot_size / 1024, boot_size / EMMC_BLOCKSIZE);
162
gfx_put_small_sep();
163
gfx_printf(" 3: %kRPMB %k\n Size: %5d KiB (LBA Sectors: 0x%07X)\n", TXT_CLR_GREENISH, TXT_CLR_DEFAULT,
164
rpmb_size / 1024, rpmb_size / EMMC_BLOCKSIZE);
165
gfx_put_small_sep();
166
gfx_printf(" 0: %kGPP (USER) %k\n Size: %5d MiB (LBA Sectors: 0x%07X)\n\n", TXT_CLR_GREENISH, TXT_CLR_DEFAULT,
167
emmc_storage.sec_cnt >> SECTORS_TO_MIB_COEFF, emmc_storage.sec_cnt);
168
gfx_put_small_sep();
169
gfx_printf("%kGPP (eMMC USER) partition table:%k\n", TXT_CLR_CYAN_L, TXT_CLR_DEFAULT);
170
171
emmc_set_partition(EMMC_GPP);
172
LIST_INIT(gpt);
173
emmc_gpt_parse(&gpt);
174
int gpp_idx = 0;
175
LIST_FOREACH_ENTRY(emmc_part_t, part, &gpt, link)
176
{
177
gfx_printf(" %02d: %k%s%k\n Size: % 5d MiB (LBA Sectors 0x%07X)\n LBA Range: %08X-%08X\n",
178
gpp_idx++, TXT_CLR_GREENISH, part->name, TXT_CLR_DEFAULT, (part->lba_end - part->lba_start + 1) >> SECTORS_TO_MIB_COEFF,
179
part->lba_end - part->lba_start + 1, part->lba_start, part->lba_end);
180
gfx_put_small_sep();
181
}
182
emmc_gpt_free(&gpt);
183
}
184
}
185
186
out:
187
emmc_end();
188
189
btn_wait();
190
}
191
192
void print_sdcard_info()
193
{
194
static const u32 SECTORS_TO_MIB_COEFF = 11;
195
196
gfx_clear_partial_grey(0x1B, 0, 1256);
197
gfx_con_setpos(0, 0);
198
199
if (sd_initialize(false))
200
{
201
gfx_printf("%kCard IDentification:%k\n", TXT_CLR_CYAN_L, TXT_CLR_DEFAULT);
202
gfx_printf(
203
" Vendor ID: %02x\n"
204
" OEM ID: %c%c\n"
205
" Model: %c%c%c%c%c\n"
206
" HW rev: %X\n"
207
" FW rev: %X\n"
208
" S/N: %08x\n"
209
" Month/Year: %02d/%04d\n\n",
210
sd_storage.cid.manfid, (sd_storage.cid.oemid >> 8) & 0xFF, sd_storage.cid.oemid & 0xFF,
211
sd_storage.cid.prod_name[0], sd_storage.cid.prod_name[1], sd_storage.cid.prod_name[2],
212
sd_storage.cid.prod_name[3], sd_storage.cid.prod_name[4],
213
sd_storage.cid.hwrev, sd_storage.cid.fwrev, sd_storage.cid.serial,
214
sd_storage.cid.month, sd_storage.cid.year);
215
216
u16 *sd_errors = sd_get_error_count();
217
gfx_printf("%kCard-Specific Data V%d.0:%k\n", TXT_CLR_CYAN_L, sd_storage.csd.structure + 1, TXT_CLR_DEFAULT);
218
gfx_printf(
219
" Cmd Classes: %02X\n"
220
" Capacity: %d MiB\n"
221
" Bus Width: %d\n"
222
" Current Rate: %d MB/s (%d MHz)\n"
223
" Speed Class: %d\n"
224
" UHS Grade: U%d\n"
225
" Video Class: V%d\n"
226
" App perf class: A%d\n"
227
" Write Protect: %d\n"
228
" SDMMC Errors: %d %d %d\n\n",
229
sd_storage.csd.cmdclass, sd_storage.sec_cnt >> 11,
230
sd_storage.ssr.bus_width, sd_storage.csd.busspeed, sd_storage.csd.busspeed * 2,
231
sd_storage.ssr.speed_class, sd_storage.ssr.uhs_grade, sd_storage.ssr.video_class,
232
sd_storage.ssr.app_class, sd_storage.csd.write_protect,
233
sd_errors[0], sd_errors[1], sd_errors[2]); // SD_ERROR_INIT_FAIL, SD_ERROR_RW_FAIL, SD_ERROR_RW_RETRY.
234
235
int res = f_mount(&sd_fs, "", 1);
236
if (!res)
237
{
238
gfx_puts("Acquiring FAT volume info...\n\n");
239
f_getfree("", &sd_fs.free_clst, NULL);
240
gfx_printf("%kFound %s volume:%k\n Free: %d MiB\n Cluster: %d KiB\n",
241
TXT_CLR_CYAN_L, sd_fs.fs_type == FS_EXFAT ? "exFAT" : "FAT32", TXT_CLR_DEFAULT,
242
sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF, (sd_fs.csize > 1) ? (sd_fs.csize >> 1) : 512);
243
f_mount(NULL, "", 1);
244
}
245
else
246
{
247
EPRINTFARGS("Failed to mount SD card (FatFS Error %d).\n"
248
"Make sure that a FAT partition exists..", res);
249
}
250
251
sd_end();
252
}
253
else
254
{
255
EPRINTF("Failed to init SD card.");
256
if (!sdmmc_get_sd_inserted())
257
EPRINTF("Make sure that it is inserted.");
258
else
259
EPRINTF("SD Card Reader is not properly seated!");
260
sd_end();
261
}
262
263
btn_wait();
264
}
265
266
void print_fuel_gauge_info()
267
{
268
int value = 0;
269
270
gfx_printf("%kFuel Gauge Info:\n%k", TXT_CLR_CYAN_L, TXT_CLR_DEFAULT);
271
272
max17050_get_property(MAX17050_RepSOC, &value);
273
gfx_printf("Capacity now: %3d%\n", value >> 8);
274
275
max17050_get_property(MAX17050_RepCap, &value);
276
gfx_printf("Capacity now: %4d mAh\n", value);
277
278
max17050_get_property(MAX17050_FullCAP, &value);
279
gfx_printf("Capacity full: %4d mAh\n", value);
280
281
max17050_get_property(MAX17050_DesignCap, &value);
282
gfx_printf("Capacity (design): %4d mAh\n", value);
283
284
max17050_get_property(MAX17050_Current, &value);
285
gfx_printf("Current now: %d mA\n", value / 1000);
286
287
max17050_get_property(MAX17050_AvgCurrent, &value);
288
gfx_printf("Current average: %d mA\n", value / 1000);
289
290
max17050_get_property(MAX17050_VCELL, &value);
291
gfx_printf("Voltage now: %4d mV\n", value);
292
293
max17050_get_property(MAX17050_OCVInternal, &value);
294
gfx_printf("Voltage open-circuit: %4d mV\n", value);
295
296
max17050_get_property(MAX17050_MinVolt, &value);
297
gfx_printf("Min voltage reached: %4d mV\n", value);
298
299
max17050_get_property(MAX17050_MaxVolt, &value);
300
gfx_printf("Max voltage reached: %4d mV\n", value);
301
302
max17050_get_property(MAX17050_V_empty, &value);
303
gfx_printf("Empty voltage (design): %4d mV\n", value);
304
305
max17050_get_property(MAX17050_TEMP, &value);
306
gfx_printf("Battery temperature: %d.%d oC\n", value / 10,
307
(value >= 0 ? value : (~value)) % 10);
308
}
309
310
void print_battery_charger_info()
311
{
312
int value = 0;
313
314
gfx_printf("%k\n\nBattery Charger Info:\n%k", TXT_CLR_CYAN_L, TXT_CLR_DEFAULT);
315
316
bq24193_get_property(BQ24193_InputCurrentLimit, &value);
317
gfx_printf("Input current limit: %4d mA\n", value);
318
319
bq24193_get_property(BQ24193_SystemMinimumVoltage, &value);
320
gfx_printf("System voltage limit: %4d mV\n", value);
321
322
bq24193_get_property(BQ24193_FastChargeCurrentLimit, &value);
323
gfx_printf("Charge current limit: %4d mA\n", value);
324
325
bq24193_get_property(BQ24193_ChargeVoltageLimit, &value);
326
gfx_printf("Charge voltage limit: %4d mV\n", value);
327
328
bq24193_get_property(BQ24193_ChargeStatus, &value);
329
gfx_printf("Charge status: ");
330
switch (value)
331
{
332
case 0:
333
gfx_printf("Not charging\n");
334
break;
335
case 1:
336
gfx_printf("Pre-charging\n");
337
break;
338
case 2:
339
gfx_printf("Fast charging\n");
340
break;
341
case 3:
342
gfx_printf("Charge terminated\n");
343
break;
344
default:
345
gfx_printf("Unknown (%d)\n", value);
346
break;
347
}
348
bq24193_get_property(BQ24193_TempStatus, &value);
349
gfx_printf("Temperature status: ");
350
switch (value)
351
{
352
case 0:
353
gfx_printf("Normal\n");
354
break;
355
case 2:
356
gfx_printf("Warm\n");
357
break;
358
case 3:
359
gfx_printf("Cool\n");
360
break;
361
case 5:
362
gfx_printf("Cold\n");
363
break;
364
case 6:
365
gfx_printf("Hot\n");
366
break;
367
default:
368
gfx_printf("Unknown (%d)\n", value);
369
break;
370
}
371
}
372
373
void print_battery_info()
374
{
375
gfx_clear_partial_grey(0x1B, 0, 1256);
376
gfx_con_setpos(0, 0);
377
378
print_fuel_gauge_info();
379
380
print_battery_charger_info();
381
382
u8 *buf = (u8 *)malloc(0x100 * 2);
383
384
gfx_printf("%k\n\nBattery Fuel Gauge Registers:\n%k", TXT_CLR_CYAN_L, TXT_CLR_DEFAULT);
385
386
for (int i = 0; i < 0x200; i += 2)
387
{
388
i2c_recv_buf_small(buf + i, 2, I2C_1, MAXIM17050_I2C_ADDR, i >> 1);
389
usleep(2500);
390
}
391
392
gfx_hexdump(0, (u8 *)buf, 0x200);
393
394
btn_wait();
395
}
396
397
#pragma GCC pop_options
398
399