mdebug

cortex m series debugger
git clone http://frotz.net/git/mdebug.git
Log | Files | Refs | README | LICENSE

nrf528xx.c (3098B)


      1 // agents/nrf528xx.c
      2 //
      3 // Copyright 2019 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 #define LOADADDR	0x20000400
     18 
     19 #define FLASH_BASE	0x00000000
     20 
     21 #include <agent/flash.h>
     22 #include <fw/io.h>
     23 
     24 #define NVMC_READY		0x4001E400
     25 #define NVMC_CONFIG		0x4001E504
     26 #define NVMC_CONFIG_READ	0
     27 #define NVMC_CONFIG_WRITE	1
     28 #define NVMC_CONFIG_ERASE	2
     29 #define NVMC_ERASEPAGE		0x4001E508
     30 
     31 #define FICR_CODEPAGESIZE	0x10000010
     32 #define FICR_CODESIZE           0x10000014
     33 
     34 static unsigned FLASH_PAGE_SIZE = 1024;
     35 static unsigned FLASH_SIZE = 192 * 1024;
     36 
     37 int flash_agent_setup(flash_agent *agent) {
     38 
     39 	// TODO - validate part ID
     40 	if (0) {
     41 		// unknown part
     42 		return ERR_INVALID;
     43 	}
     44 
     45 	// check flash size
     46 	FLASH_PAGE_SIZE = readl(FICR_CODEPAGESIZE);
     47 	FLASH_SIZE = FLASH_PAGE_SIZE * readl(FICR_CODESIZE);
     48 	
     49 	agent->flash_size = FLASH_SIZE;
     50 
     51 	return ERR_NONE;
     52 }
     53 
     54 int flash_agent_erase(u32 flash_addr, u32 length) {
     55 	int status = ERR_NONE;
     56 	if (flash_addr > FLASH_SIZE) {
     57 		return ERR_INVALID;
     58 	}
     59 	if (flash_addr & (FLASH_PAGE_SIZE - 1)) {
     60 		return ERR_ALIGNMENT;
     61 	}
     62 	writel(NVMC_CONFIG_ERASE, NVMC_CONFIG);
     63 	while (length > 0) {
     64 		if (length > FLASH_PAGE_SIZE) {
     65 			length -= FLASH_PAGE_SIZE;
     66 		} else {
     67 			length = 0;
     68 		}
     69 		writel(flash_addr, NVMC_ERASEPAGE);
     70 		while (readl(NVMC_READY) != 1) ;
     71 		for (unsigned n = 0; n < FLASH_PAGE_SIZE; n += 4) {
     72 			if (readl(flash_addr + n) != 0xFFFFFFFF) {
     73 				status = ERR_FAIL;
     74 				goto done;
     75 			}
     76 		}
     77 		flash_addr += FLASH_PAGE_SIZE;
     78 	}
     79 done:
     80 	writel(NVMC_CONFIG_READ, NVMC_CONFIG);
     81 	return status;
     82 }
     83 
     84 int flash_agent_write(u32 flash_addr, const void *_data, u32 length) {
     85 	int status = ERR_NONE;
     86 	const unsigned *data = _data;
     87 	if (flash_addr > FLASH_SIZE) {
     88 		return ERR_INVALID;
     89 	}
     90 	if ((flash_addr & 3) || (length & 3)) {
     91 		return ERR_ALIGNMENT;
     92 	}
     93 	writel(NVMC_CONFIG_WRITE, NVMC_CONFIG);
     94 	while (length > 0) {
     95 		writel(*data, flash_addr);
     96 		while (readl(NVMC_READY) != 1) ;
     97 		if (readl(flash_addr) != *data) {
     98 			status = ERR_FAIL;
     99 			goto done;
    100 		}
    101 		data++;
    102 		length -= 4;
    103 		flash_addr += 4;
    104 	}
    105 done:
    106 	writel(NVMC_CONFIG_READ, NVMC_CONFIG);
    107 	return status;
    108 }
    109 
    110 int flash_agent_ioctl(u32 op, void *ptr, u32 arg0, u32 arg1) {
    111 	return ERR_INVALID;
    112 }
    113 
    114 const flash_agent __attribute((section(".vectors"))) FlashAgent = {
    115 	.magic =	AGENT_MAGIC,
    116 	.version =	AGENT_VERSION,
    117 	.flags =	0,
    118 	.load_addr =	LOADADDR,
    119 	.data_addr =	LOADADDR + 0x400,
    120 	.data_size =	0x4000,
    121 	.flash_addr =	FLASH_BASE,
    122 	.flash_size =	0,
    123 	.setup =	flash_agent_setup,
    124 	.erase =	flash_agent_erase,
    125 	.write =	flash_agent_write,
    126 	.ioctl =	flash_agent_ioctl,
    127 };