Skip to content

Commit 22f37e8

Browse files
committed
bootloader: enable MPU, introduce delays to USB stack
1 parent 0f5c969 commit 22f37e8

File tree

12 files changed

+858
-6
lines changed

12 files changed

+858
-6
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ ifneq ($(EMULATOR),1)
2121
OBJS += timer.o
2222
endif
2323

24+
OBJS += usb_standard.o
2425
OBJS += usb21_standard.o
2526
OBJS += webusb.o
2627
OBJS += winusb.o

bootloader/bootloader.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ int main(void)
129129
oledInit();
130130
#endif
131131

132+
mpu_config_bootloader();
133+
132134
#ifndef APPVER
133135
// at least one button is unpressed
134136
uint16_t state = gpio_port_read(BTN_PORT);
@@ -147,6 +149,7 @@ int main(void)
147149
timer_init();
148150
}
149151

152+
mpu_config_off();
150153
load_app(signed_firmware);
151154
}
152155
#endif

firmware/usb.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,14 +259,16 @@ static int hid_control_request(usbd_device *dev, struct usb_setup_data *req, uin
259259
(void)complete;
260260
(void)dev;
261261

262+
wait_random();
263+
262264
if ((req->bmRequestType != 0x81) ||
263265
(req->bRequest != USB_REQ_GET_DESCRIPTOR) ||
264266
(req->wValue != 0x2200))
265267
return 0;
266268

267269
debugLog(0, "", "hid_control_request u2f");
268270
*buf = (uint8_t *)hid_report_descriptor_u2f;
269-
*len = MIN(*len, sizeof(hid_report_descriptor_u2f));
271+
*len = MIN_8bits(*len, sizeof(hid_report_descriptor_u2f));
270272
return 1;
271273
}
272274

setup.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ void setupApp(void)
141141
gpio_set_af(GPIOA, GPIO_AF10, GPIO10);
142142
}
143143

144+
#define MPU_RASR_SIZE_32B (0x04UL << MPU_RASR_SIZE_LSB)
144145
#define MPU_RASR_SIZE_1KB (0x09UL << MPU_RASR_SIZE_LSB)
145146
#define MPU_RASR_SIZE_4KB (0x0BUL << MPU_RASR_SIZE_LSB)
146147
#define MPU_RASR_SIZE_8KB (0x0CUL << MPU_RASR_SIZE_LSB)
@@ -161,6 +162,54 @@ void setupApp(void)
161162
#define FLASH_BASE (0x08000000U)
162163
#define SRAM_BASE (0x20000000U)
163164

