// erase bootloader's section and write over it with new bootloader code void write_new_bootloader(void) { uint16_t outgoing_page[SPM_PAGESIZE / 2]; int iter = 0; while (iter < sizeof(bootloader_data)) { // read in one page's worth of data from progmem int word_addr = 0; while (word_addr < SPM_PAGESIZE) { int subaddress = ((int) bootloader_data) + iter + word_addr; if (subaddress >= ((int) bootloader_data) + sizeof(bootloader_data)) { outgoing_page[word_addr / 2] = 0xFFFF; } else { outgoing_page[word_addr / 2] = pgm_read_word(subaddress); } word_addr += 2; } // erase page in destination erase_page(bootloader_address + iter); // write updated page write_page(bootloader_address + iter, outgoing_page); iter += 64; } }
// write in forwarding interrupt vector table void forward_interrupt_vector_table(void) { uint16_t vector_table[SPM_PAGESIZE / 2]; int iter = 0; while (iter < SPM_PAGESIZE / 2) { // rjmp to bootloader_address's interrupt table vector_table[iter] = 0xC000 + (bootloader_address / 2) - 1; iter++; } erase_page(0); write_page(0, vector_table); }
int flash_stm32_block_erase_loop(struct device *dev, unsigned int offset, unsigned int len) { int i, rc = 0; i = get_page(offset); for (; i <= get_page(offset + len - 1) ; ++i) { rc = erase_page(dev, i); if (rc < 0) { break; } } return rc; }
// erase first page, removing any interrupt table hooks the bootloader added when // upgrade was uploaded void secure_interrupt_vector_table(void) { uint16_t table[SPM_PAGESIZE / 2]; load_table(0, table); // wipe out any interrupt hooks the bootloader rewrote int i = 0; while (i < SPM_PAGESIZE / 2) { table[0] = 0xFFFF; i++; } erase_page(0); write_page(0, table); }
long eprom24x_io::erase(void) { try { // Lockdown the erase operation pthread_mutex_lock(&m_rw_mutex); // Use page write if supported by chip if (m_page_size_in_bytes) { erase_page(); } else { erase_byte(); } pthread_mutex_unlock(&m_rw_mutex); return EPROM24x_SUCCESS; } catch (...) { pthread_mutex_unlock(&m_rw_mutex); throw; } }
static svn_error_t * inprocess_cache_set_internal(inprocess_cache_t *cache, const void *key, void *value, apr_pool_t *scratch_pool) { struct cache_entry *existing_entry; existing_entry = apr_hash_get(cache->hash, key, cache->klen); /* Is it already here, but we can do the one-item-per-page * optimization? */ if (existing_entry && cache->items_per_page == 1) { /* Special case! ENTRY is the *only* entry on this page, so * why not wipe it (so as not to leak the previous value). */ struct cache_page *page = existing_entry->page; /* This can't be the partial page: items_per_page == 1 * *never* has a partial page (except for in the temporary state * that we're about to fake). */ SVN_ERR_ASSERT(page->next != NULL); SVN_ERR_ASSERT(cache->partial_page == NULL); erase_page(cache, page); existing_entry = NULL; } /* Is it already here, and we just have to leak the old value? */ if (existing_entry) { struct cache_page *page = existing_entry->page; SVN_ERR(move_page_to_front(cache, page)); cache->data_size -= existing_entry->size; if (value) { SVN_ERR(cache->serialize_func(&existing_entry->value, &existing_entry->size, value, page->page_pool)); cache->data_size += existing_entry->size; if (existing_entry->size == 0) existing_entry->value = NULL; } else { existing_entry->value = NULL; existing_entry->size = 0; } return SVN_NO_ERROR; } /* Do we not have a partial page to put it on, but we are allowed to * allocate more? */ if (cache->partial_page == NULL && cache->unallocated_pages > 0) { cache->partial_page = apr_pcalloc(cache->cache_pool, sizeof(*(cache->partial_page))); cache->partial_page->page_pool = svn_pool_create(cache->cache_pool); cache->partial_page_number_filled = 0; (cache->unallocated_pages)--; } /* Do we really not have a partial page to put it on, even after the * one-item-per-page optimization and checking the unallocated page * count? */ if (cache->partial_page == NULL) { struct cache_page *oldest_page = cache->sentinel->prev; SVN_ERR_ASSERT(oldest_page != cache->sentinel); /* Erase the page and put it in cache->partial_page. */ erase_page(cache, oldest_page); } SVN_ERR_ASSERT(cache->partial_page != NULL); { struct cache_page *page = cache->partial_page; struct cache_entry *new_entry = apr_pcalloc(page->page_pool, sizeof(*new_entry)); /* Copy the key and value into the page's pool. */ new_entry->key = duplicate_key(cache, key, page->page_pool); if (value) { SVN_ERR(cache->serialize_func(&new_entry->value, &new_entry->size, value, page->page_pool)); cache->data_size += new_entry->size; if (new_entry->size == 0) new_entry->value = NULL; } else { new_entry->value = NULL; new_entry->size = 0; } /* Add the entry to the page's list. */ new_entry->page = page; new_entry->next_entry = page->first_entry; page->first_entry = new_entry; /* Add the entry to the hash, using the *entry's* copy of the * key. */ apr_hash_set(cache->hash, new_entry->key, cache->klen, new_entry); /* We've added something else to the partial page. */ (cache->partial_page_number_filled)++; /* Is it full? */ if (cache->partial_page_number_filled >= cache->items_per_page) { insert_page(cache, page); cache->partial_page = NULL; } } return SVN_NO_ERROR; }
/* * ANSI x3.64 defines erase functions: */ void crt__ED (int y, int x) /* Erase to end of Display */ { crt_move (y, x); scr$erase_page (); }
int main(int argc, char *argv[]) { int fd; int i; struct context ctx; if (0 != parse_options(argc, argv)) { usage(); return 1; } if ((fd = serialOpen(device_name)) < 0) { fprintf(stderr, "Failed to open %s\n", device_name); return 1; } ctx.fd = fd; if (opt_flash) { if (0 != check_for_bootloader(fd, opt_timeout)) { fprintf(stderr, "No bootloader detected\n"); return 1; } else { printf("Bootloader detected\n"); } for (i=0;i<FLASH_SIZE_KB/FLASH_PAGE_SIZE;i++) { printf("Erasing page %d\n", i); if (0 != erase_page(fd, i)) { fprintf(stderr, "Erasing page failed\n"); return 1; } } if (0 != read_hexfile(flash_filename, handle_record_00, handle_record_04, &ctx)) { fprintf(stderr, "Failed to read %s\n", flash_filename); return 1; } if (0 != reset(fd)) { fprintf(stderr, "Reset failed\n"); return 1; } } if (opt_console) { atexit(do_exit); printf("Connected to %s, ctrl-c to exit\n", device_name); do_console(fd); } serialClose(fd); return 0; }
void load_bin(void) { unsigned char c; int ret; u32union page_addr; unsigned int crc, rcrc, i; for (i = 0; i < PAGE_SIZE; i++) page[i].b[3] = 0xff; while (1) { /* request page */ /* 3 bytes - msb first */ page_addr.b[3] = 0; ret = get_char((char*) &page_addr.b[2]); ret |= get_char((char*) &page_addr.b[1]); ret |= get_char((char*) &page_addr.b[0]); if (page_addr.l == 0x00ffffff) { put_char('e'); break; } else { put_char('p'); } page_addr.l &= ~((PAGE_SIZE << 1)-1); if ( ((page_addr.l >= BOOT_FLASH_START_ADDR) && (page_addr.l < BOOT_FLASH_END_ADDR)) || (page_addr.l == DEV_CONFIG_PAGE_ADDRESS) ) { put_char('s'); continue; } else { put_char('d'); } /* load page to sram */ ret = 0; crc = 0; for (i = 0; i < PAGE_SIZE; i++) { ret |= get_char((char*) &c); crc += c; page[i].b[2] = c; ret |= get_char((char*) &c); crc += c; page[i].b[1] = c; ret |= get_char((char*) &c); crc += c; page[i].b[0] = c; } /* get crc */ put_char('c'); rcrc = 0; ret |= get_char((char*) &c); rcrc = c << 8; ret |= get_char((char*) &c); rcrc |= c; if (rcrc != crc) { ret = 100; put_char('x'); } if (ret) break; erase_page(page_addr.l); put_char('e'); /* protect bootloader start addr */ if (page_addr.l == 0) { page[0].l = 0x040800; page[1].l = 0x000000; } for (i = 0; i < PAGE_SIZE/2; i++) { write_dword(page_addr.l + i*4, page[i*2].l, page[i*2 + 1].l); } put_char('w'); } if (ret) { put_char('X'); while (1); } else { put_char('K'); goto_usercode(); } }