Use byte-wise read/write when page size is 1 in terminal cache

This commit is contained in:
Stefan Rueger 2022-10-11 15:31:18 +01:00
parent e14e5d2f74
commit 48919f59b3
No known key found for this signature in database
GPG Key ID: B0B4F1FD86B1EC55
1 changed files with 19 additions and 3 deletions

View File

@ -114,7 +114,10 @@
* - Memory has positive page size, which is a power of two * - Memory has positive page size, which is a power of two
* - Memory has positive size, which is a multiple of the page size * - Memory has positive size, which is a multiple of the page size
* - Memory is flash type or eeprom type * - Memory is flash type or eeprom type
*
* Note that in this definition the page size can be 1
*/ */
int avr_has_paged_access(const PROGRAMMER *pgm, const AVRMEM *mem) { int avr_has_paged_access(const PROGRAMMER *pgm, const AVRMEM *mem) {
return pgm->paged_load && pgm->paged_write && return pgm->paged_load && pgm->paged_write &&
mem->page_size > 0 && (mem->page_size & (mem->page_size-1)) == 0 && mem->page_size > 0 && (mem->page_size & (mem->page_size-1)) == 0 &&
@ -127,6 +130,7 @@ int avr_has_paged_access(const PROGRAMMER *pgm, const AVRMEM *mem) {
* Read the page containing addr from the device into buf * Read the page containing addr from the device into buf
* - Caller to ensure buf has mem->page_size bytes * - Caller to ensure buf has mem->page_size bytes
* - Part memory buffer mem is unaffected by this (though temporarily changed) * - Part memory buffer mem is unaffected by this (though temporarily changed)
* - Uses read_byte() if memory page size is one, otherwise paged_load()
*/ */
int avr_read_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int addr, unsigned char *buf) { int avr_read_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int addr, unsigned char *buf) {
if(!avr_has_paged_access(pgm, mem) || addr < 0 || addr >= mem->size) if(!avr_has_paged_access(pgm, mem) || addr < 0 || addr >= mem->size)
@ -135,6 +139,9 @@ int avr_read_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
int rc, pgsize = mem->page_size, off = addr & ~(pgsize-1); int rc, pgsize = mem->page_size, off = addr & ~(pgsize-1);
unsigned char *pagecopy = cfg_malloc("avr_read_page_default()", pgsize); unsigned char *pagecopy = cfg_malloc("avr_read_page_default()", pgsize);
if(pgsize == 1)
return pgm->read_byte(pgm, p, mem, addr, buf);
memcpy(pagecopy, mem->buf + off, pgsize); memcpy(pagecopy, mem->buf + off, pgsize);
if((rc = pgm->paged_load(pgm, p, mem, pgsize, off, pgsize)) >= 0) if((rc = pgm->paged_load(pgm, p, mem, pgsize, off, pgsize)) >= 0)
memcpy(buf, mem->buf + off, pgsize); memcpy(buf, mem->buf + off, pgsize);
@ -149,6 +156,7 @@ int avr_read_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
* Write the data page to the device into the page containing addr * Write the data page to the device into the page containing addr
* - Caller to provide all mem->page_size bytes incl padding if any * - Caller to provide all mem->page_size bytes incl padding if any
* - Part memory buffer mem is unaffected by this (though temporarily changed) * - Part memory buffer mem is unaffected by this (though temporarily changed)
* - Uses write_byte() if memory page size is one, otherwise paged_write()
*/ */
int avr_write_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int addr, unsigned char *data) { int avr_write_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int addr, unsigned char *data) {
if(!avr_has_paged_access(pgm, mem) || addr < 0 || addr >= mem->size) if(!avr_has_paged_access(pgm, mem) || addr < 0 || addr >= mem->size)
@ -157,6 +165,9 @@ int avr_write_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
int rc, pgsize = mem->page_size, off = addr & ~(pgsize-1); int rc, pgsize = mem->page_size, off = addr & ~(pgsize-1);
unsigned char *pagecopy = cfg_malloc("avr_write_page_default()", pgsize); unsigned char *pagecopy = cfg_malloc("avr_write_page_default()", pgsize);
if(pgsize == 1)
return pgm->write_byte(pgm, p, mem, addr, *data);
memcpy(pagecopy, mem->buf + off, pgsize); memcpy(pagecopy, mem->buf + off, pgsize);
memcpy(mem->buf + off, data, pgsize); memcpy(mem->buf + off, data, pgsize);
rc = pgm->paged_write(pgm, p, mem, pgsize, off, pgsize); rc = pgm->paged_write(pgm, p, mem, pgsize, off, pgsize);
@ -652,11 +663,16 @@ int avr_page_erase_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
int addr = uaddr; int addr = uaddr;
if(!pgm->page_erase || !avr_has_paged_access(pgm, mem) || addr < 0 || addr >= mem->size) if(!avr_has_paged_access(pgm, mem) || addr < 0 || addr >= mem->size)
return LIBAVRDUDE_GENERAL_FAILURE; return LIBAVRDUDE_GENERAL_FAILURE;
if(pgm->page_erase(pgm, p, mem, uaddr) < 0) if(mem->page_size == 1) {
return LIBAVRDUDE_GENERAL_FAILURE; if(pgm->write_byte(pgm, p, mem, uaddr, 0xff) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
} else {
if(!pgm->page_erase || pgm->page_erase(pgm, p, mem, uaddr) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
}
AVR_Cache *cp = avr_mem_is_eeprom_type(mem)? pgm->cp_eeprom: pgm->cp_flash; AVR_Cache *cp = avr_mem_is_eeprom_type(mem)? pgm->cp_eeprom: pgm->cp_flash;