Initial version
Committed on the Free edition of March Hare Software CVSNT Server. Upgrade to CVS Suite for more features and support: http://march-hare.com/cvsnt/ git-svn-id: http://moon:8086/svn/vhdl/trunk@789 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -0,0 +1,47 @@
|
|||||||
|
ENDIAN='big'
|
||||||
|
|
||||||
|
ifeq ($(ENDIAN), 'big')
|
||||||
|
ENDIAN_FLAGS=-EB
|
||||||
|
LIB_DIRS=-L $(MIPS_TOOLS_PREFIX)/mipsel-elf/lib/eb -L $(MIPS_TOOLS_PREFIX)/lib/gcc/mipsel-elf/$(MIPS_GCC_VER)/eb
|
||||||
|
else
|
||||||
|
ENDIAN_FLAGS=-EL
|
||||||
|
LIB_DIRS=-L $(MIPS_TOOLS_PREFIX)/mipsel-elf/lib -L $(MIPS_TOOLS_PREFIX)/lib/gcc/mipsel-elf/$(MIPS_GCC_VER)
|
||||||
|
endif
|
||||||
|
|
||||||
|
CFLAGS=$(ENDIAN_FLAGS) -Os -I. -I../ -I../libsys -msoft-float -march=r3000
|
||||||
|
LFLAGS=$(ENDIAN_FLAGS) -M -T bootloader.ld
|
||||||
|
|
||||||
|
LIBS=-lc -lgcc
|
||||||
|
|
||||||
|
CC=mipsel-elf-gcc
|
||||||
|
LD=mipsel-elf-ld
|
||||||
|
OBJDUMP=mipsel-elf-objdump
|
||||||
|
OBJCOPY=mipsel-elf-objcopy
|
||||||
|
|
||||||
|
all: bootloader_flash
|
||||||
|
|
||||||
|
libsys: startup_boot.S init_boot.S kernel_boot.S libsys_boot.c
|
||||||
|
$(CC) $(CFLAGS) -c startup_boot.S -o startup.o
|
||||||
|
$(CC) $(CFLAGS) -c init_boot.S -o init.o
|
||||||
|
$(CC) $(CFLAGS) -c kernel_boot.S -o kernel.o
|
||||||
|
$(CC) $(CFLAGS) -c libsys_boot.c -o libsys.o
|
||||||
|
|
||||||
|
bootloader: libsys bootloader.c
|
||||||
|
$(CC) $(CFLAGS) -g -c bootloader.c
|
||||||
|
$(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o libsys.o bootloader.o -o bootloader.elf $(LIBS) >bootloader.map
|
||||||
|
$(OBJDUMP) -d bootloader.elf > bootloader.dis
|
||||||
|
$(OBJCOPY) bootloader.elf -O binary bootloader.ROM.bin
|
||||||
|
$(OBJCOPY) -O srec bootloader.elf bootloader.srec
|
||||||
|
romgen bootloader.ROM.bin 10 $(ENDIAN_FLAGS)
|
||||||
|
|
||||||
|
bootloader_flash: libsys bootloader_with_flash.c
|
||||||
|
$(CC) $(CFLAGS) -g -c bootloader_with_flash.c
|
||||||
|
$(CC) $(CFLAGS) -g -c ../cfiflash.c
|
||||||
|
$(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o libsys.o cfiflash.o bootloader_with_flash.o -o bootloader.elf $(LIBS) >bootloader.map
|
||||||
|
$(OBJDUMP) -d bootloader.elf > bootloader.dis
|
||||||
|
$(OBJCOPY) bootloader.elf -O binary bootloader.ROM.bin
|
||||||
|
$(OBJCOPY) -O srec bootloader.elf bootloader.srec
|
||||||
|
romgen bootloader.ROM.bin 11 $(ENDIAN_FLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf *.o *.bin *.map *.dis *.srec *.elf *.vhd* *.tcl bootloader > /dev/null
|
||||||
@@ -0,0 +1,247 @@
|
|||||||
|
#include "libsys_boot.h"
|
||||||
|
|
||||||
|
typedef struct _ssrec_t
|
||||||
|
{
|
||||||
|
UINT32 addr;
|
||||||
|
UINT32 size;
|
||||||
|
UINT32 type;
|
||||||
|
UINT8 *data;
|
||||||
|
|
||||||
|
} srec_t;
|
||||||
|
|
||||||
|
enum srec_type
|
||||||
|
{
|
||||||
|
srec_err, srec_sob, srec_data, srec_rec, srec_eob
|
||||||
|
};
|
||||||
|
|
||||||
|
UINT8 h2i(UINT8 *c)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
UINT8 t, b = 0;
|
||||||
|
|
||||||
|
for (i=0; i < 2; i++)
|
||||||
|
{
|
||||||
|
t = c[i];
|
||||||
|
if (t >= 'A')
|
||||||
|
t = t - 'A' + 10;
|
||||||
|
else
|
||||||
|
t -= '0';
|
||||||
|
|
||||||
|
b = (b << 4) | t;
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int decode_srec(srec_t *pRec, UINT8 *pBuf, int buflen)
|
||||||
|
{
|
||||||
|
UINT8 chksum, byte;
|
||||||
|
int alen, i;
|
||||||
|
|
||||||
|
if (!buflen)
|
||||||
|
return srec_err;
|
||||||
|
|
||||||
|
pRec->type = srec_rec;
|
||||||
|
alen = 0;
|
||||||
|
if ((pBuf[1] > '0') && (pBuf[1] < '4'))
|
||||||
|
{
|
||||||
|
alen = pBuf[1] - '0' + 1;
|
||||||
|
pRec->type = srec_data;
|
||||||
|
}
|
||||||
|
else if ((pBuf[1] >= '7') && (pBuf[1] <= '9'))
|
||||||
|
{
|
||||||
|
alen = 11 - (pBuf[1] - '0');
|
||||||
|
pRec->type = srec_eob;
|
||||||
|
}
|
||||||
|
else if (pBuf[1] == '0')
|
||||||
|
{
|
||||||
|
alen = 2;
|
||||||
|
pRec->type = srec_sob;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte = h2i(&pBuf[2]);
|
||||||
|
pRec->size = byte;
|
||||||
|
chksum = byte;
|
||||||
|
|
||||||
|
pRec->addr = 0;
|
||||||
|
for (i=0; i < alen; i++)
|
||||||
|
{
|
||||||
|
byte = h2i(&pBuf[4+2*i]);
|
||||||
|
pRec->addr = pRec->addr << 8 | byte;
|
||||||
|
chksum += byte;
|
||||||
|
}
|
||||||
|
pRec->size -= (alen+1);
|
||||||
|
|
||||||
|
pRec->data = (UINT8*) &pBuf[4 + 2*alen];
|
||||||
|
for (i=0; i < (int)pRec->size; i++)
|
||||||
|
{
|
||||||
|
byte = h2i(&pRec->data[2*i]);
|
||||||
|
pRec->data[i] = byte;
|
||||||
|
chksum += byte;
|
||||||
|
}
|
||||||
|
chksum = ~chksum;
|
||||||
|
byte = h2i(&pRec->data[2*i]);
|
||||||
|
if (chksum != byte)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return pRec->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srec_getline(UINT8 *pLine)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
c = readchar();
|
||||||
|
|
||||||
|
} while ((c != 's') && (c != 'S'));
|
||||||
|
|
||||||
|
while(((c != 0x0D) && (c != 0x0A)))
|
||||||
|
{
|
||||||
|
pLine[i++] = c;
|
||||||
|
c = readchar();
|
||||||
|
};
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jump_to(void *pEntry)
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
".set noreorder\n"
|
||||||
|
);
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
"jr %[pEntry]\n" // jump entry
|
||||||
|
:
|
||||||
|
: [pEntry] "r" (pEntry)
|
||||||
|
);
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
"nop\n"
|
||||||
|
);
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
".set reorder\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exec_at(void *pEntry)
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
".set noreorder\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
"mfc0 $26, $12\n" // change exception vector
|
||||||
|
"li $27, 0xFFBFFFFF\n"
|
||||||
|
"and $26, $27\n"
|
||||||
|
"mtc0 $26, $12\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
"lw $v0, 16($sp)\n"
|
||||||
|
"nop\n"
|
||||||
|
"jr $v0\n" // jump entry
|
||||||
|
"rfe\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
".set reorder\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
void PrintCPUinfo(void)
|
||||||
|
{
|
||||||
|
int result, rev_id;
|
||||||
|
|
||||||
|
char *cpu_type_str[7] = {"invalid", "R2000", "R3000", "R6000", "R4000", "reserved", "R6000A"};
|
||||||
|
|
||||||
|
// Print Status register
|
||||||
|
result = CP0_SR_read();
|
||||||
|
|
||||||
|
sputs("Status : ");
|
||||||
|
print_word(result);
|
||||||
|
sputs("\n");
|
||||||
|
|
||||||
|
// Print Revision
|
||||||
|
result = CP0_PRID_read();
|
||||||
|
rev_id = (result >> 8) & 0xFF;
|
||||||
|
sputs("CPU type: ");
|
||||||
|
if ((rev_id > 0) && (rev_id < 0x07))
|
||||||
|
{
|
||||||
|
sputs(cpu_type_str[rev_id]);
|
||||||
|
sputs(" Rev.");
|
||||||
|
rev_id = result & 0xFF;
|
||||||
|
print_byte((char)rev_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sputs("Unknown");
|
||||||
|
|
||||||
|
sputs("\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAX_IMG_SIZE (1024*1024) // bytes
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
UINT8 buf[256];
|
||||||
|
srec_t srec;
|
||||||
|
int result, srec_state, i;
|
||||||
|
UINT32 haddr;
|
||||||
|
volatile UINT8 *pMem;
|
||||||
|
haddr = 0;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------
|
||||||
|
sputs("\n\n");
|
||||||
|
PrintCPUinfo();
|
||||||
|
sputs("Booting from UART..");
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
sputs(".");
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
result = srec_getline(buf);
|
||||||
|
srec_state = decode_srec(&srec, buf, result);
|
||||||
|
switch (srec_state)
|
||||||
|
{
|
||||||
|
case srec_data:
|
||||||
|
if ((srec.addr + srec.size) > haddr)
|
||||||
|
haddr = srec.addr + srec.size;
|
||||||
|
|
||||||
|
pMem = (UINT8*)srec.addr;
|
||||||
|
for (i=0; i < srec.size; i++)
|
||||||
|
*pMem++ = srec.data[i];
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case srec_eob:
|
||||||
|
sputs("done\n\n");
|
||||||
|
sputs("Execute program at ");
|
||||||
|
print_word(srec.addr);
|
||||||
|
sputs("\n\n");
|
||||||
|
|
||||||
|
Exec_at((void*)srec.addr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
result = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (result < 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,383 @@
|
|||||||
|
#include "libsys_boot.h"
|
||||||
|
#include "cfiflash.h"
|
||||||
|
|
||||||
|
#define MAGIC_EB 0x4A464931 // "JFI1" in big-endian;
|
||||||
|
#define MAGIC_EL 0x3149464A // "JFI1" in little-endian;
|
||||||
|
|
||||||
|
typedef struct _ssrec_t
|
||||||
|
{
|
||||||
|
UINT32 addr;
|
||||||
|
UINT32 size;
|
||||||
|
UINT32 type;
|
||||||
|
UINT8 *data;
|
||||||
|
|
||||||
|
} srec_t;
|
||||||
|
typedef struct _sflash_alloc_tbl_t
|
||||||
|
{
|
||||||
|
UINT32 images[16];
|
||||||
|
|
||||||
|
} flash_alloc_tbl_t;
|
||||||
|
|
||||||
|
typedef struct _sflash_img_hdr_t
|
||||||
|
{
|
||||||
|
UINT32 magic;
|
||||||
|
UINT32 target_base;
|
||||||
|
UINT32 img_base;
|
||||||
|
UINT32 img_size;
|
||||||
|
UINT32 hdr_next;
|
||||||
|
UINT8 img_name[128];
|
||||||
|
UINT8 res[108];
|
||||||
|
|
||||||
|
} flash_img_hdr_t;
|
||||||
|
|
||||||
|
enum srec_type
|
||||||
|
{
|
||||||
|
srec_err, srec_sob, srec_data, srec_rec, srec_eob
|
||||||
|
};
|
||||||
|
|
||||||
|
UINT8 h2i(UINT8 *c)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
UINT8 t, b = 0;
|
||||||
|
|
||||||
|
for (i=0; i < 2; i++)
|
||||||
|
{
|
||||||
|
t = c[i];
|
||||||
|
if (t >= 'A')
|
||||||
|
t = t - 'A' + 10;
|
||||||
|
else
|
||||||
|
t -= '0';
|
||||||
|
|
||||||
|
b = (b << 4) | t;
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int decode_srec(srec_t *pRec, UINT8 *pBuf, int buflen)
|
||||||
|
{
|
||||||
|
UINT8 chksum, byte;
|
||||||
|
int alen, i;
|
||||||
|
|
||||||
|
if (!buflen)
|
||||||
|
return srec_err;
|
||||||
|
|
||||||
|
pRec->type = srec_rec;
|
||||||
|
alen = 0;
|
||||||
|
if ((pBuf[1] > '0') && (pBuf[1] < '4'))
|
||||||
|
{
|
||||||
|
alen = pBuf[1] - '0' + 1;
|
||||||
|
pRec->type = srec_data;
|
||||||
|
}
|
||||||
|
else if ((pBuf[1] >= '7') && (pBuf[1] <= '9'))
|
||||||
|
{
|
||||||
|
alen = 11 - (pBuf[1] - '0');
|
||||||
|
pRec->type = srec_eob;
|
||||||
|
}
|
||||||
|
else if (pBuf[1] == '0')
|
||||||
|
{
|
||||||
|
alen = 2;
|
||||||
|
pRec->type = srec_sob;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte = h2i(&pBuf[2]);
|
||||||
|
pRec->size = byte;
|
||||||
|
chksum = byte;
|
||||||
|
|
||||||
|
pRec->addr = 0;
|
||||||
|
for (i=0; i < alen; i++)
|
||||||
|
{
|
||||||
|
byte = h2i(&pBuf[4+2*i]);
|
||||||
|
pRec->addr = pRec->addr << 8 | byte;
|
||||||
|
chksum += byte;
|
||||||
|
}
|
||||||
|
pRec->size -= (alen+1);
|
||||||
|
|
||||||
|
pRec->data = (UINT8*) &pBuf[4 + 2*alen];
|
||||||
|
for (i=0; i < (int)pRec->size; i++)
|
||||||
|
{
|
||||||
|
byte = h2i(&pRec->data[2*i]);
|
||||||
|
pRec->data[i] = byte;
|
||||||
|
chksum += byte;
|
||||||
|
}
|
||||||
|
chksum = ~chksum;
|
||||||
|
byte = h2i(&pRec->data[2*i]);
|
||||||
|
if (chksum != byte)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return pRec->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srec_getline(UINT8 *pLine)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
c = readchar();
|
||||||
|
|
||||||
|
} while ((c != 's') && (c != 'S'));
|
||||||
|
|
||||||
|
while(((c != 0x0D) && (c != 0x0A)))
|
||||||
|
{
|
||||||
|
pLine[i++] = c;
|
||||||
|
c = readchar();
|
||||||
|
};
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jump_to(void *pEntry)
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
".set noreorder\n"
|
||||||
|
);
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
"jr %[pEntry]\n" // jump entry
|
||||||
|
:
|
||||||
|
: [pEntry] "r" (pEntry)
|
||||||
|
);
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
"nop\n"
|
||||||
|
);
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
".set reorder\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exec_at(void *pEntry)
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
".set noreorder\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
"li $26, 0x10000000\n"
|
||||||
|
"mtc0 $26, $12\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
"jr %[pEntry]\n" // jump entry
|
||||||
|
:
|
||||||
|
: [pEntry] "r" (pEntry)
|
||||||
|
);
|
||||||
|
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
"rfe\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
".set reorder\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exec_RE_at(void *pEntry)
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
".set noreorder\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
"mfc0 $26, $12\n" // change exception vector
|
||||||
|
"li $27, 0xFFBFFFFF\n"
|
||||||
|
"and $26, $27\n"
|
||||||
|
"li $27, 0x02000000\n" // Reverse Endianess
|
||||||
|
"or $26, $27\n"
|
||||||
|
"mtc0 $26, $12\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
"jr %[pEntry]\n" // jump entry
|
||||||
|
:
|
||||||
|
: [pEntry] "r" (pEntry)
|
||||||
|
);
|
||||||
|
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
"rfe\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
".set reorder\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAX_IMG_SIZE (1024*1024) // bytes
|
||||||
|
#define SDRAM_BASE 0x40000000
|
||||||
|
#define FLASH_USE_BLOCK 1
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
UINT8 buf[256];
|
||||||
|
srec_t srec;
|
||||||
|
int srec_state, i;
|
||||||
|
UINT32 haddr, result;
|
||||||
|
flash_t flash;
|
||||||
|
flash_img_hdr_t img_hdr = {0};
|
||||||
|
flash_img_hdr_t *pImg_hdr;
|
||||||
|
UINT32 img_size, block_sel;
|
||||||
|
|
||||||
|
volatile UINT32 *pLED = (UINT32*)SYS_LED_PORT;
|
||||||
|
volatile UINT32 *pBtn = (UINT32*)SYS_GPIO0;
|
||||||
|
volatile UINT32 *pDip = (UINT32*)SYS_GPIO1;
|
||||||
|
volatile UINT8 *pMem;
|
||||||
|
volatile UINT32 *pFlashIO = (UINT32*)SYS_FLASH_IO; // Flash in uncached area
|
||||||
|
volatile UINT32 *pFlashMem = (UINT32*)SYS_FLASH_MEM; // Flash in cached area
|
||||||
|
volatile UINT32 *ram32 = (UINT32*)SDRAM_BASE;
|
||||||
|
UINT32 flash_offset;
|
||||||
|
|
||||||
|
*pLED = 0;
|
||||||
|
haddr = 0;
|
||||||
|
block_sel = 0x7F & (UINT32)*pDip;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------
|
||||||
|
if (IS_ERROR(flash_find(&flash, SYS_FLASH_IO)))
|
||||||
|
{
|
||||||
|
sputs("Cannot find flash device. Exit now!\n\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get flash offset by value of DIP-switch
|
||||||
|
flash_offset = flash_get_offset_by_blocknum(&flash, block_sel);
|
||||||
|
|
||||||
|
ram32 = (UINT32*)(SDRAM_BASE);
|
||||||
|
pFlashIO = (UINT32*)(SYS_FLASH_IO + flash_offset);
|
||||||
|
|
||||||
|
if (!(*pBtn & 8))
|
||||||
|
{
|
||||||
|
sputs("\n\n");
|
||||||
|
pImg_hdr = (flash_img_hdr_t*)pFlashIO;
|
||||||
|
if ((pImg_hdr->magic != MAGIC_EL) && (pImg_hdr->magic != MAGIC_EB))
|
||||||
|
{
|
||||||
|
sputs("\n\n");
|
||||||
|
sputs("Invalid image found at ");print_word(flash_offset); sputs(". Abort.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sputs("Booting application from flash (");print_word(flash_offset);sputs(")...");
|
||||||
|
|
||||||
|
ram32 = (UINT32*)pImg_hdr->target_base;
|
||||||
|
img_size = pImg_hdr->img_size;
|
||||||
|
|
||||||
|
// It's safe to use cached Flash,
|
||||||
|
// because D-Cache was invalidated during execution of start code
|
||||||
|
pFlashMem = (UINT32*)(SYS_FLASH_MEM + pImg_hdr->img_base);
|
||||||
|
|
||||||
|
for (i=0; i < img_size/4; i++)
|
||||||
|
ram32[i] = pFlashMem[i];
|
||||||
|
|
||||||
|
sputs("done\n");
|
||||||
|
|
||||||
|
sputs("Execute at ");print_word(pImg_hdr->target_base); sputs("\n\n");
|
||||||
|
Exec_at((void*)ram32);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
sputs("\n\n");
|
||||||
|
|
||||||
|
sputs("Reading HEX-Record from UART..");
|
||||||
|
|
||||||
|
// Erase SDRAM
|
||||||
|
for (i=0; i < MAX_IMG_SIZE/4; i++)
|
||||||
|
ram32[i] = 0;
|
||||||
|
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
sputs(".");
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
result = srec_getline(buf);
|
||||||
|
srec_state = decode_srec(&srec, buf, result);
|
||||||
|
*pLED = 0;
|
||||||
|
switch (srec_state)
|
||||||
|
{
|
||||||
|
case srec_data:
|
||||||
|
if ((srec.addr + srec.size) > haddr)
|
||||||
|
haddr = srec.addr + srec.size;
|
||||||
|
|
||||||
|
pMem = (UINT8*)srec.addr;
|
||||||
|
for (i=0; i < srec.size; i++)
|
||||||
|
*pMem++ = srec.data[i];
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case srec_eob:
|
||||||
|
sputs("done\n\n");
|
||||||
|
img_hdr.magic = MAGIC_EB;
|
||||||
|
img_hdr.target_base = srec.addr;
|
||||||
|
img_hdr.img_size = haddr - srec.addr;
|
||||||
|
img_hdr.img_base = flash_offset + sizeof(flash_img_hdr_t);
|
||||||
|
img_hdr.hdr_next = flash_get_offset_blockaligned(&flash, img_hdr.img_base + img_hdr.img_size);
|
||||||
|
sputs("Size of application : ");print_word(img_hdr.img_size); sputs("\n");
|
||||||
|
sputs("Programming flash at : ");print_word(flash_offset); sputs("\n");
|
||||||
|
sputs("Next free flash offset : ");print_word(img_hdr.hdr_next); sputs("\n");
|
||||||
|
|
||||||
|
sputs("Flash erase...");
|
||||||
|
result = flash_erase(&flash, flash_offset, img_hdr.img_size + sizeof(flash_img_hdr_t));
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
sputs("failed (");print_word(result);sputs(")\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sputs("done\n");
|
||||||
|
|
||||||
|
sputs("Flash write...");
|
||||||
|
result = flash_program(&flash, flash_offset, (UINT8*)&img_hdr, sizeof(flash_img_hdr_t));
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
sputs("failed (");print_word(result);sputs(")\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result = flash_program(&flash, img_hdr.img_base, (UINT8*)img_hdr.target_base, img_hdr.img_size);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
sputs("failed (");print_word(result);sputs(")\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sputs("done\n");
|
||||||
|
|
||||||
|
sputs("Flash verify...");
|
||||||
|
result = flash_verify(&flash, img_hdr.img_base, (UINT8*)img_hdr.target_base, img_hdr.img_size);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
sputs("failed (");print_word(result);sputs(")\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sputs("passed\n");
|
||||||
|
|
||||||
|
// Jump to reset vector
|
||||||
|
Jump_to((void*)0xBFC00000);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
result = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
*pLED = 0x40000000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
.file "init.S"
|
||||||
|
|
||||||
|
.text
|
||||||
|
.section .init,"ax"
|
||||||
|
.align 2
|
||||||
|
.globl _init
|
||||||
|
.extern end
|
||||||
|
|
||||||
|
_init:
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
# set uart
|
||||||
|
la $26, sys_uart_baud
|
||||||
|
addiu $27, $0, baudrate
|
||||||
|
sw $27, 0($26)
|
||||||
|
|
||||||
|
jr $ra
|
||||||
|
|
||||||
|
.set reorder
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
@rem
|
||||||
|
@rem Setup Chipscope's TCL JTAG path
|
||||||
|
@rem
|
||||||
|
@rem Usage: cs_xtclsh.bat args...
|
||||||
|
@rem
|
||||||
|
@date /T > date.tmp
|
||||||
|
@date 15.03.2009
|
||||||
|
@set CS_PATH=%XILINX%\ChipScope\bin\nt
|
||||||
|
@echo %CS_PATH%
|
||||||
|
|
||||||
|
@call %CS_PATH%\cs_xtclsh bootloader.ROM.tcl
|
||||||
|
@type date.tmp | date >nul
|
||||||
|
@del date.tmp
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
.file "kernel.S"
|
||||||
|
|
||||||
|
.section .ktext,"ax"
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
.macro kpush reg
|
||||||
|
addiu $sp, 4
|
||||||
|
sw \reg, 0($sp)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro kpop reg
|
||||||
|
lw \reg, 0($sp)
|
||||||
|
addiu $sp, -4
|
||||||
|
.endm
|
||||||
|
|
||||||
|
_exc_handler:
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
# Set Error LED and ExcCode LEDs
|
||||||
|
# Get Cause
|
||||||
|
mfc0 $26, $13
|
||||||
|
li $27, 0xC0000000
|
||||||
|
srl $26, 2
|
||||||
|
andi $26, 0x000F
|
||||||
|
or $26, $27
|
||||||
|
la $27, sys_led_port
|
||||||
|
sw $26, 0($27)
|
||||||
|
|
||||||
|
# wait for all interrupts = 0
|
||||||
|
$w4x: mfc0 $26, $13
|
||||||
|
nop
|
||||||
|
srl $26, 8
|
||||||
|
andi $26, 0xFF
|
||||||
|
bnez $26, $w4x
|
||||||
|
nop
|
||||||
|
|
||||||
|
# Get return address
|
||||||
|
mfc0 $26, $14
|
||||||
|
|
||||||
|
# Return
|
||||||
|
nop
|
||||||
|
jr $26
|
||||||
|
rfe
|
||||||
|
.set reorder
|
||||||
|
|
||||||
@@ -0,0 +1,214 @@
|
|||||||
|
#include <sys/times.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "libsys_boot.h"
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
// MIPS specific
|
||||||
|
UINT32 CP0_SR_read(void)
|
||||||
|
{
|
||||||
|
UINT32 result;
|
||||||
|
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
"mfc0 %[val], $12\n"
|
||||||
|
: [val] "=r" (result)
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CP0_SR_write(UINT32 val)
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
"mtc0 %[val], $12\n"
|
||||||
|
: /* no output */
|
||||||
|
: [val] "r" (val)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 CP0_CR_read(void)
|
||||||
|
{
|
||||||
|
UINT32 result;
|
||||||
|
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
"mfc0 %[val], $13\n"
|
||||||
|
: [val] "=r" (result)
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CP0_CR_write(UINT32 val)
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
"mtc0 %[val], $13\n"
|
||||||
|
:
|
||||||
|
: [val] "r" (val)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 CP0_PRID_read(void)
|
||||||
|
{
|
||||||
|
UINT32 result;
|
||||||
|
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
"mfc0 %[val], $15\n"
|
||||||
|
: [val] "=r" (result)
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
char readchar(void)
|
||||||
|
{
|
||||||
|
volatile UINT32 *pUART_stat = (UINT32*)SYS_UART_STAT;
|
||||||
|
volatile UINT32 *pUART_data = (UINT32*)SYS_UART_DATA;
|
||||||
|
|
||||||
|
while(!(0x10 & *pUART_stat));
|
||||||
|
|
||||||
|
return (char)*pUART_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writechar(char c)
|
||||||
|
{
|
||||||
|
volatile UINT32 *pUART_stat = (UINT32*)SYS_UART_STAT;
|
||||||
|
volatile UINT32 *pUART_data = (UINT32*)SYS_UART_DATA;
|
||||||
|
|
||||||
|
while((0x02 & *pUART_stat) != 0);
|
||||||
|
|
||||||
|
*pUART_data = (UINT32)c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _putchar(char c)
|
||||||
|
{
|
||||||
|
if (c == 0x0A)
|
||||||
|
{
|
||||||
|
writechar(0x0D);
|
||||||
|
}
|
||||||
|
writechar(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sputs(char *pStr)
|
||||||
|
{
|
||||||
|
char *start;
|
||||||
|
start = pStr;
|
||||||
|
|
||||||
|
while(*pStr)
|
||||||
|
_putchar(*(pStr++));
|
||||||
|
|
||||||
|
return pStr - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_byte(char byte)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char c, nibble;
|
||||||
|
|
||||||
|
for (i=0; i < 2; i++)
|
||||||
|
{
|
||||||
|
nibble = (char)((byte >> 4) & 0xF);
|
||||||
|
byte <<= 4;
|
||||||
|
|
||||||
|
if (nibble < 10)
|
||||||
|
c = nibble + '0';
|
||||||
|
else
|
||||||
|
c = nibble + 'A' - 10;
|
||||||
|
|
||||||
|
_putchar(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_word(int word)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char c, nibble;
|
||||||
|
|
||||||
|
for (i=0; i < 4; i++)
|
||||||
|
{
|
||||||
|
c = (char) (word >> 24);
|
||||||
|
print_byte(c);
|
||||||
|
word <<= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
// PrintBuffer8()
|
||||||
|
// Prints byte buffer as hex and ascii interpretation
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
// _Parameters :
|
||||||
|
// pBuf: : IN: Buffer to display
|
||||||
|
// nbpr : Number of bytes per row to display
|
||||||
|
// len : Length of input buffer
|
||||||
|
// _Return: none
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
void PrintBuffer8(UINT8 *pBuf, int nbpr, int len)
|
||||||
|
{
|
||||||
|
memdump(pBuf, 1, nbpr, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void memdump(UINT8 *pBuf, int print_offset_only, int num_bytes_per_row, int len)
|
||||||
|
{
|
||||||
|
int i, j, cnt_hex, cnt_asc, base;
|
||||||
|
unsigned char c;
|
||||||
|
|
||||||
|
i = j = 0;
|
||||||
|
cnt_hex = len;
|
||||||
|
cnt_asc = len;
|
||||||
|
base = 0;
|
||||||
|
if (!print_offset_only)
|
||||||
|
base = (int)pBuf;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
print_word(base + i);
|
||||||
|
sputs(": ");
|
||||||
|
for (j=0; j < num_bytes_per_row; j++)
|
||||||
|
{
|
||||||
|
if (cnt_hex)
|
||||||
|
{
|
||||||
|
print_byte(pBuf[i+j]);
|
||||||
|
sputs(" ");
|
||||||
|
cnt_hex--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sputs(" ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sputs(" ");
|
||||||
|
for (j=0; j < num_bytes_per_row; j++)
|
||||||
|
{
|
||||||
|
if (cnt_asc)
|
||||||
|
{
|
||||||
|
c = pBuf[i+j];
|
||||||
|
if((c < 0x20) || (c > 0x7F))
|
||||||
|
c = '.';
|
||||||
|
|
||||||
|
_putchar(c);
|
||||||
|
cnt_asc--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sputs(" ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sputs("\n");
|
||||||
|
i += num_bytes_per_row;
|
||||||
|
|
||||||
|
} while (cnt_hex);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#ifndef LIBSYS_H
|
||||||
|
#define LIBSYS_H
|
||||||
|
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
// Types
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
#define INT8 char
|
||||||
|
#define INT16 short
|
||||||
|
#define INT32 long
|
||||||
|
#define UINT8 unsigned char
|
||||||
|
#define UINT16 unsigned short
|
||||||
|
#define UINT32 unsigned long
|
||||||
|
#define INT int
|
||||||
|
#define UINT unsigned int
|
||||||
|
#define FLOAT32 float
|
||||||
|
#define FLOAT64 double
|
||||||
|
|
||||||
|
#define IS_ERROR(e) ((e & 0x80000000) == 0x80000000)
|
||||||
|
|
||||||
|
#define SYS_GPIO0 0xA0000000
|
||||||
|
#define SYS_GPIO1 0xA0000004
|
||||||
|
#define SYS_LED_PORT SYS_GPIO0
|
||||||
|
#define SYS_USB_CTRL SYS_GPIO1
|
||||||
|
#define SYS_TIMER_USEC 0xA0000008
|
||||||
|
#define SYS_TIMER_SEC 0xA000000C
|
||||||
|
#define SYS_UART_DATA 0xA0010000
|
||||||
|
#define SYS_UART_STAT 0xA0010004
|
||||||
|
#define SYS_UART_BAUD 0xA0010008
|
||||||
|
#define SYS_USB_DATA 0xA0020000
|
||||||
|
#define SYS_USB_MBX 0xA0020004
|
||||||
|
#define SYS_USB_ADDR 0xA0020008
|
||||||
|
#define SYS_USB_STATUS 0xA002000C
|
||||||
|
#define SYS_FLASH_IO 0xA4000000
|
||||||
|
#define SYS_FLASH_MEM 0x00000000
|
||||||
|
|
||||||
|
// MIPS specific
|
||||||
|
UINT32 CP0_SR_read(void);
|
||||||
|
void CP0_SR_write(UINT32 val);
|
||||||
|
UINT32 CP0_CR_read(void);
|
||||||
|
void CP0_CR_write(UINT32 val);
|
||||||
|
UINT32 CP0_PRID_read(void);
|
||||||
|
|
||||||
|
// General
|
||||||
|
char readchar(void);
|
||||||
|
void writechar(char c);
|
||||||
|
int write(int file, char *ptr, int len);
|
||||||
|
int sputs(char *pStr);
|
||||||
|
void print_byte(char byte);
|
||||||
|
void print_word(int word);
|
||||||
|
void PrintBuffer8(UINT8 *pBuf, int nbpr, int len);
|
||||||
|
void memdump(UINT8 *pBuf, int print_offset_only, int num_bytes_per_row, int len);
|
||||||
|
|
||||||
|
#endif // LIBSYS_H
|
||||||
|
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
.file "startup.S"
|
||||||
|
|
||||||
|
.text
|
||||||
|
.section .init,"ax"
|
||||||
|
.extern _init
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
_start:
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
# set stack pointer
|
||||||
|
la $sp, stack_ptr
|
||||||
|
|
||||||
|
# Set Kernel mode
|
||||||
|
li $26, 0x1040000C
|
||||||
|
mtc0 $26, $12
|
||||||
|
li $26, 0x00000000
|
||||||
|
mtc0 $26, $13
|
||||||
|
|
||||||
|
mfc0 $26, $15
|
||||||
|
nop
|
||||||
|
mtc0 $26, $31
|
||||||
|
|
||||||
|
# Invalidate I-Cache
|
||||||
|
cop0 32
|
||||||
|
|
||||||
|
# Invalidate D-Cache
|
||||||
|
cop0 34
|
||||||
|
|
||||||
|
# jump init
|
||||||
|
la $26, _init
|
||||||
|
jalr $26
|
||||||
|
nop
|
||||||
|
|
||||||
|
la $26, main
|
||||||
|
jalr $26
|
||||||
|
nop
|
||||||
|
_terminate:
|
||||||
|
nop
|
||||||
|
j _terminate
|
||||||
|
nop
|
||||||
|
|
||||||
|
.set reorder
|
||||||
Reference in New Issue
Block a user