gitting project in git
This commit is contained in:
7
vitis/bootloader/src/blconfig.h
Normal file
7
vitis/bootloader/src/blconfig.h
Normal file
@@ -0,0 +1,7 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2004 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
#warning "Please provide the correct address value for the definition FLASH_IMAGE_BASEADDR. Please give the flash offset @ which SREC application is programmed"
|
||||
|
||||
#define FLASH_IMAGE_BASEADDR 0xd00000
|
||||
545
vitis/bootloader/src/bootloader.c
Normal file
545
vitis/bootloader/src/bootloader.c
Normal file
@@ -0,0 +1,545 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2009 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* Simple SREC Bootloader
|
||||
* It is capable of booting an SREC format image file (Mototorola S-record format),
|
||||
* given the location of the image in memory.
|
||||
* In particular, this bootloader is designed for images stored in non-volatile flash
|
||||
* memory that is addressable from the processor.
|
||||
*
|
||||
* Please modify the define "FLASH_IMAGE_BASEADDR" in the blconfig.h header file
|
||||
* to point to the memory location from which the bootloader has to pick up the
|
||||
* flash image from.
|
||||
*
|
||||
* You can include these sources in your software application project and build
|
||||
* the project for the processor for which you want the bootload to happen.
|
||||
* You can also subsequently modify these sources to adapt the bootloader for any
|
||||
* specific scenario that you might require it for.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "blconfig.h"
|
||||
#include "portab.h"
|
||||
#include "errors.h"
|
||||
#include "srec.h"
|
||||
#include "xparameters.h"
|
||||
#include "xspi.h"
|
||||
|
||||
/* Defines */
|
||||
#define CR 13
|
||||
#define RECORD_TYPE 2
|
||||
#define BYTE_COUNT 2
|
||||
#define RECORD_TERMINATOR 2
|
||||
|
||||
/* Comment the following line, if you want a smaller and faster bootloader which will be silent */
|
||||
#define VERBOSE
|
||||
|
||||
/* Declarations */
|
||||
static void display_progress (uint32_t lines);
|
||||
static uint8_t load_exec ();
|
||||
static uint8_t flash_get_srec_line (uint8_t *buf);
|
||||
extern void init_stdout();
|
||||
uint8 grab_hex_byte (uint8 *buf);
|
||||
|
||||
/*
|
||||
* The following constant defines the slave select signal that is used to
|
||||
* to select the Flash device on the SPI bus, this signal is typically
|
||||
* connected to the chip select of the device.
|
||||
*/
|
||||
#define SPI_SELECT 0x01
|
||||
|
||||
/*
|
||||
* Number of bytes per page in the flash device.
|
||||
*/
|
||||
#define PAGE_SIZE 256
|
||||
|
||||
/*
|
||||
* Byte Positions.
|
||||
*/
|
||||
#define BYTE1 0 /* Byte 1 position */
|
||||
#define BYTE2 1 /* Byte 2 position */
|
||||
#define BYTE3 2 /* Byte 3 position */
|
||||
#define BYTE4 3 /* Byte 4 position */
|
||||
#define BYTE5 4 /* Byte 5 position */
|
||||
|
||||
#define READ_WRITE_EXTRA_BYTES 4 /* Read/Write extra bytes */
|
||||
#define READ_WRITE_EXTRA_BYTES_4BYTE_MODE 5 /**< Command extra bytes */
|
||||
|
||||
#define RD_ID_SIZE 4
|
||||
|
||||
#define ISSI_ID_BYTE0 0x9D
|
||||
#define MICRON_ID_BYTE0 0x20
|
||||
|
||||
#define ENTER_4B_ADDR_MODE 0xb7 /* Enter 4Byte Mode command */
|
||||
#define EXIT_4B_ADDR_MODE 0xe9 /* Exit 4Byte Mode command */
|
||||
#define EXIT_4B_ADDR_MODE_ISSI 0x29
|
||||
#define WRITE_ENABLE 0x06 /* Write Enable command */
|
||||
|
||||
#define ENTER_4B 1
|
||||
#define EXIT_4B 0
|
||||
|
||||
#define FLASH_16_MB 0x18
|
||||
#define FLASH_MAKE 0
|
||||
#define FLASH_SIZE 2
|
||||
|
||||
#define READ_CMD 0x03
|
||||
|
||||
/* Declarations */
|
||||
static void display_progress (uint32_t lines);
|
||||
static uint8_t load_exec ();
|
||||
static uint8_t flash_get_srec_line (uint8_t *buf);
|
||||
extern void init_stdout();
|
||||
uint8 grab_hex_byte (uint8 *buf);
|
||||
int FlashReadID(void);
|
||||
|
||||
#define SPI_DEVICE_ID XPAR_SPI_2_DEVICE_ID
|
||||
|
||||
/*
|
||||
* The instances to support the device drivers are global such that they
|
||||
* are initialized to zero each time the program runs. They could be local
|
||||
* but should at least be static so they are zeroed.
|
||||
*/
|
||||
static XSpi Spi;
|
||||
|
||||
|
||||
int mode = READ_WRITE_EXTRA_BYTES;
|
||||
|
||||
u8 WriteBuffer[PAGE_SIZE + READ_WRITE_EXTRA_BYTES];
|
||||
/*
|
||||
* Buffer used during Read transactions.
|
||||
*/
|
||||
u8 ReadBuffer[PAGE_SIZE + READ_WRITE_EXTRA_BYTES];
|
||||
|
||||
u8 FlashID[3];
|
||||
|
||||
extern int srec_line;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void outbyte(char c);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Data structures */
|
||||
static srec_info_t srinfo;
|
||||
static uint8_t sr_buf[SREC_MAX_BYTES];
|
||||
static uint8_t sr_data_buf[SREC_DATA_MAX_BYTES];
|
||||
|
||||
u32 flbuf;
|
||||
|
||||
#ifdef VERBOSE
|
||||
static int8_t *errors[] = {
|
||||
"",
|
||||
"Error while copying executable image into RAM",
|
||||
"Error while reading an SREC line from flash",
|
||||
"SREC line is corrupted",
|
||||
"SREC has invalid checksum."
|
||||
};
|
||||
#endif
|
||||
|
||||
/* We don't use interrupts/exceptions.
|
||||
Dummy definitions to reduce code size on MicroBlaze */
|
||||
#ifdef __MICROBLAZE__
|
||||
void _interrupt_handler () {}
|
||||
void _exception_handler () {}
|
||||
void _hw_exception_handler () {}
|
||||
#endif
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
int Status;
|
||||
uint8_t ret;
|
||||
|
||||
#ifdef VERBOSE
|
||||
print ("\r\nSREC SPI Bootloader\r\n");
|
||||
#endif
|
||||
|
||||
sleep(3);
|
||||
|
||||
// Reset QSPI
|
||||
Xil_Out32(0x40050008, (1 << 10));
|
||||
sleep(1);
|
||||
Xil_Out32(0x40050008, 0);
|
||||
|
||||
sleep(1);
|
||||
|
||||
/*
|
||||
* Initialize the SPI driver so that it's ready to use,
|
||||
* specify the device ID that is generated in xparameters.h.
|
||||
*/
|
||||
Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID);
|
||||
if(Status != XST_SUCCESS) {
|
||||
print("init fail");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the SPI device as a master and in manual slave select mode such
|
||||
* that the slave select signal does not toggle for every byte of a
|
||||
* transfer, this must be done before the slave select is set.
|
||||
*/
|
||||
Status = XSpi_SetOptions(&Spi, XSP_MASTER_OPTION |
|
||||
XSP_MANUAL_SSELECT_OPTION);
|
||||
if(Status != XST_SUCCESS) {
|
||||
print("options fail");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Select the flash device on the SPI bus, so that it can be
|
||||
* read and written using the SPI bus.
|
||||
*/
|
||||
Status = XSpi_SetSlaveSelect(&Spi, SPI_SELECT);
|
||||
if(Status != XST_SUCCESS) {
|
||||
print("slave select fail");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start the SPI driver so that interrupts and the device are enabled.
|
||||
*/
|
||||
XSpi_Start(&Spi);
|
||||
|
||||
XSpi_IntrGlobalDisable(&Spi);
|
||||
|
||||
init_stdout();
|
||||
sleep(1);
|
||||
|
||||
print ("Read Flash ID");
|
||||
Status = FlashReadID( );
|
||||
if(Status != XST_SUCCESS) {
|
||||
print("flash read id fail");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
print ("Read Flash ID");
|
||||
Status = FlashReadID( );
|
||||
if(Status != XST_SUCCESS) {
|
||||
print("flash read id fail");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
print ("Read Flash ID");
|
||||
Status = FlashReadID( );
|
||||
if(Status != XST_SUCCESS) {
|
||||
print("flash read id fail");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef VERBOSE
|
||||
print ("Loading SREC image from flash @ address: ");
|
||||
putnum (FLASH_IMAGE_BASEADDR);
|
||||
print ("\r\n");
|
||||
#endif
|
||||
|
||||
sleep(1);
|
||||
print ("After Sleep");
|
||||
|
||||
flbuf = (u32)FLASH_IMAGE_BASEADDR;
|
||||
ret = load_exec ();
|
||||
|
||||
/* If we reach here, we are in error */
|
||||
|
||||
#ifdef VERBOSE
|
||||
if (ret > LD_SREC_LINE_ERROR) {
|
||||
print ("ERROR in SREC line: ");
|
||||
putnum (srec_line);
|
||||
print (errors[ret]);
|
||||
} else {
|
||||
print ("ERROR: ");
|
||||
print (errors[ret]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function enables writes to the Serial Flash memory.
|
||||
*
|
||||
* @param Spi is a pointer to the instance of the Spi device.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
******************************************************************************/
|
||||
int FlashWriteEnable(XSpi *Spi)
|
||||
{
|
||||
int Status;
|
||||
u8 *NULLPtr = NULL;
|
||||
|
||||
/*
|
||||
* Prepare the WriteBuffer.
|
||||
*/
|
||||
WriteBuffer[BYTE1] = WRITE_ENABLE;
|
||||
|
||||
Status = XSpi_Transfer(Spi, WriteBuffer, NULLPtr, 1);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief
|
||||
* This API enters the flash device into 4 bytes addressing mode.
|
||||
*
|
||||
* @param Spi is a pointer to the instance of the Spi device.
|
||||
* @param Enable is a either 1 or 0 if 1 then enters 4 byte if 0 exits.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_FAILURE if it fails.
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
int FlashEnterExit4BAddMode(XSpi *Spi, unsigned int Enable)
|
||||
{
|
||||
int Status;
|
||||
u8 *NULLPtr = NULL;
|
||||
|
||||
if((FlashID[FLASH_MAKE] == MICRON_ID_BYTE0) ||
|
||||
(FlashID[FLASH_MAKE] == ISSI_ID_BYTE0)) {
|
||||
|
||||
Status = FlashWriteEnable(Spi);
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (Enable) {
|
||||
WriteBuffer[BYTE1] = ENTER_4B_ADDR_MODE;
|
||||
} else {
|
||||
if (FlashID[FLASH_MAKE] == ISSI_ID_BYTE0)
|
||||
WriteBuffer[BYTE1] = EXIT_4B_ADDR_MODE_ISSI;
|
||||
else
|
||||
WriteBuffer[BYTE1] = EXIT_4B_ADDR_MODE;
|
||||
}
|
||||
|
||||
Status = XSpi_Transfer(Spi, WriteBuffer, NULLPtr, 1);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function reads serial FLASH ID connected to the SPI interface.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if read id, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int FlashReadID(void)
|
||||
{
|
||||
int Status;
|
||||
int i;
|
||||
|
||||
/* Read ID in Auto mode.*/
|
||||
WriteBuffer[BYTE1] = 0x9f;
|
||||
WriteBuffer[BYTE2] = 0xff; /* 4 dummy bytes */
|
||||
WriteBuffer[BYTE3] = 0xff;
|
||||
WriteBuffer[BYTE4] = 0xff;
|
||||
WriteBuffer[BYTE5] = 0xff;
|
||||
|
||||
Status = XSpi_Transfer(&Spi, WriteBuffer, ReadBuffer, 5);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
FlashID[i] = ReadBuffer[i + 1];
|
||||
#ifdef VERBOSE
|
||||
xil_printf("FlashID=0x%x 0x%x 0x%x\n\r", ReadBuffer[1], ReadBuffer[2],
|
||||
ReadBuffer[3]);
|
||||
#endif
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef VERBOSE
|
||||
static void display_progress (uint32_t count)
|
||||
{
|
||||
/* Send carriage return */
|
||||
outbyte (CR);
|
||||
print ("Bootloader: Processed (0x)");
|
||||
putnum (count);
|
||||
print (" S-records");
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint8_t load_exec ()
|
||||
{
|
||||
uint8_t ret;
|
||||
void (*laddr)();
|
||||
int8_t done = 0;
|
||||
int Status;
|
||||
|
||||
srinfo.sr_data = sr_data_buf;
|
||||
|
||||
if(FlashID[FLASH_SIZE] > FLASH_16_MB) {
|
||||
Status = FlashEnterExit4BAddMode(&Spi, ENTER_4B);
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
mode = READ_WRITE_EXTRA_BYTES_4BYTE_MODE;
|
||||
}
|
||||
while (!done) {
|
||||
if ((ret = flash_get_srec_line (sr_buf)) != 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = decode_srec_line (sr_buf, &srinfo)) != 0)
|
||||
return ret;
|
||||
|
||||
#ifdef VERBOSE
|
||||
if (srec_line % 16 == 0) {
|
||||
// Don't print every line because it takes forever over UART
|
||||
display_progress (srec_line);
|
||||
}
|
||||
#endif
|
||||
switch (srinfo.type) {
|
||||
case SREC_TYPE_0:
|
||||
break;
|
||||
case SREC_TYPE_1:
|
||||
case SREC_TYPE_2:
|
||||
case SREC_TYPE_3:
|
||||
memcpy ((void*)srinfo.addr, (void*)srinfo.sr_data, srinfo.dlen);
|
||||
break;
|
||||
case SREC_TYPE_5:
|
||||
break;
|
||||
case SREC_TYPE_7:
|
||||
case SREC_TYPE_8:
|
||||
case SREC_TYPE_9:
|
||||
laddr = (void (*)())srinfo.addr;
|
||||
done = 1;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(FlashID[FLASH_SIZE] > FLASH_16_MB) {
|
||||
Status = FlashEnterExit4BAddMode(&Spi, EXIT_4B);
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
mode = READ_WRITE_EXTRA_BYTES;
|
||||
}
|
||||
#ifdef VERBOSE
|
||||
print ("\r\nExecuting program starting at address: ");
|
||||
putnum ((uint32_t)laddr);
|
||||
print ("\r\n");
|
||||
#endif
|
||||
(*laddr)();
|
||||
|
||||
/* We will be dead at this point */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t flash_get_srec_line (uint8_t *buf)
|
||||
{
|
||||
int Status;
|
||||
int i;
|
||||
int len;
|
||||
u8 ReadCmd = READ_CMD;
|
||||
|
||||
/*
|
||||
* Read 1st 4bytes of a record. Its contains the information about
|
||||
* the type of the record and number of bytes that follow in the
|
||||
* rest of the record (address + data + checksum).
|
||||
*/
|
||||
if(mode == READ_WRITE_EXTRA_BYTES) {
|
||||
WriteBuffer[BYTE1] = ReadCmd;
|
||||
WriteBuffer[BYTE2] = (u8) (flbuf >> 16);
|
||||
WriteBuffer[BYTE3] = (u8) (flbuf >> 8);
|
||||
WriteBuffer[BYTE4] = (u8) flbuf;
|
||||
} else {
|
||||
WriteBuffer[BYTE1] = ReadCmd;
|
||||
WriteBuffer[BYTE2] = (u8) (flbuf >> 24);
|
||||
WriteBuffer[BYTE3] = (u8) (flbuf >> 16);
|
||||
WriteBuffer[BYTE4] = (u8) (flbuf >> 8);
|
||||
WriteBuffer[BYTE5] = (u8) flbuf;
|
||||
}
|
||||
|
||||
Status = XSpi_Transfer(&Spi, WriteBuffer, ReadBuffer,
|
||||
(RECORD_TYPE + BYTE_COUNT + mode));
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
flbuf += RECORD_TYPE + BYTE_COUNT;
|
||||
|
||||
/*
|
||||
* Get the number of bytes (address + data + checksum) in a record.
|
||||
*/
|
||||
len = grab_hex_byte((ReadBuffer + mode + RECORD_TYPE)) * 2;
|
||||
|
||||
for(i = 0; i < (RECORD_TYPE + BYTE_COUNT); i++)
|
||||
*buf++ = ReadBuffer[mode + i];
|
||||
|
||||
/*
|
||||
* Read address + data + checksum from the record.
|
||||
*/
|
||||
if(mode == READ_WRITE_EXTRA_BYTES) {
|
||||
WriteBuffer[BYTE1] = ReadCmd;
|
||||
WriteBuffer[BYTE2] = (u8) (flbuf >> 16);
|
||||
WriteBuffer[BYTE3] = (u8) (flbuf >> 8);
|
||||
WriteBuffer[BYTE4] = (u8) flbuf;
|
||||
} else {
|
||||
WriteBuffer[BYTE1] = ReadCmd;
|
||||
WriteBuffer[BYTE2] = (u8) (flbuf >> 24);
|
||||
WriteBuffer[BYTE3] = (u8) (flbuf >> 16);
|
||||
WriteBuffer[BYTE4] = (u8) (flbuf >> 8);
|
||||
WriteBuffer[BYTE5] = (u8) flbuf;
|
||||
}
|
||||
|
||||
Status = XSpi_Transfer(&Spi, WriteBuffer, ReadBuffer, (len + mode));
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
flbuf += (len + RECORD_TERMINATOR);
|
||||
|
||||
for(i = 0; i < len; i++)
|
||||
*buf++ = ReadBuffer[mode + i];
|
||||
|
||||
if ((RECORD_TYPE + BYTE_COUNT + len) > SREC_MAX_BYTES)
|
||||
return LD_SREC_LINE_ERROR;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
#ifdef __PPC__
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
/* Save some code and data space on PowerPC
|
||||
by defining a minimal exit */
|
||||
void exit (int ret):
|
||||
{
|
||||
_exit (ret);
|
||||
}
|
||||
#endif
|
||||
13
vitis/bootloader/src/errors.h
Normal file
13
vitis/bootloader/src/errors.h
Normal file
@@ -0,0 +1,13 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2004 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
#ifndef BL_ERRORS_H
|
||||
#define BL_ERRORS_H
|
||||
|
||||
#define LD_MEM_WRITE_ERROR 1
|
||||
#define LD_SREC_LINE_ERROR 2
|
||||
#define SREC_PARSE_ERROR 3
|
||||
#define SREC_CKSUM_ERROR 4
|
||||
|
||||
#endif /* BL_ERRORS_H */
|
||||
221
vitis/bootloader/src/lscript.ld
Normal file
221
vitis/bootloader/src/lscript.ld
Normal file
@@ -0,0 +1,221 @@
|
||||
/*******************************************************************/
|
||||
/* */
|
||||
/* This file is automatically generated by linker script generator.*/
|
||||
/* */
|
||||
/* Version: 2018.3 */
|
||||
/* */
|
||||
/* Copyright (c) 2010-2019 Xilinx, Inc. All rights reserved. */
|
||||
/* */
|
||||
/* Description : MicroBlaze Linker Script */
|
||||
/* */
|
||||
/*******************************************************************/
|
||||
|
||||
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x400;
|
||||
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x0;
|
||||
|
||||
/* Define Memories in the system */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem : ORIGIN = 0x50, LENGTH = 0x7FB0
|
||||
ddr4_0_C0_DDR4_MEMORY_MAP_BASEADDR_C0_DDR4_ADDRESS_BLOCK : ORIGIN = 0x80000000, LENGTH = 0x80000000
|
||||
axi_bram_ctrl_0_Mem0 : ORIGIN = 0x10000, LENGTH = 0x8000
|
||||
axi_bram_ctrl_1_Mem0 : ORIGIN = 0x20000, LENGTH = 0x8000
|
||||
axi_bram_ctrl_2_Mem0 : ORIGIN = 0x30000, LENGTH = 0x8000
|
||||
axi_bram_ctrl_3_Mem0 : ORIGIN = 0x40000, LENGTH = 0x8000
|
||||
}
|
||||
|
||||
/* Specify the default entry point to the program */
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
/* Define the sections, and where they are mapped in memory */
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.vectors.reset 0x0 : {
|
||||
KEEP (*(.vectors.reset))
|
||||
}
|
||||
|
||||
.vectors.sw_exception 0x8 : {
|
||||
KEEP (*(.vectors.sw_exception))
|
||||
}
|
||||
|
||||
.vectors.interrupt 0x10 : {
|
||||
KEEP (*(.vectors.interrupt))
|
||||
}
|
||||
|
||||
.vectors.hw_exception 0x20 : {
|
||||
KEEP (*(.vectors.hw_exception))
|
||||
}
|
||||
|
||||
.text : {
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.note.gnu.build-id : {
|
||||
KEEP (*(.note.gnu.build-id))
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.init : {
|
||||
KEEP (*(.init))
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.fini : {
|
||||
KEEP (*(.fini))
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.ctors : {
|
||||
__CTOR_LIST__ = .;
|
||||
___CTORS_LIST___ = .;
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
__CTOR_END__ = .;
|
||||
___CTORS_END___ = .;
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.dtors : {
|
||||
__DTOR_LIST__ = .;
|
||||
___DTORS_LIST___ = .;
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
PROVIDE(__DTOR_END__ = .);
|
||||
PROVIDE(___DTORS_END___ = .);
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.rodata : {
|
||||
__rodata_start = .;
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
__rodata_end = .;
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.sdata2 : {
|
||||
. = ALIGN(8);
|
||||
__sdata2_start = .;
|
||||
*(.sdata2)
|
||||
*(.sdata2.*)
|
||||
*(.gnu.linkonce.s2.*)
|
||||
. = ALIGN(8);
|
||||
__sdata2_end = .;
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.sbss2 : {
|
||||
__sbss2_start = .;
|
||||
*(.sbss2)
|
||||
*(.sbss2.*)
|
||||
*(.gnu.linkonce.sb2.*)
|
||||
__sbss2_end = .;
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.data : {
|
||||
. = ALIGN(4);
|
||||
__data_start = .;
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
__data_end = .;
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.got : {
|
||||
*(.got)
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.got1 : {
|
||||
*(.got1)
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.got2 : {
|
||||
*(.got2)
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.eh_frame : {
|
||||
*(.eh_frame)
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.jcr : {
|
||||
*(.jcr)
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.gcc_except_table : {
|
||||
*(.gcc_except_table)
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.sdata : {
|
||||
. = ALIGN(8);
|
||||
__sdata_start = .;
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
__sdata_end = .;
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.sbss (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
__sbss_start = .;
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
. = ALIGN(8);
|
||||
__sbss_end = .;
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.tdata : {
|
||||
__tdata_start = .;
|
||||
*(.tdata)
|
||||
*(.tdata.*)
|
||||
*(.gnu.linkonce.td.*)
|
||||
__tdata_end = .;
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.tbss : {
|
||||
__tbss_start = .;
|
||||
*(.tbss)
|
||||
*(.tbss.*)
|
||||
*(.gnu.linkonce.tb.*)
|
||||
__tbss_end = .;
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
|
||||
|
||||
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
|
||||
|
||||
/* Generate Stack and Heap definitions */
|
||||
|
||||
.heap (NOLOAD) : {
|
||||
. = ALIGN(8);
|
||||
_heap = .;
|
||||
_heap_start = .;
|
||||
. += _HEAP_SIZE;
|
||||
_heap_end = .;
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
.stack (NOLOAD) : {
|
||||
_stack_end = .;
|
||||
. += _STACK_SIZE;
|
||||
. = ALIGN(8);
|
||||
_stack = .;
|
||||
__stack = _stack;
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
|
||||
|
||||
_end = .;
|
||||
}
|
||||
|
||||
20
vitis/bootloader/src/platform.c
Normal file
20
vitis/bootloader/src/platform.c
Normal file
@@ -0,0 +1,20 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2004 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
#include "xparameters.h"
|
||||
#include "platform_config.h"
|
||||
|
||||
#ifdef STDOUT_IS_16550
|
||||
#include "xuartns550_l.h"
|
||||
#endif
|
||||
|
||||
void
|
||||
init_stdout()
|
||||
{
|
||||
/* if we have a uart 16550, then that needs to be initialized */
|
||||
#ifdef STDOUT_IS_16550
|
||||
XUartNs550_SetBaud(STDOUT_BASEADDR, XPAR_XUARTNS550_CLOCK_HZ, 9600);
|
||||
XUartNs550_SetLineControlReg(STDOUT_BASEADDR, XUN_LCR_8_DATA_BITS);
|
||||
#endif
|
||||
}
|
||||
4
vitis/bootloader/src/platform_config.h
Normal file
4
vitis/bootloader/src/platform_config.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#ifndef __PLATFORM_CONFIG_H_
|
||||
#define __PLATFORM_CONFIG_H_
|
||||
|
||||
#endif
|
||||
33
vitis/bootloader/src/portab.h
Normal file
33
vitis/bootloader/src/portab.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2004 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
#ifndef BL_PORTAB_H
|
||||
#define BL_PORTAB_H
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned int uint32;
|
||||
|
||||
typedef char int8;
|
||||
typedef short int16;
|
||||
typedef int int32;
|
||||
|
||||
|
||||
|
||||
/* An anonymous union allows the compiler to report typedef errors automatically */
|
||||
/* Does not work with gcc. Might work only for g++ */
|
||||
|
||||
/* static union */
|
||||
/* { */
|
||||
/* char int8_incorrect [sizeof( int8) == 1]; */
|
||||
/* char uint8_incorrect [sizeof( uint8) == 1]; */
|
||||
/* char int16_incorrect [sizeof( int16) == 2]; */
|
||||
/* char uint16_incorrect [sizeof(uint16) == 2]; */
|
||||
/* char int32_incorrect [sizeof( int32) == 4]; */
|
||||
/* char uint32_incorrect [sizeof(uint32) == 4]; */
|
||||
/* }; */
|
||||
|
||||
|
||||
|
||||
#endif /* BL_PORTTAB_H */
|
||||
153
vitis/bootloader/src/srec.c
Normal file
153
vitis/bootloader/src/srec.c
Normal file
@@ -0,0 +1,153 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2004 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
#include "portab.h"
|
||||
#include "srec.h"
|
||||
#include "errors.h"
|
||||
|
||||
uint8 grab_hex_byte (uint8 *buf);
|
||||
uint16 grab_hex_word (uint8 *buf);
|
||||
uint32 grab_hex_dword (uint8 *buf);
|
||||
uint32 grab_hex_word24 (uint8 *buf);
|
||||
|
||||
int srec_line = 0;
|
||||
|
||||
uint8 nybble_to_val (char x)
|
||||
{
|
||||
if (x >= '0' && x <= '9')
|
||||
return (uint8)(x-'0');
|
||||
|
||||
return (uint8)((x-'A') + 10);
|
||||
}
|
||||
|
||||
uint8 grab_hex_byte (uint8 *buf)
|
||||
{
|
||||
return (uint8)((nybble_to_val ((char)buf[0]) << 4) +
|
||||
nybble_to_val ((char)buf[1]));
|
||||
}
|
||||
|
||||
uint16 grab_hex_word (uint8 *buf)
|
||||
{
|
||||
return (uint16)(((uint16)grab_hex_byte (buf) << 8) +
|
||||
grab_hex_byte ((uint8*)((int)buf+2)));
|
||||
}
|
||||
|
||||
uint32 grab_hex_word24 (uint8 *buf)
|
||||
{
|
||||
return (uint32)(((uint32)grab_hex_byte (buf) << 16) +
|
||||
grab_hex_word ((uint8*)((int)buf+2)));
|
||||
}
|
||||
|
||||
uint32 grab_hex_dword (uint8 *buf)
|
||||
{
|
||||
return (uint32)(((uint32)grab_hex_word (buf) << 16) +
|
||||
grab_hex_word ((uint8*)((int)buf+4)));
|
||||
}
|
||||
|
||||
uint8 decode_srec_data (uint8 *bufs, uint8 *bufd, uint8 count, uint8 skip)
|
||||
{
|
||||
uint8 cksum = 0, cbyte;
|
||||
int i;
|
||||
|
||||
/* Parse remaining character pairs */
|
||||
for (i=0; i < count; i++) {
|
||||
cbyte = grab_hex_byte (bufs);
|
||||
if ((i >= skip - 1) && (i != count-1)) /* Copy over only data bytes */
|
||||
*bufd++ = cbyte;
|
||||
bufs += 2;
|
||||
cksum += cbyte;
|
||||
}
|
||||
|
||||
return cksum;
|
||||
}
|
||||
|
||||
uint8 eatup_srec_line (uint8 *bufs, uint8 count)
|
||||
{
|
||||
int i;
|
||||
uint8 cksum = 0;
|
||||
|
||||
for (i=0; i < count; i++) {
|
||||
cksum += grab_hex_byte(bufs);
|
||||
bufs += 2;
|
||||
}
|
||||
|
||||
return cksum;
|
||||
}
|
||||
|
||||
uint8 decode_srec_line (uint8 *sr_buf, srec_info_t *info)
|
||||
{
|
||||
uint8 count;
|
||||
uint8 *bufs;
|
||||
uint8 cksum = 0, skip;
|
||||
int type;
|
||||
|
||||
bufs = sr_buf;
|
||||
|
||||
srec_line++; /* for debug purposes on errors */
|
||||
|
||||
if ( *bufs != 'S') {
|
||||
return SREC_PARSE_ERROR;
|
||||
}
|
||||
|
||||
type = *++bufs - '0';
|
||||
count = grab_hex_byte (++bufs);
|
||||
bufs += 2;
|
||||
cksum = count;
|
||||
|
||||
switch (type) {
|
||||
case 0:
|
||||
info->type = SREC_TYPE_0;
|
||||
info->dlen = count;
|
||||
cksum += eatup_srec_line (bufs, count);
|
||||
break;
|
||||
case 1:
|
||||
info->type = SREC_TYPE_1;
|
||||
skip = 3;
|
||||
info->addr = (uint8*)(uint32)grab_hex_word (bufs);
|
||||
info->dlen = count - skip;
|
||||
cksum += decode_srec_data (bufs, info->sr_data, count, skip);
|
||||
break;
|
||||
case 2:
|
||||
info->type = SREC_TYPE_2;
|
||||
skip = 4;
|
||||
info->addr = (uint8*)(uint32)grab_hex_word24 (bufs);
|
||||
info->dlen = count - skip;
|
||||
cksum += decode_srec_data (bufs, info->sr_data, count, skip);
|
||||
break;
|
||||
case 3:
|
||||
info->type = SREC_TYPE_3;
|
||||
skip = 5;
|
||||
info->addr = (uint8*)(uint32)grab_hex_dword (bufs);
|
||||
info->dlen = count - skip;
|
||||
cksum += decode_srec_data (bufs, info->sr_data, count, skip);
|
||||
break;
|
||||
case 5:
|
||||
info->type = SREC_TYPE_5;
|
||||
info->addr = (uint8*)(uint32)grab_hex_word (bufs);
|
||||
cksum += eatup_srec_line (bufs, count);
|
||||
break;
|
||||
case 7:
|
||||
info->type = SREC_TYPE_7;
|
||||
info->addr = (uint8*)(uint32)grab_hex_dword (bufs);
|
||||
cksum += eatup_srec_line (bufs, count);
|
||||
break;
|
||||
case 8:
|
||||
info->type = SREC_TYPE_8;
|
||||
info->addr = (uint8*)(uint32)grab_hex_word24 (bufs);
|
||||
cksum += eatup_srec_line (bufs, count);
|
||||
break;
|
||||
case 9:
|
||||
info->type = SREC_TYPE_9;
|
||||
info->addr = (uint8*)(uint32)grab_hex_word (bufs);
|
||||
cksum += eatup_srec_line (bufs, count);
|
||||
break;
|
||||
default:
|
||||
return SREC_PARSE_ERROR;
|
||||
}
|
||||
|
||||
if (++cksum) {
|
||||
return SREC_CKSUM_ERROR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
38
vitis/bootloader/src/srec.h
Normal file
38
vitis/bootloader/src/srec.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2004 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Note: This file depends on the following files having been included prior to self being included.
|
||||
1. portab.h
|
||||
*/
|
||||
|
||||
#ifndef BL_SREC_H
|
||||
#define BL_SREC_H
|
||||
|
||||
#define SREC_MAX_BYTES 255 /* Maximum record length */
|
||||
#define SREC_DATA_MAX_BYTES 123 /* Maximum of 123 data bytes */
|
||||
|
||||
#define SREC_TYPE_0 0
|
||||
#define SREC_TYPE_1 1
|
||||
#define SREC_TYPE_2 2
|
||||
#define SREC_TYPE_3 3
|
||||
#define SREC_TYPE_5 5
|
||||
#define SREC_TYPE_7 7
|
||||
#define SREC_TYPE_8 8
|
||||
#define SREC_TYPE_9 9
|
||||
|
||||
|
||||
typedef struct srec_info_s {
|
||||
int8 type;
|
||||
uint8* addr;
|
||||
uint8* sr_data;
|
||||
uint8 dlen;
|
||||
} srec_info_t;
|
||||
|
||||
uint8 decode_srec_line (uint8 *sr_buf, srec_info_t *info);
|
||||
|
||||
#endif /* BL_SREC_H */
|
||||
Reference in New Issue
Block a user