xdebug

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

stm32fxxx.c (3823B)


      1 // agents/stm-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 #include <fw/io.h>
     19 
     20 #define _FLASH_BASE		0x40023C00
     21 #define FLASH_ACR		(_FLASH_BASE + 0x00)
     22 
     23 #define FLASH_KEYR		(_FLASH_BASE + 0x04)
     24 #define FLASH_KEYR_KEY1		0x45670123
     25 #define FLASH_KEYR_KEY2		0xCDEF89AB
     26 
     27 #define FLASH_SR		(_FLASH_BASE + 0x0C)
     28 #define FLASH_SR_BSY		(1 << 16)
     29 #define FLASH_SR_PGSERR		(1 << 7) // sequence error
     30 #define FLASH_SR_PGPERR		(1 << 6) // parallelism error
     31 #define FLASH_SR_PGAERR		(1 << 5) // alignment error
     32 #define FLASH_SR_WRPERR		(1 << 4) // write-protect error
     33 #define FLASH_SR_OPERR		(1 << 1) // operation error
     34 #define FLASH_SR_ERRMASK	0xF2
     35 #define FLASH_SR_EOP		(1 << 0) // end of operation
     36 
     37 #define FLASH_CR		(_FLASH_BASE + 0x10)
     38 #define FLASH_CR_LOCK		(1 << 31)
     39 #define FLASH_CR_ERRIE		(1 << 25) // error irq en
     40 #define FLASH_CR_EOPIE		(1 << 24) // end of op irq en
     41 #define FLASH_CR_STRT		(1 << 16) // start
     42 #define FLASH_CR_PSIZE_8	(0 << 8)
     43 #define FLASH_CR_PSIZE_16	(1 << 8)
     44 #define FLASH_CR_PSIZE_32	(2 << 8)
     45 #define FLASH_CR_PSIZE_64	(3 << 8)
     46 #define FLASH_CR_SNB(n)		(((n) & 15) << 3) // sector number
     47 #define FLASH_CR_MER		(1 << 2) // mass erase
     48 #define FLASH_CR_SER		(1 << 1) // sector erase
     49 #define FLASH_CR_PG		(1 << 0) // programming
     50 
     51 
     52 #define SECTORS 12
     53 
     54 static uint32_t sectors[SECTORS + 1] = {
     55 	0x00000000,
     56 	0x00004000,
     57 	0x00008000,
     58 	0x0000C000,
     59 	0x00010000,
     60 	0x00020000,
     61 	0x00040000,
     62 	0x00060000,
     63 	0x00080000,
     64 	0x000A0000,
     65 	0x000C0000,
     66 	0x000E0000,
     67 	0x00100000,
     68 };
     69 
     70 int flash_agent_setup(flash_agent *agent) {
     71 	writel(FLASH_KEYR_KEY1, FLASH_KEYR);
     72 	writel(FLASH_KEYR_KEY2, FLASH_KEYR);
     73 	if (readl(FLASH_CR) & FLASH_CR_LOCK) {
     74 		return ERR_FAIL;
     75 	} else {
     76 		return ERR_NONE;
     77 	}
     78 }
     79 
     80 int flash_agent_erase(uint32_t flash_addr, uint32_t length) {
     81 	uint32_t v;
     82 	int n;
     83 	for (n = 0; n < SECTORS; n++) {
     84 		if (flash_addr == sectors[n]) goto ok;
     85 	}
     86 	return ERR_ALIGNMENT;
     87 ok:
     88 	for (;;) {
     89 		writel(FLASH_CR_SER | FLASH_CR_SNB(n), FLASH_CR);
     90 		writel(FLASH_CR_STRT | FLASH_CR_SER | FLASH_CR_SNB(n), FLASH_CR);
     91 		while ((v = readl(FLASH_SR)) & FLASH_SR_BSY) ;
     92 		if (v & FLASH_SR_ERRMASK) {
     93 			return ERR_FAIL;
     94 		}
     95 		n++;
     96 		if (n == SECTORS) break;
     97 		if ((sectors[n] - flash_addr) >= length) break;
     98 	}
     99 	return ERR_NONE;
    100 }
    101 
    102 int flash_agent_write(uint32_t flash_addr, const void *_data, uint32_t length) {
    103 	const uint32_t *data = _data;
    104 	uint32_t v;
    105 	if ((flash_addr & 3) || (length & 3)) {
    106 		return ERR_ALIGNMENT;
    107 	}
    108 	writel(FLASH_CR_PG | FLASH_CR_PSIZE_32, FLASH_CR);
    109 	while (length > 0) {
    110 		writel(*data, flash_addr);
    111 		data++;
    112 		length -= 4;
    113 		flash_addr += 4;
    114 		while ((v = readl(FLASH_SR)) & FLASH_SR_BSY) ;
    115 		if (v & FLASH_SR_ERRMASK) {
    116 			writel(0, FLASH_CR);
    117 			return ERR_FAIL;
    118 		}
    119 	}
    120 	writel(0, FLASH_CR);
    121 	return ERR_NONE;
    122 }
    123 
    124 int flash_agent_ioctl(uint32_t op, void *ptr, uint32_t arg0, uint32_t arg1) {
    125 	return ERR_INVALID;
    126 }
    127 
    128 const flash_agent __attribute((section(".vectors"))) FlashAgent = {
    129 	.magic =	AGENT_MAGIC,
    130 	.version =	AGENT_VERSION,
    131 	.flags =	0,
    132 	.load_addr =	LOADADDR,
    133 	.data_addr =	LOADADDR + 0x400,
    134 	.data_size =	0x8000,
    135 	.flash_addr =	FLASH_BASE,
    136 	.flash_size =	FLASH_SIZE,
    137 	.setup =	flash_agent_setup,
    138 	.erase =	flash_agent_erase,
    139 	.write =	flash_agent_write,
    140 	.ioctl =	flash_agent_ioctl,
    141 };