OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 7 to Rev 8
    Reverse comparison

Rev 7 → Rev 8

/altor32/trunk/sw/bootloader/xmodem.h
0,0 → 1,25
#ifndef __XMODEM_H__
#define __XMODEM_H__
 
//-----------------------------------------------------------------
// Defines
//-----------------------------------------------------------------
 
// Support 128 byte transfers
#define XMODEM_BUFFER_SIZE 128
 
// Support 1024 byte transfers
//#define XMODEM_BUFFER_SIZE 1024
 
// xmodem timeout/retry parameters
#define XMODEM_TIMEOUT_DELAY 1000
#define XMODEM_RETRY_LIMIT 16
 
//-----------------------------------------------------------------
// Prototypes
//-----------------------------------------------------------------
void xmodem_init(int (*sputc)(char c), int (*sgetc)(void));
int xmodem_receive( int (*write)(unsigned char* buffer, int size) );
 
#endif // __XMODEM_H__
 
/altor32/trunk/sw/bootloader/boot_serial.c
0,0 → 1,117
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// AltOR32
// Alternative Lightweight OpenRisc
// Ultra-Embedded.com
// Copyright 2011 - 2012
//
// Email: admin@ultra-embedded.com
//
// License: GPL
// Please contact the above address if you would like a version of this
// software with a more permissive license for use in closed source commercial
// applications.
//-----------------------------------------------------------------------------
//
// This file is part of AltOR32 OpenRisc Simulator.
//
// AltOR32 OpenRisc Simulator is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// AltOR32 OpenRisc Simulator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AltOR32 OpenRisc Simulator; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#include "serial.h"
#include "boot_serial.h"
#include "xmodem.h"
#include "mem_map.h"
#include "spi_flash.h"
 
//-----------------------------------------------------------------
// Defines:
//-----------------------------------------------------------------
#define FLASH_SECTOR_SIZE SPIFLASH_BLOCKSIZE
 
//-----------------------------------------------------------------
// Locals:
//-----------------------------------------------------------------
static unsigned long xfer_offset = 0;
static unsigned long xfer_base;
static int xfer_flash;
 
//-----------------------------------------------------------------
// Prototypes:
//-----------------------------------------------------------------
static int xmodem_write(unsigned char* buffer, int size);
 
static unsigned char _tmpbuf[128];
 
//-----------------------------------------------------------------
// boot_serial:
//-----------------------------------------------------------------
void boot_serial(unsigned long target, int flash)
{
int res;
 
// Load target memory address
xfer_base = target;
xfer_flash = flash;
 
// Init X-Modem transfer
xmodem_init(serial_putchar, serial_getchar);
 
do
{
// Reset
xfer_offset = xfer_base;
 
res = xmodem_receive( xmodem_write );
}
while (res < 0);
}
//-----------------------------------------------------------------
// xmodem_write:
//-----------------------------------------------------------------
static int xmodem_write(unsigned char* buffer, int size)
{
// Write to flash
int i;
int flush = 0;
 
// Flush final block
if (size == 0)
flush = 1;
 
// We are relying on the Flash sector size to be a multiple
// of Xmodem transfer sizes (128 or 1024)...
if (xfer_flash)
{
// Write block to SPI flash
spiflash_writeblock(xfer_offset, buffer, size);
 
// Increment end point to include new data
xfer_offset += size;
}
else
{
// Write to memory
unsigned char *ptr = (unsigned char *)(xfer_offset);
 
for (i=0;i<size;i++)
*ptr++ = buffer[i];
 
// Increment end point to include new data
xfer_offset += size;
}
 
return 0;
}
/altor32/trunk/sw/bootloader/assert.h
0,0 → 1,10
#ifndef __ASSERT_H__
#define __ASSERT_H__
 
extern void assert_handler(const char * type, const char *reason, const char *file, int line);
 
#define assert(exp) do { if (!(exp)) assert_handler("ASSERT", #exp, __FILE__, __LINE__ ); } while (0)
#define panic(reason) do { assert_handler("PANIC", #reason, __FILE__, __LINE__ ); } while (0)
 
#endif
 
/altor32/trunk/sw/bootloader/boot_serial.h
0,0 → 1,18
#ifndef __BOOT_SERIAL_H__
#define __BOOT_SERIAL_H__
 
//-----------------------------------------------------------------
// Defines
//-----------------------------------------------------------------
 
//-----------------------------------------------------------------
// Types
//-----------------------------------------------------------------
 
//-----------------------------------------------------------------
// Prototypes
//-----------------------------------------------------------------
void boot_serial(unsigned long target, int flash);
 
 
#endif //__BOOT_SERIAL_H__
/altor32/trunk/sw/bootloader/spi_flash.c
0,0 → 1,341
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// AltOR32
// Alternative Lightweight OpenRisc
// Ultra-Embedded.com
// Copyright 2011 - 2012
//
// Email: admin@ultra-embedded.com
//
// License: GPL
// Please contact the above address if you would like a version of this
// software with a more permissive license for use in closed source commercial
// applications.
//-----------------------------------------------------------------------------
//
// This file is part of AltOR32 OpenRisc Simulator.
//
// AltOR32 OpenRisc Simulator is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// AltOR32 OpenRisc Simulator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AltOR32 OpenRisc Simulator; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#include "assert.h"
#include "mem_map.h"
#include "spi_flash.h"
 
