Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Sami Nurmenniemi
u-boot-stm32
Commits
663dec14
Commit
663dec14
authored
Oct 14, 2011
by
Sergei Poselenov
Browse files
RT #72064. Enhanced the ENVM erase ("cptf"), now only the needed ENVM sectors
are erased.
parent
c615cdac
Changes
1
Hide whitespace changes
Inline
Side-by-side
cpu/arm_cortexm3/stm32/envm.c
View file @
663dec14
...
...
@@ -29,7 +29,20 @@
* Flash data area definitions
*/
#define STM32_FLASH_BASE 0x08000000
#define STM32_FLASH_SIZE (8*128*1024)
#define STM32_FLASH_SIZE ((4 * 16 + 64 + 7 * 128) * 1024)
/*
* This array defines the layout of the Embedded Flash on the STM32F2x chips
*/
static
u32
flash_bsize
[]
=
{
[
0
...
3
]
=
16
*
1024
,
[
4
]
=
64
*
1024
,
[
5
...
11
]
=
128
*
1024
};
/*
* Number of flash blocks for STM32F2x chips
*/
#define STM32_FLASH_BLOCKS (sizeof(flash_bsize)/sizeof(flash_bsize[0]))
/*
* Flash registers base
...
...
@@ -40,15 +53,15 @@
* Flash register map
*/
struct
stm32_flash_regs
{
u32
acr
;
/* Access control */
u32
keyr
;
/* Key */
u32
optkeyr
;
/* Option key */
u32
sr
;
/* Status */
u32
cr
;
/* Control */
u32
optcr
;
/* Option control */
u32
acr
;
/* Access control */
u32
keyr
;
/* Key */
u32
optkeyr
;
/* Option key */
u32
sr
;
/* Status */
u32
cr
;
/* Control */
u32
optcr
;
/* Option control */
};
#define STM32_FLASH_REGS ((volatile struct stm32_flash_regs *)
\
STM32_FLASHREGS_BASE)
#define STM32_FLASH_REGS ((volatile struct stm32_flash_regs *) \
STM32_FLASHREGS_BASE)
/*
* Flash CR definitions
...
...
@@ -69,16 +82,16 @@ struct stm32_flash_regs {
/*
* Flash ACR definitions
*/
#define STM32_FLASH_ACR_LAT_BIT 0
/* Latency
*/
#define STM32_FLASH_ACR_LAT_MSK 0x
3
#define STM32_FLASH_ACR_PRFTEN (1 << 8)
/* Prefetch enable */
#define STM32_FLASH_ACR_ICEN (1 << 9)
/* Instruction cache enable */
#define STM32_FLASH_ACR_LAT_BIT 0
/* Latency
*/
#define STM32_FLASH_ACR_LAT_MSK 0x
7
#define STM32_FLASH_ACR_PRFTEN (1 << 8)
/* Prefetch enable */
#define STM32_FLASH_ACR_ICEN (1 << 9)
/* Instruction cache enable */
/*
* Flash KEYR definitions
*/
#define STM32_FLASH_KEYR_KEY1 0x45670123
/* KEY1
value
to unlock CR
*/
#define STM32_FLASH_KEYR_KEY2 0xCDEF89AB
/* KEY2
value
to unlock CR
*/
#define STM32_FLASH_KEYR_KEY1 0x45670123
/* KEY1 to unlock CR
*/
#define STM32_FLASH_KEYR_KEY2 0xCDEF89AB
/* KEY2 to unlock CR
*/
/*
* Flash SR definitions
...
...
@@ -115,33 +128,81 @@ stm32_flash_cr_lock(void)
}
/*
* Erase the whole embedded flash of the STM32.
* Given the flash address, return the block number.
* Return error if the address is not a start block address.
*/
static
s32
stm32_flash_get_block
(
u8
*
addr
)
{
s32
i
=
0
;
u8
*
base
=
(
u8
*
)
STM32_FLASH_BASE
;
while
(
i
<
STM32_FLASH_BLOCKS
)
{
if
(
addr
==
base
)
break
;
base
+=
flash_bsize
[
i
];
i
++
;
}
if
(
i
==
STM32_FLASH_BLOCKS
)
i
=
-
EINVAL
;
return
i
;
}
/*
* Erase the embedded flash of the STM32. Start block is calculated from the
* given offset, end block - from size.
*/
static
int
__attribute__
((
section
(
".ramcode"
)))
static
s32
__attribute__
((
section
(
".ramcode"
)))
__attribute__
((
long_call
))
stm32_flash_erase
(
u
int32_t
offset
,
u
int32_t
size
)
stm32_flash_erase
(
u
32
offset
,
u
32
size
)
{
int32_t
ret
=
-
EBUSY
;
/* No sanity check of address here, proceed to erase */
s32
ret
;
s32
n
,
num
;
u32
erasesize
;
if
((
n
=
stm32_flash_get_block
((
u8
*
)
offset
))
<
0
)
{
printf
(
"%s: Address %#x is not block-aligned
\n
"
,
__func__
,
offset
);
ret
=
n
;
goto
xit
;
}
/* Calculate the number of blocks to erase */
erasesize
=
0
;
num
=
n
;
while
(
erasesize
<
size
)
{
erasesize
+=
flash_bsize
[
num
];
num
++
;
}
/* Check there is no pending operations */
if
(
STM32_FLASH_REGS
->
sr
&
STM32_FLASH_SR_BSY
)
{
printf
(
"%s: Flash is busy
\n
"
,
__func__
);
ret
=
-
EBUSY
;
goto
xit
;
}
stm32_flash_cr_unlock
();
STM32_FLASH_REGS
->
cr
|=
STM32_FLASH_CR_MER
;
STM32_FLASH_REGS
->
cr
|=
STM32_FLASH_CR_START
;
stm32_flash_cr_unlock
();
/*
* Warning! As soon as the erase operation starts, you can't access
* U-Boot functions except of marked as ".ramcode".
*/
while
(
STM32_FLASH_REGS
->
sr
&
STM32_FLASH_SR_BSY
)
;
while
(
n
<
num
)
{
STM32_FLASH_REGS
->
cr
&=
~
(
STM32_FLASH_CR_SECT_MSK
<<
STM32_FLASH_CR_SECT_SHIFT
);
STM32_FLASH_REGS
->
cr
|=
((
n
<<
STM32_FLASH_CR_SECT_SHIFT
)
|
STM32_FLASH_CR_SER
);
STM32_FLASH_REGS
->
cr
|=
STM32_FLASH_CR_START
;
/*
* Warning! As soon as the erase operation starts, you can't
* access U-Boot functions except of marked as ".ramcode"!
*/
while
(
STM32_FLASH_REGS
->
sr
&
STM32_FLASH_SR_BSY
)
;
n
++
;
}
STM32_FLASH_REGS
->
cr
&=
~
STM32_FLASH_CR_MER
;
STM32_FLASH_REGS
->
cr
&=
~
(
STM32_FLASH_CR_SER
|
(
STM32_FLASH_CR_SECT_MSK
<<
STM32_FLASH_CR_SECT_SHIFT
));
stm32_flash_cr_lock
();
ret
=
0
;
...
...
@@ -149,22 +210,23 @@ xit:
return
ret
;
}
static
int
__attribute__
((
section
(
".ramcode"
)))
static
s32
__attribute__
((
section
(
".ramcode"
)))
__attribute__
((
long_call
))
stm32_flash_program
(
u
int32_t
offset
,
void
*
buf
,
u
int32_t
size
)
stm32_flash_program
(
u
32
offset
,
void
*
buf
,
u
32
size
)
{
u
int32_t
*
src
=
(
u
int32_t
*
)
buf
;
u
int32_t
*
dst
=
(
u
int32_t
*
)
offset
;
/* I
know I
can read 1-3 bytes beyond the input buffer, but this is OK */
u
int32_t
words
=
(
size
+
sizeof
(
u
int32_t
)
-
1
)
/
sizeof
(
u
int32_t
);
int32_t
ret
=
-
EBUSY
;
u
32
*
src
=
(
u
32
*
)
buf
;
u
32
*
dst
=
(
u
32
*
)
offset
;
/* I can read 1-3 bytes beyond the input buffer, but this is OK */
u
32
words
=
(
size
+
sizeof
(
u
32
)
-
1
)
/
sizeof
(
u
32
);
s32
ret
;
/* No sanity check on flash address here, proceed to program */
/* Check there is no pending operations */
if
(
STM32_FLASH_REGS
->
sr
&
STM32_FLASH_SR_BSY
)
if
(
STM32_FLASH_REGS
->
sr
&
STM32_FLASH_SR_BSY
)
{
ret
=
-
EBUSY
;
goto
xit
;
}
stm32_flash_cr_unlock
();
STM32_FLASH_REGS
->
cr
|=
STM32_FLASH_CR_PG
;
...
...
@@ -219,16 +281,17 @@ void envm_init(void)
* Note that we need for this function to reside in RAM since it
* will be used to self-upgrade U-boot in internal Flash.
*/
u
nsigned
int
__attribute__
((
section
(
".ramcode"
)))
u
32
__attribute__
((
section
(
".ramcode"
)))
__attribute__
((
long_call
))
envm_write
(
u
int32_t
offset
,
void
*
buf
,
u
int32_t
size
)
envm_write
(
u
32
offset
,
void
*
buf
,
u
32
size
)
{
int32_t
ret
=
0
;
s32
ret
=
0
;
/*
S
anity check */
/*
Basic s
anity check
. More checking in the "get_block" routine
*/
if
((
offset
<
STM32_FLASH_BASE
)
||
((
offset
+
size
)
>
(
STM32_FLASH_BASE
+
STM32_FLASH_SIZE
)))
{
printf
(
"Offset %#x is not in flash or size %d is too big
\n
"
,
offset
,
size
);
printf
(
"%s: Address %#x is not in flash or size %d is too big
\n
"
,
__func__
,
offset
,
size
);
goto
xit
;
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment