v2.0.0
picoboot.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _BOOT_PICOBOOT_H
8#define _BOOT_PICOBOOT_H
9
10#include <stdint.h>
11#include <stdbool.h>
12#include <assert.h>
13
14#ifndef NO_PICO_PLATFORM
15#include "pico/platform.h"
16#endif
17
24#include "picoboot_constants.h"
25
26#define PICOBOOT_MAGIC 0x431fd10bu
27
28// --------------------------------------------
29// CONTROL REQUESTS FOR THE PICOBOOT INTERFACE
30// --------------------------------------------
31
32// size 0 OUT - un-stall EPs and reset
33#define PICOBOOT_IF_RESET 0x41
34
35// size 16 IN - return the status of the last command
36#define PICOBOOT_IF_CMD_STATUS 0x42
37
38// --------------------------------------------------
39// COMMAND REQUESTS SENT TO THE PICOBOOT OUT ENDPOINT
40// --------------------------------------------------
41//
42// picoboot_cmd structure of size 32 is sent to OUT endpoint
43// transfer_length bytes are transferred via IN/OUT
44// device responds on success with 0 length ACK packet set via OUT/IN
45// device may stall the transferring endpoint in case of error
46
47enum picoboot_cmd_id {
48 PC_EXCLUSIVE_ACCESS = 0x1,
49 PC_REBOOT = 0x2,
50 PC_FLASH_ERASE = 0x3,
51 PC_READ = 0x84, // either RAM or FLASH
52 PC_WRITE = 0x5, // either RAM or FLASH (does no erase)
53 PC_EXIT_XIP = 0x6,
54 PC_ENTER_CMD_XIP = 0x7,
55 PC_EXEC = 0x8,
56 PC_VECTORIZE_FLASH = 0x9,
57 // RP2350 only below here
58 PC_REBOOT2 = 0xa,
59 PC_GET_INFO = 0x8b,
60 PC_OTP_READ = 0x8c,
61 PC_OTP_WRITE = 0xd,
62 //PC_EXEC2 = 0xe, // currently unused
63};
64
65enum picoboot_status {
66 PICOBOOT_OK = 0,
67 PICOBOOT_UNKNOWN_CMD = 1,
68 PICOBOOT_INVALID_CMD_LENGTH = 2,
69 PICOBOOT_INVALID_TRANSFER_LENGTH = 3,
70 PICOBOOT_INVALID_ADDRESS = 4,
71 PICOBOOT_BAD_ALIGNMENT = 5,
72 PICOBOOT_INTERLEAVED_WRITE = 6,
73 PICOBOOT_REBOOTING = 7,
74 PICOBOOT_UNKNOWN_ERROR = 8,
75 PICOBOOT_INVALID_STATE = 9,
76 PICOBOOT_NOT_PERMITTED = 10,
77 PICOBOOT_INVALID_ARG = 11,
78 PICOBOOT_BUFFER_TOO_SMALL = 12,
79 PICOBOOT_PRECONDITION_NOT_MET = 13,
80 PICOBOOT_MODIFIED_DATA = 14,
81 PICOBOOT_INVALID_DATA = 15,
82 PICOBOOT_NOT_FOUND = 16,
83 PICOBOOT_UNSUPPORTED_MODIFICATION = 17,
84};
85
86 struct __packed picoboot_reboot_cmd {
87 uint32_t dPC; // 0 means reset into regular boot path
88 uint32_t dSP;
89 uint32_t dDelayMS;
90};
91
92
93// note this (with pc_sp) union member has the same layout as picoboot_reboot_cmd except with extra dFlags
94 struct __packed picoboot_reboot2_cmd {
95 uint32_t dFlags;
96 uint32_t dDelayMS;
97 uint32_t dParam0;
98 uint32_t dParam1;
99};
100
101// used for EXEC, VECTORIZE_FLASH
102 struct __packed picoboot_address_only_cmd {
103 uint32_t dAddr;
104};
105
106// used for READ, WRITE, FLASH_ERASE
107 struct __packed picoboot_range_cmd {
108 uint32_t dAddr;
109 uint32_t dSize;
110};
111
112 struct __packed picoboot_exec2_cmd {
113 uint32_t image_base;
114 uint32_t image_size;
115 uint32_t workarea_base;
116 uint32_t workarea_size;
117};
118
119enum picoboot_exclusive_type {
120 NOT_EXCLUSIVE = 0,
121 EXCLUSIVE,
122 EXCLUSIVE_AND_EJECT
123};
124
125 struct __packed picoboot_exclusive_cmd {
126 uint8_t bExclusive;
127};
128
129 struct __packed picoboot_otp_cmd {
130 uint16_t wRow; // OTP row
131 uint16_t wRowCount; // number of rows to transfer
132 uint8_t bEcc; // use error correction (16 bit per register vs 24 (stored as 32) bit raw)
133};
134
135
136 struct __packed picoboot_get_info_cmd {
137 uint8_t bType;
138 uint8_t bParam;
139 uint16_t wParam;
140 uint32_t dParams[3];
141};
142
143// little endian
144struct __packed __aligned(4) picoboot_cmd {
145 uint32_t dMagic;
146 uint32_t dToken; // an identifier for this token to correlate with a status response
147 uint8_t bCmdId; // top bit set for IN
148 uint8_t bCmdSize; // bytes of actual data in the arg part of this structure
149 uint16_t _unused;
150 uint32_t dTransferLength; // length of IN/OUT transfer (or 0) if none
151 union {
152 uint8_t args[16];
153 struct picoboot_reboot_cmd reboot_cmd;
154 struct picoboot_range_cmd range_cmd;
155 struct picoboot_address_only_cmd address_only_cmd;
156 struct picoboot_exclusive_cmd exclusive_cmd;
157 struct picoboot_reboot2_cmd reboot2_cmd;
158 struct picoboot_otp_cmd otp_cmd;
159 struct picoboot_get_info_cmd get_info_cmd;
160 struct picoboot_exec2_cmd exec2_cmd;
161 };
162};
163static_assert(32 == sizeof(struct picoboot_cmd), "picoboot_cmd must be 32 bytes big");
164
165struct __packed __aligned(4) picoboot_cmd_status {
166 uint32_t dToken;
167 uint32_t dStatusCode;
168 uint8_t bCmdId;
169 uint8_t bInProgress;
170 uint8_t _pad[6];
171};
172
173static_assert(16 == sizeof(struct picoboot_cmd_status), "picoboot_cmd_status must be 16 bytes big");
174
175#endif
platform.h
otp_cmd
Definition: bootrom_constants.h:273
picoboot_address_only_cmd
Definition: picoboot.h:102
picoboot_exclusive_cmd
Definition: picoboot.h:125
picoboot_exec2_cmd
Definition: picoboot.h:112
picoboot_get_info_cmd
Definition: picoboot.h:136
picoboot_otp_cmd
Definition: picoboot.h:129
picoboot_range_cmd
Definition: picoboot.h:107
picoboot_reboot2_cmd
Definition: picoboot.h:94
picoboot_reboot_cmd
Definition: picoboot.h:86