xfdump: implement dump-to-xflash functionality
Update xflash_layout to include information about the dump, which sits at the end of xflash.
This commit is contained in:
parent
b398a09a4f
commit
6dfef76346
4 changed files with 163 additions and 1 deletions
|
@ -278,7 +278,7 @@ void dcode_1()
|
||||||
*/
|
*/
|
||||||
void dcode_2()
|
void dcode_2()
|
||||||
{
|
{
|
||||||
dcode_core(0x200, 0x2200, dcode_mem_t::sram, 2, _N("SRAM"));
|
dcode_core(SRAM_START, SRAM_START + SRAM_SIZE, dcode_mem_t::sram, 2, _N("SRAM"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
106
Firmware/xflash_dump.cpp
Normal file
106
Firmware/xflash_dump.cpp
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <avr/wdt.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
#include "xflash_dump.h"
|
||||||
|
#include "xflash.h"
|
||||||
|
|
||||||
|
|
||||||
|
bool xfdump_check_state()
|
||||||
|
{
|
||||||
|
uint32_t magic;
|
||||||
|
|
||||||
|
XFLASH_SPI_ENTER();
|
||||||
|
xflash_rd_data(DUMP_OFFSET + offsetof(dump_t, header.magic),
|
||||||
|
(uint8_t*)&magic, sizeof(magic));
|
||||||
|
|
||||||
|
return magic == DUMP_MAGIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xfdump_check_crash()
|
||||||
|
{
|
||||||
|
// check_state with SPI_ENTER for us
|
||||||
|
if(!xfdump_check_state())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint8_t crash;
|
||||||
|
xflash_rd_data(DUMP_OFFSET + offsetof(dump_t, header.crash),
|
||||||
|
(uint8_t*)&crash, sizeof(crash));
|
||||||
|
return crash;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xfdump_reset()
|
||||||
|
{
|
||||||
|
XFLASH_SPI_ENTER();
|
||||||
|
xflash_enable_wr();
|
||||||
|
xflash_sector_erase(DUMP_OFFSET + offsetof(dump_t, header.magic));
|
||||||
|
xflash_wait_busy();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void xfdump_erase()
|
||||||
|
{
|
||||||
|
XFLASH_SPI_ENTER();
|
||||||
|
for(uint32_t addr = DUMP_OFFSET;
|
||||||
|
addr < DUMP_OFFSET + DUMP_SIZE;
|
||||||
|
addr += 4096)
|
||||||
|
{
|
||||||
|
xflash_enable_wr();
|
||||||
|
xflash_sector_erase(DUMP_OFFSET);
|
||||||
|
xflash_wait_busy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void xfdump_dump_core(dump_header_t& hdr, uint32_t addr, uint8_t* buf, uint16_t cnt)
|
||||||
|
{
|
||||||
|
XFLASH_SPI_ENTER();
|
||||||
|
|
||||||
|
// start by clearing all sectors (we need all of them in any case)
|
||||||
|
xfdump_erase();
|
||||||
|
|
||||||
|
// write header
|
||||||
|
static_assert(sizeof(hdr) < 256, "header is larger than a single page write");
|
||||||
|
xflash_enable_wr();
|
||||||
|
xflash_page_program(DUMP_OFFSET, (uint8_t*)&hdr, sizeof(hdr));
|
||||||
|
xflash_wait_busy();
|
||||||
|
|
||||||
|
// write data
|
||||||
|
xflash_multipage_program(addr, buf, cnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xfdump_dump()
|
||||||
|
{
|
||||||
|
dump_header_t buf;
|
||||||
|
buf.magic = DUMP_MAGIC;
|
||||||
|
buf.regs_present = false;
|
||||||
|
buf.crash = false;
|
||||||
|
|
||||||
|
// write sram only
|
||||||
|
xfdump_dump_core(buf, DUMP_OFFSET + offsetof(dump_t, data.sram),
|
||||||
|
(uint8_t*)SRAM_START, SRAM_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xfdump_full_dump_and_reset(bool crash)
|
||||||
|
{
|
||||||
|
dump_header_t buf;
|
||||||
|
buf.magic = DUMP_MAGIC;
|
||||||
|
buf.regs_present = true;
|
||||||
|
buf.crash = crash;
|
||||||
|
|
||||||
|
// disable interrupts for a cleaner register dump
|
||||||
|
cli();
|
||||||
|
|
||||||
|
// write all addressable ranges (this will trash bidirectional registers)
|
||||||
|
xfdump_dump_core(buf, DUMP_OFFSET + offsetof(dump_t, data),
|
||||||
|
0, SRAM_START + SRAM_SIZE);
|
||||||
|
|
||||||
|
// force a reset soon
|
||||||
|
wdt_enable(0);
|
||||||
|
while(true);
|
||||||
|
}
|
14
Firmware/xflash_dump.h
Normal file
14
Firmware/xflash_dump.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// XFLASH dumper
|
||||||
|
#pragma once
|
||||||
|
#include "xflash_layout.h"
|
||||||
|
#ifdef XFLASH_DUMP
|
||||||
|
|
||||||
|
void xfdump_reset(); // reset XFLASH dump state
|
||||||
|
bool xfdump_check_state(); // return true if a dump is present
|
||||||
|
bool xfdump_check_crash(); // return true if a dump is present and is a crash dump
|
||||||
|
void xfdump_dump(); // create a new SRAM memory dump
|
||||||
|
|
||||||
|
// create a new dump containing registers and SRAM, then reset
|
||||||
|
void xfdump_full_dump_and_reset(bool crash = false);
|
||||||
|
|
||||||
|
#endif
|
|
@ -4,5 +4,47 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#define XFLASH_SIZE 0x40000ul // size of XFLASH
|
#define XFLASH_SIZE 0x40000ul // size of XFLASH
|
||||||
|
#define SRAM_SIZE 0x2000u // size of SRAM
|
||||||
|
#define SRAM_START 0x200u // start of SRAM
|
||||||
|
|
||||||
#define LANG_OFFSET 0x0 // offset for language data
|
#define LANG_OFFSET 0x0 // offset for language data
|
||||||
|
|
||||||
|
#ifndef XFLASH_DUMP
|
||||||
#define LANG_SIZE XFLASH_SIZE
|
#define LANG_SIZE XFLASH_SIZE
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define DUMP_MAGIC 0x47555255ul
|
||||||
|
|
||||||
|
struct dump_header_t
|
||||||
|
{
|
||||||
|
// start with a magic value to indicate the presence of a dump, so that clearing
|
||||||
|
// a single page is sufficient for resetting the state
|
||||||
|
uint32_t magic;
|
||||||
|
|
||||||
|
uint8_t regs_present; // true when the lower segment containing registers is present
|
||||||
|
uint8_t crash; // true if triggered by EMERGENCY_DUMP
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dump_data_t
|
||||||
|
{
|
||||||
|
// contiguous region containing all addressable ranges
|
||||||
|
uint8_t regs[SRAM_START];
|
||||||
|
uint8_t sram[SRAM_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dump_t
|
||||||
|
{
|
||||||
|
struct dump_header_t header;
|
||||||
|
|
||||||
|
// data is page aligned (no real space waste, due to the larger
|
||||||
|
// alignment required for the whole dump)
|
||||||
|
struct dump_data_t __attribute__((aligned(256))) data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// dump offset must be aligned to lower 4kb sector boundary
|
||||||
|
#define DUMP_OFFSET ((XFLASH_SIZE - sizeof(dump_t)) & ~0xFFFul)
|
||||||
|
|
||||||
|
#define DUMP_SIZE (XFLASH_SIZE - DUMP_OFFSET) // effective dump size area
|
||||||
|
#define LANG_SIZE DUMP_OFFSET // available language space
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue