URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 815 to Rev 816
- ↔ Reverse comparison
Rev 815 → Rev 816
/trunk/orpmon/include/support.h
8,7 → 8,6
#include <stdarg.h> |
#include <stddef.h> |
#include <limits.h> |
//#include <_ansi.h> |
|
/* Register access macros */ |
#define REG8(add) *((volatile unsigned char *)(add)) |
30,18 → 29,18
/* return value by making a syscall */ |
extern void exit (int i) __attribute__ ((__noreturn__)); |
|
/* memcpy clone */ |
extern void *memcpy (void *__restrict __dest, |
__const void *__restrict __src, size_t __n); |
int memcmp (void *__restrict dstvoid, |
__const void *__restrict srcvoid, size_t length); |
extern void *memchr (void *__restrict dstvoid, |
__const char data, size_t length); |
|
extern int strlen (__const char *srcvoid); |
/* some stdlib functions */ |
extern void *memcpy (void *dest, const void *src, unsigned long n); |
extern void *memmove (void *dest, const void *src, unsigned long n); |
int memcmp (void *dstvoid, const void *srcvoid, unsigned long length); |
extern void *memchr (void * dstvoid, const char data, unsigned long length); |
extern unsigned long strtoul (const char *str, char **endptr, int base); |
extern int strlen (const char *src); |
extern int strcmp (const char *s1, const char *s2); |
extern char *strcpy (char *dst0, char *src0); |
|
#define isspace(c) ((c) == ' ' || (c) == '\t') |
|
extern unsigned long timestamp; |
extern void reset_timer (void); |
extern unsigned long get_timer (unsigned long base); |
/trunk/orpmon/include/flash.h
1,11 → 1,6
#ifndef _FLASH_H |
#define _FLASH_H |
|
#define FL_BASE_ADD 0x04000000 |
#define FL_SIZE 0x02000000 |
#define FL_BLOCK_SIZE 0x20000 |
#define START_ADD 0x0 |
|
#define FL_SR_WSM_READY 0x80 |
#define FL_SR_ERASE_ERR 0x20 |
#define FL_SR_PROG_ERR 0x40 |
12,8 → 7,13
#define FL_SR_PROG_LV 0x08 |
#define FL_SR_LOCK 0x02 |
|
unsigned long fl_block_erase (unsigned long addr); |
unsigned long fl_word_program (unsigned long addr, unsigned long val); |
int fl_init (void); |
int fl_unlock_blocks (void); |
int fl_word_program (unsigned long addr, unsigned long val); |
int fl_block_erase (unsigned long addr); |
|
/* erase = 1 (whole chip), erase = 2 (required only) */ |
int fl_program (unsigned long src_addr, unsigned long dst_addr, unsigned long len, int erase, int verify); |
|
|
#endif /* _FLASH_H */ |
/trunk/orpmon/include/net.h
258,7 → 258,7
extern char BootFile[128]; /* Boot File name */ |
|
/* Initialize the network adapter */ |
extern int NetLoop(proto_t protocol, char *filename); |
extern int NetLoop(proto_t protocol); |
|
/* Shutdown adapters and cleanup */ |
extern void NetStop(void); |
/trunk/orpmon/include/board.h
14,11 → 14,15
|
#define MC_CSR_VAL 0x0B000300 |
#define MC_MASK_VAL 0x000000e0 |
#define FLASH_BASE_ADD 0x04000000 |
#define FLASH_BASE_ADDR 0x04000000 |
#define FLASH_SIZE 0x02000000 |
#define FLASH_BLOCK_SIZE 0x20000 |
#define FLASH_TMS_VAL 0x00102102 |
#define SDRAM_BASE_ADD 0x00000000 |
#define SDRAM_BASE_ADDR 0x00000000 |
#define SDRAM_TMS_VAL 0x07248230 |
|
|
|
#ifdef XESS |
#define IN_CLK 10000000 |
#else |
/trunk/orpmon/include/common.h
36,6 → 36,7
typedef struct { |
unsigned long src_addr; |
unsigned long dst_addr; |
unsigned long start_addr; |
unsigned long length; |
unsigned long ip; |
unsigned long gw_ip; |
42,6 → 43,7
unsigned long mask; |
unsigned long srv_ip; |
unsigned char eth_add[6]; |
unsigned long erase_method; /* 0 = do not erase, 1 = fully, 2 = as needed */ |
} global_struct; |
|
extern bd_t bd; |
54,7 → 56,6
extern void putc (const char c); |
extern int printf (const char *fmt, ...); |
|
extern unsigned long strtoul (const char *str, char **endptr, int base); |
extern unsigned long parse_ip (char *ip); |
|
/* simulator stdout */ |
/trunk/orpmon/reset.S
11,6 → 11,9
.extern _dst_end |
.extern _c_reset |
.extern _int_main |
|
/* Used by global.src_addr for default value */ |
.extern _src_addr |
|
.global _lolev_ie |
.global _lolev_idis |
/trunk/orpmon/services/net.c
123,6 → 123,8
/* |
* Setup packet buffers, aligned correctly. |
*/ |
printf("%s - %s: %d\n", __FILE__, __FUNCTION__, __LINE__); |
printf(" NetTxPacket %.8lx\n", NetTxPacket); |
NetTxPacket = &PktBuf[0] + (PKTALIGN - 1); |
NetTxPacket -= (unsigned long)NetTxPacket % PKTALIGN; |
for (i = 0; i < PKTBUFSRX; i++) { |
146,6 → 148,8
|
if (protocol == TFTP) { /* TFTP */ |
NetOurIP = global.ip; |
printf("%s - %s: %d\n", __FILE__, __FUNCTION__, __LINE__); |
printf(" global.srv_ip = %.8lx\n", global.srv_ip); |
NetServerIP = global.srv_ip; |
NetOurGatewayIP = global.gw_ip; |
NetOurSubnetMask= global.mask; |
209,11 → 213,13
* Check the ethernet for a new packet. The ethernet |
* receive routine will process it. |
*/ |
printf("%s - %s: %d\n", __FILE__, __FUNCTION__, __LINE__); |
eth_rx(); |
|
/* |
* Abort if ctrl-c was pressed. |
*/ |
printf("%s - %s: %d\n", __FILE__, __FUNCTION__, __LINE__); |
if (ctrlc()) { |
eth_halt(); |
printf("\nAbort\n"); |
225,9 → 231,11
* Check for a timeout, and run the timeout handler |
* if we have one. |
*/ |
printf("%s - %s: %d\n", __FILE__, __FUNCTION__, __LINE__); |
if (timeHandler && (get_timer(0) > timeValue)) { |
thand_f *x; |
|
printf("%s - %s: %d\n", __FILE__, __FUNCTION__, __LINE__); |
x = timeHandler; |
timeHandler = (thand_f *)0; |
(*x)(); |
237,9 → 245,11
switch (NetState) { |
|
case NETLOOP_RESTART: |
printf("%s - %s: %d\n", __FILE__, __FUNCTION__, __LINE__); |
goto restart; |
|
case NETLOOP_SUCCESS: |
printf("%s - %s: %d\n", __FILE__, __FUNCTION__, __LINE__); |
if (NetBootFileXferSize > 0) { |
printf("Bytes transferred = %ld (%lx hex)\n", |
NetBootFileXferSize, |
249,6 → 259,7
return NetBootFileXferSize; |
|
case NETLOOP_FAIL: |
printf("%s - %s: %d\n", __FILE__, __FUNCTION__, __LINE__); |
return 0; |
} |
} |
/trunk/orpmon/cmds/tftp.c
File deleted
/trunk/orpmon/cmds/load.c
0,0 → 1,76
#include "common.h" |
#include "support.h" |
#include "flash.h" |
#include "net.h" |
|
extern char *tftp_filename; |
|
int tftp_cmd (int argc, char *argv[]) |
{ |
switch (argc) { |
case 0: tftp_filename = "boot.img"; |
break; |
case 3: global.src_addr = strtoul (argv[2], 0, 0); |
case 2: global.srv_ip = parse_ip (argv[1]); |
case 1: tftp_filename = &argv[0][0]; |
break; |
} |
NetLoop(TFTP); |
return 0; |
} |
|
/* WARNING: stack and non-const globals should not be used in this function -- it may corrupt what have we loaded; |
start_addr should be 0xffffffff if only copying should be made |
no return, when start_addr != 0xffffffff, if successful */ |
int copy_memory_run (register unsigned long src_addr, register unsigned long dst_addr, register unsigned long length, register int erase, register unsigned long start_addr) |
{ |
register int i; |
if (dst_addr >= FLASH_BASE_ADDR && dst_addr < FLASH_SIZE) { |
if (dst_addr + length >= FLASH_BASE_ADDR && dst_addr + length < FLASH_SIZE) { |
printf ("error: region does not fit into flash.\n"); |
return 1; |
} |
i = fl_program (src_addr, dst_addr, length, erase, 1 /* do verify */); |
if (start_addr == 0xffffffff || i) return i; |
} else { |
if (start_addr == 0xffffffff) { |
memmove ((void *)dst_addr, (void *)src_addr, length); |
return 0; |
} else { /* we need to do the copying inside this function -- stack may be corrupted */ |
register char *dst = (char *) dst_addr; |
register const char *src = (const char *) src_addr; |
while (length--) *dst++ = *src++; |
} |
} |
/* Run the program */ |
((void (*)(void)) start_addr)(); |
return 0; /* just to satisfy the cc */ |
} |
|
int copy_cmd (int argc, char *argv[]) |
{ |
switch (argc) { |
case 3: global.src_addr = strtoul (argv[2], 0, 0); |
case 2: global.length = strtoul (argv[2], 0, 0); |
case 1: global.src_addr = strtoul (argv[2], 0, 0); |
case 0: return copy_memory_run (global.src_addr, global.dst_addr, global.length, global.erase_method, 0xffffffff); |
} |
return -1; |
} |
|
int boot_cmd (int argc, char *argv[]) |
{ |
switch (argc) { |
case 3: global.src_addr = strtoul (argv[2], 0, 0); |
case 2: global.length = strtoul (argv[2], 0, 0); |
case 1: global.src_addr = strtoul (argv[2], 0, 0); |
case 0: return copy_memory_run (global.src_addr, global.dst_addr, global.length, global.erase_method, global.start_addr); /* no return, if successful */ |
} |
return -1; |
} |
|
void module_load_init (void) |
{ |
register_command ("tftp", "[<file> [<srv_ip> [<src_addr>]]]", "TFTP download", tftp_cmd); |
register_command ("copy", "[<dst_addr> [<src_addr [<length>]]]", "Copy memory", copy_cmd); |
} |
trunk/orpmon/cmds/load.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/orpmon/cmds/global.c
===================================================================
--- trunk/orpmon/cmds/global.c (revision 815)
+++ trunk/orpmon/cmds/global.c (revision 816)
@@ -1,4 +1,5 @@
#include "common.h"
+#include "support.h"
global_struct global;
@@ -42,9 +43,20 @@
} else return -1;
}
+int erase_method_cmd (int argc, char *argv[])
+{
+ if (argc == 1) {
+ int a = strtoul (argv[0], 0, 0);
+ if (a < 0 || a > 2) return -1;
+ global.erase_method = a;
+ return 0;
+ } else return -1;
+}
+
#if HELP_ENABLED
int globals_cmd (int argc, char *argv[])
{
+ const char *erase_method_desc[] = {"do not erase", "fully", "as needed"};
if (argc) return -1;
printf ("src_addr = %08lx\n", global.src_addr);
printf ("dst_addr = %08lx\n", global.dst_addr);
@@ -51,6 +63,7 @@
printf ("length = %08lx\n", global.length);
printf ("ip = %08lx\n", global.ip);
printf ("srv_ip = %08lx\n", global.srv_ip);
+ printf ("erase_method = %i (%s)\n", (int)global.erase_method, erase_method_desc[global.erase_method]);
return 0;
}
#endif /* HELP_ENABLED */
@@ -62,6 +75,6 @@
register_command ("length", "", "sets global parameter length", length_cmd);
register_command ("ip", " ", "sets global parameter ip address", ip_cmd);
register_command ("srv_ip", " ", "sets global parameter server ip address", srv_ip_cmd);
+ register_command ("erase_method", " ", "sets flash erase method (0 = do not erase, 1 = fully, 2 = as needed)", erase_method_cmd);
if (HELP_ENABLED) register_command ("globals", "", "show globals", globals_cmd);
}
-
/trunk/orpmon/cmds/dhry.c
119,7 → 119,6
/* main program, corresponds to procedures */ |
/* Main and Proc_0 in the Ada version */ |
{ |
#if 0 |
One_Fifty Int_1_Loc; |
REG One_Fifty Int_2_Loc; |
One_Fifty Int_3_Loc; |
373,7 → 372,6
printf ("%d \n", Dhrystones_Per_Second); |
} |
return 0; |
#endif |
} |
|
|
696,7 → 694,7
|
int dhry_cmd (int argc, char *argv[]) |
{ |
if (argc == 1) dhry_main(strtoul (argv[0])); |
if (argc == 1) dhry_main(strtoul (argv[0], 0, 0)); |
else if (argc == 0) dhry_main(20); |
else return -1; |
return 0; |
/trunk/orpmon/cmds/cpu.c
1,4 → 1,5
#include "common.h" |
#include "support.h" |
#include "spr_defs.h" |
|
int ic_enable_cmd (int argc, char *argv[]) |
/trunk/orpmon/cmds/Makefile
1,7 → 1,6
|
LIB = cmds.o |
#OBJS = dhry.o eth.o cpu.o camera.o tftp.o memory.o |
OBJS = eth.o cpu.o camera.o tftp.o memory.o global.o |
OBJS = dhry.o eth.o cpu.o camera.o load.o memory.o global.o |
|
all: $(LIB) |
|
/trunk/orpmon/common/common.c
2,7 → 2,6
#include "uart.h" |
#include "screen.h" |
#include "support.h" |
#include <ctype.h> |
|
#define MAX_COMMANDS 100 |
|
17,57 → 16,6
int (*func)(int argc, char *argv[]); |
} command[MAX_COMMANDS]; |
|
/* Parses hex or decimal number */ |
unsigned long strtoul (const char *str, char **endptr, int base) |
{ |
unsigned long number = 0; |
char *pos = (char *) str; |
char *fail_char = (char *) str; |
|
while (isspace(*pos)) pos++; /* skip leading whitespace */ |
|
if ((base == 16) && (*pos == '0')) { /* handle option prefix */ |
++pos; |
fail_char = pos; |
if ((*pos == 'x') || (*pos == 'X')) ++pos; |
} |
|
if (base == 0) { /* dynamic base */ |
base = 10; /* default is 10 */ |
if (*pos == '0') { |
++pos; |
base -= 2; /* now base is 8 (or 16) */ |
fail_char = pos; |
if ((*pos == 'x') || (*pos == 'X')) { |
base += 8; /* base is 16 */ |
++pos; |
} |
} |
} |
|
if ((base < 2) || (base > 36)) goto done; /* illegal base */ |
|
while (1) { |
int digit = 40; |
if ((*pos >= '0') && (*pos <= '9')) { |
digit = (*pos - '0'); |
} else if (*pos >= 'a') { |
digit = (*pos - 'a' + 10); |
} else if (*pos >= 'A') { |
digit = (*pos - 'A' + 10); |
} else break; |
|
if (digit >= base) break; |
|
fail_char = ++pos; |
number = number * base + digit; |
} |
|
done: |
if (endptr) *endptr = fail_char; |
return number; |
} |
|
void putc (const char c) |
{ |
debug ("getc %i, %i = %c\n", bd.bi_console_type, c, c); |
259,21 → 207,26
void module_cpu_init (void); |
void module_memory_init (void); |
void module_eth_init (void); |
//void module_dhry_init (void); |
void module_dhry_init (void); |
void module_camera_init (void); |
void module_tftp_init (void); |
void module_load_init (void); |
void tick_init(void); |
|
/* List of all initializations */ |
void mon_init (void) |
{ |
/* Set defaults */ |
global.erase_method = 2; /* as needed */ |
global.src_addr = |
global.dst_addr = FLASH_BASE_ADDR; |
|
/* Init modules */ |
module_cpu_init (); |
module_memory_init (); |
module_eth_init (); |
// module_dhry_init (); |
module_dhry_init (); |
module_camera_init (); |
module_tftp_init (); |
|
module_load_init (); |
// tick_init(); |
} |
|
/trunk/orpmon/common/support.c
54,11 → 54,10
return value; |
} |
|
void *memcpy (void *__restrict dstvoid, |
__const void *__restrict srcvoid, size_t length) |
void *memcpy (void *dstv, const void *srcv, unsigned long length) |
{ |
char *dst = dstvoid; |
const char *src = (const char *) srcvoid; |
char *dst = dstv; |
const char *src = (const char *) srcv; |
|
while (length--) |
*dst++ = *src++; |
65,46 → 64,55
return dst; |
} |
|
int memcmp (void *__restrict dstvoid, |
__const void *__restrict srcvoid, size_t length) |
void *memmove (void *dstv, const void *srcv, unsigned long length) |
{ |
char *dst = dstvoid; |
const char *src = (const char *) srcvoid; |
char *dst = dstv; |
const char *src = srcv; |
|
/* Copy backwards? */ |
if (src < dst && dst < src + length) { |
src += length; |
dst += length; |
while (length--) *--dst = *--src; |
return dstv; |
} else return memcpy (dstv, srcv, length); |
} |
|
int memcmp (void *dstv, const void *srcv, unsigned long length) |
{ |
char *dst = dstv; |
const char *src = (const char *) srcv; |
|
while (length--) |
if(*dst++ != *src++) |
if(*dst++ != *src++) { |
if(*(--dst) > *(--src)) |
return 1; |
else |
return -1; |
} |
return 1; |
} |
|
|
void *memchr (void *__restrict dstvoid, |
__const char data, size_t length) |
void *memchr (void *dstvoid, const char data, unsigned long length) |
{ |
char *dst = dstvoid; |
|
while (length--) *dst++ = data; |
return dst; |
} |
|
int strlen (__const char *srcvoid) |
int strlen (const char *src) |
{ |
int len = 0; |
while (*srcvoid++) len++; |
while (*src++) len++; |
return len; |
} |
|
int strcmp (const char *s1, const char *s2) |
{ |
|
while (*s1 != '\0' && *s1 == *s2) { |
s1++; |
s2++; |
} |
|
return (*(unsigned char *) s1) - (*(unsigned char *) s2); |
} |
|
111,9 → 119,7
char *strcpy (char *dst0, char *src0) |
{ |
char *s = dst0; |
|
while ((*dst0++ = *src0++)); |
|
return s; |
} |
|
121,6 → 127,57
{ |
timestamp = 0; |
} |
|
/* Parses hex or decimal number */ |
unsigned long strtoul (const char *str, char **endptr, int base) |
{ |
unsigned long number = 0; |
char *pos = (char *) str; |
char *fail_char = (char *) str; |
|
while (isspace(*pos)) pos++; /* skip leading whitespace */ |
|
if ((base == 16) && (*pos == '0')) { /* handle option prefix */ |
++pos; |
fail_char = pos; |
if ((*pos == 'x') || (*pos == 'X')) ++pos; |
} |
|
if (base == 0) { /* dynamic base */ |
base = 10; /* default is 10 */ |
if (*pos == '0') { |
++pos; |
base -= 2; /* now base is 8 (or 16) */ |
fail_char = pos; |
if ((*pos == 'x') || (*pos == 'X')) { |
base += 8; /* base is 16 */ |
++pos; |
} |
} |
} |
|
if ((base < 2) || (base > 36)) goto done; /* illegal base */ |
|
while (1) { |
int digit = 40; |
if ((*pos >= '0') && (*pos <= '9')) { |
digit = (*pos - '0'); |
} else if (*pos >= 'a') { |
digit = (*pos - 'a' + 10); |
} else if (*pos >= 'A') { |
digit = (*pos - 'A' + 10); |
} else break; |
|
if (digit >= base) break; |
|
fail_char = ++pos; |
number = number * base + digit; |
} |
|
done: |
if (endptr) *endptr = fail_char; |
return number; |
} |
|
unsigned long get_timer (unsigned long base) |
{ |
/trunk/orpmon/config.mk
22,7 → 22,7
OBJDUMP = $(CROSS_COMPILE)objdump |
RANLIB = $(CROSS_COMPILE)ranlib |
|
CFLAGS += -I$(TOPDIR)/include -DOR1K -Wall -Wstrict-prototypes -Werror-implicit-function-declaration -fomit-frame-pointer -fno-strength-reduce -O2 -g -pipe -fno-builtin -nostdlib |
CFLAGS += -I$(TOPDIR)/include -DOR1K -Wall -Wstrict-prototypes -Werror-implicit-function-declaration -fomit-frame-pointer -fno-strength-reduce -Os -g -pipe -fno-builtin -nostdlib |
|
######################################################################### |
|
/trunk/orpmon/flash.ld
51,5 → 51,6
.stack : |
{ |
*(.stack) |
_src_addr = .; |
} > ram |
} |
/trunk/orpmon/drivers/flash.c
6,57 → 6,80
int fl_init (void) |
{ |
unsigned long tmp; |
REG32(FL_BASE_ADD) = 0x00ff00ff; |
REG32(FLASH_BASE_ADDR) = 0x00ff00ff; |
|
REG32(FL_BASE_ADD) = 0x00900090; |
tmp = REG32(FL_BASE_ADD) << 8; |
REG32(FL_BASE_ADD) = 0x00900090; |
tmp = tmp | REG32(FL_BASE_ADD + 4); |
REG32(FLASH_BASE_ADDR) = 0x00900090; |
tmp = REG32(FLASH_BASE_ADDR) << 8; |
REG32(FLASH_BASE_ADDR) = 0x00900090; |
tmp = tmp | REG32(FLASH_BASE_ADDR + 4); |
debug("id = %08x ", tmp); |
if (tmp != 0x89188918) { |
debug ("bad ID\n"); |
printf ("bad ID\n"); |
return 1; |
} else debug ("good ID\n"); |
REG32(FL_BASE_ADD) = 0x00ff00ff; |
REG32(FLASH_BASE_ADDR) = 0x00ff00ff; |
return 0; |
} |
|
unsigned long fl_block_erase (unsigned long addr) |
int check_error (unsigned long sr, unsigned long addr) |
{ |
if ((sr & (FL_SR_ERASE_ERR << 16)) || (sr & FL_SR_ERASE_ERR)) { |
printf ("erase error at %08lx\n", addr); |
/* Clear status register */ |
REG32(FLASH_BASE_ADDR) = 0x05D00050; |
return 1; |
} else if ((sr & (FL_SR_PROG_ERR << 16)) || (sr & FL_SR_PROG_ERR)) { |
printf ("program error at %08lx\n", addr); |
/* Clear status register */ |
REG32(FLASH_BASE_ADDR) = 0x05D00050; |
return 1; |
} else if ((sr & (FL_SR_PROG_LV << 16)) || (sr & FL_SR_PROG_LV)) { |
printf ("low voltage error\n"); |
/* Clear status register */ |
REG32(FLASH_BASE_ADDR) = 0x05D00050; |
return 1; |
} else if ((sr & (FL_SR_LOCK << 16)) || (sr & FL_SR_LOCK)) { |
printf ("lock bit error at %08lx\n", addr); |
/* Clear status register */ |
REG32(FLASH_BASE_ADDR) = 0x05D00050; |
return 1; |
} |
return 0; |
} |
|
int fl_block_erase (unsigned long addr) |
{ |
unsigned long sr; |
|
REG32(addr & ~(FL_BLOCK_SIZE - 1)) = 0x00200020; |
REG32(addr & ~(FL_BLOCK_SIZE - 1)) = 0x00D000D0; |
REG32(addr & ~(FLASH_BLOCK_SIZE - 1)) = 0x00200020; |
REG32(addr & ~(FLASH_BLOCK_SIZE - 1)) = 0x00D000D0; |
|
do { |
REG32(FL_BASE_ADD) = 0x00700070; |
sr = REG32(FL_BASE_ADD); |
REG32(FLASH_BASE_ADDR) = 0x00700070; |
sr = REG32(FLASH_BASE_ADDR); |
} while (!(sr & (FL_SR_WSM_READY << 16)) || !(sr & FL_SR_WSM_READY)); |
|
REG32(FL_BASE_ADD) = 0x00ff00ff; |
REG32(FLASH_BASE_ADDR) = 0x00ff00ff; |
return check_error (sr, addr); |
} |
|
if ((sr & (FL_SR_ERASE_ERR << 16)) || (sr & FL_SR_ERASE_ERR)) { |
debug ("erase error: "); |
return -1; |
int fl_unlock_blocks (void) |
{ |
unsigned long sr; |
|
printf ("Clearing all lock bits... "); |
REG32(FLASH_BASE_ADDR) = 0x00600060; |
REG32(FLASH_BASE_ADDR) = 0x00d000d0; |
|
if ((sr & (FL_SR_PROG_ERR << 16)) || (sr & FL_SR_PROG_ERR)) { |
debug ("program error\n"); |
return -1; |
} |
else if ((sr & (FL_SR_PROG_LV << 16)) || (sr & FL_SR_PROG_LV)) { |
debug ("low voltage error\n"); |
return -1; |
} |
else if ((sr & (FL_SR_LOCK << 16)) || (sr & FL_SR_LOCK)) { |
debug ("lock bit error\n"); |
return -1; |
} |
/* Clear status register */ |
REG32(FL_BASE_ADD) = 0x05D00050; |
} else return 0; |
do { |
REG32(FLASH_BASE_ADDR) = 0x00700070; |
sr = REG32(FLASH_BASE_ADDR); |
} while (!(sr & (FL_SR_WSM_READY << 16)) || !(sr & FL_SR_WSM_READY)); |
printf ("done\n"); |
return check_error (sr, FLASH_BASE_ADDR); |
} |
|
unsigned long fl_word_program (unsigned long addr, unsigned long val) |
int fl_word_program (unsigned long addr, unsigned long val) |
{ |
unsigned long sr; |
|
64,29 → 87,81
REG32(addr) = val; |
|
do { |
REG32(FL_BASE_ADD) = 0x00700070; |
sr = REG32(FL_BASE_ADD); |
REG32(FLASH_BASE_ADDR) = 0x00700070; |
sr = REG32(FLASH_BASE_ADDR); |
} while (!(sr & (FL_SR_WSM_READY << 16)) || !(sr & FL_SR_WSM_READY)); |
|
REG32(FL_BASE_ADD) = 0x00ff00ff; |
REG32(FLASH_BASE_ADDR) = 0x00ff00ff; |
return check_error (sr, addr); |
} |
|
if ((sr & (FL_SR_ERASE_ERR << 16)) || (sr & FL_SR_ERASE_ERR)) { |
debug ("erase error: "); |
return -1; |
/* erase = 1 (whole chip), erase = 2 (required only) */ |
int fl_program (unsigned long src_addr, unsigned long dst_addr, unsigned long len, int erase, int verify) |
{ |
unsigned long tmp, taddr, tlen; |
unsigned long i; |
|
if (erase) { |
fl_unlock_blocks (); |
|
if (erase == 2) { |
taddr = dst_addr & ~(FLASH_BLOCK_SIZE - 1); |
tlen = (dst_addr + len + FLASH_BLOCK_SIZE - 1) / FLASH_BLOCK_SIZE; |
} else { |
taddr = FLASH_BASE_ADDR; |
tlen = FLASH_SIZE / FLASH_BLOCK_SIZE; |
} |
|
printf ("Erasing flash... "); |
for (i = 0, tmp = taddr; i < tlen; i++, tmp += FLASH_BLOCK_SIZE) |
if (fl_block_erase (tmp)) return 1; |
printf ("done\n"); |
|
if (verify) { |
printf ("Writing test pattern... "); |
for (tmp = taddr; tmp < taddr + tlen * FLASH_BLOCK_SIZE; i++, tmp += 4) |
if (fl_word_program (tmp, tmp)) return 1; |
printf ("done\n"); |
|
printf ("Checking... "); |
for (tmp = taddr; tmp < taddr + tlen * FLASH_BLOCK_SIZE; i++, tmp += 4) |
if (REG32(tmp) != tmp) { |
printf ("failed on location %08lx: %08lx\n", tmp, REG32(tmp)); |
return 1; |
} |
printf ("done\n"); |
} |
} |
|
REG32(FLASH_BASE_ADDR) = 0x00ff00ff; |
printf ("Copying from %08lx-%08lx to %08lx-%08lx\n", src_addr, src_addr + len - 1, dst_addr, dst_addr + len - 1); |
|
if ((sr & (FL_SR_PROG_ERR << 16)) || (sr & FL_SR_PROG_ERR)) { |
debug ("program error\n"); |
return -1; |
tlen = len / 8; |
tmp = 0; |
printf ("Programing"); |
for (i = 0; i < len; i += 4) { |
if (fl_word_program (dst_addr + i, REG32(src_addr + i))) return 1; |
if (i > tmp) { |
printf ("."); |
tmp += tlen; |
} |
else if ((sr & (FL_SR_PROG_LV << 16)) || (sr & FL_SR_PROG_LV)) { |
debug ("low voltage error\n"); |
return -1; |
} |
printf (" done\n"); |
|
if (verify) { |
printf ("Verifying"); |
tmp = 0; |
for (i = 0; i < len; i += 4) { |
if (REG32(src_addr + i) != REG32(dst_addr + i)) { |
printf ("error at %08lx: %08lx != %08lx\n", REG32(src_addr + i), REG32(dst_addr + i)); |
return 1; |
} |
if (i > tmp) { |
printf ("."); |
tmp += tlen; |
} |
} |
else if ((sr & (FL_SR_LOCK << 16)) || (sr & FL_SR_LOCK)) { |
debug ("lock bit error\n"); |
return -1; |
} |
/* Clear status register */ |
REG32(FL_BASE_ADD) = 0x05D00050; |
} else return 0; |
} |
printf (" done\n"); |
return 0; |
} |