URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/orpsocv2/sw/apps
- from Rev 542 to Rev 655
- ↔ Reverse comparison
Rev 542 → Rev 655
/cfi_ctrl_programmer/cfi_ctrl_programmer.c
0,0 → 1,366
// Program that will erase and program a flash via cfi_ctrl module |
|
#include "cpu-utils.h" |
#include "board.h" |
#include "uart.h" |
#include "printf.h" |
#include "cfi_ctrl.h" |
|
// TODO: detect this manually - it is CFI after all! |
#define BLOCK_SIZE_BYTES (128*1024) |
|
//#define VERBOSE_PROGRAMMING |
#define VERBOSE_VERIFY_ERRORS |
//#define VERIFY_WHEN_WRITE |
|
unsigned long programming_file_start; |
unsigned long programming_file_end; |
unsigned long programming_file_length; |
|
extern unsigned long userprogram_data, _userprogram_data; |
extern unsigned long end_userprogram_data, _end_userprogram_data; |
|
// Globals |
int timeout_counter; |
volatile char dump; |
int programming_base_offset; |
|
#define RESET_PC 0xf0000100 |
|
int |
console_get_num(void) |
{ |
char c = 0x30; |
int num_nums = 0; |
int num_nums_total; |
char nums[16]; // up to 16 decimal digits long |
int retval = 0; |
int decimal_multiplier; |
int i; |
|
printf("Enter decimal value: "); |
|
while (c >= 0x30 && c < 0x40) |
{ |
c = uart_getc(DEFAULT_UART); |
|
if (c >= 0x30 && c < 0x40) |
{ |
printf("%d", c-0x30); |
nums[num_nums] = c-0x30; |
num_nums++; |
} |
|
} |
printf("\n"); |
|
num_nums_total = num_nums; |
|
while(num_nums--) |
{ |
decimal_multiplier = 1; |
for(i=1;i<num_nums_total - num_nums;i++) |
decimal_multiplier *= 10; |
//printf("%d * %d\n",decimal_multiplier,nums[num_nums]); |
|
retval += (decimal_multiplier * nums[num_nums]); |
} |
//printf("%d\n",retval); |
return retval; |
} |
|
void |
console_browse_buffer(char* buf) |
{ |
char c = 0; |
int offset = 0; |
const int linesize = 16; |
int i; |
printf("Press space to scroll through buffer, q to return\n"); |
printf("+/- alter address offset\n"); |
cfi_ctrl_enable_data_read(); |
while (1) |
{ |
c = uart_getc(DEFAULT_UART); |
|
if (c == 'q') |
return; |
else if (c == 'r') |
offset=0; |
else if (c == '+') |
{ |
offset+=linesize; |
printf("%04x:\r",offset); |
} |
else if (c == '-') |
{ |
if (offset >=linesize) |
offset-=linesize; |
|
printf("%04x:\r",offset); |
} |
else if (c == 0x20) // space, print al ine |
{ |
printf("%04x:",offset); |
// print another line of the buffer |
for (i=0;i<linesize;i++) |
{ |
printf(" %02x", buf[offset+i]&0xff); |
} |
printf("\n"); |
|
offset += linesize; |
|
} |
} |
|
} |
|
void |
delay(int n) |
{ |
volatile int i=0; |
while(i<n) |
i++; |
} |
|
void |
timeout_reset(void) |
{ |
timeout_counter = 0; |
} |
|
int |
timeout(void) |
{ |
timeout_counter++; |
if (timeout_counter == 20000) |
{ |
printf("timeout\n"); |
cfi_ctrl_reset_flash(); |
|
return 1; |
} |
return 0; |
} |
|
void |
print_cfi_status(void) |
{ |
char flashid[5]; |
int i; |
printf("\tcfi_ctrl flash status:\n"); |
|
printf("Device status byte: 0x%02x\n",cfi_ctrl_get_status()&0xff); |
printf("\n"); |
printf("Programming file from 0x%x-0x%x, %d bytes\n", |
programming_file_start, programming_file_end, |
programming_file_length); |
// printf("Embedded length: %d\n", (unsigned long) userprogram_data); |
printf("Page programming base: %d (set with 'o' command)\n", |
programming_base_offset); |
} |
|
void |
verify_image(int base_offset, char* data, int length_bytes) |
{ |
|
int base_block = base_offset / BLOCK_SIZE_BYTES; |
|
int num_blocks = (length_bytes/BLOCK_SIZE_BYTES) + 1; |
int i; |
|
int verify_error = 0; |
|
printf("\tVerifying %d bytes of image from 0x%08x\n",length_bytes, |
base_offset); |
|
unsigned int waddr; |
short * data_shorts; |
int short_counter; |
data_shorts = (short*) data; |
|
// Read the pages |
cfi_ctrl_enable_data_read(); |
for(waddr=base_offset, short_counter=0; |
waddr<(base_offset + length_bytes); |
waddr +=2, short_counter++) |
{ |
/* Check what we wrote */ |
short verify_data = REG16(CFI_CTRL_BASE+waddr); |
|
if (verify_data != data_shorts[short_counter]) |
{ |
printf("\tERROR: word verify failed at 0x%08x.\n",waddr); |
printf("\tERROR: Read 0x%04x instead of 0x%04x.\n",verify_data, |
data_shorts[short_counter]); |
verify_error ++; |
} |
|
} |
|
if (verify_error) |
printf("\tVerify complete - %d errors were detected\n", |
verify_error); |
else |
printf("\tImage verified. Press esacpe to boot from 0x%08x.\n",RESET_PC); |
} |
|
void |
program_image(int base_offset, char* data, int length_bytes) |
{ |
|
int base_block = base_offset / BLOCK_SIZE_BYTES; |
|
int num_blocks = (length_bytes/BLOCK_SIZE_BYTES) + 1; |
|
int i; |
|
unsigned int waddr; |
|
short * data_shorts; |
int short_counter; |
|
printf("\tErasing blocks (%d - %d)\n",base_block, |
base_block + num_blocks-1); |
|
// Erase the appropriate blocks |
for(i=base_block;i<base_block + num_blocks;i++) |
{ |
printf("\tErasing block %d\n",i); |
cfi_ctrl_unlock_block(i*BLOCK_SIZE_BYTES); |
if (cfi_ctrl_erase_block(i*BLOCK_SIZE_BYTES)) |
{ |
printf("\tErase failed, trying again\n"); |
i--; // Try erasing again |
continue; |
} |
} |
printf("\tErase complete\n"); |
|
printf("\n\tProgramming %d bytes\n", length_bytes); |
|
data_shorts = (short*) data; |
|
// Program the pages |
for(waddr=base_offset, short_counter=0; |
waddr<(base_offset + length_bytes); |
waddr +=2, short_counter++) |
{ |
if (cfi_ctrl_write_short(data_shorts[short_counter],waddr)) |
{ |
printf("\tERROR: word program failed at 0x%08x\n",waddr); |
return; |
} |
else |
{ |
#ifdef VERIFY_WHEN_WRITE |
/* Check what we wrote */ |
cfi_ctrl_enable_data_read(); |
short verify_data = REG16(CFI_CTRL_BASE+waddr); |
if (verify_data != data_shorts[short_counter]) |
{ |
printf("\tERROR: word verify failed at 0x%08x.\n",waddr); |
printf("\tERROR: Read 0x%04x instead of 0x%04x.\n",verify_data, |
data_shorts[short_counter]); |
return; |
} |
#endif |
} |
} |
|
printf("\tProgramming %d bytes complete\n", length_bytes); |
} |
|
#define printhelp() printf("\nUsage: \n \ |
\t[p]rogram\t\terase req. blocks, write image to flash\n \ |
\t[o]ffset\t\tset page offset to write to\n \ |
\t[v]erify\t\tverify written program\n \ |
\t[s]tatus\t\tprint status of CFI flash\n \ |
\t[e]rase\t\t\terase block of CFI flash\n \ |
\t[r]ead\t\t\tread, browse page of CFI flash\n \ |
\t[i]nspect\t\tinspect page of image in RAM\n \ |
\t[R]eset\t\t\treset CFI flash controller\n \ |
\t[ESC]\t\t\treset by jumping to 0x%08x\n \ |
\n",RESET_PC) |
|
int |
main() |
{ |
uart_init(0); // init the UART before we can printf |
|
volatile char c; |
int i,j; |
|
programming_base_offset = 0; |
|
programming_file_start = (unsigned long) &userprogram_data; |
programming_file_end = (unsigned long) &end_userprogram_data; |
programming_file_length = programming_file_end - programming_file_start; |
|
printf("\n\n\tcfi_ctrl flash programming app\n\n"); |
printf("\ttype 'h' for help menu\n\n"); |
|
while(1){ |
printf(" > "); |
c = uart_getc(DEFAULT_UART); |
printf("%c",c); |
printf("\n"); |
|
if (c == 'h') |
printhelp(); |
else if (c == 's') |
print_cfi_status(); |
else if (c == 'c') |
cfi_ctrl_clear_status(); |
else if (c == 'p') |
program_image(programming_base_offset, |
(char *) &userprogram_data, |
programming_file_length); |
else if (c == 'v') |
verify_image(programming_base_offset, |
(char *) &userprogram_data, |
programming_file_length); |
else if (c == 'o') |
{ |
printf("Enter byte offset to program from.\n"); |
programming_base_offset = console_get_num(); |
} |
// Support/debug commands: |
else if (c == 'e') |
{ |
printf("Erase a block.\n"); |
i = console_get_num(); |
// program a specific page |
cfi_ctrl_erase_block_no_wait(i*BLOCK_SIZE_BYTES); |
} |
else if (c == 'r') |
{ |
printf("Inspect memory.\n"); |
i = console_get_num(); |
// read a page |
console_browse_buffer((char*)CFI_CTRL_BASE + i); |
} |
else if (c == 'i') |
{ |
printf("Inspect image to program.\n"); |
console_browse_buffer((char*) &userprogram_data); |
} |
else if (c == 'R') |
{ |
printf("Reset command to controller\n"); |
cfi_ctrl_reset_flash(); |
} |
else if (c == 0x1b) // Esacpe key |
{ |
// Reset |
void (*reset_function) (void) = |
(void *)RESET_PC; |
(*reset_function)(); |
} |
|
} |
|
return 0; |
|
} |
/cfi_ctrl_programmer/Makefile
0,0 → 1,31
# Program to control the cfi_ctrl module to manage contents of flash memory. |
# |
# author: julius.baxter@orsoc.se |
# |
|
SW_ROOT=../.. |
|
#PROGRAMMINGFILE= |
PROGRAMMINGFILE_SWBIN=progfile.swbin # Binary file with sizeword |
PROGRAMMINGFILE_DATA=progfile.o |
|
ELF_DEPENDS +=$(PROGRAMMINGFILE_DATA) |
|
include $(SW_ROOT)/Makefile.inc |
|
OR32_LDFLAGS = -L$(SW_ROOT)/lib -lorpsoc -lgcc -Tcfi_ctrl_programmer.ld -e 256 |
|
$(PROGRAMMINGFILE_DATA): $(PROGRAMMINGFILE) |
$(Q)$(OR32_LD) -r -b binary -o $@ $< |
$(Q)$(OR32_OBJCOPY) --rename-section .data=.userprogram $@ |
|
%.dis: %.elf |
$(Q)$(OR32_OBJDUMP) -d $< > $@ |
|
%.bin: %.elf |
$(Q)$(OR32_OBJCOPY) -O binary $< $@ |
|
clean: |
$(Q)rm -f *.elf *.bin *.vmem *.flashin *.dis $(PROGRAMMINGFILE_SWBIN) $(PROGRAMMINGFILE_DATA) |
|
#distclean: clean |
/cfi_ctrl_programmer/cfi_ctrl_programmer.ld
0,0 → 1,113
/*STARTUP(../support/crt0.o)*/ |
/*ENTRY()*/ |
OUTPUT_ARCH(or32) |
/*GROUP()*/ |
SEARCH_DIR(.) |
__DYNAMIC = 0; |
|
MEMORY |
{ |
vectors : ORIGIN = 0, LENGTH = 0x1000 |
ram : ORIGIN = 0x1000, LENGTH = (8M - 0x1000) |
} |
|
|
/* |
* Allocate the stack to be at the top of memory, since the stack |
* grows down. |
*/ |
_min_stack = 0x2000; /* 8K - minimum stack space to reserve */ |
|
SECTIONS |
{ |
.vectors : |
{ |
*(.vectors) |
} > vectors |
|
.text : { |
stext = .; |
_stext = .; |
*(.text) |
_etext = .; |
__CTOR_LIST__ = .; |
LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) |
*(.ctors) |
LONG(0) |
__CTOR_END__ = .; |
__DTOR_LIST__ = .; |
LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) |
*(.dtors) |
LONG(0) |
__DTOR_END__ = .; |
*(.lit) |
*(.shdata) |
_endtext = .; |
} > ram |
|
.rodata : { |
*(.rodata); |
*(.rodata.*) |
} > ram |
|
/* Section we'll use for storing the program to load into the flash */ |
.shbss : |
{ |
*(.shbss) |
} > ram |
|
.talias : |
{ |
} > ram |
|
.data : { |
sdata = .; |
_sdata = .; |
*(.data) |
edata = .; |
_edata = .; |
} > ram |
|
.bss SIZEOF(.data) + ADDR(.data) : |
{ |
_bss_start = ALIGN(0x8); |
*(.bss) |
*(COMMON) |
_bss_end = .; |
} |
|
|
/* ensure there is enough room for stack */ |
.stack (NOLOAD): { |
. = ALIGN(4); |
sstack = . ; |
_sstack = . ; |
. = . + _min_stack ; |
. = ALIGN(4); |
stack = . ; |
_stack = . ; |
estack = . ; |
_estack = . ; |
} > ram |
|
. = . + 0x2000 ; |
.userprogram : { |
. = ALIGN(4); |
userprogram_data = .; |
_userprogram_data = .; |
*(.userprogram) |
end_userprogram_data = .; |
_end_userprogram_data = .; |
} > ram |
|
|
.stab 0 (NOLOAD) : |
{ |
[ .stab ] |
} |
|
.stabstr 0 (NOLOAD) : |
{ |
[ .stabstr ] |
} |
} |