165+
void mpu_config_off(void)
166+
{
167+
// Disable MPU
168+
MPU_CTRL = 0;
169+
170+
__asm__ volatile("dsb");
171+
__asm__ volatile("isb");
172+
}
173+
174+
void mpu_config_bootloader(void)
175+
{
176+
// Disable MPU
177+
MPU_CTRL = 0;
178+
179+
// Note: later entries overwrite previous ones
180+
// Flash (0x08000000 - 0x0807FFFF, 1 MiB, read-write)
181+
MPU_RBAR = FLASH_BASE | MPU_RBAR_VALID | (0 << MPU_RBAR_REGION_LSB);
182+
MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_FLASH | MPU_RASR_SIZE_1MB | MPU_RASR_ATTR_AP_PRW_URW;
183+
184+
// Flash (0x8007FE0 - 0x08007FFF, 32 B, no-access)
185+
MPU_RBAR = (FLASH_BASE + 0x7FE0) | MPU_RBAR_VALID | (1 << MPU_RBAR_REGION_LSB);
186+
MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_FLASH | MPU_RASR_SIZE_32B | MPU_RASR_ATTR_AP_PNO_UNO;
187+
188+
// SRAM (0x20000000 - 0x2001FFFF, read-write, execute never)
189+
MPU_RBAR = SRAM_BASE | MPU_RBAR_VALID | (2 << MPU_RBAR_REGION_LSB);
190+
MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_SRAM | MPU_RASR_SIZE_128KB | MPU_RASR_ATTR_AP_PRW_URW | MPU_RASR_ATTR_XN;
191+
192+
// Peripherals (0x40000000 - 0x4001FFFF, read-write, execute never)
193+
MPU_RBAR = PERIPH_BASE | MPU_RBAR_VALID | (3 << MPU_RBAR_REGION_LSB);
194+
MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_PERIPH | MPU_RASR_SIZE_128KB | MPU_RASR_ATTR_AP_PRW_URW | MPU_RASR_ATTR_XN;
195+
// Peripherals (0x40020000 - 0x40023FFF, read-write, execute never)
196+
MPU_RBAR = 0x40020000 | MPU_RBAR_VALID | (4 << MPU_RBAR_REGION_LSB);
197+
MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_PERIPH | MPU_RASR_SIZE_16KB | MPU_RASR_ATTR_AP_PRW_URW | MPU_RASR_ATTR_XN;
198+
// Don't enable DMA controller access
199+
// Peripherals (0x50000000 - 0x5007ffff, read-write, execute never)
200+
MPU_RBAR = 0x50000000 | MPU_RBAR_VALID | (5 << MPU_RBAR_REGION_LSB);
201+
MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_PERIPH | MPU_RASR_SIZE_512KB | MPU_RASR_ATTR_AP_PRW_URW | MPU_RASR_ATTR_XN;
202+
203+
// Enable MPU
204+
MPU_CTRL = MPU_CTRL_ENABLE | MPU_CTRL_HFNMIENA;
205+
206+
// Enable memory fault handler
207+
SCB_SHCSR |= SCB_SHCSR_MEMFAULTENA;
208+
209+
__asm__ volatile("dsb");
210+
__asm__ volatile("isb");
211+
}
212+
164213
// Never use in bootloader! Disables access to PPB (including MPU, NVIC, SCB)
165214
void mpu_config_firmware(void)
166215
{

setup.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ extern uint32_t __stack_chk_guard;
2727
void setup(void);
2828
void setupApp(void);
2929

30+
void mpu_config_off(void);
31+
void mpu_config_bootloader(void);
3032
void mpu_config_firmware(void);
3133

3234
#endif

usb21_standard.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,15 @@ static int usb21_standard_get_descriptor(usbd_device* usbd_dev,
6262
(void)complete;
6363
(void)usbd_dev;
6464

65+
wait_random();
66+
6567
if (req->bRequest == USB_REQ_GET_DESCRIPTOR) {
6668
int descr_type = req->wValue >> 8;
6769
if (descr_type == USB_DT_BOS) {
6870
if (!usb21_bos) {
6971
return USBD_REQ_NOTSUPP;
7072
}
71-
*len = MIN(*len, build_bos_descriptor(usb21_bos, *buf, *len));
73+
*len = MIN_8bits(*len, build_bos_descriptor(usb21_bos, *buf, *len));
7274
return USBD_REQ_HANDLED;
7375
}
7476
}

usb_private.h

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/** @defgroup usb_private_defines USB Private Structures
2+
3+
@brief <b>Defined Constants and Types for the USB Private Structures</b>
4+
5+
@ingroup USB_defines
6+
7+
@version 1.0.0
8+
9+
@author @htmlonly &copy; @endhtmlonly 2010
10+
Gareth McMullin <gareth@blacksphere.co.nz>
11+
12+
@date 10 March 2013
13+
14+
LGPL License Terms @ref lgpl_license
15+
*/
16+
17+
/*
18+
* This file is part of the libopencm3 project.
19+
*
20+
* Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
21+
*
22+
* This library is free software: you can redistribute it and/or modify
23+
* it under the terms of the GNU Lesser General Public License as published by
24+
* the Free Software Foundation, either version 3 of the License, or
25+
* (at your option) any later version.
26+
*
27+
* This library is distributed in the hope that it will be useful,
28+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
29+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30+
* GNU Lesser General Public License for more details.
31+
*
32+
* You should have received a copy of the GNU Lesser General Public License
33+
* along with this library. If not, see <http://www.gnu.org/licenses/>.
34+
*/
35+
36+
/**@{*/
37+
38+
#ifndef __USB_PRIVATE_H
39+
#define __USB_PRIVATE_H
40+
41+
#define MAX_USER_CONTROL_CALLBACK 4
42+
#define MAX_USER_SET_CONFIG_CALLBACK 4
43+
44+
/** Internal collection of device information. */
45+
struct _usbd_device {
46+
const struct usb_device_descriptor *desc;
47+
const struct usb_config_descriptor *config;
48+
const char **strings;
49+
int num_strings;
50+
51+
uint8_t *ctrl_buf; /**< Internal buffer used for control transfers */
52+
uint16_t ctrl_buf_len;
53+
54+
uint8_t current_address;
55+
uint8_t current_config;
56+
57+
uint16_t pm_top; /**< Top of allocated endpoint buffer memory */
58+
59+
/* User callback functions for various USB events */
60+
void (*user_callback_reset)(void);
61+
void (*user_callback_suspend)(void);
62+
void (*user_callback_resume)(void);
63+
void (*user_callback_sof)(void);
64+
65+
struct usb_control_state {
66+
enum {
67+
IDLE, STALLED,
68+
DATA_IN, LAST_DATA_IN, STATUS_IN,
69+
DATA_OUT, LAST_DATA_OUT, STATUS_OUT,
70+
} state;
71+
struct usb_setup_data req __attribute__((aligned(4)));
72+
uint8_t *ctrl_buf;
73+
uint16_t ctrl_len;
74+
usbd_control_complete_callback complete;
75+
bool needs_zlp;
76+
} control_state;
77+
78+
struct user_control_callback {
79+
usbd_control_callback cb;
80+
uint8_t type;
81+
uint8_t type_mask;
82+
} user_control_callback[MAX_USER_CONTROL_CALLBACK];
83+
84+
usbd_endpoint_callback user_callback_ctr[8][3];
85+
86+
/* User callback function for some standard USB function hooks */
87+
usbd_set_config_callback user_callback_set_config[MAX_USER_SET_CONFIG_CALLBACK];
88+
89+
usbd_set_altsetting_callback user_callback_set_altsetting;
90+
91+
const struct _usbd_driver *driver;
92+
93+
/* private driver data */
94+
95+
uint16_t fifo_mem_top;
96+
uint16_t fifo_mem_top_ep0;
97+
uint8_t force_nak[4];
98+
/*
99+
* We keep a backup copy of the out endpoint size registers to restore
100+
* them after a transaction.
101+
*/
102+
uint32_t doeptsiz[4];
103+
/*
104+
* Received packet size for each endpoint. This is assigned in
105+
* stm32f107_poll() which reads the packet status push register GRXSTSP
106+
* for use in stm32f107_ep_read_packet().
107+
*/
108+
uint16_t rxbcnt;
109+
};
110+
111+
enum _usbd_transaction {
112+
USB_TRANSACTION_IN,
113+
USB_TRANSACTION_OUT,
114+
USB_TRANSACTION_SETUP,
115+
};
116+
117+
/* Do not appear to belong to the API, so are omitted from docs */
118+
/**@}*/
119+
120+
void _usbd_control_in(usbd_device *usbd_dev, uint8_t ea);
121+
void _usbd_control_out(usbd_device *usbd_dev, uint8_t ea);
122+
void _usbd_control_setup(usbd_device *usbd_dev, uint8_t ea);
123+
124+
int _usbd_standard_request_device(usbd_device *usbd_dev,
125+
struct usb_setup_data *req, uint8_t **buf,
126+
uint16_t *len);
127+
int _usbd_standard_request_interface(usbd_device *usbd_dev,
128+
struct usb_setup_data *req, uint8_t **buf,
129+
uint16_t *len);
130+
int _usbd_standard_request_endpoint(usbd_device *usbd_dev,
131+
struct usb_setup_data *req, uint8_t **buf,
132+
uint16_t *len);
133+
int _usbd_standard_request(usbd_device *usbd_dev, struct usb_setup_data *req,
134+
uint8_t **buf, uint16_t *len);
135+
136+
void _usbd_reset(usbd_device *usbd_dev);
137+
138+
/* Functions provided by the hardware abstraction. */
139+
struct _usbd_driver {
140+
usbd_device *(*init)(void);
141+
void (*set_address)(usbd_device *usbd_dev, uint8_t addr);
142+
void (*ep_setup)(usbd_device *usbd_dev, uint8_t addr, uint8_t type,
143+
uint16_t max_size, usbd_endpoint_callback cb);
144+
void (*ep_reset)(usbd_device *usbd_dev);
145+
void (*ep_stall_set)(usbd_device *usbd_dev, uint8_t addr,
146+
uint8_t stall);
147+
void (*ep_nak_set)(usbd_device *usbd_dev, uint8_t addr, uint8_t nak);
148+
uint8_t (*ep_stall_get)(usbd_device *usbd_dev, uint8_t addr);
149+
uint16_t (*ep_write_packet)(usbd_device *usbd_dev, uint8_t addr,
150+
const void *buf, uint16_t len);
151+
uint16_t (*ep_read_packet)(usbd_device *usbd_dev, uint8_t addr,
152+
void *buf, uint16_t len);
153+
void (*poll)(usbd_device *usbd_dev);
154+
void (*disconnect)(usbd_device *usbd_dev, bool disconnected);
155+
uint32_t base_address;
156+
bool set_address_before_status;
157+
uint16_t rx_fifo_size;
158+
};
159+
160+
#endif
161+

0 commit comments

Comments
 (0)