cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
@alxtrnk
Adventurer
Adventurer
232 Views
Registered: ‎10-24-2016

Bootloader not jumping to application in DDR memory

Hello, 

I am facing a problem to jump from bootloader to DDR memory where my application resides. I am using a Spartan 6 custom board with SPI flash memory by Spansion, and a 128Mbit DDR3 memory. I am using ISE 14.7 and EDK 14.7.

 

FPGA configuration works fine. Bootloader is correctly loaded at BRAM after power on, and it executes correctly (I have some print functions and I can see that it is working). Bootloader is in charge to move my application from flash to DDR memory, and reallocate vectors of my application to BRAM before jump to DDR memory. I have debugged with SDK and I have seen that data is correctly moved from SPI Flash to DDR memory, so my application is correctly loaded in DDR memory. 

 

I have two different situations. If I run the code from flash (after power on), the bootloader is executed continously (after trying to jump to DDR memory, bootloader excecutes again and again in an infinite loop). But if I debug through SDK, loading the same bootloader code to the BRAM, when the SW tries to jump to DDR, it stucks in a memory position not assigned (0x0000410A). I have 16KB of BRAM so my last memory position is 0x3FB0. 

 

Debugging, I have observed the following situation: This is my binary file, which is loaded to the Flash memory from 0x178000 (see the data highlighted in Blue color. It is my application. Previous 40 bytes are vectors of my application which are moved to BRAM before jumping to DDR memory):

Download_bin.jpg

But If I load the application through SDK debugger, when I check DDR memory to see how data has been loaded, I see this:

mrd_DDR3.jpg

 

 

 

 

 

 

 

 

As you see, every four bytes, the order of these bytes is swapped!!! I dont know why. I use promgen to create the final binary file to download to SPI flash. I have used this method with other boards (also with Spartan 6) and with this method I have not had problems to jump from bootloader to DDR memory. 

 

Anyway, I have tried to move data to DDR from flash in both formats (with bytes swapped, and with bytes not swapped), and I continue without having succes to jump to DDR memory.

I attach my bootloader application for you to check if there is something incorrect, but I think that all is ok:

 

/*
 * *********************************************************************
 * AHED_Bootloader.c: Bootloader created to work with AHED_MFB_MB board
 * *********************************************************************
 *
 * -----------------------------------------------------------------------------------------
 * NOTE: This bootloader requires a VHDL core in charge of SPI bus to S25FL256S Flash memory
 * -----------------------------------------------------------------------------------------
 *
*/

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "platform_config.h"
#include "xil_io.h"
#include "xil_types.h"
#include "xil_cache.h"
#include "xil_exception.h"
#include "xdebug.h"
#include "xbasic_types.h"
#include "xgpio.h"
#include "xuartlite.h"


#define GPIO_CHANNEL1 1
#define GPIO_CHANNEL2 2

// #define's for memories address
#define FLASH_IMAGE_START_ADDRESS 0x178000
#define FLASH_VECTORS_OFFSET 0x28
#define DDR_MEMORY_START_ADDRESS  0xA8000000
#define BRAM_START_ADDRESS 0X00000000
#define VECTORS_SIZE_IN_BYTES 40
#define APPLICATION_START_ADDRESS 0xA8000028
#define DEBUG_MEMORY_POINTER 0xA9000000
#define FLASH_IMAGE_SIZE     0x10000
//#define READ_CMD			 0x03  /*De este comando se encarga el core VHDL de enviarlo */


#define PRINT_BUFFER_SIZE 200
#define DEBUG 1

static XGpio Gpio0, Gpio1;  // Gpio0: DATA FROM FLASH GPIOs - Gpio1: DATA TO FLASH Gpios
static XUartLite UartLite;          /* The instance of the UartLite Device */

int Status;

/*
 * Pointer to void function used to jump to DDR memory to start application image
 */

void (*JumpToApplicationImage)();

/*
 * BOOTLOADER FUNCTIONS
 */


void DebugPrint(char message[PRINT_BUFFER_SIZE])
{
#if (DEBUG==1)
  	xil_printf(message);
#endif
}

static int InitializeUartLite ()
{
	Status = XUartLite_Initialize(&UartLite, XPAR_UARTLITE_1_DEVICE_ID);
	if (Status != XST_SUCCESS) {
	    DebugPrint ("UART Initialization FAILED\n\r");
		return XST_FAILURE;
	}else{
		DebugPrint ("UART Initialization OK\n\r");
	}
	return XST_SUCCESS;
}