//-------------------------------------------------------------
// Defines:
//-------------------------------------------------------------
 
// Chip select control
#define SPIFLASH_CS_HIGH SPI_PROM_CTRL = SPI_PROM_CS
#define SPIFLASH_CS_LOW SPI_PROM_CTRL = 0
 
// ID addresses
#define SPIFLASH_MAN_ADDR 0x00
#define SPIFLASH_DEV_ADDR 0x01
 
// Instructions
#define SPIFLASH_OP_WRSR 0x01
#define SPIFLASH_OP_PROGRAM 0x02
#define SPIFLASH_OP_READ 0x03
#define SPIFLASH_OP_RDSR 0x05
#define SPIFLASH_STAT_BUSY (1 << 0)
#define SPIFLASH_STAT_WEL (1 << 1)
#define SPIFLASH_STAT_BP0 (1 << 2)
#define SPIFLASH_STAT_BP1 (1 << 3)
#define SPIFLASH_STAT_BP2 (1 << 4)
#define SPIFLASH_STAT_BP3 (1 << 5)
#define SPIFLASH_STAT_AAI (1 << 6)
#define SPIFLASH_STAT_BPL (1 << 7)
#define SPIFLASH_OP_WREN 0x06
#define SPIFLASH_OP_ERASESECTOR 0x20
#define SPIFLASH_OP_ERASECHIP 0x60
#define SPIFLASH_OP_RDID 0x9F
#define SPIFLASH_OP_AAIP 0xAD
 
typedef enum
{
SPI_FLASH_GENERIC,
SPI_FLASH_SST25VF040B,
SPI_FLASH_AT25DF041A
} tSpiDevice;
 
//-------------------------------------------------------------
// Locals:
//-------------------------------------------------------------
static tSpiDevice _device = SPI_FLASH_GENERIC;
 
//-------------------------------------------------------------
// spiflash_writebyte:
//-------------------------------------------------------------
static void spiflash_writebyte(unsigned char data)
{
SPI_PROM_DATA = data;
while (SPI_PROM_STAT & SPI_PROM_BUSY);
}
//-------------------------------------------------------------
// spiflash_readbyte:
//-------------------------------------------------------------
static unsigned char spiflash_readbyte(void)
{
SPI_PROM_DATA = 0xFF;
while (SPI_PROM_STAT & SPI_PROM_BUSY);
return SPI_PROM_DATA;
}
//-------------------------------------------------------------
// spiflash_command:
//-------------------------------------------------------------
static void spiflash_command(unsigned char command, unsigned long address)
{
spiflash_writebyte(command);
spiflash_writebyte(address >> 16);
spiflash_writebyte(address >> 8);
spiflash_writebyte(address >> 0);
}
//-------------------------------------------------------------
// spiflash_readid:
//-------------------------------------------------------------
static unsigned char spiflash_readid(unsigned long address)
{
unsigned long i;
unsigned char id;
 
SPIFLASH_CS_LOW;
 
spiflash_writebyte(SPIFLASH_OP_RDID);
for (i=0;i<=address;i++)
{
id = spiflash_readbyte();
}
 
SPIFLASH_CS_HIGH;
 
return id;
}
//-------------------------------------------------------------
// spiflash_readstatus:
//-------------------------------------------------------------
static unsigned char spiflash_readstatus(void)
{
unsigned char stat;
 
SPIFLASH_CS_LOW;
 
spiflash_writebyte(SPIFLASH_OP_RDSR);
stat = spiflash_readbyte();
 
SPIFLASH_CS_HIGH;
 
return stat;
}
//-------------------------------------------------------------
// spiflash_writeenable:
//-------------------------------------------------------------
static void spiflash_writeenable(void)
{
SPIFLASH_CS_LOW;
spiflash_writebyte(SPIFLASH_OP_WREN);
SPIFLASH_CS_HIGH;
}
//-------------------------------------------------------------
// spiflash_writestatus:
//-------------------------------------------------------------
static void spiflash_writestatus(unsigned char value)
{
// Execute write enable command
spiflash_writeenable();
 
SPIFLASH_CS_LOW;
spiflash_writebyte(SPIFLASH_OP_WRSR);
spiflash_writebyte(value);
SPIFLASH_CS_HIGH;
}
//-------------------------------------------------------------
// spiflash_programbyte:
//-------------------------------------------------------------
static void spiflash_programbyte(unsigned long address, unsigned char data)
{
// Execute write enable command
spiflash_writeenable();
 
// Program a word at a specific address
SPIFLASH_CS_LOW;
spiflash_command(SPIFLASH_OP_PROGRAM, address);
spiflash_writebyte(data);
SPIFLASH_CS_HIGH;
 
// Wait until operation completed
while (spiflash_readstatus() & SPIFLASH_STAT_BUSY)
;
}
//-------------------------------------------------------------
// spiflash_programpage:
//-------------------------------------------------------------
static void spiflash_programpage(unsigned long address, unsigned char *data, unsigned int size)
{
int i;
 
// Execute write enable command
spiflash_writeenable();
 
// Program a word at a specific address
SPIFLASH_CS_LOW;
 
spiflash_command(SPIFLASH_OP_PROGRAM, address);
 
for (i=0;i<size;i++)
spiflash_writebyte(data[i]);
 
SPIFLASH_CS_HIGH;
 
// Wait until operation completed
while (spiflash_readstatus() & SPIFLASH_STAT_BUSY)
;
}
 
