24 #define PIC32MX_MANUF_ID    0x029 
   28 #define PIC32MX_PHYS_RAM            0x00000000 
   29 #define PIC32MX_PHYS_PGM_FLASH      0x1D000000 
   30 #define PIC32MX_PHYS_PERIPHERALS    0x1F800000 
   31 #define PIC32MX_PHYS_BOOT_FLASH     0x1FC00000 
   38 #define virt2phys(v)    ((v) & 0x1FFFFFFF) 
   42 #define PIC32MX_DEVCFG0_1XX_2XX 0xBFC00BFC 
   43 #define PIC32MX_DEVCFG0     0xBFC02FFC 
   44 #define PIC32MX_DEVCFG1     0xBFC02FF8 
   45 #define PIC32MX_DEVCFG2     0xBFC02FF4 
   46 #define PIC32MX_DEVCFG3     0xBFC02FF0 
   47 #define PIC32MX_DEVID       0xBF80F220 
   49 #define PIC32MX_BMXPFMSZ    0xBF882060 
   50 #define PIC32MX_BMXBOOTSZ   0xBF882070 
   51 #define PIC32MX_BMXDRMSZ    0xBF882040 
   55 #define PIC32MX_NVMCON      0xBF80F400 
   56 #define PIC32MX_NVMCONCLR   0xBF80F404 
   57 #define PIC32MX_NVMCONSET   0xBF80F408 
   58 #define PIC32MX_NVMCONINV   0xBF80F40C 
   59 #define NVMCON_NVMWR        (1 << 15) 
   60 #define NVMCON_NVMWREN      (1 << 14) 
   61 #define NVMCON_NVMERR       (1 << 13) 
   62 #define NVMCON_LVDERR       (1 << 12) 
   63 #define NVMCON_LVDSTAT      (1 << 11) 
   64 #define NVMCON_OP_PFM_ERASE     0x5 
   65 #define NVMCON_OP_PAGE_ERASE    0x4 
   66 #define NVMCON_OP_ROW_PROG      0x3 
   67 #define NVMCON_OP_WORD_PROG     0x1 
   68 #define NVMCON_OP_NOP           0x0 
   70 #define PIC32MX_NVMKEY      0xBF80F410 
   71 #define PIC32MX_NVMADDR     0xBF80F420 
   72 #define PIC32MX_NVMADDRCLR  0xBF80F424 
   73 #define PIC32MX_NVMADDRSET  0xBF80F428 
   74 #define PIC32MX_NVMADDRINV  0xBF80F42C 
   75 #define PIC32MX_NVMDATA     0xBF80F430 
   76 #define PIC32MX_NVMSRCADDR  0xBF80F440 
   80 #define NVMKEY1         0xAA996655 
   81 #define NVMKEY2         0x556699AA 
   99     {0x04A07053, 
"110F016B"},
 
  100     {0x04A09053, 
"110F016C"},
 
  101     {0x04A0B053, 
"110F016D"},
 
  102     {0x04A06053, 
"120F032B"},
 
  103     {0x04A08053, 
"120F032C"},
 
  104     {0x04A0A053, 
"120F032D"},
 
  105     {0x04D07053, 
"130F064B"},
 
  106     {0x04D09053, 
"130F064C"},
 
  107     {0x04D0B053, 
"130F064D"},
 
  108     {0x04D06053, 
"150F128B"},
 
  109     {0x04D08053, 
"150F128C"},
 
  110     {0x04D0A053, 
"150F128D"},
 
  111     {0x06610053, 
"170F256B"},
 
  112     {0x0661A053, 
"170F256D"},
 
  113     {0x04A01053, 
"210F016B"},
 
  114     {0x04A03053, 
"210F016C"},
 
  115     {0x04A05053, 
"210F016D"},
 
  116     {0x04A00053, 
"220F032B"},
 
  117     {0x04A02053, 
"220F032C"},
 
  118     {0x04A04053, 
"220F032D"},
 
  119     {0x04D01053, 
"230F064B"},
 
  120     {0x04D03053, 
"230F064C"},
 
  121     {0x04D05053, 
"230F064D"},
 
  122     {0x04D00053, 
"250F128B"},
 
  123     {0x04D02053, 
"250F128C"},
 
  124     {0x04D04053, 
"250F128D"},
 
  125     {0x06600053, 
"270F256B"},
 
  126     {0x0660A053, 
"270F256D"},
 
  127     {0x05600053, 
"330F064H"},
 
  128     {0x05601053, 
"330F064L"},
 
  129     {0x05602053, 
"430F064H"},
 
  130     {0x05603053, 
"430F064L"},
 
  131     {0x0570C053, 
"350F128H"},
 
  132     {0x0570D053, 
"350F128L"},
 
  133     {0x0570E053, 
"450F128H"},
 
  134     {0x0570F053, 
"450F128L"},
 
  135     {0x05704053, 
"350F256H"},
 
  136     {0x05705053, 
"350F256L"},
 
  137     {0x05706053, 
"450F256H"},
 
  138     {0x05707053, 
"450F256L"},
 
  139     {0x05808053, 
"370F512H"},
 
  140     {0x05809053, 
"370F512L"},
 
  141     {0x0580A053, 
"470F512H"},
 
  142     {0x0580B053, 
"470F512L"},
 
  143     {0x00938053, 
"360F512L"},
 
  144     {0x00934053, 
"360F256L"},
 
  145     {0x0092D053, 
"340F128L"},
 
  146     {0x0092A053, 
"320F128L"},
 
  147     {0x00916053, 
"340F512H"},
 
  148     {0x00912053, 
"340F256H"},
 
  149     {0x0090D053, 
"340F128H"},
 
  150     {0x0090A053, 
"320F128H"},
 
  151     {0x00906053, 
"320F064H"},
 
  152     {0x00902053, 
"320F032H"},
 
  153     {0x00978053, 
"460F512L"},
 
  154     {0x00974053, 
"460F256L"},
 
  155     {0x0096D053, 
"440F128L"},
 
  156     {0x00952053, 
"440F256H"},
 
  157     {0x00956053, 
"440F512H"},
 
  158     {0x0094D053, 
"440F128H"},
 
  159     {0x00942053, 
"420F032H"},
 
  160     {0x04307053, 
"795F512L"},
 
  161     {0x0430E053, 
"795F512H"},
 
  162     {0x04306053, 
"775F512L"},
 
  163     {0x0430D053, 
"775F512H"},
 
  164     {0x04312053, 
"775F256L"},
 
  165     {0x04303053, 
"775F256H"},
 
  166     {0x04417053, 
"764F128L"},
 
  167     {0x0440B053, 
"764F128H"},
 
  168     {0x04341053, 
"695F512L"},
 
  169     {0x04325053, 
"695F512H"},
 
  170     {0x04311053, 
"675F512L"},
 
  171     {0x0430C053, 
"675F512H"},
 
  172     {0x04305053, 
"675F256L"},
 
  173     {0x0430B053, 
"675F256H"},
 
  174     {0x04413053, 
"664F128L"},
 
  175     {0x04407053, 
"664F128H"},
 
  176     {0x04411053, 
"664F064L"},
 
  177     {0x04405053, 
"664F064H"},
 
  178     {0x0430F053, 
"575F512L"},
 
  179     {0x04309053, 
"575F512H"},
 
  180     {0x04333053, 
"575F256L"},
 
  181     {0x04317053, 
"575F256H"},
 
  182     {0x0440F053, 
"564F128L"},
 
  183     {0x04403053, 
"564F128H"},
 
  184     {0x0440D053, 
"564F064L"},
 
  185     {0x04401053, 
"564F064H"},
 
  186     {0x04400053, 
"534F064H"},
 
  187     {0x0440C053, 
"534F064L"},
 
  261     uint32_t config0_address;
 
  263     unsigned int s, num_pages;
 
  282     if ((devcfg0 & (1 << 28)) == 0) 
 
  285         if (devcfg0 & (1 << 24))
 
  293             num_pages = (~devcfg0 >> 10) & 0x7f;
 
  296             num_pages = (~devcfg0 >> 10) & 0x1ff;
 
  299             num_pages = (~devcfg0 >> 12) & 0xff;
 
  304     for (s = 0; s < 
bank->num_sectors && s < num_pages; s++)
 
  305         bank->sectors[s].is_protected = 1;
 
  306     for (; s < 
bank->num_sectors; s++)
 
  307         bank->sectors[s].is_protected = 0;
 
  323     if ((first == 0) && (last == (
bank->num_sectors - 1))
 
  327         LOG_DEBUG(
"Erasing entire program flash");
 
  336     for (
unsigned int i = first; i <= last; i++) {
 
  436     uint32_t buffer_size = 16384;
 
  450         LOG_WARNING(
"no working area available, can't do block memory writes");
 
  485         if (buffer_size <= 256) {
 
  490             LOG_WARNING(
"no large enough working area available, can't do block memory writes");
 
  502     int row_offset = 
offset % row_size;
 
  503     uint8_t *new_buffer = 
NULL;
 
  504     if (row_offset && (
count >= (row_size / 4))) {
 
  505         new_buffer = malloc(buffer_size);
 
  510         memset(new_buffer,  0xff, row_offset);
 
  511         address -= row_offset;
 
  517         uint32_t thisrun_count;
 
  520             thisrun_count = (
count > ((buffer_size - row_offset) / 4)) ?
 
  521                 ((buffer_size - row_offset) / 4) : 
count;
 
  523             memcpy(new_buffer + row_offset, 
buffer, thisrun_count * 4);
 
  526                 row_offset + thisrun_count * 4, new_buffer);
 
  530             thisrun_count = (
count > (buffer_size / 4)) ?
 
  531                     (buffer_size / 4) : 
count;
 
  534                     thisrun_count * 4, 
buffer);
 
  541         buf_set_u32(reg_params[2].value, 0, 32, thisrun_count + row_offset / 4);
 
  545                 0, 10000, &mips32_info);
 
  547             LOG_ERROR(
"error executing pic32mx flash write algorithm");
 
  555             LOG_ERROR(
"Flash write error NVMERR (status = 0x%08" PRIx32 
")", 
status);
 
  561             LOG_ERROR(
"Flash write error LVDERR (status = 0x%08" PRIx32 
")", 
status);
 
  566         buffer += thisrun_count * 4;
 
  567         address += thisrun_count * 4;
 
  568         count -= thisrun_count;
 
  570             address += row_offset;
 
  598     uint32_t words_remaining = (
count / 4);
 
  599     uint32_t bytes_remaining = (
count & 0x00000003);
 
  601     uint32_t bytes_written = 0;
 
  619     if (words_remaining > 0) {
 
  626                 LOG_WARNING(
"couldn't use block writes, falling back to single memory accesses");
 
  632             buffer += words_remaining * 4;
 
  633             address += words_remaining * 4;
 
  638     while (words_remaining > 0) {
 
  640         memcpy(&value, 
buffer + bytes_written, 
sizeof(uint32_t));
 
  645             LOG_ERROR(
"Flash write error NVMERR (status = 0x%08" PRIx32 
")", 
status);
 
  650             LOG_ERROR(
"Flash write error LVDERR (status = 0x%08" PRIx32 
")", 
status);
 
  659     if (bytes_remaining) {
 
  660         uint32_t value = 0xffffffff;
 
  661         memcpy(&value, 
buffer + bytes_written, bytes_remaining);
 
  666             LOG_ERROR(
"Flash write error NVMERR (status = 0x%08" PRIx32 
")", 
status);
 
  671             LOG_ERROR(
"Flash write error LVDERR (status = 0x%08" PRIx32 
")", 
status);
 
  686     uint32_t num_pages = 0;
 
  692     device_id = ejtag_info->
idcode;
 
  693     LOG_INFO(
"device id = 0x%08" PRIx32 
" (manuf 0x%03x dev 0x%04x, ver 0x%02x)",
 
  695               (
unsigned)((device_id >> 1) & 0x7ff),
 
  696               (
unsigned)((device_id >> 12) & 0xffff),
 
  697               (
unsigned)((device_id >> 28) & 0xf));
 
  700         LOG_WARNING(
"Cannot identify target as a PIC32MX family.");
 
  706         if (
pic32mx_devs[i].devid == (device_id & 0x0fffffff)) {
 
  730             LOG_WARNING(
"PIC32MX flash size failed, probe inaccurate - assuming 12k flash");
 
  731             num_pages = (12 * 1024);
 
  738             num_pages = (3 * 1024);
 
  741             num_pages = (12 * 1024);
 
  751                 LOG_WARNING(
"PIC32MX flash size failed, probe inaccurate - assuming 32k flash");
 
  752                 num_pages = (32 * 1024);
 
  755                 LOG_WARNING(
"PIC32MX flash size failed, probe inaccurate - assuming 512k flash");
 
  756                 num_pages = (512 * 1024);
 
  762     LOG_INFO(
"flash size = %" PRIu32 
" KiB", num_pages / 1024);
 
  767     num_pages /= page_size;
 
  768     bank->size = (num_pages * page_size);
 
  769     bank->num_sectors = num_pages;
 
  772     for (i = 0; i < (int)num_pages; i++) {
 
  773         bank->sectors[i].offset = i * page_size;
 
  774         bank->sectors[i].size = page_size;
 
  775         bank->sectors[i].is_erased = -1;
 
  776         bank->sectors[i].is_protected = 1;
 
  799     device_id = ejtag_info->
idcode;
 
  803                 "Cannot identify target as a PIC32MX family (manufacturer 0x%03x != 0x%03x)\n",
 
  804                 (
unsigned)((device_id >> 1) & 0x7ff),
 
  811         if (
pic32mx_devs[i].devid == (device_id & 0x0fffffff)) {
 
  821             (
unsigned)((device_id >> 28) & 0xf));
 
  828     uint32_t address, value;
 
  842     if (address < bank->
base || address >= (
bank->base + 
bank->size)) {
 
  890     if (mchip_cmd & (1 << 7)) {
 
  905             LOG_DEBUG(
"timeout waiting for unlock: 0x%" PRIx8 
"", mchip_cmd);
 
  909     } 
while ((mchip_cmd & (1 << 2)) || (!(mchip_cmd & (1 << 3))));
 
  917             "INFO: a reset or power cycle is required " 
  918             "for the new settings to take effect.");
 
  926         .usage = 
"<addr> <value> <bank>",
 
  927         .handler = pic32mx_handle_pgm_word_command,
 
  929         .help = 
"program a word",
 
  933         .handler = pic32mx_handle_unlock_command,
 
  935         .usage = 
"[bank_id]",
 
  936         .help = 
"Unlock/Erase entire device.",
 
  945         .help = 
"pic32mx flash command group",
 
  955     .flash_bank_command = pic32mx_flash_bank_command,
 
void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)
void destroy_reg_param(struct reg_param *param)
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned first, unsigned num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
static void buf_set_u32(uint8_t *_buffer, unsigned first, unsigned num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
void command_print(struct command_invocation *cmd, const char *format,...)
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
#define ERROR_FLASH_OPERATION_FAILED
#define ERROR_FLASH_DST_BREAKS_ALIGNMENT
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
int default_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default read implementation for flash memory.
void default_flash_free_driver_priv(struct flash_bank *bank)
Deallocates bank->driver_priv.
void jtag_add_sleep(uint32_t us)
The JTAG interface can be implemented with a software or hardware fifo.
void alive_sleep(uint64_t ms)
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
#define MIPS32_COMMON_MAGIC
int mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint8_t *data)
void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, uint32_t new_instr)
void mips_ejtag_drscan_8_out(struct mips_ejtag *ejtag_info, uint8_t data)
#define MCHP_DE_ASSERT_RST
static struct mips_m4k_common * target_to_m4k(struct target *target)
static uint32_t pic32mx_wait_status_busy(struct flash_bank *bank, int timeout)
static const struct command_registration pic32mx_command_handlers[]
#define NVMCON_OP_PFM_ERASE
#define PIC32MX_NVMCONSET
static int pic32mx_write_block(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
#define NVMCON_OP_PAGE_ERASE
static int pic32mx_write_word(struct flash_bank *bank, uint32_t address, uint32_t word)
FLASH_BANK_COMMAND_HANDLER(pic32mx_flash_bank_command)
#define PIC32MX_BMXBOOTSZ
const struct flash_driver pic32mx_flash
static uint32_t pic32mx_get_flash_status(struct flash_bank *bank)
static const struct pic32mx_devs_s pic32mx_devs[]
static int pic32mx_nvm_exec(struct flash_bank *bank, uint32_t op, uint32_t timeout)
#define NVMCON_OP_WORD_PROG
#define PIC32MX_NVMCONCLR
static const struct command_registration pic32mx_exec_command_handlers[]
#define PIC32MX_PHYS_PGM_FLASH
static int pic32mx_protect_check(struct flash_bank *bank)
static int pic32mx_probe(struct flash_bank *bank)
#define PIC32MX_PHYS_BOOT_FLASH
static int pic32mx_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
static int pic32mx_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
static uint32_t pic32mx_flash_write_code[]
#define PIC32MX_DEVCFG0_1XX_2XX
COMMAND_HANDLER(pic32mx_handle_pgm_word_command)
static int pic32mx_auto_probe(struct flash_bank *bank)
static int pic32mx_info(struct flash_bank *bank, struct command_invocation *cmd)
static int pic32mx_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Provides details of a flash bank, available either on-chip or through a major interface.
target_addr_t base
The base address of this bank.
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
Describes the geometry and status of a single flash sector within a flash bank.
enum mips32_isa_mode isa_mode
unsigned int common_magic
struct mips_ejtag ejtag_info
struct mips32_common mips32
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
int target_free_working_area(struct target *target, struct working_area *area)
Free a working area.
int target_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, target_addr_t entry_point, target_addr_t exit_point, int timeout_ms, void *arch_info)
Downloads a target-specific native code algorithm to the target, and executes it.
int target_alloc_working_area_try(struct target *target, uint32_t size, struct working_area **area)
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
void target_buffer_set_u32_array(struct target *target, uint8_t *buffer, uint32_t count, const uint32_t *srcbuf)
#define ERROR_TARGET_NOT_HALTED
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.