附上我二次bootloader的所有代码
/*
* boo.h
*
* Created on: 2015-8-28
* Author: lsxxjx
*/
#ifndef __BOOT_H__
#define __BOOT_H__
//#include ""
#define SPIROM_SIZE 0x00008000
#define SPIROM_BASE 0x00000000
#define SPIROM_PAGESIZE 256
#define SPIROM_SECTORSIZE 4096
#define SPIROM_PAGEMASK 0xffffff00
#define SPIROM_SECTORMASK 0xfffff000
#define Uint32 unsigned long
#define Uint16 unsigned short
#define Uint8 unsigned char
#define Int32 int
#define Int16 short
#define Int8 char
/* ------------------------------------------------------------------------ *
* System Module *
* ------------------------------------------------------------------------ */
#define SYS_EXBUSSEL *(volatile ioport Uint16*)(0x1c00)
#define SYS_PCGCR1 *(volatile ioport Uint16*)(0x1c02)
#define SYS_PCGCR2 *(volatile ioport Uint16*)(0x1c03)
#define SYS_PRCNTR *(volatile ioport Uint16*)(0x1c04)
#define SYS_PRCNTRLR *(volatile ioport Uint16*)(0x1c05)
#define SYS_GPIO_DIR0 *(volatile ioport Uint16*)(0x1c06)
#define SYS_GPIO_DIR1 *(volatile ioport Uint16*)(0x1c07)
#define SYS_GPIO_DATAIN0 *(volatile ioport Uint16*)(0x1c08)
#define SYS_GPIO_DATAIN1 *(volatile ioport Uint16*)(0x1c09)
#define SYS_GPIO_DATAOUT0 *(volatile ioport Uint16*)(0x1c0a)
#define SYS_GPIO_DATAOUT1 *(volatile ioport Uint16*)(0x1c0b)
#define SYS_OUTDRSTR *(volatile ioport Uint16*)(0x1c16)
#define SYS_SPPDIR *(volatile ioport Uint16*)(0x1c17)
#define CCR1 *(volatile ioport Uint16*)(0x1c1e)
#define CCR2 *(volatile ioport Uint16*)(0x1c1f)
#define PMR *(volatile ioport Uint16*)(0x1c20)
#define PICR *(volatile ioport Uint16*)(0x1c21)
#define PCR *(volatile ioport Uint16*)(0x1c22)
#define PODCR *(volatile ioport Uint16*)(0x1c23)
#define ESCR *(volatile ioport Uint16*)(0x1c33)
#define ICR *(volatile ioport Uint16*)(0x0001)
#define IER0 *(volatile Uint16*)(0x0000)
#define IFR0 *(volatile Uint16*)(0x0001)
#define ST1_55 *(volatile Uint16*)(0x0003)
#define IER1 *(volatile Uint16*)(0x0006)
#define IFR1 *(volatile Uint16*)(0x0007)
/* ------------------------------------------------------------------------ *
* EMIF Module *
* ------------------------------------------------------------------------ */
#define SDTIMR1 *((volatile ioport Uint16*)(0x1020))
#define SDTIMR2 *((volatile ioport Uint16*)(0x1021))
#define SDCR1 *((volatile ioport Uint16*)(0x1008))
#define SDCR2 *((volatile ioport Uint16*)(0x1009))
#define SDSRETR *((volatile ioport Uint16*)(0x103C))
#define SDRCR *((volatile ioport Uint16*)(0x100C))
/* ------------------------------------------------------------------------ *
* SPI ROM Commands *
* ------------------------------------------------------------------------ */
#define SPIROM_CMD_WRSR 0x01
#define SPIROM_CMD_WRITE 0x02
#define SPIROM_CMD_READ 0x03
#define SPIROM_CMD_WRDI 0x04
#define SPIROM_CMD_RDSR 0x05
#define SPIROM_CMD_WREN 0x06
#define SPIROM_CMD_ERASESEC 0x20
#define SPIROM_CMD_UNPROTECTSEC 0x39
/* ------------------------------------------------------------------------ *
* SPIOCP Module *
* ------------------------------------------------------------------------ */
#define MCSPI_BASE 0x3400
#define MCSPI_REVISION *(volatile ioport Uint16*)( MCSPI_BASE + 0x100 )
#define MCSPI_SYSCONFIGL *(volatile ioport Uint16*)( MCSPI_BASE + 0x110 )
#define MCSPI_SYSSTATUSL *(volatile ioport Uint16*)( MCSPI_BASE + 0x114 )
#define MCSPI_IRQSTATUSL *(volatile ioport Uint16*)( MCSPI_BASE + 0x118 )
#define MCSPI_IRQSTATUSU *(volatile ioport Uint16*)( MCSPI_BASE + 0x119 )
#define MCSPI_IRQENABLEL *(volatile ioport Uint16*)( MCSPI_BASE + 0x11C )
#define MCSPI_IRQENABLEU *(volatile ioport Uint16*)( MCSPI_BASE + 0x11D )
#define MCSPI_WAKEUPENABLEL *(volatile ioport Uint16*)( MCSPI_BASE + 0x120 )
//#define MCSPI_SYST *(volatile ioport Uint16*)( MCSPI_BASE + 0x20 )
#define MCSPI_MODULCTRLL *(volatile ioport Uint16*)( MCSPI_BASE + 0x128 )
#define MCSPI_CH0CONFL *(volatile ioport Uint16*)( MCSPI_BASE + 0x12C )
#define MCSPI_CH0CONFU *(volatile ioport Uint16*)( MCSPI_BASE + 0x12D )
#define MCSPI_CH0STATL *(volatile ioport Uint16*)( MCSPI_BASE + 0x130 )
#define MCSPI_CH0CTRLL *(volatile ioport Uint16*)( MCSPI_BASE + 0x134 )
#define MCSPI_CH0TXL *(volatile ioport Uint16*)( MCSPI_BASE + 0x138 )
#define MCSPI_CH0TXU *(volatile ioport Uint16*)( MCSPI_BASE + 0x139 )
#define MCSPI_CH0RXL *(volatile ioport Uint16*)( MCSPI_BASE + 0x13C )
#define MCSPI_CH0RXU *(volatile ioport Uint16*)( MCSPI_BASE + 0x13D )
#define MCSPI_CH1CONFL *(volatile ioport Uint16*)( MCSPI_BASE + 0x140 )
#define MCSPI_CH1CONFU *(volatile ioport Uint16*)( MCSPI_BASE + 0x141 )
#define MCSPI_CH1STATL *(volatile ioport Uint16*)( MCSPI_BASE + 0x144 )
#define MCSPI_CH1CTRLL *(volatile ioport Uint16*)( MCSPI_BASE + 0x148 )
#define MCSPI_CH1TXL *(volatile ioport Uint16*)( MCSPI_BASE + 0x14C )
#define MCSPI_CH1TXU *(volatile ioport Uint16*)( MCSPI_BASE + 0x14D )
#define MCSPI_CH1RXL *(volatile ioport Uint16*)( MCSPI_BASE + 0x150 )
#define MCSPI_CH1RXU *(volatile ioport Uint16*)( MCSPI_BASE + 0x151 )
/* ------------------------------------------------------------------------ *
* type define *
* ------------------------------------------------------------------------ */
typedef struct
[
unsigned char boot_signature[2];
unsigned char entry_point[4];
/* register configuration count */
unsigned char reg_conf_cnt[2];
] boot_image_head;
typedef struct
[
unsigned char word_count[2];
unsigned char load_address[4];
] section_head;
/* current section information*/
typedef struct
[
unsigned long load_address;
unsigned int word_count;
unsigned int pad_size;
] cur_section_info;
/* flash information */
typedef struct
[
/* current reading address*/
unsigned long cur_rd_addr;
] flash_info;
/* ------------------------------------------------------------------------ *
* Prototype *
* ------------------------------------------------------------------------ */
void spirom_init( );
void spirom_read1( Uint32 src, Uint32 length );
void spirom_erase( unsigned long base, unsigned long length );
void spirom_read( unsigned long src, unsigned long dst, unsigned long length );
void spirom_write( unsigned long src, unsigned long dst, unsigned long length );
void set_PLL_100Hz(void);
void EMIF_SDRAM_Init(void);
unsigned int get_pad_size(unsigned int cword_of_section);
#endif /* __BOOT_H__ */
/*
* main.c
*
* Created on: 2015-8-28
* Author: lsxxjx
*/
#include "boot.h"
#include "stdio.h"
//#include "evm5517.h"
//Int16 EVM5517_I2CGPIO_configLine( Uint16 line, Uint16 dir );
//Int16 EVM5517_I2CGPIO_writeLine( Uint16 line, Uint16 val );
static unsigned char spirombuf[SPIROM_PAGESIZE + 5];
static unsigned char statu***uf[8];
void (*enter_new_point)(void);
boot_image_head *boot_image_head_p;
section_head *section_head_p;
flash_info flash_info_r;
cur_section_info cur_section_info_r;
/*
*
* main
*
*/
void main( )
[
volatile unsigned long i;
volatile unsigned long j;
ICR = 0x000E;
asm(" idle");
/* Disable global interrupts */
asm("tNOP ;====> CODE AUTO-GENERATED by CSL");
asm("tBSET INTM ;====> CODE AUTO-GENERATED by CSL");
/* Disable all the interrupts */
//IER0 = 0x0000;
//IER1 = 0x0000;
/* Clear any pending interrupts */
//IFR0 = 0xFFFF;
//IFR1 = 0xFFFF;
SYS_PCGCR1 = 0x0000;
SYS_PCGCR2 = 0x0000;
set_PLL_100Hz();
EMIF_SDRAM_Init();
/* Configure EBSR for McSPI */
SYS_EXBUSSEL &= ~0x0C00; // Clear SP1MODE
SYS_EXBUSSEL |= 0x0400; // Set SP1MODE to McSPI
/* Initialize the SPI interface */
spirom_init( );
for(i = 0; i < 0xff; i++)
asm(" nop");
#if 1
while(1)
[
asm(" bset XF");
asm(" nop");
for(j = 0; j < 100; j++)
for(i = 0; i < 100000; i++ );
asm(" bclr XF");
asm(" nop");
for(j = 0; j < 100; j++)
for(i = 0; i < 50000; i++ );
]
#endif
//flash_info_r.cur_rd_addr = 1726;
flash_info_r.cur_rd_addr = 0;
/* read the boot image file's head */
spirom_read1( flash_info_r.cur_rd_addr, sizeof(boot_image_head));
boot_image_head_p = (boot_image_head *)(spirombuf + 4);
if(boot_image_head_p->boot_signature[0] == 0x09
&& boot_image_head_p->boot_signature[1] == 0xaa)
[
flash_info_r.cur_rd_addr += sizeof(boot_image_head);
/* get boot image file's entry point */
enter_new_point = (void(*)(void))((unsigned long)boot_image_head_p->entry_point[0] << 24
| (unsigned long)boot_image_head_p->entry_point[1] << 16
| (unsigned long)boot_image_head_p->entry_point[2] << 8
| (unsigned long)boot_image_head_p->entry_point[3]);
/* ignore the register configuration informaton */
flash_info_r.cur_rd_addr += ((unsigned long)boot_image_head_p->reg_conf_cnt[0] << 8 |
boot_image_head_p->reg_conf_cnt[1]) << 2;
/* load section data */
for(;;)
[
/* read a secion's head */
spirom_read1( flash_info_r.cur_rd_addr, sizeof(section_head));
flash_info_r.cur_rd_addr += sizeof(section_head);
section_head_p = (section_head *)(spirombuf + 4);
cur_section_info_r.word_count = ((unsigned int)section_head_p->word_count[0] << 8
| (unsigned int)section_head_p->word_count[1]);
cur_section_info_r.load_address = ((unsigned long)section_head_p->load_address[0] << 24
| (unsigned long)section_head_p->load_address[1] << 16
| (unsigned long)section_head_p->load_address[2] << 8
| (unsigned long)section_head_p->load_address[3]);
if(cur_section_info_r.word_count == 0)
break;
cur_section_info_r.pad_size = get_pad_size(cur_section_info_r.word_count);
while(cur_section_info_r.word_count > 0)
[
if(cur_section_info_r.word_count > 128)
[
spirom_read1( flash_info_r.cur_rd_addr, 256);
for(i = 0; i < 128; i++)
[
*(unsigned int *)(cur_section_info_r.load_address + i)
= (unsigned int)(*(unsigned char *)(spirombuf + 4 + i * 2)) << 8
|(unsigned int)(*(unsigned char *)(spirombuf + 4 + i * 2 + 1));
]
flash_info_r.cur_rd_addr += 256;
cur_section_info_r.word_count -= 128;
cur_section_info_r.load_address += 128;
]
else
[
spirom_read1( flash_info_r.cur_rd_addr, cur_section_info_r.word_count << 1);
for(i = 0; i < cur_section_info_r.word_count; i++)
[
*(unsigned int *)(cur_section_info_r.load_address + i)
= (unsigned int)(*(unsigned char *)(spirombuf + 4 + i * 2)) << 8
|(*(unsigned char *)(spirombuf + 4 + i * 2 + 1));
]
flash_info_r.cur_rd_addr += (unsigned long)cur_section_info_r.word_count << 1;
cur_section_info_r.word_count = 0;
]
]
flash_info_r.cur_rd_addr += cur_section_info_r.pad_size;
]
enter_new_point();
]
]
/*
* get the byte sizes of pad data
*/
unsigned int get_pad_size(unsigned int cword_of_section)
[
unsigned long cbyte_of_section;
unsigned long cbyte_alignment;
cbyte_of_section = ((unsigned long)cword_of_section + 2) << 1;
//return ((cbyte_of_section & 0x7 > 0 ? cbyte_of_section & 0xFFFFFFF8 + 0x8 : cbyte_of_section) - cbyte_of_section);
cbyte_alignment = (cbyte_of_section + 0x7) & ~0x7;
return cbyte_alignment - cbyte_of_section;
]
void set_PLL_100Hz(void)
[
volatile unsigned int i;
/* Enable clocks to all peripherals */
SYS_PCGCR1 = 0x0000;
SYS_PCGCR2 = 0x0000;
/* Bypass PLL */
CCR2 = 0x0000;
/* Turn off PLL */
PMR = 0x1000;
/* For CLKIN = 12MHz */
PICR = 0x0005; // Enable reference divider = 2+1
PODCR = 0x0000; // Output divider = 0
PCR = 0x0010;
PMR = 0x6300;// Multiplier = 99*256+1
/* Wait for PLL lock (atleast 4ms)*/
for(i=0;i<0x7fff;i++)
asm(" nop");
/* Switch to PLL clk */
CCR2 = 0x1;
]
void EMIF_SDRAM_Init(void)
[
volatile unsigned int i;
/* configure EBSR for EMIF */
SYS_EXBUSSEL |= 0x1000;
/* enable the EM_SDCLK */
CCR1 |= 0x0001;
for(i = 0; i < 0x200; i++)
asm(" nop");
/* reset the EMIF */
SYS_PRCNTR = 0x20;
SYS_PRCNTRLR |= 0x0002;
for(i = 0; i < 0x200; i++)
asm(" nop");
/* enable word writes to EMIF*/
ESCR = 0x0000;
//-reg_config 0x1c1e,0x0001
/* step 1 */
SDTIMR1 = 0x4510;
SDTIMR2 = 0x3911;
SDSRETR = 0x000b;
/* step 2 */
SDRCR = 0x030d;
/* step 3 */
SDCR1 = 0x4720;
SDCR2 = 0x0001;
/* step 4 */
for(i = 0; i < 0x200; i++)
asm(" nop");
/* step 5 */
SDRCR = 0x030d;
]
/* ------------------------------------------------------------------------ *
* spirom_init( ) *
* ------------------------------------------------------------------------ */
void spirom_init( )
[
volatile unsigned int i;
/* Reset SPI */
//MCSPI_SYSCONFIGL |= 0x02; // Bit is automatically reset by hardware
/* Wait for reset to complete */
//while(MCSPI_SYSSTATUSL & 0x01 == 0x00);
SYS_PRCNTR = 0x20;
SYS_PRCNTRLR |= 0x0020;
for(i = 0; i < 0x200; i++)
asm(" nop");
/* Configure MCSPI Module */
MCSPI_MODULCTRLL = 0
| ( 0 << 8 ) // Data managed by MCSPI_TX(i) and MCSPI_RX(i) registers
| ( 0 << 7 ) // Multiple word access disabled
| ( 0 << 4 ) // No delay for first spi transfer
| ( 0 << 3 ) // Functional mode
| ( 0 << 2 ) // Master
| ( 0 << 1 ) // SPIEN is used as a chip select
| ( 1 << 0 );// Only one channel will be used in master mode
MCSPI_CH0CONFL = 0
| ( 0 << 15 ) // DMA Read Request disabled
| ( 0 << 14 ) // DMA Write Request disabled
| ( 0 << 12 ) // Transmit and Receive mode
| ( 7 << 7 ) // SPI word length = 8
| ( 1 << 6 ) // SPIEN is held high during the active state
| ( 8 << 2 ) // CLKD = 8 Clock devider
| ( 0 << 1 ) // SPICLK is held high during the active state
| ( 0 << 0 );// Data are latched on even numbered edges of SPICLK
MCSPI_CH0CONFU = 0
| ( 0 << 13 ) // Clock divider granularity of power of two
| ( 1 << 12 ) // The buffer is used to receive data
| ( 1 << 11 ) // The buffer is used to transmit data
| ( 1 << 9 ) // 1.5 cycles between CS toggling and first or last edge of SPI clock
| ( 0 << 8 ) // Start bit polarity
| ( 0 << 7 ) // Disable start bit
| ( 0 << 4 ) // SPIEN active between SPI words
| ( 0 << 3 ) // Turbo is deactivated
| ( 1 << 2 ) // Data Line0 selected for reception
| ( 1 << 1 ) // Data Line1 selected for transmission
| ( 0 << 0 );// No transmission on Data Line0
/* Enable MCSPI channel */
MCSPI_MODULCTRLL = 0x01; // Enable Channel
]
/*
* spirom_cycle( buf, len )
*
* Execute a SPI spirom data transfer cycle. Each byte in buf is shifted
* out and replaced with data coming back from the spirom.
*/
void spirom_cycle( Uint8 *buf, Uint16 len )
[
Uint16 i;
/* Enable Channel */
MCSPI_CH0CTRLL = 0x01;
/* SPIROM access cycle */
MCSPI_CH0CONFU |= 0x0010;
for ( i = 0 ; i <= len ; i++ )
[
/* Wait for transmit empty */
while ( (MCSPI_CH0STATL & 0x02) == 0 );
MCSPI_CH0TXL = buf
; // Write to RX buffer 0 ??? Use upper register
/* Wait for receive data full */
while ( (MCSPI_CH0STATL & 0x01) == 0 );
buf= MCSPI_CH0RXL; // Read from RX buffer 0 ??? Use upper register
]
MCSPI_CH0CONFU &= ~0x0010;
/* Disable Channel */
MCSPI_CH0CTRLL = 0x00;
]
/*
* spirom_status( )
*/
Uint8 spirom_status( )
[
/* Issue read status command */
statu***uf[0] = SPIROM_CMD_RDSR;
statu***uf[1] = 0;
spirom_cycle( statu***uf, 2 );
return statu***uf[1];
]
void spirom_read1( Uint32 src, Uint32 length )
[
// Setup command
spirombuf[0] = SPIROM_CMD_READ;
spirombuf[1] = ( src >> 16 );
spirombuf[2] = ( src >> 8 );
spirombuf[3] = ( src >> 0 );
// Execute spirom read cycle
spirom_cycle( spirombuf, length + 4 );
]f