//-------------------------------------------------------------
// External API
//-------------------------------------------------------------
 
//-------------------------------------------------------------
// spiflash_init:
//-------------------------------------------------------------
int spiflash_init(void)
{
int res;
unsigned char id;
 
// Do dummy reads first
spiflash_readstatus();
spiflash_readid(SPIFLASH_DEV_ADDR);
 
// Check device ID
switch ((id = spiflash_readid(SPIFLASH_MAN_ADDR)))
{
// Atmel
case 0x1F:
id = spiflash_readid(SPIFLASH_DEV_ADDR);
res = ( id == 0x44 );
assert( res && "Unknown device ID" );
_device = SPI_FLASH_AT25DF041A;
break;
// SST
case 0xBF:
id = spiflash_readid(SPIFLASH_DEV_ADDR);
res = ( id == 0x25 );
assert( res && "Unknown device ID" );
_device = SPI_FLASH_SST25VF040B;
break;
default:
res = 0;
assert(res && "Unknown manufacturer ID");
break;
}
 
// Enable device writes
spiflash_writestatus(0);
return res;
}
//-------------------------------------------------------------
// spiflash_readblock:
//-------------------------------------------------------------
int spiflash_readblock(unsigned long address, unsigned char *buf, int length)
{
int i;
 
SPIFLASH_CS_LOW;
 
spiflash_command(SPIFLASH_OP_READ, address);
 
for (i=0;i<length;i++)
buf[i] = spiflash_readbyte();
 
SPIFLASH_CS_HIGH;
 
return 0;
}
//-------------------------------------------------------------
// spiflash_writeblock:
//-------------------------------------------------------------
int spiflash_writeblock(unsigned long address, unsigned char *buf, int length)
{
int i, j;
 
// Sector boundary? Erase sector
if ((address & (SPIFLASH_SECTORSIZE - 1)) == 0)
spiflash_eraseblock(address);
 
for (i=0;i<length;i+=SPIFLASH_PAGESIZE)
{
int size = length - i;
 
if (size > SPIFLASH_PAGESIZE)
size = SPIFLASH_PAGESIZE;
 
// Byte program device
if (_device == SPI_FLASH_SST25VF040B)
{
for (j=0;j<size;j++)
spiflash_programbyte(address + j, buf[j]);
}
// Block program device
else
spiflash_programpage(address, buf, size);
 
address += SPIFLASH_PAGESIZE;
buf += SPIFLASH_PAGESIZE;
}
 
return 0;
}
//-------------------------------------------------------------
// spiflash_eraseblock:
//-------------------------------------------------------------
int spiflash_eraseblock(unsigned long address)
{
// Enable write mode
spiflash_writeenable();
 
// Erase sector
SPIFLASH_CS_LOW;
spiflash_command(SPIFLASH_OP_ERASESECTOR, address);
SPIFLASH_CS_HIGH;
 
// Wait until operation completed
while (spiflash_readstatus() & SPIFLASH_STAT_BUSY)
;
 
return 0;
}
//-------------------------------------------------------------
// spiflash_erasechip:
//-------------------------------------------------------------
int spiflash_erasechip(void)
{
// Enable write mode
spiflash_writeenable();
 
// Erase chip
SPIFLASH_CS_LOW;
spiflash_writebyte(SPIFLASH_OP_ERASECHIP);
SPIFLASH_CS_HIGH;
 
// Wait until operation completed
while (spiflash_readstatus() & SPIFLASH_STAT_BUSY)
;
 
return 0;
}
 
/altor32/trunk/sw/bootloader/spi_flash.h
0,0 → 1,25
#ifndef __SPI_FLASH_H__
#define __SPI_FLASH_H__
 
//-----------------------------------------------------------------
// Defines:
//-----------------------------------------------------------------
#define SPIFLASH_PAGESIZE (256)
#define SPIFLASH_BLOCKSIZE (4 * 1024)
#define SPIFLASH_SECTORSIZE (SPIFLASH_BLOCKSIZE)
#define SPIFLASH_SIZE (512 * 1024) // 4Mbit
#define SPIFLASH_FPGA_OFFSET (0)
#define SPIFLASH_FPGA_SIZE (352 * 1024)
#define SPIFLASH_APP_OFFSET (SPIFLASH_FPGA_SIZE)
#define SPIFLASH_APP_SIZE (SPIFLASH_SIZE - SPIFLASH_APP_OFFSET)
 
//-----------------------------------------------------------------
// Prototypes:
//-----------------------------------------------------------------
int spiflash_init(void);
int spiflash_readblock(unsigned long address, unsigned char *buf, int length);
int spiflash_writeblock(unsigned long address, unsigned char *buf, int length);
int spiflash_eraseblock(unsigned long address);
int spiflash_erasechip(void);
 
#endif // __SPI_FLASH_H__
/altor32/trunk/sw/bootloader/serial.c
0,0 → 1,128
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// AltOR32
// Alternative Lightweight OpenRisc
// Ultra-Embedded.com
// Copyright 2011 - 2012
//
// Email: admin@ultra-embedded.com
//
// License: GPL
// Please contact the above address if you would like a version of this
// software with a more permissive license for use in closed source commercial
// applications.
//-----------------------------------------------------------------------------
//
// This file is part of AltOR32 OpenRisc Simulator.
//
// AltOR32 OpenRisc Simulator is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// AltOR32 OpenRisc Simulator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AltOR32 OpenRisc Simulator; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#include "mem_map.h"
#include "serial.h"
 
