diff --git a/flashlib.c b/flashlib.c index 9226ed4..7552cc7 100644 --- a/flashlib.c +++ b/flashlib.c @@ -43,6 +43,12 @@ flstatus_t flash_commit(flash_operation_t op); #error "When defining PROTECTED_FLASH_SECTOR_TO you should also provide PROTECTED_FLASH_SECTOR_FROM" #endif +unsigned char is_address_kseg(fladdr_t address) { + // KSEG0 = 0x9xxxxxxx + // KSEG1 = 0xBxxxxxxx + return (address & 0xF0000000) >= 0x90000000; +} + #ifdef ENABLE_EEPROM_EMU #ifndef EEPROM_SECTOR_START #error "EEPROM_SECTOR_START is not defined. Provide a physical program flash address for this" @@ -65,6 +71,8 @@ flstatus_t flash_commit(flash_operation_t op); } flword_t eeprom_read_word(flword_t* ee_address) { + if(!is_address_kseg((fladdr_t)ee_address)) + return FLASH_ADDRESS_NOT_KERNEL_SPACE; if(!is_address_within_eeprom_sector((fladdr_t)ee_address)) return EEPROM_OUT_OF_RANGE_ERR; return *ee_address; @@ -87,21 +95,25 @@ unsigned char is_address_within_protected_sector(fladdr_t address) { #endif } -flstatus_t flash_program_page(fladdr_t address, const flword_t* data, flword_t data_byte_size) { - if(is_address_within_protected_sector(address)) +flstatus_t flash_program_page(fladdr_t kseg1_address, const flword_t* data, flword_t data_byte_size) { + if(!is_address_kseg(kseg1_address)) + return FLASH_ADDRESS_NOT_KERNEL_SPACE; + if(is_address_within_protected_sector(kseg1_address)) return FLASH_PROTECTED_ERR; - if(address % PAGE_SIZE != 0) + if(kseg1_address % PAGE_SIZE != 0) return FLASH_NOT_ALIGNED; flword_t flash_page[PAGE_SIZE]; - memcpy(flash_page, (flword_t*)address, PAGE_SIZE); + memcpy(flash_page, (flword_t*)kseg1_address, PAGE_SIZE); memcpy(flash_page, data, data_byte_size); - return flash_write_page(address, flash_page); + return flash_write_page(kseg1_address, flash_page); } -flstatus_t flash_program_page_offset(fladdr_t address, const flword_t* data, flword_t data_byte_size) { - flword_t offset = address % PAGE_SIZE; - fladdr_t offset_address = address - offset; +flstatus_t flash_program_page_offset(fladdr_t kseg1_address, const flword_t* data, flword_t data_byte_size) { + if(!is_address_kseg(kseg1_address)) + return FLASH_ADDRESS_NOT_KERNEL_SPACE; + flword_t offset = kseg1_address % PAGE_SIZE; + fladdr_t offset_address = kseg1_address - offset; if(is_address_within_protected_sector(offset_address)) return FLASH_PROTECTED_ERR; diff --git a/flashlib.h b/flashlib.h index d5c524d..5a4e0ff 100644 --- a/flashlib.h +++ b/flashlib.h @@ -26,10 +26,12 @@ typedef uint16_t flstatus_t; #define FLASH_PROTECTED_ERR 0x8 #define EEPROM_OUT_OF_RANGE_ERR 0x9 #define FLASH_NOT_ALIGNED 0x10 +#define FLASH_ADDRESS_NOT_KERNEL_SPACE 0x11 #ifdef ENABLE_EEPROM_EMU /// Read a word from provided eeprom address /// Returns EEPROM_OUT_OF_RANGE_ERR if provided address is not in the eeprom sector +/// Returns FLASH_ADDRESS_NOT_KERNEL_SPACE if kseg1_address is not in kernel space (cant read from physical address) flword_t eeprom_read_word(flword_t* ee_address); /// Write a single word to provided eeprom address @@ -62,18 +64,21 @@ flstatus_t flash_erase_page(fladdr_t address); flstatus_t flash_write_page(fladdr_t address, const flword_t* data); /// Read / Modify / Write cycle for programming a page with data with size -/// Note: provided address should be page-aligned +/// Note: provided kseg1_address should be page-aligned /// Note: if data_byte_size is larger than PAGE_SIZE, only PAGE_SIZE amount of data is written. Rest is ignored -/// Returns FLASH_PROTECTED_ERR if address is in the protected sector -/// Returns FLASH_NOT_ALIGNED if address is not page-aligned +/// Returns FLASH_PROTECTED_ERR if kseg1_address is in the protected sector +/// Returns FLASH_NOT_ALIGNED if kseg1_address is not page-aligned +/// Returns FLASH_ADDRESS_NOT_KERNEL_SPACE if kseg1_address is not in kernel space (required for the read-part of the algorithm) /// Returns 0 (nil) if successful -flstatus_t flash_program_page(fladdr_t address, const flword_t* data, flword_t data_byte_size); +flstatus_t flash_program_page(fladdr_t kseg1_address, const flword_t* data, flword_t data_byte_size); /// Read / Modify / Write cycle for programming a page with data with size /// Note: if data_byte_size is larger than PAGE_SIZE, only PAGE_SIZE amount of data is written. Rest is ignored -/// Returns FLASH_PROTECTED_ERR if address is in the protected sector +/// Note: make sure that provided address is in kernel space. Otherwise the read step fails. +/// Returns FLASH_PROTECTED_ERR if kseg1_address is in the protected sector +/// Returns FLASH_ADDRESS_NOT_KERNEL_SPACE if kseg1_address is not in kernel space (required for the read-part of the algorithm) /// Returns 0 (nil) if successful -flstatus_t flash_program_page_offset(fladdr_t address, const flword_t* data, flword_t data_byte_size); +flstatus_t flash_program_page_offset(fladdr_t kseg1_address, const flword_t* data, flword_t data_byte_size); #ifndef DISABLE_ERASE_ALL_PROGRAM_MEM /// Erase all data in program memory.