xdebug

next generation of mdebug (work in progress)
git clone http://frotz.net/git/xdebug.git
Log | Files | Refs | README

lpc13xx_lpc15xx.c (2778B)


      1 // agent-lpc15xx/main.c
      2 //
      3 // Copyright 2015 Brian Swetland <swetland@frotz.net>
      4 // 
      5 // Licensed under the Apache License, Version 2.0 (the "License");
      6 // you may not use this file except in compliance with the License.
      7 // You may obtain a copy of the License at
      8 //
      9 //     http://www.apache.org/licenses/LICENSE-2.0
     10 //
     11 // Unless required by applicable law or agreed to in writing, software
     12 // distributed under the License is distributed on an "AS IS" BASIS,
     13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 // See the License for the specific language governing permissions and
     15 // limitations under the License.
     16 
     17 #include <agent/flash.h>
     18 
     19 #ifdef ARCH_LPC15XX
     20 #define LPC_IAP_FUNC	0x03000205
     21 #else
     22 #define LPC_IAP_FUNC	0x1fff1ff1
     23 #endif
     24 
     25 #define LPC_IAP_PREPARE	50
     26 #define LPC_IAP_WRITE	51
     27 #define LPC_IAP_ERASE	52
     28 
     29 // Note that while the databook claims you can reuse the same array
     30 // for both parameters and results, this is a lie.  Attempting to 
     31 // do so causes an invalid command failure.
     32 
     33 
     34 int flash_agent_setup(flash_agent *agent) {
     35 	return ERR_NONE;
     36 }
     37 
     38 int flash_agent_erase(uint32_t flash_addr, uint32_t length) {
     39 	void (*romcall)(uint32_t *, uint32_t *) = (void*) LPC_IAP_FUNC;
     40 	uint32_t p[5],r[4];
     41 	uint32_t page = flash_addr >> 12;
     42 	uint32_t last = page + ((length - 1) >> 12);
     43 	if (flash_addr & 0xFFF) {
     44 		return ERR_ALIGNMENT;
     45 	}
     46 
     47 	p[0] = LPC_IAP_PREPARE;
     48 	p[1] = page;
     49 	p[2] = last;
     50 	romcall(p,r);
     51 	if (r[0]) {
     52 		return ERR_FAIL;
     53 	}
     54 
     55 	p[0] = LPC_IAP_ERASE;
     56 	p[1] = page;
     57 	p[2] = last;
     58 	p[3] = 0x2ee0;
     59 	romcall(p,r);
     60 	if (r[0]) {
     61 		return ERR_FAIL;
     62 	}
     63 	return ERR_NONE;
     64 }
     65 
     66 int flash_agent_write(uint32_t flash_addr, const void *data, uint32_t length) {
     67 	void (*romcall)(uint32_t *,uint32_t *) = (void*) LPC_IAP_FUNC;
     68 	uint32_t p[5],r[4];
     69 	uint32_t page = flash_addr >> 12;
     70 	if (flash_addr & 0xFFF) {
     71 		return ERR_ALIGNMENT;
     72 	}
     73 
     74 	p[0] = LPC_IAP_PREPARE;
     75 	p[1] = page;
     76 	p[2] = page;
     77 	romcall(p,r);
     78 	if (r[0]) {
     79 		return ERR_FAIL;
     80 	}
     81 
     82 	// todo: smaller writes, etc
     83 	if (length != 4096) {
     84 		int n;
     85 		for (n = length; n < 4096; n++) {
     86 			((char*) data)[n] = 0;
     87 		}
     88 	}
     89 	p[0] = LPC_IAP_WRITE;
     90 	p[1] = flash_addr;
     91 	p[2] = (uint32_t) data;
     92 	p[3] = 0x1000;
     93 	p[4] = 0x2ee0;
     94 	romcall(p,r);
     95 	if (r[0]) {
     96 		return ERR_FAIL;
     97 	}
     98 
     99 	return ERR_NONE;
    100 }
    101 
    102 int flash_agent_ioctl(uint32_t op, void *ptr, uint32_t arg0, uint32_t arg1) {
    103 	return ERR_INVALID;
    104 }
    105 
    106 const flash_agent __attribute((section(".vectors"))) FlashAgent = {
    107 	.magic =	AGENT_MAGIC,
    108 	.version =	AGENT_VERSION,
    109 	.flags =	FLAG_BOOT_ROM_HACK,
    110 	.load_addr =	LOADADDR,
    111 	.data_addr =	LOADADDR + 0x400,
    112 	.data_size =	0x1000,
    113 	.flash_addr =	FLASH_BASE,
    114 	.flash_size =	FLASH_SIZE,
    115 	.setup =	flash_agent_setup,
    116 	.erase =	flash_agent_erase,
    117 	.write =	flash_agent_write,
    118 	.ioctl =	flash_agent_ioctl,
    119 };