static int InitializeGpioFromFlash()
{
	Status = XGpio_Initialize (&Gpio0, XPAR_DATA_FROM_SPI_BOOTLOADER_DEVICE_ID );
	if (Status != XST_SUCCESS){
		return XST_FAILURE;
	}else{
		DebugPrint ("GPIO from Flash initialization OK\n\r");
	}
	XGpio_SetDataDirection (&Gpio0, GPIO_CHANNEL1, 1);
	XGpio_SetDataDirection (&Gpio0, GPIO_CHANNEL2, 1);
	return XST_SUCCESS;
}

static int InitializeGpioToFlash()
{
	Status = XGpio_Initialize(&Gpio1, XPAR_DATA_TO_SPI_BOOTLOADER_DEVICE_ID );
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}else{
		DebugPrint ("GPIO to Flash initialization OK\n\r");
	}
	XGpio_SetDataDirection(&Gpio1, GPIO_CHANNEL1, 0);
	XGpio_SetDataDirection(&Gpio1, GPIO_CHANNEL2, 0);
	return XST_SUCCESS;
}

void VectorsReallocation(void){
	int i;
	u8 *Bram_memory_pointer = BRAM_START_ADDRESS;
	u8 *DDR_memory_pointer = DDR_MEMORY_START_ADDRESS;
	for(i=0;i<=VECTORS_SIZE_IN_BYTES;i++){
		*Bram_memory_pointer = *DDR_memory_pointer;
		Bram_memory_pointer+=0x1;
		DDR_memory_pointer+=0x1;
	}
	xil_printf("Reallocation of Vectors completed\n\r");
}

int main()
{
	int i;
	Xuint32 DataFromFlash = 0x00000000;
	Xuint32 FlashPointer = FLASH_IMAGE_START_ADDRESS;
	u32 DDRWriteOffset = 0;

    Xil_ICacheEnable();
    Xil_DCacheEnable();

	xil_printf("Starting Bootloader.........\n\r");

    Status = InitializeUartLite();
    if(Status!=XST_SUCCESS){
    	DebugPrint("Uart Lite Initialization Failed\n\r");
    }

    Status = InitializeGpioToFlash();
    if(Status!=XST_SUCCESS){
    	DebugPrint("Initialization of GPIO to FLASH failed\n\r");
    }

    Status = InitializeGpioFromFlash();
    if(Status!=XST_SUCCESS){
    	DebugPrint("Initialization of GPIO from FLASH failed\n\r");
    }

    for(i=0;i<(FLASH_IMAGE_SIZE);i++){
		XGpio_DiscreteWrite(&Gpio1,GPIO_CHANNEL2,FlashPointer); //Cargamos datos del Address en el bus al CORE VHDL
		XGpio_DiscreteWrite(&Gpio1,GPIO_CHANNEL1,0x1); // Mandamos señal START a core VHDL
		while(XGpio_DiscreteRead(&Gpio0,GPIO_CHANNEL1)==0){

		}
		DataFromFlash = XGpio_DiscreteRead(&Gpio0,GPIO_CHANNEL2); //Leemos datos entregados por el core VHDL desde la Flash
		*((u32*)(DDRWriteOffset + DDR_MEMORY_START_ADDRESS)) = *((u32*)(&DataFromFlash));
		DDRWriteOffset +=4;
		FlashPointer+=4;
		i++;
		XGpio_DiscreteWrite(&Gpio1,GPIO_CHANNEL1,0x0); // Mandamos señal START a cero en core VHDL
		while(XGpio_DiscreteRead(&Gpio0,GPIO_CHANNEL1)==1){

		}
    }
    xil_printf ("Data transfer from Flash memory completed\n\r");

    Xil_ICacheInvalidate();
    Xil_DCacheInvalidate();

    VectorsReallocation();

    xil_printf ("Jumping to DDR memory to execute application image.........\n\r");

    JumpToApplicationImage = (void (*)())(APPLICATION_START_ADDRESS);
    (*JumpToApplicationImage)();
    xil_printf("If you can see this message, jump to DDR memory is not working.....\n\r");
    xil_printf("Exiting bootloader application...........\n\r");

    /*We should not be here */
        return;
}

Do you have an idea about what is wrong ? Am I missing something? Let me know if you need additional information. 

Thanks by advance. 

0 Kudos
0 Replies