//-----------------------------------------------------------------
// Registers
//-----------------------------------------------------------------
#define UART_RX_AVAIL (1<<0)
#define UART_TX_AVAIL (1<<1)
#define UART_RX_FULL (1<<2)
#define UART_TX_BUSY (1<<3)
#define UART_RX_ERROR (1<<4)
 
//-------------------------------------------------------------
// serial_init:
//-------------------------------------------------------------
void serial_init (void)
{
 
}
//-------------------------------------------------------------
// serial_putchar: Write character to Serial Port (used by printf)
//-------------------------------------------------------------
int serial_putchar(char ch)
{
if (ch == '\n')
serial_putchar('\r');
{
register char t1 asm ("r3") = ch;
asm volatile ("\tl.nop\t%0" : : "K" (0x0004), "r" (t1));
}
 
UART_UDR = ch;
while (UART_USR & UART_TX_BUSY);
 
return 0;
}
//-------------------------------------------------------------
// serial_getchar: Read character from Serial Port
//-------------------------------------------------------------
int serial_getchar (void)
{
// Read character in from UART0 Recieve Buffer and return
if (serial_haschar())
return UART_UDR;
else
return -1;
}
//-------------------------------------------------------------
// serial_haschar:
//-------------------------------------------------------------
int serial_haschar()
{
return (UART_USR & UART_RX_AVAIL);
}
//-------------------------------------------------------------
// serial_putstr:
//-------------------------------------------------------------
void serial_putstr(char *str)
{
while (*str)
serial_putchar(*str++);
}
//-------------------------------------------------------------
// serial_putnum:
//-------------------------------------------------------------
void serial_putnum( int n )
{
char* cp;
int negative;
char outbuf[32];
const char digits[] = "0123456789ABCDEF";
unsigned long num;
 
/* Check if number is negative */
if (n < 0L) {
negative = 1;
num = -(n);
}
else{
num = (n);
negative = 0;
}
/* Build number (backwards) in outbuf */
cp = outbuf;
do {
*cp++ = digits[(int)(num % 10)];
} while ((num /= 10) > 0);
if (negative)
*cp++ = '-';
*cp-- = 0;
while (cp >= outbuf)
serial_putchar(*cp--);
}
/altor32/trunk/sw/bootloader/timer.c
0,0 → 1,51
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// AltOR32
// Alternative Lightweight OpenRisc
// Ultra-Embedded.com
// Copyright 2011 - 2012
//
// Email: admin@ultra-embedded.com
//
// License: GPL
// Please contact the above address if you would like a version of this
// software with a more permissive license for use in closed source commercial
// applications.
//-----------------------------------------------------------------------------
//
// This file is part of AltOR32 OpenRisc Simulator.
//
// AltOR32 OpenRisc Simulator is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// AltOR32 OpenRisc Simulator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AltOR32 OpenRisc Simulator; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#include "timer.h"
 
//--------------------------------------------------------------------------
// timer_init:
//--------------------------------------------------------------------------
void timer_init(void)
{
 
}
//--------------------------------------------------------------------------
// timer_sleep:
//--------------------------------------------------------------------------
void timer_sleep(int timeMs)
{
t_time t = timer_now();
 
while (timer_diff(timer_now(), t) < timeMs)
;
}
/altor32/trunk/sw/bootloader/mem_map.h
0,0 → 1,53
#ifndef __MEM_MAP_H__
#define __MEM_MAP_H__
 
//-----------------------------------------------------------------
// Defines:
//-----------------------------------------------------------------
#define INT_BASE 0x00000000
#define INT_APP_BASE 0x00002000
#define EXT_BASE 0x10000000
#define IO_BASE 0x20000000
 
//-----------------------------------------------------------------
// Macros:
//-----------------------------------------------------------------
#define REG8 (volatile unsigned char*)
#define REG16 (volatile unsigned short*)
#define REG32 (volatile unsigned int*)
 
//-----------------------------------------------------------------
// I/O:
//-----------------------------------------------------------------
 
// General
#define CORE_ID (*(REG32 (IO_BASE + 0x0)))
 
// Basic Peripherals
#define UART_USR (*(REG32 (IO_BASE + 0x4)))
#define UART_UDR (*(REG32 (IO_BASE + 0x8)))
#define TIMER_VAL (*(REG32 (IO_BASE + 0x10)))
#define IRQ_MASK_SET (*(REG32 (IO_BASE + 0x14)))
#define IRQ_MASK_STATUS (*(REG32 (IO_BASE + 0x14)))
#define IRQ_MASK_CLR (*(REG32 (IO_BASE + 0x18)))
#define IRQ_STATUS (*(REG32 (IO_BASE + 0x1C)))
#define IRQ_SYSTICK (0)
#define IRQ_UART_RX_AVAIL (1)
#define IRQ_SW (2)
#define IRQ_PIT (6)
#define EXT_INT_OFFSET (8)
 
// [Optional] Watchdog
#define WATCHDOG_CTRL (*(REG32 (IO_BASE + 0x20)))
#define WATCHDOG_EXPIRED (16)
 
