Skip to content

precache() - preload code into the flash cache. #6628

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Nov 3, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions cores/esp8266/core_esp8266_features.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

/*
core_esp8266_features.cpp

Copyright (c) 2019 Mike Nix. All rights reserved.
This file is part of the esp8266 core for Arduino environment.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <stdint.h>

/* precache()
* pre-loads flash data into the flash cache
* if f==0, preloads instructions starting at the address we were called from.
* otherwise preloads flash at the given address.
* All preloads are word aligned.
*/
#ifdef __cplusplus
extern "C" {
#endif

void precache(void *f, uint32_t bytes) {
// Size of a cache page in bytes. We only need to read one word per
// page (ie 1 word in 8) for this to work.
#define CACHE_PAGE_SIZE 32

register uint32_t a0 asm("a0");
register uint32_t lines = (bytes/CACHE_PAGE_SIZE)+2;
volatile uint32_t *p = (uint32_t*)((f ? (uint32_t)f : a0) & ~0x03);
uint32_t x;
for (uint32_t i=0; i<lines; i++, p+=CACHE_PAGE_SIZE/sizeof(uint32_t)) x=*p;
(void)x;
}

#ifdef __cplusplus
}
#endif
22 changes: 22 additions & 0 deletions cores/esp8266/core_esp8266_features.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,26 @@ inline uint32_t esp_get_cycle_count() {
}
#endif // not CORE_MOCK


// Tools for preloading code into the flash cache
#define PRECACHE_ATTR __attribute__((optimize("no-reorder-blocks"))) \
__attribute__((noinline))

#define PRECACHE_START(tag) \
precache(NULL,(uint8_t *)&&_precache_end_##tag - (uint8_t*)&&_precache_start_##tag); \
_precache_start_##tag:

#define PRECACHE_END(tag) \
_precache_end_##tag:

#ifdef __cplusplus
extern "C" {
#endif

void precache(void *f, uint32_t bytes);

#ifdef __cplusplus
}
#endif

#endif // CORE_ESP8266_FEATURES_H