diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader/Makefile b/lib/CPUs/MIPS/bsp/examples/bootloader/Makefile new file mode 100644 index 0000000..513a332 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader/Makefile @@ -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 diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader/bootloader.c b/lib/CPUs/MIPS/bsp/examples/bootloader/bootloader.c new file mode 100644 index 0000000..7ade222 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader/bootloader.c @@ -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; +} + diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader/bootloader_with_flash.c b/lib/CPUs/MIPS/bsp/examples/bootloader/bootloader_with_flash.c new file mode 100644 index 0000000..197ab44 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader/bootloader_with_flash.c @@ -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; +} + diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader/init_boot.S b/lib/CPUs/MIPS/bsp/examples/bootloader/init_boot.S new file mode 100644 index 0000000..84a8d9d --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader/init_boot.S @@ -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 diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader/jtag_upd.bat b/lib/CPUs/MIPS/bsp/examples/bootloader/jtag_upd.bat new file mode 100644 index 0000000..33bc43a --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader/jtag_upd.bat @@ -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 diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader/kernel_boot.S b/lib/CPUs/MIPS/bsp/examples/bootloader/kernel_boot.S new file mode 100644 index 0000000..b4a8694 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader/kernel_boot.S @@ -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 + diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader/libsys_boot.c b/lib/CPUs/MIPS/bsp/examples/bootloader/libsys_boot.c new file mode 100644 index 0000000..0f39d80 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader/libsys_boot.c @@ -0,0 +1,214 @@ +#include +#include +#include +#include +#include +#include +#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); +} + diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader/libsys_boot.h b/lib/CPUs/MIPS/bsp/examples/bootloader/libsys_boot.h new file mode 100644 index 0000000..3bf4ecc --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader/libsys_boot.h @@ -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 + diff --git a/lib/CPUs/MIPS/bsp/examples/bootloader/startup_boot.S b/lib/CPUs/MIPS/bsp/examples/bootloader/startup_boot.S new file mode 100644 index 0000000..8da9ee0 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/examples/bootloader/startup_boot.S @@ -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