#define SYS_CLK_COUNT (*(REG32 (IO_BASE + 0x60)))
 
// SPI Configuration PROM
#define SPI_PROM_CTRL (*(REG32 (IO_BASE + 0x70)))
#define SPI_PROM_CS (1 << 0)
#define SPI_PROM_STAT (*(REG32 (IO_BASE + 0x70)))
#define SPI_PROM_BUSY (1 << 0)
#define SPI_PROM_DATA (*(REG32 (IO_BASE + 0x74)))
 
#endif
/altor32/trunk/sw/bootloader/boot_header.h
0,0 → 1,20
#ifndef __BOOT_HEADER_H__
#define __BOOT_HEADER_H__
 
//-----------------------------------------------------------------
// Defines:
//-----------------------------------------------------------------
#define BOOT_HDR_SIZE sizeof(struct boot_header)
#define BOOT_HDR_MAGIC 0xb00710ad
 
//-----------------------------------------------------------------
// Types:
//-----------------------------------------------------------------
struct boot_header
{
unsigned int jmp_code[2];
unsigned int magic;
unsigned int file_length;
};
 
#endif // __BOOT_HEADER_H__
/altor32/trunk/sw/bootloader/boot_flash.c
0,0 → 1,80
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// AltOR32
// Alternative Lightweight OpenRisc
// Ultra-Embedded.com
// Copyright 2011 - 2012
//
// Email: admin@ultra-embedded.com
//
// License: GPL
// Please contact the above address if you would like a version of this
// software with a more permissive license for use in closed source commercial
// applications.
//-----------------------------------------------------------------------------
//
// This file is part of AltOR32 OpenRisc Simulator.
//
// AltOR32 OpenRisc Simulator is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// AltOR32 OpenRisc Simulator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AltOR32 OpenRisc Simulator; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#include "assert.h"
#include "spi_flash.h"
#include "boot_flash.h"
#include "boot_header.h"
 
//-----------------------------------------------------------------
// Defines:
//-----------------------------------------------------------------
#define BOOTFLASH_BLOCK_SIZE SPIFLASH_BLOCKSIZE
 
//-----------------------------------------------------------------
// Locals:
//-----------------------------------------------------------------
static struct boot_header hdr;
 
//-------------------------------------------------------------
// bootflash:
//-------------------------------------------------------------
int bootflash(unsigned long target)
{
unsigned char *ptr = (unsigned char *)(target);
unsigned int length;
unsigned int pos = 0;
 
// Load header
spiflash_readblock(SPIFLASH_APP_OFFSET, (unsigned char*)&hdr, BOOT_HDR_SIZE);
 
// Check header magic number
if (hdr.magic != BOOT_HDR_MAGIC)
return 0;
 
// Load file to memory
while (pos < hdr.file_length)
{
// Calculate count of data to load
length = hdr.file_length - pos;
if (length > BOOTFLASH_BLOCK_SIZE)
length = BOOTFLASH_BLOCK_SIZE;
 
// Load block of data into target
spiflash_readblock(SPIFLASH_APP_OFFSET + pos, ptr, length);
 
pos += length;
ptr += length;
}
 
return 1;
}
/altor32/trunk/sw/bootloader/boot.s
0,0 → 1,67
#-------------------------------------------------------------
# VECTOR 0x100 - Reset
#-------------------------------------------------------------
.org 0x100
vector_reset:
 
# Setup SP (R1)
l.movhi r4,hi(_sp);
l.ori r1,r4,lo(_sp);
# R4 = _bss_start
l.movhi r4,hi(_bss_start);
l.ori r4,r4,lo(_bss_start);
# R5 = _end
l.movhi r5,hi(_end);
l.ori r5,r5,lo(_end);
BSS_CLEAR:
l.sw 0x0(r4),r0 # Write 0x00 to mem[r4]
l.sfleu r4,r5 # SR[F] = (r4 < r5)
l.bf BSS_CLEAR # If SR[F] == 0, jump to BSS_CLEAR
l.addi r4, r4, 4 # r4 += 4
 
# Jump to main routine
l.jal main
l.nop
 
#-------------------------------------------------------------
# VECTOR 0x200 - Fault / Illegal Instruction
#-------------------------------------------------------------
.org 0x200
vector_fault:
 
# Jump to 0x2000 + vector
l.j (0x2000 >> 2)
l.nop
#-------------------------------------------------------------
# VECTOR 0x300 - External Interrupt
#-------------------------------------------------------------
.org 0x300
vector_extint:
 
# Jump to 0x2000 + vector
l.j (0x2000 >> 2)
l.nop
 
#-------------------------------------------------------------
# VECTOR 0x400 - Syscall
#-------------------------------------------------------------
.org 0x400
vector_syscall:
 
# Jump to 0x2000 + vector
l.j (0x2000 >> 2)
l.nop
#-------------------------------------------------------------
# VECTOR 0x600 - Trap
#-------------------------------------------------------------
.org 0x600
vector_trap:
 
# Jump to 0x2000 + vector
l.j (0x2000 >> 2)
l.nop
/altor32/trunk/sw/bootloader/serial.h
0,0 → 1,15
#ifndef __SERIAL_H__
#define __SERIAL_H__
 
