-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpalawan_bl.h
204 lines (183 loc) · 4.91 KB
/
palawan_bl.h
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#ifndef __PALAWAN_B_H__
#define __PALAWAN_B_H__
#define PACKED __attribute__((packed))
// This describes the structure that allows the OS to communicate
// with the bootloader. It keeps track of how many times we've
// tried booting, as well as a magic value that tells us to enter
// the bootloader instead of booting the app.
// It also keeps track of the board model.
struct boot_token
{
uint32_t magic;
uint8_t boot_count;
uint8_t board_model;
uint16_t reserved;
} PACKED;
__attribute__((section("boot_token"))) extern struct boot_token boot_token;
struct reboot_pkt
{
uint8_t reboot_key[7]; // Must be 0x91 0x82 0x73 0x64 0xad 0xef 0xba
} PACKED;
struct raw_pkt
{
uint8_t data[7];
} PACKED;
struct info_pkt
{
uint8_t result; // Result error code
uint16_t block_size; // Block size (in bits, e.g. a size of '1024' results in '10')
uint8_t bl_enter_reason; // The reason we entered the bootloader
uint8_t bl_version; // Version of the bootloader
uint16_t app_offset; // The offset of the application (in blocks)
} PACKED;
struct erase_sector_pkt
{
uint8_t reserved;
uint16_t count; // Number of sectors to erase
uint32_t offset; // First sector to erase
} PACKED;
struct start_programming_pkt
{
uint8_t reserved;
uint16_t count; // Number of bytes to program
uint32_t offset; // Offset where program will start
} PACKED;
struct program_pkt
{
uint8_t data[7]; // Bytes to program
} PACKED;
struct hash_pkt
{
uint8_t reserved;
uint16_t size; // Number of bytes to hash
uint32_t offset; // Address to start hashing from
} PACKED;
struct read_write_pkt
{
uint8_t type; // xRPPooSS
// SS: Size of operation
// 00 - 8-bit
// 01 - 16-bit
// 10 - 32-bit
// 11 - Dummy operation -- No read/write/increment is done, but address is set
#define PEEK_POKE_SIZE_MASK (3 << 0)
#define PEEK_POKE_SIZE_8 (0 << 0)
#define PEEK_POKE_SIZE_16 (1 << 0)
#define PEEK_POKE_SIZE_32 (2 << 0)
#define PEEK_POKE_SIZE_DUMMY (3 << 0)
// oo: Operation
#define PEEK_POKE_OP_MASK (3 << 2)
#define PEEK_POKE_OP_NONE (0 << 2)
#define PEEK_POKE_OP_SET (1 << 2)
#define PEEK_POKE_OP_CLR (2 << 2)
#define PEEK_POKE_OP_TOG (3 << 2)
// 00 - no operation
// 01 - set bits
// 10 - clear bits
// 11 - toggle bits
// PP: Modify/increment pointer
#define PEEK_POKE_INCR_MASK (3 << 4)
#define PEEK_POKE_INCR (2 << 4)
#define PEEK_POKE_DECR (3 << 4)
// 00 - Do not increment
// 01 - Reserved
// 10 - Increment pointer after operation
// 11 - Decrement pointer after operation
// R: 1 for read, 0 for write
#define PEEK_POKE_READ (1 << 6)
uint16_t increment;
// c: Number of units to increment/decrement, minus one
// 0 - Increment/decrement by 1 (i.e. for a 32-bit read, increment/decrement by 4 bytes)
// 1 - Increment/decrement by 2
// ...
union {
uint32_t value; // For a 'write', uses the address from the last 'read'
uint32_t address; // For a 'read', this is the address
};
} PACKED;
struct jump_to_address_pkt
{
uint8_t reserved[3];
uint32_t address;
} PACKED;
struct ongoing_pkt
{
uint8_t cmd;
uint16_t reserved;
uint32_t progress;
} PACKED;
struct result_pkt
{
uint8_t small;
uint16_t medium;
uint32_t large;
} PACKED;
struct bl_pkt
{
uint8_t cmd; // Upper four bits are sequence number.
union {
struct raw_pkt raw;
struct info_pkt info;
struct erase_sector_pkt erase_sector;
struct start_programming_pkt start_programming;
struct program_pkt program;
struct hash_pkt hash;
struct read_write_pkt read_write;
struct jump_to_address_pkt jump_to_address;
struct reboot_pkt reboot;
struct ongoing_pkt ongoing;
struct result_pkt result;
} PACKED;
} __attribute__((packed, aligned(4)));
#undef PACKED
enum bl_pkt_command
{
bootloader_info = 0,
erase_block = 1,
erase_app = 2,
start_programming = 3,
program_data = 4,
hash_memory = 5,
jump_cmd = 6,
peek_poke_cmd = 8,
echo_back_cmd = 9,
reboot_cmd = 10,
ongoing_process_cmd = 14,
result_cmd = 15,
};
enum bl_pkt_result
{
no_error = 0,
unhandled_command = 1,
address_out_of_range = 2,
no_address_set = 3,
subsystem_error = 4,
address_not_valid = 5,
size_not_valid = 6,
key_not_valid = 7,
flash_not_erased = 8,
command_ongoing = 9,
};
struct bl_state
{
uint32_t offset;
uint32_t count;
int (*continue_function)(struct bl_state *state, struct result_pkt *result, void *arg);
void *continue_arg;
union {
uint8_t buffer[4];
uint32_t buffer32;
};
uint32_t buffer_offset;
uint32_t flash_is_protected;
};
enum bootloader_reason
{
NOT_ENTERING_BOOTLOADER = 0,
BOOT_TOKEN_PRESENT = 1,
BOOT_FAILED_TOO_MANY_TIMES = 2,
NO_PROGRAM_PRESENT = 3,
BUTTON_HELD_DOWN = 4,
};
extern enum bootloader_reason bootloader_reason;
#endif /* __PALAWAN_BL_H__ */