Skip to content

Commit 692e542

Browse files
ChocolateFrogsNutsdevyte
authored andcommitted
precache() - preload code into the flash cache. (#6628)
* precache() - preload code into the flash cache. By preloading code into the flash cache we can take control over when SPI Flash reads will occur when code is executing. This can be useful where the timing of a section of code is extremely critical and we don't want random pauses to pull code in from the SPI flash chip. It can also be useful for code that accesses/uses SPI0 which is connected to the flash chip. Non interrupt handler code that is infrequently called but might otherwise require being in valuable IRAM - such as bit-banging I/O code or some code run at bootup can avoid being permanently in IRAM. Macros are provided to make precaching one or more blocks of code in any function easy. * Fix missing include * Make precache extern "C" * Attempt 2 at making precache extern "C" * Fix calculation of number of cache lines to preload With certain alignments/lengths of code it was possible to not read enough into the flash cache. This commit makes the length calculation clearer and adds an extra cache line to ensure we precache enough code. * Add noinline to PRECACHE_ATTR macro Precached code needs to be noinline to ensure the no-reorder-blocks is applied.
1 parent bf4a435 commit 692e542

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

Diff for: cores/esp8266/core_esp8266_features.cpp

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
/*
3+
core_esp8266_features.cpp
4+
5+
Copyright (c) 2019 Mike Nix. All rights reserved.
6+
This file is part of the esp8266 core for Arduino environment.
7+
8+
This library is free software; you can redistribute it and/or
9+
modify it under the terms of the GNU Lesser General Public
10+
License as published by the Free Software Foundation; either
11+
version 2.1 of the License, or (at your option) any later version.
12+
13+
This library is distributed in the hope that it will be useful,
14+
but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
Lesser General Public License for more details.
17+
18+
You should have received a copy of the GNU Lesser General Public
19+
License along with this library; if not, write to the Free Software
20+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21+
*/
22+
23+
#include <stdint.h>
24+
25+
/* precache()
26+
* pre-loads flash data into the flash cache
27+
* if f==0, preloads instructions starting at the address we were called from.
28+
* otherwise preloads flash at the given address.
29+
* All preloads are word aligned.
30+
*/
31+
#ifdef __cplusplus
32+
extern "C" {
33+
#endif
34+
35+
void precache(void *f, uint32_t bytes) {
36+
// Size of a cache page in bytes. We only need to read one word per
37+
// page (ie 1 word in 8) for this to work.
38+
#define CACHE_PAGE_SIZE 32
39+
40+
register uint32_t a0 asm("a0");
41+
register uint32_t lines = (bytes/CACHE_PAGE_SIZE)+2;
42+
volatile uint32_t *p = (uint32_t*)((f ? (uint32_t)f : a0) & ~0x03);
43+
uint32_t x;
44+
for (uint32_t i=0; i<lines; i++, p+=CACHE_PAGE_SIZE/sizeof(uint32_t)) x=*p;
45+
(void)x;
46+
}
47+
48+
#ifdef __cplusplus
49+
}
50+
#endif

Diff for: cores/esp8266/core_esp8266_features.h

+22
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,26 @@ inline uint32_t esp_get_cycle_count() {
9393
}
9494
#endif // not CORE_MOCK
9595

96+
97+
// Tools for preloading code into the flash cache
98+
#define PRECACHE_ATTR __attribute__((optimize("no-reorder-blocks"))) \
99+
__attribute__((noinline))
100+
101+
#define PRECACHE_START(tag) \
102+
precache(NULL,(uint8_t *)&&_precache_end_##tag - (uint8_t*)&&_precache_start_##tag); \
103+
_precache_start_##tag:
104+
105+
#define PRECACHE_END(tag) \
106+
_precache_end_##tag:
107+
108+
#ifdef __cplusplus
109+
extern "C" {
110+
#endif
111+
112+
void precache(void *f, uint32_t bytes);
113+
114+
#ifdef __cplusplus
115+
}
116+
#endif
117+
96118
#endif // CORE_ESP8266_FEATURES_H

0 commit comments

Comments
 (0)