//-----------------------------------------------------------------
// Prototypes:
//-----------------------------------------------------------------
void serial_init (void);
int serial_putchar(char ch);
int serial_getchar(void);
int serial_haschar();
void serial_putstr(char *str);
void serial_putnum( int n );
void serial_printstrnum(char *str1, unsigned int hexnum, char *str2);
 
#endif // __SERIAL_H__
/altor32/trunk/sw/bootloader/main.c
0,0 → 1,139
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// AltOR32
// Alternative Lightweight OpenRisc
// Ultra-Embedded.com
// Copyright 2011 - 2012
//
// Email: admin@ultra-embedded.com
//
// License: GPL
// Please contact the above address if you would like a version of this
// software with a more permissive license for use in closed source commercial
// applications.
//-----------------------------------------------------------------------------
//
// This file is part of AltOR32 OpenRisc Simulator.
//
// AltOR32 OpenRisc Simulator is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// AltOR32 OpenRisc Simulator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AltOR32 OpenRisc Simulator; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#include "timer.h"
#include "serial.h"
#include "boot_serial.h"
#include "boot_flash.h"
#include "spi_flash.h"
#include "mem_map.h"
 
//-----------------------------------------------------------------
// Defines:
//-----------------------------------------------------------------
#define BOOT_TIMEOUT 10000
#define BOOT_FLASH_TARGET INT_APP_BASE
 
//-----------------------------------------------------------------
// application_boot:
//-----------------------------------------------------------------
static application_boot(unsigned long addr)
{
typedef int (*fnptr)(void);
fnptr app_start;
 
app_start = (fnptr)(addr);
app_start();
 
while (1)
;
}
//-----------------------------------------------------------------
// main:
//-----------------------------------------------------------------
int main(void)
{
t_time tStart;
int no_flash_boot = 0;
 
serial_putstr("\nBootROM\n");
 
// Initialise SPI Flash
spiflash_init();
 
do
{
serial_putstr("<I> Internal\n");
serial_putstr("<E> External\n");
serial_putstr("<A> PROM (App)\n");
serial_putstr("<F> PROM (FPGA)\n");
 
tStart = timer_now();
while (timer_diff(timer_now(), tStart) < BOOT_TIMEOUT || no_flash_boot == 1)
{
int ch = serial_getchar();
if (ch == 'I')
{
serial_putstr("Internal (BRAM) X-modem boot...\n");
boot_serial(INT_APP_BASE, 0);
 
// Jump to application reset vector
application_boot(INT_APP_BASE + 0x100);
}
else if (ch == 'E')
{
serial_putstr("External X-modem boot...\n");
boot_serial(EXT_BASE, 0);
 
// Jump to application reset vector
application_boot(EXT_BASE + 0x100);
}
else if (ch == 'A')
{
serial_putstr("PROM (App) X-modem flash...\n");
boot_serial(SPIFLASH_APP_OFFSET, 1);
no_flash_boot = 1;
continue;
}
else if (ch == 'F')
{
serial_putstr("PROM (FPGA) X-modem flash...\n");
boot_serial(SPIFLASH_FPGA_OFFSET, 1);
no_flash_boot = 1;
continue;
}
}
 
serial_putstr("Boot from PROM (App)...\n");
 
// Auto boot SPI PROM image if available
if (bootflash(BOOT_FLASH_TARGET))
{
// Normal boot
application_boot(BOOT_FLASH_TARGET + 0x100);
}
// No image available, wait for X-modem image
else
{
serial_putstr("No app image available in PROM\n");
no_flash_boot = 1;
}
}
while (1);
}
//-----------------------------------------------------------------
// assert_handler:
//-----------------------------------------------------------------
void assert_handler(const char * type, const char *reason, const char *file, int line)
{
while (1);
}
/altor32/trunk/sw/bootloader/boot_flash.h
0,0 → 1,9
#ifndef __BOOT_FLASH_H__
#define __BOOT_FLASH_H__
 
//-----------------------------------------------------------------
// Prototypes:
//-----------------------------------------------------------------
int bootflash(unsigned long target);
 
#endif // __BOOT_FLASH_H__
/altor32/trunk/sw/bootloader/timer.h
0,0 → 1,21
#ifndef __TIMER_H__
#define __TIMER_H__
 
#include "mem_map.h"
 
//-----------------------------------------------------------------
// Defines:
//-----------------------------------------------------------------
typedef unsigned long t_time;
 
//-----------------------------------------------------------------
// Prototypes:
//-----------------------------------------------------------------
 
// General timer
void timer_init(void);
static t_time timer_now(void) { return TIMER_VAL; }
static long timer_diff(t_time a, t_time b) { return (long)(a - b); }
void timer_sleep(int timeMs);
 
#endif
/altor32/trunk/sw/bootloader/linker_script
0,0 → 1,51
GROUP("libgcc.a")
 
MEMORY
{
sram (rwx) : ORIGIN = 0x00000000, LENGTH = 8K
}
 
SECTIONS
{
/* first section is .text which is used for code */
.text :
{
*(.text .text.*) /* remaining code */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.rdata*)
. = ALIGN(4);
} > sram
 
/* .data section which is used for initialized data */
.data :
{
*(.got.plt) *(.got)
*(.shdata)
*(.data .data.* .gnu.linkonce.d.*)
. = ALIGN(16);
*(.lit8)
*(.lit4)
*(.sdata .sdata.* .gnu.linkonce.s.*)
. = ALIGN (8);
*(.ram)
. = ALIGN (8);
_edata = .;
} > sram
.bss :
{
. = ALIGN(4);
_bss_start = . ;
*(.bss*)
*(COMMON)
/* Allocate room for stack */
. = ALIGN(8) ;
. += 512 ;
_sp = . - 16;
} > sram
 
