sunxi-tools/bootinfo.c
Bernhard Nortmann 4564e7822b Fix some issues that showed up as compiler warnings with mingw64
Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de>
2016-10-26 21:37:29 +02:00

385 lines
12 KiB
C

/*
* (C) Copyright 2012 Henrik Nordstrom <henrik@henriknordstrom.net>
*
* display information about sunxi boot headers
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "common.h"
#include "types.h"
/* boot_file_head copied from mksunxiboot */
/* boot head definition from sun4i boot code */
typedef struct boot_file_head
{
u32 jump_instruction; // one intruction jumping to real code
u8 magic[8]; // ="eGON.BT0" or "eGON.BT1", not C-style string.
u32 check_sum; // generated by PC
u32 length; // generated by PC
u32 pub_head_size; // the size of boot_file_head_t
u8 pub_head_vsn[4]; // the version of boot_file_head_t
u8 file_head_vsn[4]; // the version of boot0_file_head_t or boot1_file_head_t
u8 Boot_vsn[4]; // Boot version
u8 eGON_vsn[4]; // eGON version
u8 platform[8]; // platform information
} boot_file_head_t;
typedef struct brom_file_head
{
u32 jump_instruction; // one intruction jumping to real code
u8 magic[8]; // ="eGON.BRM", not C-style string.
u32 length; // generated by PC
u8 Boot_vsn[4]; // Boot version
u8 eGON_vsn[4]; // eGON version
u8 platform[8]; // platform information
} brom_file_head_t;
typedef struct _boot_dram_para_t {
__u32 dram_baseaddr;
__u32 dram_clk;
__u32 dram_type;
__u32 dram_rank_num;
__u32 dram_chip_density;
__u32 dram_io_width;
__u32 dram_bus_width;
__u32 dram_cas;
__u32 dram_zq;
__u32 dram_odt_en;
__u32 dram_size;
__u32 dram_tpr0;
__u32 dram_tpr1;
__u32 dram_tpr2;
__u32 dram_tpr3;
__u32 dram_tpr4;
__u32 dram_tpr5;
__u32 dram_emr1;
__u32 dram_emr2;
__u32 dram_emr3;
} boot_dram_para_t;
typedef struct _normal_gpio_cfg {
__u8 port;
__u8 port_num;
__u8 mul_sel;
__u8 pull;
__u8 drv_level;
__u8 data;
__u8 reserved[2];
} normal_gpio_cfg;
typedef struct _boot0_private_head_t {
__u32 prvt_head_size;
char prvt_head_vsn[4];
boot_dram_para_t dram_para;
__s32 uart_port;
normal_gpio_cfg uart_ctrl[2];
__s32 enable_jtag;
normal_gpio_cfg jtag_gpio[5];
normal_gpio_cfg storage_gpio[32];
__u8 storage_data[256];
} boot0_private_head_t;
typedef struct _boot0_file_head_t {
boot_file_head_t boot_head;
boot0_private_head_t prvt_head;
} boot0_file_head_t;
typedef struct _boot_core_para_t {
__u32 user_set_clock;
__u32 user_set_core_vol;
__u32 vol_threshold;
} boot_core_para_t;
typedef struct _boot1_private_head_t {
__u32 prvt_head_size;
__u8 prvt_head_vsn[4];
__s32 uart_port;
normal_gpio_cfg uart_ctrl[2];
boot_dram_para_t dram_para;
char script_buf[32768];
boot_core_para_t core_para;
__s32 twi_port;
normal_gpio_cfg twi_ctrl[2];
__s32 debug_enable;
__s32 hold_key_min;
__s32 hold_key_max;
__u32 work_mode;
__u32 storage_type;
normal_gpio_cfg storage_gpio[32];
__u8 storage_data[256];
} boot1_private_head_t;
typedef struct _boot1_file_head_t {
boot_file_head_t boot_head;
boot1_private_head_t prvt_head;
} boot1_file_head_t;
/* STORAGE DATA on SD loaders */
typedef struct _boot_sdcard_info_t {
__s32 card_ctrl_num;
__s32 boot_offset;
__s32 card_no[4];
__s32 speed_mode[4];
__s32 line_sel[4];
__s32 line_count[4];
} boot_sdcard_info_t;
#define BROM_MAGIC "eGON.BRM"
#define BOOT0_MAGIC "eGON.BT0"
#define BOOT1_MAGIC "eGON.BT1"
union {
boot_file_head_t boot;
boot0_file_head_t boot0;
boot1_file_head_t boot1;
brom_file_head_t brom;
} boot_hdr;
typedef enum {
ALLWINNER_UNKNOWN_LOADER=0,
ALLWINNER_SD_LOADER,
ALLWINNER_NAND_LOADER
} loader_type;
void fail(char *msg) {
perror(msg);
exit(1);
}
void pprintf(void *addr, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
printf("%8x:\t", (unsigned)((char *)addr - (char *)&boot_hdr));
vprintf(fmt, ap);
va_end(ap);
}
void print_brom_file_head(brom_file_head_t *hdr)
{
pprintf(&hdr->magic, "Magic : %.8s\n", hdr->magic);
pprintf(&hdr->length, "Length : %u\n", hdr->length);
pprintf(&hdr->Boot_vsn, "BOOT ver : %.4s\n", hdr->Boot_vsn);
pprintf(&hdr->eGON_vsn, "eGON ver : %.4s\n", hdr->eGON_vsn);
pprintf(&hdr->platform, "Chip? : %.8s\n", hdr->platform);
}
void print_boot_file_head(boot_file_head_t *hdr)
{
pprintf(&hdr->magic, "Magic : %.8s\n", hdr->magic);
pprintf(&hdr->length, "Length : %u\n", hdr->length);
pprintf(&hdr->pub_head_size, "HSize : %u\n", hdr->pub_head_size);
pprintf(&hdr->pub_head_vsn, "HEAD ver : %.4s\n", hdr->pub_head_vsn);
pprintf(&hdr->file_head_vsn, "FILE ver : %.4s\n", hdr->file_head_vsn);
pprintf(&hdr->Boot_vsn, "BOOT ver : %.4s\n", hdr->Boot_vsn);
pprintf(&hdr->eGON_vsn, "eGON ver : %.4s\n", hdr->eGON_vsn);
pprintf(&hdr->platform, "platform : %c%c%c%c%c%c%c%c\n", hdr->platform[0], hdr->platform[1], hdr->platform[2], hdr->platform[3], hdr->platform[4], hdr->platform[5], hdr->platform[6], hdr->platform[7]);
}
void print_boot_dram_para(boot_dram_para_t *dram)
{
pprintf(&dram->dram_baseaddr, "DRAM base : %p\n", (void *)(uintptr_t)dram->dram_baseaddr);
pprintf(&dram->dram_clk, "DRAM clk : %d\n", dram->dram_clk);
pprintf(&dram->dram_type, "DRAM type : %d\n", dram->dram_type);
pprintf(&dram->dram_rank_num, "DRAM rank : %d\n", dram->dram_rank_num);
pprintf(&dram->dram_chip_density,"DRAM den : %d\n", dram->dram_chip_density);
pprintf(&dram->dram_io_width, "DRAM iow : %d\n", dram->dram_io_width);
pprintf(&dram->dram_bus_width, "DRAM busw : %d\n", dram->dram_bus_width);
pprintf(&dram->dram_cas, "DRAM cas : %d\n", dram->dram_cas);
pprintf(&dram->dram_zq, "DRAM zq : %d\n", dram->dram_zq);
pprintf(&dram->dram_odt_en, "DRAM odt : 0x%x\n", dram->dram_odt_en);
pprintf(&dram->dram_size, "DRAM size : %d\n", dram->dram_size);
pprintf(&dram->dram_tpr0, "DRAM tpr0 : 0x%x\n", dram->dram_tpr0);
pprintf(&dram->dram_tpr1, "DRAM tpr1 : 0x%x\n", dram->dram_tpr1);
pprintf(&dram->dram_tpr2, "DRAM tpr2 : 0x%x\n", dram->dram_tpr2);
pprintf(&dram->dram_tpr3, "DRAM tpr3 : 0x%x\n", dram->dram_tpr3);
pprintf(&dram->dram_tpr4, "DRAM tpr4 : 0x%x\n", dram->dram_tpr4);
pprintf(&dram->dram_tpr5, "DRAM tpr5 : 0x%x\n", dram->dram_tpr5);
pprintf(&dram->dram_emr1, "DRAM emr1 : 0x%x\n", dram->dram_emr1);
pprintf(&dram->dram_emr2, "DRAM emr2 : 0x%x\n", dram->dram_emr2);
pprintf(&dram->dram_emr3, "DRAM emr3 : 0x%x\n", dram->dram_emr3);
}
void print_normal_gpio_cfg(normal_gpio_cfg *gpio, int count)
{
int i;
for (i = 0; i < count; i++) {
if (gpio[i].port)
pprintf(&gpio[i], " GPIO %d : port=%c%d, sel=%d, pull=%d, drv=%d, data=%d, reserved=%02x,%02x\n", i, 'A'+gpio[i].port-1, gpio[i].port_num, gpio[i].mul_sel, gpio[i].pull, gpio[i].drv_level, gpio[i].data, gpio[i].reserved[0], gpio[i].reserved[1]);
}
}
void print_boot_sdcard_info(boot_sdcard_info_t *info)
{
pprintf(&info->card_ctrl_num, " CARD Ctrl Num: %d\n", info->card_ctrl_num);
pprintf(&info->boot_offset, " BOOT Offset: %08x\n", info->boot_offset);
for (int i = 0; i < 4; i++) {
if (info->card_no[i] == -1)
continue;
pprintf(&info->card_no[i], " CARD No : %d (%d)\n", info->card_no[i], i);
pprintf(&info->speed_mode[i], " Speed : %d\n", info->speed_mode[i]);
pprintf(&info->line_sel[i], " Line sel: %d\n", info->line_sel[i]);
pprintf(&info->line_count[i], " Line cnt: %d\n", info->line_count[i]);
}
}
void print_boot0_private_head(boot0_private_head_t *hdr, loader_type type)
{
pprintf(&hdr->prvt_head_size, "FHSize : %u\n", hdr->prvt_head_size);
pprintf(&hdr->prvt_head_vsn, "FILE ver : %.4s\n", hdr->prvt_head_vsn);
print_boot_dram_para(&hdr->dram_para);
pprintf(&hdr->uart_port, "UART port : %d\n", hdr->uart_port);
print_normal_gpio_cfg(hdr->uart_ctrl, 2);
pprintf(&hdr->enable_jtag, "JTAG en : %d\n", hdr->enable_jtag);
print_normal_gpio_cfg(hdr->jtag_gpio, 5);
pprintf(&hdr->storage_gpio, "STORAGE :\n");
print_normal_gpio_cfg(hdr->storage_gpio, 32);
int i = 0;
if (type == ALLWINNER_SD_LOADER) {
print_boot_sdcard_info((boot_sdcard_info_t *)hdr->storage_data);
i = sizeof(boot_sdcard_info_t);
}
for (int n = 0; i < 256; i++, n++) {
if (n % 16 == 0) {
if (n) {
printf("\n");
}
pprintf(&hdr->storage_data[i], " DATA %02x :", i);
}
printf(" %02x", hdr->storage_data[i]);
}
printf("\n");
}
void print_script(void *UNUSED(script))
{
}
void print_core_para(boot_core_para_t *core)
{
pprintf(&core->user_set_clock, "Set Clock : %d\n", core->user_set_clock);
pprintf(&core->user_set_core_vol, "Set Core Vol: %d\n", core->user_set_core_vol);
pprintf(&core->vol_threshold, "Vol Threshold: %d\n", core->vol_threshold);
}
void print_boot1_private_head(boot1_private_head_t *hdr, loader_type type)
{
pprintf(&hdr->prvt_head_size, "FHSize : %u\n", hdr->prvt_head_size);
pprintf(&hdr->prvt_head_vsn, "FILE ver : %.4s\n", hdr->prvt_head_vsn);
pprintf(&hdr->uart_port, "UART port : %d\n", hdr->uart_port);
print_normal_gpio_cfg(hdr->uart_ctrl, 2);
print_boot_dram_para(&hdr->dram_para);
print_script(&hdr->script_buf);
print_core_para(&hdr->core_para);
pprintf(&hdr->twi_port, "TWI port : %d\n", hdr->twi_port);
print_normal_gpio_cfg(hdr->twi_ctrl, 2);
pprintf(&hdr->debug_enable, "Debug : %d\n", hdr->debug_enable);
pprintf(&hdr->hold_key_min, "Hold key min : %d\n", hdr->hold_key_min);
pprintf(&hdr->hold_key_max, "Hold key max : %d\n", hdr->hold_key_max);
pprintf(&hdr->work_mode, "Work mode : %d\n", hdr->work_mode);
pprintf(&hdr->storage_type, "STORAGE :\n");
pprintf(&hdr->storage_type, " type : %d\n", hdr->storage_type);
print_normal_gpio_cfg(hdr->storage_gpio, 32);
int i = 0;
if (type == ALLWINNER_SD_LOADER) {
print_boot_sdcard_info((boot_sdcard_info_t *)hdr->storage_data);
i = sizeof(boot_sdcard_info_t);
}
for (int n = 0; i < 256; i++, n++) {
if (n % 16 == 0) {
if (n) {
printf("\n");
}
pprintf(&hdr->storage_data[i], " DATA %02x :", i);
}
printf(" %02x", hdr->storage_data[i]);
}
printf("\n");
}
void print_boot0_file_head(boot0_file_head_t *hdr, loader_type type)
{
print_boot_file_head(&hdr->boot_head);
if (strncmp((char *)hdr->boot_head.file_head_vsn, "1230", 4) == 0)
print_boot0_private_head(&hdr->prvt_head, type);
else
printf("Unknown boot0 header version\n");
}
void print_boot1_file_head(boot1_file_head_t *hdr, loader_type type)
{
print_boot_file_head(&hdr->boot_head);
if (strncmp((char *)hdr->boot_head.file_head_vsn, "1230", 4) == 0)
print_boot1_private_head(&hdr->prvt_head, type);
else
printf("Unknown boot0 header version\n");
}
static void usage(const char *cmd)
{
puts("sunxi-bootinfo " VERSION "\n");
printf("Usage: %s [<filename>]\n", cmd);
printf(" With no <filename> given, will read from stdin instead\n");
}
int main(int argc, char * argv[])
{
FILE *in = stdin;
loader_type type = ALLWINNER_UNKNOWN_LOADER;
if (argc > 1 && strcmp(argv[1], "--type=sd") == 0) {
type = ALLWINNER_SD_LOADER;
argc--;
argv++;
}
if (argc > 1 && strcmp(argv[1], "--type=nand") == 0) {
type = ALLWINNER_NAND_LOADER;
argc--;
argv++;
}
if (argc > 1) {
in = fopen(argv[1], "rb");
if (!in) {
if (*argv[1] == '-')
usage(argv[0]);
fail("open input");
}
}
int len;
len = fread(&boot_hdr, 1, sizeof(boot_hdr), in);
if (len < (int)sizeof(boot_file_head_t))
fail("Failed to read header:");
if (strncmp((char *)boot_hdr.boot.magic, BOOT0_MAGIC, strlen(BOOT0_MAGIC)) == 0) {
print_boot0_file_head(&boot_hdr.boot0, type);
} else if (strncmp((char *)boot_hdr.boot.magic, BOOT1_MAGIC, strlen(BOOT1_MAGIC)) == 0) {
print_boot1_file_head(&boot_hdr.boot1, type);
} else if (strncmp((char *)boot_hdr.boot.magic, BROM_MAGIC, strlen(BROM_MAGIC)) == 0) {
print_brom_file_head(&boot_hdr.brom);
} else {
fail("Invalid magic\n");
}
return 0;
}