summaryrefslogtreecommitdiffstats
path: root/utils/imxtools/sbtools/sb1.h
blob: d5ab042c950ec6b5fbab4990f88bab16c03ee5d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * Copyright (C) 2012 Amaury Pouly
 *
 * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/
#ifndef __SB1_H__
#define __SB1_H__

#include <stdint.h>
#include <stdbool.h>

#include "misc.h"

#define SECTOR_SIZE      512

/* All fields are in big-endian BCD */
struct sb1_version_t
{
    uint16_t major;
    uint16_t pad0;
    uint16_t minor;
    uint16_t pad1;
    uint16_t revision;
    uint16_t pad2;
};

struct sb1_header_t
{
    uint32_t rom_version;
    uint32_t image_size;
    uint32_t header_size;
    uint32_t userdata_offset;
    uint32_t pad2;
    uint8_t signature[4]; /* Signature "STMP" */
    struct sb1_version_t product_ver;
    struct sb1_version_t component_ver;
    uint32_t drive_tag;
} __attribute__((packed));

struct sb1_cmd_header_t
{
    uint32_t cmd; // 31:21=cmd size, 20=critical, 19:6=size 5:4=datatype, 3:0=boot cmd
    uint32_t addr;
} __attribute__((packed));

#define SB1_CMD_MAX_LOAD_SIZE   0x1ff8
#define SB1_CMD_MAX_FILL_SIZE   0x3fff

#define SB1_CMD_SIZE(cmd)       ((cmd) >> 21)
#define SB1_CMD_CRITICAL(cmd)   !!(cmd & (1 << 20))
#define SB1_CMD_BYTES(cmd)      (((cmd) >> 6) & 0x3fff)
#define SB1_CMD_DATATYPE(cmd)   (((cmd) >> 4) & 0x3)
#define SB1_CMD_BOOT(cmd)       ((cmd) & 0xf)

#define SB1_MK_CMD(boot,data,bytes,crit,size) \
    ((boot) | (data) << 4 | (bytes) << 6 | (crit) << 20 | (size) << 21)

#define SB1_ADDR_SDRAM_CS(addr) ((addr) & 0x3)
#define SB1_ADDR_SDRAM_SZ(addr) ((addr) >> 16)

#define SB1_MK_ADDR_SDRAM(cs,sz)    ((cs) | (sz) << 16)

int sb1_sdram_size_by_index(int index); // returns - 1 on error
int sb1_sdram_index_by_size(int size); // returns -1 on error

#define SB1_INST_LOAD   0x1
#define SB1_INST_FILL   0x2
#define SB1_INST_JUMP   0x3
#define SB1_INST_CALL   0x4
#define SB1_INST_MODE   0x5
#define SB1_INST_SDRAM  0x6

#define SB1_DATATYPE_UINT32 0
#define SB1_DATATYPE_UINT16 1
#define SB1_DATATYPE_UINT8  2

/*******
 * API *
 *******/

struct sb1_inst_t
{
    uint8_t cmd;
    uint16_t size;
    // <union>
    struct
    {
        uint8_t chip_select;
        uint8_t size_index;
    }sdram;
    uint8_t mode;
    uint32_t addr;
    // </union>
    uint8_t datatype;
    uint8_t critical;
    // <union>
    void *data;
    uint32_t pattern;
    uint32_t argument;
    // </union>
};

struct sb1_file_t
{
    uint32_t rom_version;
    uint32_t pad2; // unknown meaning but copy it anyway !
    uint32_t drive_tag;
    struct sb1_version_t product_ver;
    struct sb1_version_t component_ver;
    int nr_insts;
    struct sb1_inst_t *insts;
    void *userdata;
    int userdata_size;
    struct crypto_key_t key;
};

enum sb1_error_t
{
    SB1_SUCCESS = 0,
    SB1_ERROR = -1,
    SB1_OPEN_ERROR = -2,
    SB1_READ_ERROR = -3,
    SB1_WRITE_ERROR = -4,
    SB1_FORMAT_ERROR = -5,
    SB1_CHECKSUM_ERROR = -6,
    SB1_NO_VALID_KEY = -7,
    SB1_FIRST_CRYPTO_ERROR = -8,
    SB1_LAST_CRYPTO_ERROR = SB1_FIRST_CRYPTO_ERROR - CRYPTO_NUM_ERRORS,
};

enum sb1_error_t sb1_write_file(struct sb1_file_t *sb, const char *filename);

typedef void (*sb1_color_printf)(void *u, bool err, color_t c, const char *f, ...);
struct sb1_file_t *sb1_read_file(const char *filename, void *u,
    sb1_color_printf printf, enum sb1_error_t *err);
/* use size_t(-1) to use maximum size */
struct sb1_file_t *sb1_read_file_ex(const char *filename, size_t offset, size_t size,
    void *u, sb1_color_printf printf, enum sb1_error_t *err);
struct sb1_file_t *sb1_read_memory(void *buffer, size_t size, void *u,
    sb1_color_printf printf, enum sb1_error_t *err);

/* do as little checks as possible, make sure the image is valid (advance use only).
 * Buffer should be of size SECTOR_SIZE at least. */
bool sb1_is_key_valid_fast(void *buffer, union xorcrypt_key_t key[2]);
bool sb1_brute_force(const char *filename, void *u, sb1_color_printf printf,
    enum sb1_error_t *err, struct crypto_key_t *key);

void sb1_get_default_key(struct crypto_key_t *key);

void sb1_dump(struct sb1_file_t *file, void *u, sb1_color_printf printf);
void sb1_free(struct sb1_file_t *file);

#endif /* __SB1_H__ */