. = ALIGN(4);
_end = . ;
}
/altor32/trunk/sw/bootloader/xmodem.c
0,0 → 1,324
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// AltOR32
// Alternative Lightweight OpenRisc
// Ultra-Embedded.com
// Copyright 2011 - 2012
//
// Email: admin@ultra-embedded.com
//
// License: GPL
// Please contact the above address if you would like a version of this
// software with a more permissive license for use in closed source commercial
// applications.
//-----------------------------------------------------------------------------
//
// This file is part of AltOR32 OpenRisc Simulator.
//
// AltOR32 OpenRisc Simulator is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// AltOR32 OpenRisc Simulator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AltOR32 OpenRisc Simulator; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#include <string.h>
#include "xmodem.h"
#include "timer.h"
 
//-----------------------------------------------------------------
// Defines
//-----------------------------------------------------------------
#define XMODEM_HDR_SIZE 6
 
// Control character codes
#define SOH 0x01
#define STX 0x02
#define EOT 0x04
#define ACK 0x06
#define NAK 0x15
#define CAN 0x18
#define CTRLZ 0x1A
 
#define XMODEM_CRC_REQ 'C'
 
//-----------------------------------------------------------------
// Locals
//-----------------------------------------------------------------
 
// Serial IO function pointers
static int (*_serial_putc)(char c) = 0;
static int (*_serial_getc)(void) = 0;
 
// Xmodem buffer
static unsigned char xbuffer[XMODEM_BUFFER_SIZE+XMODEM_HDR_SIZE];
 
//-----------------------------------------------------------------
// Prototypes
//-----------------------------------------------------------------
static unsigned short calc_crc_16(unsigned char *data, int length);
static unsigned char calc_checksum(unsigned char *data, int length);
static int xmodem_verify_checksum(unsigned char *buffer, int size, int useCRC);
static int xmodem_getc(unsigned int timeout);
static void xmodem_flush(void);
 
//-----------------------------------------------------------------
// xmodem_init: Initialise X-Modem module
//-----------------------------------------------------------------
void xmodem_init(int (*sputc)(char c), int (*sgetc)(void))
{
_serial_putc = sputc;
_serial_getc = sgetc;
}
//-----------------------------------------------------------------
// xmodem_receive: Receive a X-Modem transfer
//-----------------------------------------------------------------
int xmodem_receive( int (*write)(unsigned char* buffer, int size) )
{
unsigned char seq_num = 1;
unsigned short packet_length = 128;
unsigned char response;
char retry = XMODEM_RETRY_LIMIT;
unsigned char useCrc = 0;
int totalbytes = 0;
int i, c;
 
// No I/O functions? No transfer!
if (!_serial_putc || !_serial_getc)
return -1;
 
// Start by requesting CRC transfer
response = XMODEM_CRC_REQ;
 
while(retry > 0)
{
// solicit a connection/packet
_serial_putc(response);
 
// wait for start of packet
if( (c = xmodem_getc(XMODEM_TIMEOUT_DELAY)) >= 0)
{
switch(c)
{
// Start of transfer (128 bytes)
case SOH:
packet_length = 128;
break;
 
// Start of transfer (1024 bytes)
#if(XMODEM_BUFFER_SIZE>=1024)
case STX:
packet_length = 1024;
break;
#endif
 
// End of transfer
case EOT:
xmodem_flush();
_serial_putc(ACK);
// Inform app layer of end of transfer
write(0, 0);
return totalbytes;
 
// Cancel transfer
case CAN:
if((c = xmodem_getc(XMODEM_TIMEOUT_DELAY)) == CAN)
{
xmodem_flush();
_serial_putc(ACK);
return -1;
}
default:
break;
}
}
// No response, retry
else
{
retry--;
continue;
}
 
// Using CRC mode (as requested)
if(response == 'C')
useCrc = 1;
 
// Add header character to buffer (SOH/STX)
xbuffer[0] = c;
// Wait for rest of packet
for(i=0; i<(packet_length+useCrc+4-1); i++)
{
// Get a byte of data
if((c = xmodem_getc(XMODEM_TIMEOUT_DELAY)) >= 0)
xbuffer[1+i] = c;
// Timeout while expecting data
else
{
retry--;
xmodem_flush();
response = NAK;
break;
}
}
 
// If timeout, retry
if( i < (packet_length+useCrc+4-1) )
continue;
// Packet received, check checksum & sequence number
else if( (xbuffer[1] == (unsigned char)(~xbuffer[2])) && xmodem_verify_checksum(&xbuffer[3], packet_length, useCrc))
{
// Is this the sequence number waited on?
if(xbuffer[1] == seq_num)
{
// Pass data to user call-back
write(&xbuffer[3], packet_length);
// Increment receive count
totalbytes += packet_length;
 
// Next sequence number
seq_num++;
 
// Reset retries
retry = XMODEM_RETRY_LIMIT;
 
// ACK packet
response = ACK;
 
continue;
}
// Last packet resent?
else if(xbuffer[1] == (unsigned char)(seq_num-1))
{
// Just ACK it
response = ACK;
continue;
}
// Some other failure!
else
{
xmodem_flush();
_serial_putc(CAN);
_serial_putc(CAN);
_serial_putc(CAN);
 
return -1;
}
}
// Checksum / sequence number check byte are wrong
else
{
// Send NAK
retry--;
xmodem_flush();
response = NAK;
continue;
}
}
 
// Retries count exceeded
xmodem_flush();
_serial_putc(CAN);
_serial_putc(CAN);
_serial_putc(CAN);
 
return -1;
}
//-----------------------------------------------------------------
// calc_crc_16: Calculate 16 bit CRC used by XModem(CRC)
// Polynomial x^16 + x^12 + x^5 + 1 (0x1021)
//-----------------------------------------------------------------
static unsigned short calc_crc_16(unsigned char *data, int length)
{
unsigned char c;
unsigned short crc = 0;
int i;
 
while (length)
{
c = *data++;
crc = crc ^ ((unsigned short)c << 8);
for (i=0; i<8; i++)
{
if(crc & 0x8000)
crc = (crc << 1) ^ 0x1021;
else
crc <<= 1;
}
 
length--;
}
 
return crc;
}
//-----------------------------------------------------------------
// calc_checksum: Calculate standard (summation) checksum used by
// older XModem protocol versions
//-----------------------------------------------------------------
static unsigned char calc_checksum(unsigned char *data, int length)
{
unsigned char sum = 0;
while (length)
{
sum += *data++;
length--;
}
 
return sum;
}
//-----------------------------------------------------------------
// xmodem_verify_checksum: Verify the checksum for the received packet
//-----------------------------------------------------------------
static int xmodem_verify_checksum(unsigned char *buffer, int size, int useCRC)
{
int res = 0;
 
// CRC-16
if(useCRC)
{
unsigned short crc = (buffer[size]<<8) + buffer[size+1];
if(calc_crc_16((unsigned char*)buffer, size) == crc)
res = 1;
}
// Old sum checksum
else
{
// check checksum against packet
if(calc_checksum(buffer, size) == buffer[size])
res = 1;
}
 
return res;
}
//-----------------------------------------------------------------
// xmodem_getc: Get a character from serial port within timeout
//-----------------------------------------------------------------
static int xmodem_getc(unsigned int timeout)
{
int c = -1;
t_time startTime = timer_now();
 
while ( (c = _serial_getc()) < 0 )
if (timer_diff(timer_now(), startTime) >= timeout)
break;
 
return c;
}
//-----------------------------------------------------------------
// xmodem_flush: Flush serial port
//-----------------------------------------------------------------
static void xmodem_flush(void)
{
while(xmodem_getc(XMODEM_TIMEOUT_DELAY) >= 0);
}
/altor32/trunk/sw/bootloader/makefile
0,0 → 1,70
###############################################################################
## Makefile
###############################################################################
 
