From 6b71c162b9fd73cefcaf121e62ea557556d61595 Mon Sep 17 00:00:00 2001 From: sts1u16 <sts1u16@ecs.soton.ac.uk> Date: Tue, 13 Aug 2019 16:09:48 +0100 Subject: [PATCH] Update of build system to build allocated state and managed state simulaneously. --- CMakeLists.txt | 11 + aes/CMakeLists.txt | 26 + {aes128 => aes}/TI_aes_128_encr_only.c | 0 {aes128 => aes}/TI_aes_128_encr_only.h | 0 {aes128 => aes}/debug.gdb | 0 {aes128 => aes}/generate-reference-output.c | 0 {aes128 => aes}/lipsum.h | 0 {aes128 => aes}/main.c | 0 aes128/CMakeLists.txt | 30 -- blink/CMakeLists.txt | 19 +- common.cmake | 9 +- crc32/CMakeLists.txt | 49 +- iclib/CMakeLists.txt | 41 +- iclib/common.c | 24 + iclib/common.h | 9 + iclib/config.h | 10 +- iclib/ic.c | 62 +-- iclib/memory_management.c | 518 ++++++++++---------- iclib/memory_management.h | 12 +- matmul-tiled/CMakeLists.txt | 44 +- matmul/CMakeLists.txt | 43 +- 21 files changed, 465 insertions(+), 442 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 aes/CMakeLists.txt rename {aes128 => aes}/TI_aes_128_encr_only.c (100%) rename {aes128 => aes}/TI_aes_128_encr_only.h (100%) rename {aes128 => aes}/debug.gdb (100%) rename {aes128 => aes}/generate-reference-output.c (100%) rename {aes128 => aes}/lipsum.h (100%) rename {aes128 => aes}/main.c (100%) delete mode 100644 aes128/CMakeLists.txt create mode 100644 iclib/common.c create mode 100644 iclib/common.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ec1f1de --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.2) + +include(common.cmake) + +project(ic-examples) + +#target_compile_options(aes PUBLIC -finstrument-functions) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +add_subdirectory(iclib) +add_subdirectory(aes) diff --git a/aes/CMakeLists.txt b/aes/CMakeLists.txt new file mode 100644 index 0000000..9721b18 --- /dev/null +++ b/aes/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.0) + +FOREACH(METHOD "MS" "AS") + set(TESTNAME "aes-${METHOD}") + add_executable( + ${TESTNAME} + main.c + TI_aes_128_encr_only.c + TI_aes_128_encr_only.h + lipsum.h + ) + IF (${METHOD} STREQUAL "AS") + target_compile_definitions( ${TESTNAME} PUBLIC -DALLOCATEDSTATE) + ENDIF() + add_msp_upload(${TESTNAME}) + target_link_libraries( + ${TESTNAME} + LINK_PUBLIC ic-${METHOD} + ${SUPPORT_LIBS}) + set_target_properties(${TESTNAME} PROPERTIES SUFFIX ".elf") + add_custom_command(TARGET ${TESTNAME} POST_BUILD + COMMAND ${MSP430-SIZE} -A -d "$<TARGET_FILE:${TESTNAME}>" + COMMENT "Invoking: msp430-elf-size") +ENDFOREACH() + + diff --git a/aes128/TI_aes_128_encr_only.c b/aes/TI_aes_128_encr_only.c similarity index 100% rename from aes128/TI_aes_128_encr_only.c rename to aes/TI_aes_128_encr_only.c diff --git a/aes128/TI_aes_128_encr_only.h b/aes/TI_aes_128_encr_only.h similarity index 100% rename from aes128/TI_aes_128_encr_only.h rename to aes/TI_aes_128_encr_only.h diff --git a/aes128/debug.gdb b/aes/debug.gdb similarity index 100% rename from aes128/debug.gdb rename to aes/debug.gdb diff --git a/aes128/generate-reference-output.c b/aes/generate-reference-output.c similarity index 100% rename from aes128/generate-reference-output.c rename to aes/generate-reference-output.c diff --git a/aes128/lipsum.h b/aes/lipsum.h similarity index 100% rename from aes128/lipsum.h rename to aes/lipsum.h diff --git a/aes128/main.c b/aes/main.c similarity index 100% rename from aes128/main.c rename to aes/main.c diff --git a/aes128/CMakeLists.txt b/aes128/CMakeLists.txt deleted file mode 100644 index 93c7f94..0000000 --- a/aes128/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -cmake_minimum_required(VERSION 3.0) - -include(${CMAKE_CURRENT_LIST_DIR}/../common.cmake) - -project(aes-MS) - -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -include_directories(${ICLIB_ROOT}) -link_directories(${ICLIB_ROOT}) - -add_executable( - ${PROJECT_NAME} - main.c - TI_aes_128_encr_only.c - TI_aes_128_encr_only.h - lipsum.h -) - -add_msp_upload(${PROJECT_NAME}) - -target_link_libraries(${PROJECT_NAME} ${SUPPORT_LIBS}) - -set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".elf") - -#target_compile_options(${PROJECT_NAME} PUBLIC -finstrument-functions) - -add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${MSP430-SIZE} -A -d "$<TARGET_FILE:${PROJECT_NAME}>" - COMMENT "Invoking: msp430-elf-size") diff --git a/blink/CMakeLists.txt b/blink/CMakeLists.txt index 56c7f0c..178a3ae 100644 --- a/blink/CMakeLists.txt +++ b/blink/CMakeLists.txt @@ -1,21 +1,12 @@ cmake_minimum_required(VERSION 3.0) -include(${CMAKE_CURRENT_LIST_DIR}/../common.cmake) +add_executable(blink blink.c) +add_msp_upload(blink) -project(blink) +target_link_libraries(blink LINK_PUBLIC ic ${SUPPORT_LIBS}) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -include_directories(${ICLIB_ROOT}) -link_directories(${ICLIB_ROOT}) - -add_executable(${PROJECT_NAME} blink.c) -add_msp_upload(${PROJECT_NAME}) - -target_link_libraries(${PROJECT_NAME} ic mul_none gcc c) - -set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".elf") +set_target_properties(blink PROPERTIES SUFFIX ".elf") add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${MSP430-SIZE} "$<TARGET_FILE:${PROJECT_NAME}>" + COMMAND ${MSP430-SIZE} "$<TARGET_FILE:blink>" COMMENT "Invoking: msp430-elf-size") diff --git a/common.cmake b/common.cmake index d6243bb..ab1c7dd 100644 --- a/common.cmake +++ b/common.cmake @@ -1,8 +1,5 @@ # paths -set(ICLIB_ROOT "${CMAKE_SOURCE_DIR}/../iclib") - -set(CMAKE_TOOLCHAIN_FILE - ${CMAKE_CURRENT_LIST_DIR}/msp430-toolchain.cmake) +set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/msp430-toolchain.cmake) # Force compiler detection so we can set up flags enable_language(C ASM) @@ -19,7 +16,7 @@ add_compile_options( # Linker scripts set(CMAKE_EXE_LINKER_FLAGS - "${CMAKE_EXE_LINKER_FLAGS} -T ${CMAKE_SOURCE_DIR}/../msp430fr5994.ld ") + "${CMAKE_EXE_LINKER_FLAGS} -T ${CMAKE_CURRENT_SOURCE_DIR}/msp430fr5994.ld ") # Add to search path for linker scripts (xx_symbols.ld, included by main linker script) link_directories( @@ -36,4 +33,4 @@ link_libraries( # Global link flags ) # Utility for linking targets to std libs -set(SUPPORT_LIBS ic c gcc mul_none) +set(SUPPORT_LIBS c gcc mul_none) diff --git a/crc32/CMakeLists.txt b/crc32/CMakeLists.txt index b7058b7..fa034f9 100644 --- a/crc32/CMakeLists.txt +++ b/crc32/CMakeLists.txt @@ -1,29 +1,26 @@ cmake_minimum_required(VERSION 3.0) -include(${CMAKE_CURRENT_LIST_DIR}/../common.cmake) +FOREACH(METHOD "MS" "AS") + set(TESTNAME "crc-${METHOD}") + add_executable( + ${TESTNAME} + main.c + crc.h + crc_32.c + lipsum.h + sniptype.h + ) + IF (${METHOD} STREQUAL "AS") + target_compile_definitions( ${TESTNAME} PUBLIC -DALLOCATEDSTATE) + ENDIF() + add_msp_upload(${TESTNAME}) + target_link_libraries( + ${TESTNAME} + LINK_PUBLIC ic-${METHOD} + ${SUPPORT_LIBS}) + set_target_properties(${TESTNAME} PROPERTIES SUFFIX ".elf") + add_custom_command(TARGET ${TESTNAME} POST_BUILD + COMMAND ${MSP430-SIZE} -A -d "$<TARGET_FILE:${TESTNAME}>" + COMMENT "Invoking: msp430-elf-size") +ENDFOREACH() -project(crc) - -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -include_directories(${ICLIB_ROOT}) -link_directories(${ICLIB_ROOT}) - -add_executable( - ${PROJECT_NAME} - main.c - crc.h - crc_32.c - lipsum.h - sniptype.h -) - -add_msp_upload(${PROJECT_NAME}) - -target_link_libraries(${PROJECT_NAME} ${SUPPORT_LIBS}) - -set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".elf") - -add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${MSP430-SIZE} "$<TARGET_FILE:${PROJECT_NAME}>" - COMMENT "Invoking: msp430-elf-size") diff --git a/iclib/CMakeLists.txt b/iclib/CMakeLists.txt index b7e1822..7c2f0d5 100644 --- a/iclib/CMakeLists.txt +++ b/iclib/CMakeLists.txt @@ -2,26 +2,29 @@ cmake_minimum_required(VERSION 3.0) include(${CMAKE_CURRENT_LIST_DIR}/../common.cmake) -project(ic) +FOREACH(METHOD "MS" "AS") + set(TESTNAME "ic-${METHOD}") + add_library( + ${TESTNAME} + ic.c + ic.h + ic.S + memory_management.c + memory_management.h + common.c + common.h + ) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + IF (${METHOD} STREQUAL "AS") + target_compile_definitions( ${TESTNAME} PUBLIC -DALLOCATEDSTATE) + ENDIF() -add_library( - ${CMAKE_PROJECT_NAME} - STATIC - ic.c - ic.h - ic.S - memory_management.c - memory_management.h - ) + target_link_libraries(${TESTNAME} ${SUPPORT_LIBS}) -target_link_libraries( - ${CMAKE_PROJECT_NAME} - mul_none - c - gcc) + target_include_directories(${TESTNAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD - COMMAND ${MSP430-SIZE} -A -d "$<TARGET_FILE:${PROJECT_NAME}>" - COMMENT "Invoking: msp430-elf-size") + add_custom_command(TARGET ${TESTNAME} POST_BUILD + COMMAND ${MSP430-SIZE} -A -d "$<TARGET_FILE:${TESTNAME}>" + COMMENT "Invoking: msp430-elf-size") + +ENDFOREACH() diff --git a/iclib/common.c b/iclib/common.c new file mode 100644 index 0000000..5b1d58c --- /dev/null +++ b/iclib/common.c @@ -0,0 +1,24 @@ +#include "common.h" + +void __attribute__((naked)) fastmemcpy(uint8_t *dst, uint8_t *src, size_t len) { + __asm__(" push r5\n" + " tst r14\n" // Test for len=0 + " jz return\n" + " mov #2, r5\n" // r5 = word size + " xor r15, r15\n" // Clear r15 + " mov r14, r15\n" // r15=len + " and #1, r15\n" // r15 = len%2 + " sub r15, r14\n" // r14 = len - len%2 + "loopmemcpy: \n" + " mov.w @r13+, @r12\n" + " add r5, r12 \n" + " sub r5, r14 \n" + " jnz loopmemcpy \n" + " tst r15\n" + " jz return\n" + " mov.b @r13, @r12\n" // move last byte + "return:\n" + " pop r5\n" + " ret\n"); +} + diff --git a/iclib/common.h b/iclib/common.h new file mode 100644 index 0000000..9c745fe --- /dev/null +++ b/iclib/common.h @@ -0,0 +1,9 @@ +#pragma once + +#include <stddef.h> +#include <stdint.h> + +/** + * Hand-written fast version of memcpy + * */ +void fastmemcpy(uint8_t *dst, uint8_t *src, size_t len); diff --git a/iclib/config.h b/iclib/config.h index df901c8..b7a5510 100644 --- a/iclib/config.h +++ b/iclib/config.h @@ -24,11 +24,15 @@ /* ------ Threshold Calculation ---------------------------------------------*/ #define VMAX 3665 // 3.58 V maximum operating voltage -#define VON 2048 // On-voltage +#define VON 1945 // On-voltage // DVDT: 1024 x voltage delta per byte saved/restored -#define DVDT (80 * 5) // 5 +#ifdef ALLOCATEDSTATE +#define DVDT (33 * 5) //(33 * 5) // (60*5) +#else +#define DVDT (60 * 5) //(33 * 5) // (60*5) +#endif -#define V_C 205 // ~0.2 V Voltage buffer for useful compute +#define V_C 102 // 205 // ~0.2 V Voltage buffer for useful compute #endif /* SRC_CONFIG_H_ */ diff --git a/iclib/ic.c b/iclib/ic.c index c10b3c1..81a522a 100644 --- a/iclib/ic.c +++ b/iclib/ic.c @@ -1,5 +1,6 @@ #include <msp430fr5994.h> +#include "common.h" #include "config.h" #include "ic.h" #include "memory_management.h" @@ -13,7 +14,7 @@ extern uint8_t __boot_stack_high; extern uint8_t __npdata_loadLow, __npdata_low, __npdata_high; // ------------- Globals ------------------------------------------------------- -static stackTrunk = &__stack_low; +static uint16_t *stackTrunk = (uint16_t *)&__stack_low; // ------------- PERSISTENT VARIABLES ------------------------------------------ #define PERSISTENT __attribute__((section(".fram_vars"))) @@ -40,7 +41,6 @@ static void adc_init(void); static void gpio_init(void); static void clock_init(void); static void restore(void); -static void fastmemcpy(uint8_t *dst, uint8_t *src, size_t len); /* ------ ASM functions ---------------------------------------------------- */ extern void suspend(uint16_t *regSnapshot); @@ -48,7 +48,8 @@ extern void restore_registers(uint16_t *regSnapshot); /* ------ Function Declarations ---------------------------------------------*/ -void __attribute__((interrupt(RESET_VECTOR), naked, used)) iclib_boot() { +void __attribute__((interrupt(RESET_VECTOR), naked, used, optimize("O0"))) +iclib_boot() { __set_SP_register(&__boot_stack_high); // Boot stack WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer @@ -66,14 +67,15 @@ void __attribute__((interrupt(RESET_VECTOR), naked, used)) iclib_boot() { // *!Remaining code in this function is only executed during the first // boot!* // - // Boot: Set SP, load data and initialize LRU + // First time boot: Set SP, load data and initialize LRU __set_SP_register(&__stack_high); // Runtime stack fastmemcpy(&__data_low, &__data_loadLow, &__data_high - &__data_low); mm_init_lru(); -#ifndef TRACK_MMDATA +#ifdef ALLOCATEDSTATE uint16_t mmdata_size = &__mmdata_end - &__mmdata_start; ic_update_thresholds(mmdata_size, mmdata_size); + mm_restore(); #endif int main(); // Suppress implicit decl. warning @@ -137,15 +139,15 @@ void suspendVM(void) { size_t len; // mmdata -#ifdef TRACK_MMDATA - // Save modified pages - nBytesToSave = mm_flush(); -#else +#ifdef ALLOCATEDSTATE // Save entire section src = &__mmdata_start; dst = (uint8_t *)&__mmdata_loadStart; len = &__mmdata_end - src; fastmemcpy(dst, src, len); +#else + // Save modified pages + nBytesToSave = mm_flush(); #endif // bss @@ -197,17 +199,8 @@ void restore(void) { len = &__bss_high - dst; fastmemcpy(dst, src, len); - // mmdata -#ifdef TRACK_MMDATA - // Restore active pages only - mm_restoreStatic(); -#else - // Restore entire section - dst = &__mmdata_start; - len = &__mmdata_end - dst; - src = (uint8_t *)&__mmdata_loadStart; - fastmemcpy(dst, src, len); -#endif + // Restore mmdata + mm_restore(); // stack #ifdef TRACK_STACK @@ -280,7 +273,8 @@ static void adc_init(void) { ADC12CTL0 |= (ADC12SC | ADC12ENC); // Enable & start conversion } -void __attribute__((__interrupt__(ADC12_B_VECTOR))) adc12_isr(void) { +void __attribute__((__interrupt__(ADC12_B_VECTOR), optimize("O0"))) +adc12_isr(void) { __disable_interrupt(); switch (__even_in_range(ADC12IV, ADC12IV__ADC12RDYIFG)) { @@ -440,34 +434,12 @@ void comparator_init() { // CEINT = CEIE; } -void __attribute__((naked)) fastmemcpy(uint8_t *dst, uint8_t *src, size_t len) { - __asm__(" push r5\n" - " tst r14\n" // Test for len=0 - " jz return\n" - " mov #2, r5\n" // r5 = word size - " xor r15, r15\n" // Clear r15 - " mov r14, r15\n" // r15=len - " and #1, r15\n" // r15 = len%2 - " sub r15, r14\n" // r14 = len - len%2 - "loopmemcpy: \n" - " mov.w @r13+, @r12\n" - " add r5, r12 \n" - " sub r5, r14 \n" - " jnz loopmemcpy \n" - " tst r15\n" - " jz return\n" - " mov.b @r13, @r12\n" // move last byte - "return:\n" - " pop r5\n" - " ret\n"); -} - void __attribute__((no_instrument_function)) __cyg_profile_func_enter(void *this_fn, void *call_site) {} void __attribute__((no_instrument_function)) __cyg_profile_func_exit(void *this_fn, void *call_site) { - if (__get_SP_register() < stackTrunk) { - stackTrunk = __get_SP_register(); + if ((uint16_t *)__get_SP_register() < stackTrunk) { + stackTrunk = (uint16_t *)_get_SP_register(); } } diff --git a/iclib/memory_management.c b/iclib/memory_management.c index 83d0dfe..648e93b 100644 --- a/iclib/memory_management.c +++ b/iclib/memory_management.c @@ -3,6 +3,7 @@ #include <stdint.h> #include <string.h> +#include "common.h" #include "ic.h" #include "memory_management.h" @@ -17,8 +18,8 @@ extern uint8_t __mmdata_end; extern uint8_t __mmdata_loadStart; struct LRU_candidate { - uint8_t pageNumber; - uint8_t tableIdx; + uint8_t pageNumber; + uint8_t tableIdx; }; /**************************** Type Definitions *******************************/ @@ -30,10 +31,10 @@ struct LRU_candidate { #error Too many pages, increase page size or reduce memory usage #endif -#define DUMMY_PAGE 255 //! Used for LRU table -#define REFCNT_MASK 0x3F //! Reference count -#define LOADED 0x80 //! Mask to check if loaded -#define MODIFIED 0x40 //! Mask to check if modified +#define DUMMY_PAGE 255 //! Used for LRU table +#define REFCNT_MASK 0x3F //! Reference count +#define LOADED 0x80 //! Mask to check if loaded +#define MODIFIED 0x40 //! Mask to check if modified /************************** Function Prototypes ******************************/ static void writePageFRAM(uint8_t pageNumber); @@ -52,116 +53,132 @@ static uint8_t lruTable[MAX_DIRTY_PAGES]; /*************************** Function definitions ****************************/ int mm_acquire(const uint8_t *memPtr, mm_mode mode) { - if ((&__mmdata_start > (uint8_t *)memPtr) || - (&__mmdata_end < (uint8_t *)memPtr)) { - while (1) - ; // Error: Pointer out of bounds. - } - - uint16_t pageNumber = - ((uint16_t)memPtr - (uint16_t)&__mmdata_start) / PAGE_SIZE; +#ifdef ALLOCATEDSTATE + return 0; +#endif + if ((&__mmdata_start > (uint8_t *)memPtr) || + (&__mmdata_end < (uint8_t *)memPtr)) { + while (1) + ; // Error: Pointer out of bounds. + } + + uint16_t pageNumber = + ((uint16_t)memPtr - (uint16_t)&__mmdata_start) / PAGE_SIZE; + + if ((attributeTable[pageNumber] & REFCNT_MASK) >= 64) { + while (1) + ; // Error: Too many references to a single page + } + + if (mode == MM_READWRITE) { // && !(attributeTable[pageNumber] & MODIFIED)){ + if (mm_n_dirty_pages >= MAX_DIRTY_PAGES) { + // Need to write back an inactive and dirty page first + for (int i = MAX_DIRTY_PAGES - 1; i >= 0; i--) { + uint8_t candidate = lruTable[i]; + if (candidate != DUMMY_PAGE) { + if ((attributeTable[candidate] & REFCNT_MASK) == 0 && + (attributeTable[candidate] & LOADED) && + (attributeTable[candidate] & MODIFIED)) { + writePageFRAM(candidate); + clearLRU(i); + break; + } + } + } - if ((attributeTable[pageNumber] & REFCNT_MASK) >= 64) { + if (mm_n_dirty_pages >= MAX_DIRTY_PAGES) { while (1) - ; // Error: Too many references to a single page + ; // Error: MAX_DIRTY_PAGES exceeded + } } - if (mode == - MM_READWRITE) { // && !(attributeTable[pageNumber] & MODIFIED)){ - if (mm_n_dirty_pages >= MAX_DIRTY_PAGES) { - // Need to write back an inactive and dirty page first - for (int i = MAX_DIRTY_PAGES - 1; i >= 0; i--) { - uint8_t candidate = lruTable[i]; - if (candidate != DUMMY_PAGE) { - if ((attributeTable[candidate] & REFCNT_MASK) == 0 && - (attributeTable[candidate] & LOADED) && - (attributeTable[candidate] & MODIFIED)) { - writePageFRAM(candidate); - clearLRU(i); - break; - } - } - } - - if (mm_n_dirty_pages >= MAX_DIRTY_PAGES) { - while (1) - ; // Error: MAX_DIRTY_PAGES exceeded - } - } + if (!(attributeTable[pageNumber] & + MODIFIED)) { // if page isn't already dirty + mm_n_dirty_pages++; + attributeTable[pageNumber] |= MODIFIED; + } - if (!(attributeTable[pageNumber] & - MODIFIED)) { // if page isn't already dirty - mm_n_dirty_pages++; - attributeTable[pageNumber] |= MODIFIED; - } + // Update LRU with the new dirty page + addLRU(pageNumber); + } - // Update LRU with the new dirty page - addLRU(pageNumber); - } + loadPage(pageNumber); - loadPage(pageNumber); + if ((attributeTable[pageNumber] & REFCNT_MASK) == 0) { + mm_n_active_pages++; + } + attributeTable[pageNumber]++; - if ((attributeTable[pageNumber] & REFCNT_MASK) == 0) { - mm_n_active_pages++; - } - attributeTable[pageNumber]++; - - // Update suspend/restore thresholds - static int oldPageTotal = 0; - if (oldPageTotal != mm_n_dirty_pages + mm_n_active_pages) { - ic_update_thresholds(mm_n_dirty_pages * PAGE_SIZE, - mm_n_active_pages * PAGE_SIZE); - oldPageTotal = mm_n_dirty_pages + mm_n_active_pages; - } + // Update suspend/restore thresholds + static int oldPageTotal = 0; + if (oldPageTotal != mm_n_dirty_pages + mm_n_active_pages) { + ic_update_thresholds(mm_n_dirty_pages * PAGE_SIZE, + mm_n_active_pages * PAGE_SIZE); + oldPageTotal = mm_n_dirty_pages + mm_n_active_pages; + } - return 0; + return 0; } int mm_release(const uint8_t *memPtr) { - uint16_t pageNumber = - ((uint16_t)memPtr - (uint16_t)&__mmdata_start) / PAGE_SIZE; - if ((attributeTable[pageNumber] & REFCNT_MASK) > 0) { - attributeTable[pageNumber]--; - if ((attributeTable[pageNumber] & REFCNT_MASK) == 0) { - mm_n_active_pages--; - } - } else { - while (1) - ; // Error: Attempt to release inactive page +#ifdef ALLOCATEDSTATE + return 0; +#endif + uint16_t pageNumber = + ((uint16_t)memPtr - (uint16_t)&__mmdata_start) / PAGE_SIZE; + if ((attributeTable[pageNumber] & REFCNT_MASK) > 0) { + attributeTable[pageNumber]--; + if ((attributeTable[pageNumber] & REFCNT_MASK) == 0) { + mm_n_active_pages--; } - return 0; + } else { + while (1) + ; // Error: Attempt to release inactive page + } + return 0; } -void mm_restoreStatic(void) { - for (int pageNumber = 0; pageNumber < NPAGES; pageNumber++) { - // Clear loaded pages (bits are set again when calling loadPage) - attributeTable[pageNumber] &= ~LOADED; +void mm_restore(void) { +#ifdef ALLOCATEDSTATE + fastmemcpy(&__mmdata_start, &__mmdata_loadStart, + &__mmdata_end - &__mmdata_start); +#endif - if ((attributeTable[pageNumber] & REFCNT_MASK) > 0) { - loadPage(pageNumber); - } + for (int pageNumber = 0; pageNumber < NPAGES; pageNumber++) { + // Clear loaded pages (bits are set again when calling loadPage) + attributeTable[pageNumber] &= ~LOADED; + + if ((attributeTable[pageNumber] & REFCNT_MASK) > 0) { + loadPage(pageNumber); } + } } unsigned mm_flush(void) { - unsigned pagesSaved = 0; - - for (int pageNumber = 0; pageNumber < NPAGES; pageNumber++) { - if (mm_n_dirty_pages == 0) { - break; - } else if (attributeTable[pageNumber] & MODIFIED) { - writePageFRAM(pageNumber); - pagesSaved++; - if ((attributeTable[pageNumber] & REFCNT_MASK) == 0) { - clearLRUPage(pageNumber); - } - } +#ifdef ALLOCATEDSTATE + // Save entire section + fastmemcpy(&__mmdata_loadStart, &__mmdata_start, + &__mmdata_end - &__mmdata_start); + return (size_t)(&__mmdata_end - &__mmdata_start); +#endif + unsigned pagesSaved = 0; + + for (int pageNumber = 0; pageNumber < NPAGES; pageNumber++) { + if (mm_n_dirty_pages == 0) { + break; + } else if (attributeTable[pageNumber] & MODIFIED) { + writePageFRAM(pageNumber); + pagesSaved++; + if ((attributeTable[pageNumber] & REFCNT_MASK) == 0) { + clearLRUPage(pageNumber); + } } + } - ic_update_thresholds(mm_n_dirty_pages * PAGE_SIZE, - mm_n_active_pages * PAGE_SIZE); + ic_update_thresholds(mm_n_dirty_pages * PAGE_SIZE, + mm_n_active_pages * PAGE_SIZE); - return pagesSaved * PAGE_SIZE; + return pagesSaved * PAGE_SIZE; } /** @@ -169,124 +186,133 @@ unsigned mm_flush(void) { * @param pageNumber */ static void writePageFRAM(uint8_t pageNumber) { - uint16_t dstStart; - uint16_t srcStart; - uint16_t pageOffset = pageNumber * PAGE_SIZE; - uint16_t len; - - if (!(attributeTable[pageNumber] & MODIFIED)) { - return; - } - - uint16_t old_gie = __get_SR_register() & GIE; - __disable_interrupt(); // Critical section (attributes get messed up if - // interrupted) - srcStart = (uint16_t)&__mmdata_start + pageOffset; - dstStart = (uint16_t)(&__mmdata_loadStart) + pageOffset; - len = PAGE_SIZE; - if (srcStart + PAGE_SIZE > (uint16_t)&__mmdata_end) { - len = (uint16_t)&__mmdata_end - srcStart; - } - - // Save page - memcpy((uint8_t *)dstStart, (uint8_t *)srcStart, len); - - if ((attributeTable[pageNumber] & REFCNT_MASK) == 0) { - // Page is clean - attributeTable[pageNumber] &= ~MODIFIED; - mm_n_dirty_pages--; - } - if (old_gie) { - __enable_interrupt(); - } + uint16_t dstStart; + uint16_t srcStart; + uint16_t pageOffset = pageNumber * PAGE_SIZE; + uint16_t len; + + if (!(attributeTable[pageNumber] & MODIFIED)) { + return; + } + + uint16_t old_gie = __get_SR_register() & GIE; + __disable_interrupt(); // Critical section (attributes get messed up if + // interrupted) + srcStart = (uint16_t)&__mmdata_start + pageOffset; + dstStart = (uint16_t)(&__mmdata_loadStart) + pageOffset; + len = PAGE_SIZE; + if (srcStart + PAGE_SIZE > (uint16_t)&__mmdata_end) { + len = (uint16_t)&__mmdata_end - srcStart; + } + + // Save page + fastmemcpy((uint8_t *)dstStart, (uint8_t *)srcStart, len); + + if ((attributeTable[pageNumber] & REFCNT_MASK) == 0) { + // Page is clean + attributeTable[pageNumber] &= ~MODIFIED; + mm_n_dirty_pages--; + } + if (old_gie) { + __enable_interrupt(); + } } int mm_acquire_array(const uint8_t *memPtr, size_t len, mm_mode mode) { - int status = 0; - // Acquire each page referenced - const uint8_t *ptr = memPtr; - size_t remaining = len; - while (remaining > 0) { - status = mm_acquire(ptr, mode); - if (remaining > PAGE_SIZE) { - ptr += PAGE_SIZE; - remaining -= PAGE_SIZE; - } else { - ptr += remaining; - remaining = 0; - } +#ifdef ALLOCATEDSTATE + return 0; +#endif + int status = 0; + // Acquire each page referenced + const uint8_t *ptr = memPtr; + size_t remaining = len; + while (remaining > 0) { + status = mm_acquire(ptr, mode); + if (remaining > PAGE_SIZE) { + ptr += PAGE_SIZE; + remaining -= PAGE_SIZE; + } else { + ptr += remaining; + remaining = 0; } - return status; + } + return status; } int mm_release_array(const uint8_t *memPtr, size_t len) { - int status = 0; - - // Error check - if ((memPtr > &__mmdata_end) || (memPtr < &__mmdata_start) || - (memPtr + len) > &__mmdata_end) { - while (1) - ; // Error: access out of bounds - } - - // Release each page referenced - const uint8_t *ptr = memPtr; - size_t remaining = len; - while (remaining > 0) { - status = mm_release(ptr); - if (remaining > PAGE_SIZE) { - ptr += PAGE_SIZE; - remaining -= PAGE_SIZE; - } else { - ptr += remaining; - remaining = 0; - } +#ifdef ALLOCATEDSTATE + return 0; +#endif + int status = 0; + + // Error check + if ((memPtr > &__mmdata_end) || (memPtr < &__mmdata_start) || + (memPtr + len) > &__mmdata_end) { + while (1) + ; // Error: access out of bounds + } + + // Release each page referenced + const uint8_t *ptr = memPtr; + size_t remaining = len; + while (remaining > 0) { + status = mm_release(ptr); + if (remaining > PAGE_SIZE) { + ptr += PAGE_SIZE; + remaining -= PAGE_SIZE; + } else { + ptr += remaining; + remaining = 0; } - return status; + } + return status; } size_t mm_get_n_active_pages(void) { - size_t nActive = 0; - for (int i = 0; i < NPAGES; i++) { - if ((attributeTable[i] & REFCNT_MASK) > 0) { - nActive++; - } + size_t nActive = 0; + for (int i = 0; i < NPAGES; i++) { + if ((attributeTable[i] & REFCNT_MASK) > 0) { + nActive++; } - return nActive; + } + return nActive; } size_t mm_get_n_dirty_pages(void) { return mm_n_dirty_pages; } int mm_acquire_page(const uint8_t *memPtr, size_t nElements, size_t elementSize, mm_mode mode) { - int bytesAcquired; - - // Check if first element crosses a page boundary - uint16_t pageNumberStart = (memPtr - &__mmdata_start) / PAGE_SIZE; - uint16_t pageNumberEnd = - (memPtr + elementSize - 1 // end address of first element - - &__mmdata_start // - start address - ) / - PAGE_SIZE; - - if (pageNumberStart != pageNumberEnd) { - // Need to load 2 pages - mm_acquire(memPtr, mode); - mm_acquire(memPtr + elementSize - 1, mode); - bytesAcquired = (pageNumberStart + 1) * PAGE_SIZE - - (memPtr - &__mmdata_start) + PAGE_SIZE; - } else { - mm_acquire(memPtr, mode); - bytesAcquired = - (pageNumberStart + 1) * PAGE_SIZE - (memPtr - &__mmdata_start); - } - - // Don't report acquiring more elements than requested - if (bytesAcquired / elementSize >= nElements) { - return nElements; - } else { - return bytesAcquired / elementSize; - } +#ifdef ALLOCATEDSTATE + return nElements; +#endif + int bytesAcquired; + + // Check if first element crosses a page boundary + uint16_t pageNumberStart = (memPtr - &__mmdata_start) / PAGE_SIZE; + uint16_t pageNumberEnd = + (memPtr + elementSize - 1 // end address of first element + - &__mmdata_start // - start address + ) / + PAGE_SIZE; + + if (pageNumberStart != pageNumberEnd) { + // Need to load 2 pages + mm_acquire(memPtr, mode); + mm_acquire(memPtr + elementSize - 1, mode); + bytesAcquired = (pageNumberStart + 1) * PAGE_SIZE - + (memPtr - &__mmdata_start) + PAGE_SIZE; + } else { + mm_acquire(memPtr, mode); + bytesAcquired = + (pageNumberStart + 1) * PAGE_SIZE - (memPtr - &__mmdata_start); + } + + // Don't report acquiring more elements than requested + if (bytesAcquired / elementSize >= nElements) { + return nElements; + } else { + return bytesAcquired / elementSize; + } } /** @@ -294,31 +320,31 @@ int mm_acquire_page(const uint8_t *memPtr, size_t nElements, size_t elementSize, * @param pageNumber */ static void loadPage(uint8_t pageNumber) { - if (!(attributeTable[pageNumber] & LOADED)) { - uint8_t *srcStart; - uint8_t *dstStart; - uint16_t len; - uint16_t pageOffset = pageNumber * PAGE_SIZE; - - dstStart = &__mmdata_start + pageOffset; // Memory address - srcStart = &__mmdata_loadStart + pageOffset; // Snapshot address - len = PAGE_SIZE; - if ((uint16_t)dstStart + PAGE_SIZE > (uint16_t)&__mmdata_end) { - len = (uint16_t)&__mmdata_end - (uint16_t)dstStart; - } + if (!(attributeTable[pageNumber] & LOADED)) { + uint8_t *srcStart; + uint8_t *dstStart; + uint16_t len; + uint16_t pageOffset = pageNumber * PAGE_SIZE; - memcpy((uint8_t *)dstStart, (uint8_t *)srcStart, len); - attributeTable[pageNumber] |= LOADED; + dstStart = &__mmdata_start + pageOffset; // Memory address + srcStart = &__mmdata_loadStart + pageOffset; // Snapshot address + len = PAGE_SIZE; + if ((uint16_t)dstStart + PAGE_SIZE > (uint16_t)&__mmdata_end) { + len = (uint16_t)&__mmdata_end - (uint16_t)dstStart; } + + fastmemcpy((uint8_t *)dstStart, (uint8_t *)srcStart, len); + attributeTable[pageNumber] |= LOADED; + } } /** * @brief Initialise LRU table with dummy pages */ void mm_init_lru(void) { - for (int i = 0; i < MAX_DIRTY_PAGES; i++) { - lruTable[i] = DUMMY_PAGE; - } + for (int i = 0; i < MAX_DIRTY_PAGES; i++) { + lruTable[i] = DUMMY_PAGE; + } } /** @@ -326,39 +352,39 @@ void mm_init_lru(void) { * @param pageNumber */ static void addLRU(uint8_t pageNumber) { - uint8_t tmp1, tmp2; - - if (pageNumber > NPAGES) { - while (1) - ; // Error: page number out of bounds. - } - - tmp1 = pageNumber; - for (int i = 0; i < MAX_DIRTY_PAGES; i++) { - if (lruTable[i] == pageNumber) { - lruTable[i] = tmp1; - for (int j = i + 1; j < MAX_DIRTY_PAGES; j++) { - if (lruTable[j] == tmp1) { - lruTable[j] = DUMMY_PAGE; - break; - } - } - break; - } else if (lruTable[i] == DUMMY_PAGE) { - lruTable[i] = tmp1; - for (int j = i + 1; j < MAX_DIRTY_PAGES; j++) { - if (lruTable[j] == tmp1) { - lruTable[j] = DUMMY_PAGE; - break; - } - } - break; - } else { - tmp2 = lruTable[i]; - lruTable[i] = tmp1; - tmp1 = tmp2; + uint8_t tmp1, tmp2; + + if (pageNumber > NPAGES) { + while (1) + ; // Error: page number out of bounds. + } + + tmp1 = pageNumber; + for (int i = 0; i < MAX_DIRTY_PAGES; i++) { + if (lruTable[i] == pageNumber) { + lruTable[i] = tmp1; + for (int j = i + 1; j < MAX_DIRTY_PAGES; j++) { + if (lruTable[j] == tmp1) { + lruTable[j] = DUMMY_PAGE; + break; + } + } + break; + } else if (lruTable[i] == DUMMY_PAGE) { + lruTable[i] = tmp1; + for (int j = i + 1; j < MAX_DIRTY_PAGES; j++) { + if (lruTable[j] == tmp1) { + lruTable[j] = DUMMY_PAGE; + break; } + } + break; + } else { + tmp2 = lruTable[i]; + lruTable[i] = tmp1; + tmp1 = tmp2; } + } } /** @@ -372,11 +398,11 @@ static void clearLRU(uint8_t index) { lruTable[index] = DUMMY_PAGE; } * @param pageNumber */ static void clearLRUPage(uint8_t pageNumber) { - for (int i = MAX_DIRTY_PAGES - 1; i >= 0; i--) { - if (lruTable[i] == pageNumber) { - lruTable[i] = DUMMY_PAGE; - return; - } + for (int i = MAX_DIRTY_PAGES - 1; i >= 0; i--) { + if (lruTable[i] == pageNumber) { + lruTable[i] = DUMMY_PAGE; + return; } + } } diff --git a/iclib/memory_management.h b/iclib/memory_management.h index a0d8c3a..2f8409f 100644 --- a/iclib/memory_management.h +++ b/iclib/memory_management.h @@ -23,14 +23,14 @@ typedef enum { MM_READONLY, MM_READWRITE } mm_mode; * @param Pointer to variable held in static memory * @parapm mm_mode access mode */ -int mm_acquire(const uint8_t* memPtr, mm_mode mode); +int mm_acquire(const uint8_t *memPtr, mm_mode mode); /** * @brief Release a byte from managed memory. * @param Pointer to variable held in static memory * @return Status: 0=success */ -int mm_release(const uint8_t* memPtr); +int mm_release(const uint8_t *memPtr); /** * @brief Acquire an array from static memory @@ -39,7 +39,7 @@ int mm_release(const uint8_t* memPtr); * @param mm_mode access mode * @return */ -int mm_acquire_array(const uint8_t* memPtr, size_t len, mm_mode mode); +int mm_acquire_array(const uint8_t *memPtr, size_t len, mm_mode mode); /** * @brief Release array @@ -47,7 +47,7 @@ int mm_acquire_array(const uint8_t* memPtr, size_t len, mm_mode mode); * @param len size of array * @return */ -int mm_release_array(const uint8_t* memPtr, size_t len); +int mm_release_array(const uint8_t *memPtr, size_t len); /** * @brief Aquire data from an array one page at a time. May load two pages if @@ -57,7 +57,7 @@ int mm_release_array(const uint8_t* memPtr, size_t len); * @param mm_mode access mode * @return Number of elements acquired. */ -int mm_acquire_page(const uint8_t* memPtr, size_t nElements, size_t elementSize, +int mm_acquire_page(const uint8_t *memPtr, size_t nElements, size_t elementSize, mm_mode mode); /** * @brief Get the number of currently active pages @@ -75,7 +75,7 @@ void mm_init_lru(void); /** * @brief Restore all active pages to memory from FRAM */ -void mm_restoreStatic(void); +void mm_restore(void); /** * @brief Save all modified pages to FRAM diff --git a/matmul-tiled/CMakeLists.txt b/matmul-tiled/CMakeLists.txt index a56fc5c..9144a8c 100644 --- a/matmul-tiled/CMakeLists.txt +++ b/matmul-tiled/CMakeLists.txt @@ -1,26 +1,22 @@ cmake_minimum_required(VERSION 3.0) -include(${CMAKE_CURRENT_LIST_DIR}/../common.cmake) - -project(matmul-tiled) - -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -include_directories(${ICLIB_ROOT}) -link_directories(${ICLIB_ROOT}) - -add_executable( - ${PROJECT_NAME} - main.c - input.h -) - -add_msp_upload(${PROJECT_NAME}) - -target_link_libraries(${PROJECT_NAME} ${SUPPORT_LIBS}) - -set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".elf") - -add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${MSP430-SIZE} "$<TARGET_FILE:${PROJECT_NAME}>" - COMMENT "Invoking: msp430-elf-size") +FOREACH(METHOD "MS" "AS") + set(TESTNAME "matmul-tiled-${METHOD}") + add_executable( + ${TESTNAME} + main.c + input.h + ) + IF (${METHOD} STREQUAL "AS") + target_compile_definitions( ${TESTNAME} PUBLIC -DALLOCATEDSTATE) + ENDIF() + add_msp_upload(${TESTNAME}) + target_link_libraries( + ${TESTNAME} + LINK_PUBLIC ic-${METHOD} + ${SUPPORT_LIBS}) + set_target_properties(${TESTNAME} PROPERTIES SUFFIX ".elf") + add_custom_command(TARGET ${TESTNAME} POST_BUILD + COMMAND ${MSP430-SIZE} -A -d "$<TARGET_FILE:${TESTNAME}>" + COMMENT "Invoking: msp430-elf-size") +ENDFOREACH() diff --git a/matmul/CMakeLists.txt b/matmul/CMakeLists.txt index e04f5a7..f393841 100644 --- a/matmul/CMakeLists.txt +++ b/matmul/CMakeLists.txt @@ -1,26 +1,23 @@ cmake_minimum_required(VERSION 3.0) -include(${CMAKE_CURRENT_LIST_DIR}/../common.cmake) +FOREACH(METHOD "MS" "AS") + set(TESTNAME "matmul-${METHOD}") + add_executable( + ${TESTNAME} + main.c + input.h + ) + IF (${METHOD} STREQUAL "AS") + target_compile_definitions( ${TESTNAME} PUBLIC -DALLOCATEDSTATE) + ENDIF() + add_msp_upload(${TESTNAME}) + target_link_libraries( + ${TESTNAME} + LINK_PUBLIC ic-${METHOD} + ${SUPPORT_LIBS}) + set_target_properties(${TESTNAME} PROPERTIES SUFFIX ".elf") + add_custom_command(TARGET ${TESTNAME} POST_BUILD + COMMAND ${MSP430-SIZE} -A -d "$<TARGET_FILE:${TESTNAME}>" + COMMENT "Invoking: msp430-elf-size") +ENDFOREACH() -project(matmul) - -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -include_directories(${ICLIB_ROOT}) -link_directories(${ICLIB_ROOT}) - -add_executable( - ${PROJECT_NAME} - main.c - input.h -) - -add_msp_upload(${PROJECT_NAME}) - -target_link_libraries(${PROJECT_NAME} ${SUPPORT_LIBS}) - -set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".elf") - -add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${MSP430-SIZE} "$<TARGET_FILE:${PROJECT_NAME}>" - COMMENT "Invoking: msp430-elf-size") -- GitLab