# Tools
CC_PREFIX = or32-elf
CC = $(CC_PREFIX)-gcc $(CFLAGS)
AS = $(CC_PREFIX)-as
LD = $(CC_PREFIX)-ld
OBJDUMP = $(CC_PREFIX)-objdump
OBJCOPY = $(CC_PREFIX)-objcopy
 
# BootRAM
BOOTRAM_GEN = ../../tools/bootram_gen
BOOTRAM_TEMPLATE = ../../tools/bootram_template.vhd
BOOTRAM_TARGET ?= ./program.vhd
 
# Target
TARGET = bootloader
 
# Options
LDSCRIPT = linker_script
CFLAGS += -Ttext 0x0 -O2 -g -Wall
CFLAGS += -msoft-div -msoft-float -msoft-mul -mno-ror -mno-cmov -mno-sext
CFLAGS += -nostartfiles -nodefaultlibs -nostdlib -lgcc
CFLAGS += -L ./ -lgcc -L ./ -T$(LDSCRIPT)
ASFLAGS = -Wa
LDFLAGS =
 
OBJ += boot.o
OBJ += main.o
OBJ += boot_serial.o
OBJ += boot_flash.o
OBJ += xmodem.o
OBJ += serial.o
OBJ += timer.o
OBJ += spi_flash.o
 
CFLAGS += -I.
 
 
###############################################################################
# Rules
###############################################################################
all: bootram $(TARGET).elf lst bin
clean:
-rm $(OBJ) *.map $(TARGET).lst $(TARGET).hex *.txt $(TARGET).elf $(TARGET).bin $(BOOTRAM_TARGET)
 
%.o : %.s
$(CC) -c $(ASFLAGS) $< -o $@
 
%.o : %.c
$(CC) -c $(CFLAGS) $< -o $@
 
$(TARGET).elf: $(OBJ) $(LDSCRIPT) makefile
$(CC) $(LDFLAGS) $(LIBS) $(OBJ) -o $@
lst: $(TARGET).lst
 
%.lst: $(TARGET).elf
$(OBJDUMP) -h -d -S $< > $@
 
bin: $(TARGET).bin
 
%.bin: %.elf
$(OBJCOPY) -O binary $< $@
bootram: bin
$(BOOTRAM_GEN) -f $(TARGET).bin -t $(BOOTRAM_TEMPLATE) -o $(BOOTRAM_TARGET)
altor32/trunk/sw/bootloader Property changes : Added: bugtraq:number ## -0,0 +1 ## +true \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.