void main( void )
{
  int status;

  // System init
  if (DEVICE_init() != E_PASS)
  {
    return;
  }

  // Set PLL to 27 MHz
//  DEVICE_PLL1Init(1);

  DEVICE_pinmuxControl( 0, DEVICE_PINMUX_EMIF_MASK, DEVICE_PINMUX_EMIF_EN );

	// Execute the NAND flashing
  status = nandreader_ROM();

  if (status != E_PASS)
  {
    DEBUG_printString("\n\nNAND reading failed!\r\n");
  }
  else
  {
    DEBUG_printString( "\n\nNAND reading was successful!\r\n" );
  }
}
Beispiel #2
0
void main( void )
{
  Uint32 status;

  // Init memory alloc pointer to start of DDR heap
  UTIL_setCurrMemPtr(0);

  // System init
  if (DEVICE_init() !=E_PASS)
  {
    exit();
  }

  // Execute the NOR flashing
  status = norwriter();

  if (status != E_PASS)
  {
    DEBUG_printString("\tNOR flashing failed!\r\n");
  }
  else
  {
    DEBUG_printString("\tNOR boot preparation was successful!\r\n" );
  }
}
Beispiel #3
0
Uint32 PCIBOOT_copy()
{
  Uint32 bootComplete = 0;
  int *entry_point = (int *)0x00017ffc;

  //===================================================
  // Clear Boot Complete Flag
  //===================================================
  SYSTEM->BOOTSTAT &= ~0x1;

  DEBUG_printString("\r\nBooting via PCI Boot Mode\r\n");

  //===================================================
  // Wait Boot Complete Flag become to '1'
  //===================================================
  bootComplete = 0;
  while(!bootComplete)
  {
    bootComplete = (SYSTEM->BOOTSTAT & 0x1);
    DEBUG_printString(".");
  }

  DEBUG_printString("\r\n");

  /* Set the entry point */
  gEntryPoint = *entry_point;  	

  return E_PASS;
}
void main( void )
{
  int status;

  // Init memory alloc pointer
  UTIL_setCurrMemPtr(0);

  // System init
  if (DEVICE_init() !=E_PASS)
  {
    exit();
  }

  // Execute the NAND flashing
  status = nandwriter();

  if (status != E_PASS)
  {
    DEBUG_printString("\n\nNAND flashing failed!\r\n");
  }
  else
  {
    DEBUG_printString( "\n\nNAND boot preparation was successful!\r\n" );
  }
}
Beispiel #5
0
static Uint32 LOCAL_boot(void)
{
  DEVICE_BootMode bootMode;
  
  // Read boot mode 
  bootMode = DEVICE_bootMode();
    
  if (bootMode == DEVICE_BOOTMODE_UART)
  {
    // Wait until the RBL is done using the UART. 
    while((UART0->LSR & 0x40) == 0 );
  }

  // Platform Initialization
  DEVICE_init();

  // Set RAM pointer to beginning of RAM space
  UTIL_setCurrMemPtr(0);

  // Send some information to host
  DEBUG_printString("TI SLT Version: ");
  DEBUG_printString(SLT_VERSION_STRING);
  DEBUG_printString("\r\nBooting Catalog Boot Loader\r\nBootMode = ");
  
  // Select Boot Mode
  switch(bootMode)
  {
    case DEVICE_BOOTMODE_UART:
    {
      //Report Bootmode to host
      DEBUG_printString("UART\r\n");
    }
    default:
    {
      UARTBOOT_copy();
      break;
    }
  }
    
  UART_sendString("   DONE", TRUE);
  
  UTIL_waitLoop(10000);

  DEVICE_TIMER0Stop();

  return E_PASS;    
}
Beispiel #6
0
static Uint32 LOCAL_spiwriter()
{
  SPI_MEM_InfoHandle hSpiMemInfo;

  Int8	fileName[256];
  Uint32  baseAddress = 0;
  Bool  useHeaderForApp = FALSE;

  DEBUG_printString( "Starting ");
  DEBUG_printString( (String) devString);
  DEBUG_printString( " SPIWriter.\r\n");
  
  // Prep device for SPI writing (pinmux/PSC)
  DEVICE_SPIInit(DEVICE_SPIBOOT_PERIPHNUM);
  
  // Initialize SPI Memory Device
  hSpiMemInfo = SPI_MEM_open(DEVICE_SPIBOOT_PERIPHNUM, DEVICE_SPIBOOT_CSNUM, hDEVICE_SPI_config);
  if (hSpiMemInfo == NULL)
  {
    DEBUG_printString( "\tERROR: SPI Memory Initialization failed.\r\n" );
    return E_FAIL;
  }
  
  DEBUG_printString("Will you be writing a UBL image? (Y or y) \r\n");
  DEBUG_readString(fileName);
  fflush(stdin);

  if ((strcmp(fileName,"y") == 0) || (strcmp(fileName,"Y") == 0))
  {
    // Read the AIS file from host
    DEBUG_printString("Enter the binary AIS UBL file name (enter 'none' to skip): \r\n");
    DEBUG_readString(fileName);
    fflush(stdin);
    
    LOCAL_GetAndWriteFileData(hSpiMemInfo, fileName, baseAddress, FALSE);
    
    // Assume that the UBL will fit in the first block of the SPI flash
    baseAddress += hSpiMemInfo->hMemParams->blockSize;
    useHeaderForApp = TRUE;
  }

  // Read the AIS file from host
  DEBUG_printString("Enter the application file name (enter 'none' to skip): \r\n");
  DEBUG_readString(fileName);
  fflush(stdin);
  
  if (LOCAL_GetAndWriteFileData(hSpiMemInfo, fileName, baseAddress, useHeaderForApp) != E_PASS)
  {
    DEBUG_printString("SPI Flashing Failed!");
    return E_FAIL;
  }
  
  return E_PASS;
}
Beispiel #7
0
static Uint32 LOCAL_recvHeaderAndData(UARTBOOT_HeaderHandle ackHeader)
{
  Uint32 error = E_FAIL, recvLen;

  // Recv ACK command
  error = UART_checkSequence("    ACK", TRUE);
  if(error != E_PASS)
  {
    return E_FAIL;
  }

  // Get the ACK header elements
  error =  UART_recvHexData( 4, (Uint32 *) &(ackHeader->magicNum)     );
  error |= UART_recvHexData( 4, (Uint32 *) &(ackHeader->startAddr) );
  error |= UART_recvHexData( 4, (Uint32 *) &(ackHeader->byteCnt)  );
  error |= UART_checkSequence("0000", FALSE);
  if(error != E_PASS)
  {
    return E_FAIL;
  }

  // Verify that the data size is appropriate
  if((ackHeader->byteCnt == 0) || (ackHeader->byteCnt > APP_IMAGE_SIZE))
  {
    LOCAL_sendSequence(" BADCNT");  // trailing /0 will come along
      return E_FAIL;
  }

  // Verify application start address is in RAM (lower 16bit of appStartAddr also used 
  // to hold UBL entry point if this header describes a UBL)
  if( (ackHeader->startAddr < DEVICE_DDR2_START_ADDR) || (ackHeader->startAddr > DEVICE_DDR2_END_ADDR) )
  {
    LOCAL_sendSequence("BADADDR");  // trailing /0 will come along
    return E_FAIL;
  }

  // Send BEGIN command
  if (LOCAL_sendSequence("  BEGIN") != E_PASS)
    return E_FAIL;

  // Receive the data over UART
  recvLen = ackHeader->byteCnt;
  error = UART_recvStringN((String)(ackHeader->loadAddr), &recvLen, FALSE );
  if ( (error != E_PASS) || (recvLen != ackHeader->byteCnt) )
  {
    DEBUG_printString("\r\nUART Receive Error\r\n");
    return E_FAIL;
  }

  // Return DONE when all data arrives
  if ( LOCAL_sendSequence("   DONE") != E_PASS )
    return E_FAIL;

  return E_PASS;
}
static Uint32 LOCAL_NAND_verifyPage(Uint8 *writeBuf, Uint8 *readBuf, Uint32 numBytes)
{
  Uint32 i = 0;
  for (i=0; i<numBytes; i++)
  {  
    if (writeBuf[i] != readBuf[i])
    {
      DEBUG_printString("Data Verify failed!");
      return E_FAIL;
    }
  }
  return E_PASS;
}
Beispiel #9
0
Uint32 UARTBOOT_copy(void)
{
  UARTBOOT_HeaderObj  ackHeader;
  Uint32              bootCmd;

UART_tryAgain:
  DEBUG_printString("Starting UART Boot...\r\n");

  // UBL Sends 'BOOTUBL/0'
  if (LOCAL_sendSequence("BOOTUBL") != E_PASS)
    goto UART_tryAgain;

  // Receive the BOOT command
  if(LOCAL_recvCommand(&bootCmd) != E_PASS)
    goto UART_tryAgain;

  switch(bootCmd)
  {
    // Only used for doing simple boot of UART
    case UBL_MAGIC_SAFE:
    {
      if (LOCAL_sendSequence("SENDAPP") != E_PASS)
        goto UART_tryAgain;
      if (LOCAL_recvHeaderAndData(&ackHeader) != E_PASS)
        goto UART_tryAgain;
      gEntryPoint = ackHeader.startAddr;
      break;
    }
    default:
    {
      DEBUG_printString("Boot command not supported!");
      return E_FAIL;
    }
  }

  return E_PASS;
}
Beispiel #10
0
static Uint32 LOCAL_boot(void)
{
  DEVICE_BootMode bootMode;

  // Read boot mode 
  bootMode = DEVICE_bootMode();
  
  if (bootMode == DEVICE_BOOTMODE_UART)
  {
    // Wait until the RBL is done using the UART. 
    while((UART0->LSR & 0x40) == 0 );
  }

  // Platform Initialization
  if ( DEVICE_init() != E_PASS )
  {
    DEBUG_printString(devString);
    DEBUG_printString(" initialization failed!\r\n");
    asm(" MOV PC, #0");
  }
  else
  {
    DEBUG_printString(devString);
    DEBUG_printString(" initialization passed!\r\n");
  }

  // Set RAM pointer to beginning of RAM space
  UTIL_setCurrMemPtr(0);

  // Send some information to host
  DEBUG_printString("TI SFT Version: ");
  DEBUG_printString(SFT_VERSION_STRING);
  DEBUG_printString("\r\nBooting Catalog Serial Flasher\r\n");
  
  // Perform UART boot (always assume UART boot since this is only used for serial flashing)
  UARTBOOT_copy();
    
  DEBUG_printString("   DONE");
  
  UTIL_waitLoop(10000);

  DEVICE_TIMER0Stop();

  return E_PASS;    
}
static Uint32 nandwriter()
{
  Uint32 numPagesUBL;
  Uint32 numPagesAPP;

  NANDWRITER_Boot  gNandBoot;
  NAND_InfoHandle  hNandInfo;

  FILE	*fPtr;
  Uint8	*ublPtr, *appPtr;
  Int32	ublFileSize = 0,ublAllocSize = 0, appFileSize = 0,appAllocSize = 0;
  Int8  fileName[256];
  Int8  answer[24];
  Int32 i=0;

  DEBUG_printString("Starting DM644x_NANDWriter.\r\n");

  // Initialize NAND Flash
  hNandInfo = NAND_open((Uint32)&EMIFStart, (Uint8) DEVICE_emifBusWidth() );
  
  if (hNandInfo == NULL)
  {
    DEBUG_printString( "\tERROR: NAND Initialization failed.\r\n" );
    return E_FAIL;
  }

  // Read the file from host
  DEBUG_printString("Enter the binary UBL file Name (enter 'none' to skip) :\r\n");
  DEBUG_readString(fileName);
  fflush(stdin);

  if (strcmp(fileName,"none") != 0)
  {
	// Open an File from the hard drive
	fPtr = fopen(fileName, "rb");
	if(fPtr == NULL)
	{
      DEBUG_printString("\tERROR: File ");
      DEBUG_printString(fileName);
      DEBUG_printString(" open failed.\r\n");
      return E_FAIL;
	}

    // Read file size
    fseek(fPtr,0,SEEK_END);
    ublFileSize = ftell(fPtr);

    if(ublFileSize == 0)
    {
      DEBUG_printString("\tERROR: File read failed.. Closing program.\r\n");
      fclose (fPtr);
      return E_FAIL;
    }

    numPagesUBL = 0;
    while ( (numPagesUBL * hNandInfo->dataBytesPerPage)  < ublFileSize )
    {
      numPagesUBL++;
    }

    //We want to allocate an even number of pages.
    ublAllocSize = numPagesUBL * hNandInfo->dataBytesPerPage;

    // Setup pointer in RAM
    ublPtr = (Uint8 *) UTIL_allocMem(ublAllocSize);


    for (i=0; i<ublAllocSize; i++)
      ublPtr[i]=0x00;

    fseek(fPtr,0,SEEK_SET);

    if (ublFileSize != fread(ublPtr, 1, ublFileSize, fPtr))
    {
      DEBUG_printString("\tWARNING: File Size mismatch.\r\n");
    }

    fclose (fPtr);

    gNandBoot.magicNum    = UBL_MAGIC_SAFE;
    gNandBoot.block       = DEVICE_NAND_RBL_SEARCH_START_BLOCK;
    gNandBoot.page        = 0;
    gNandBoot.numPage     = numPagesUBL;
    gNandBoot.entryPoint  = 0x0100;       // This fixed entry point will work with the UBLs
    gNandBoot.ldAddress   = 0;            // This doesn't matter for the UBL

    if (LOCAL_writeHeaderAndData(hNandInfo,&gNandBoot,ublPtr) != E_PASS)
    {
      printf("\tERROR: Write failed.\r\n");
      return E_FAIL;
    }
  }

  // Read the file from host
  DEBUG_printString("Enter the U-boot or application file name (enter 'none' to skip):\r\n");
  DEBUG_readString(fileName);
  fflush(stdin);

  if (strcmp(fileName,"none") != 0)
  {
    // Open an File from the hard drive
    fPtr = fopen(fileName, "rb");
    if(fPtr == NULL)
    {
      DEBUG_printString("\tERROR: File ");
      DEBUG_printString(fileName);
      DEBUG_printString(" open failed.\r\n");
      return E_FAIL;
    }

    // Read file size
    fseek(fPtr,0,SEEK_END);
    appFileSize = ftell(fPtr);

    if(appFileSize == 0)
    {
      DEBUG_printString("\tERROR: File read failed.. Closing program.\r\n");
      fclose (fPtr);
      return E_FAIL;
    }

    numPagesAPP = 0;
    while ( (numPagesAPP * hNandInfo->dataBytesPerPage)  < (appFileSize) )
    {
      numPagesAPP++;
    }

    // We want to allocate an even number of pages.
    appAllocSize = numPagesAPP * hNandInfo->dataBytesPerPage;
     
    // Setup pointer in RAM
    appPtr = (Uint8 *) UTIL_allocMem(appAllocSize);

    fseek(fPtr,0,SEEK_SET);

    if (appFileSize != fread(appPtr, 1, appFileSize, fPtr))
    {
      DEBUG_printString("\tWARNING: File Size mismatch\n");
    }

    fclose(fPtr);

    // Get the entry point and load addresses
    DEBUG_printString("Enter the U-boot or application entry point (in hex): \n");
    DEBUG_readString(answer);
    gNandBoot.entryPoint = strtoul(answer, NULL, 16);
    fflush(stdin);

    if ( (gNandBoot.entryPoint < DEVICE_DDR2_START_ADDR) || (gNandBoot.entryPoint >= DEVICE_DDR2_END_ADDR) )
    {
      DEBUG_printString("\tWARNING: Entry point not in acceptable range - using default 0x81080000.\r\n");
      gNandBoot.entryPoint = 0x81080000;
    }
    else
    {
      DEBUG_printString("Selected entry point is ");
      DEBUG_printHexInt(gNandBoot.entryPoint);
      DEBUG_printString("\r\n");
    }

    DEBUG_printString("Enter the U-boot or application load address (in hex): \r\n");
    DEBUG_readString(answer);
    gNandBoot.ldAddress = strtoul(answer, NULL, 16);

    if ( (gNandBoot.ldAddress < DEVICE_DDR2_START_ADDR) || (gNandBoot.ldAddress >= DEVICE_DDR2_END_ADDR) )
    {
      DEBUG_printString("\tWARNING: Load address not in acceptable range - using default 0x81080000.\r\n");
      gNandBoot.ldAddress = 0x81080000;
    }

    gNandBoot.magicNum = UBL_MAGIC_BIN_IMG;
    gNandBoot.block = DEVICE_NAND_UBL_SEARCH_START_BLOCK;
    gNandBoot.page = 0;
    gNandBoot.numPage = numPagesAPP;

    if (LOCAL_writeHeaderAndData(hNandInfo, &gNandBoot, appPtr) != E_PASS)
    {
      DEBUG_printString("\tERROR: Write Failed\n");
      return E_FAIL;
    }
  }

  return E_PASS;
}
// Generic function to write a UBL or Application header and the associated data
static Uint32 LOCAL_writeData(NAND_InfoHandle hNandInfo, Uint8 *srcBuf, Uint32 totalPageCnt)
{
  Uint32    blockNum,pageNum,pageCnt;
  Uint32    numBlks;
  Uint32    i;
  Uint8     *dataPtr;

  gNandTx = (Uint8 *) UTIL_allocMem(NAND_MAX_PAGE_SIZE);
  gNandRx = (Uint8 *) UTIL_allocMem(NAND_MAX_PAGE_SIZE);

  for (i=0; i<NAND_MAX_PAGE_SIZE; i++)  
  {
    gNandTx[i]=0xff;
	  gNandRx[i]=0xff;
  }	
	
  // Get total number of blocks needed
  numBlks = 0;
  while ( (numBlks*hNandInfo->pagesPerBlock)  < totalPageCnt )
  {
    numBlks++;
  }
  DEBUG_printString("Number of blocks needed for data: ");
  DEBUG_printHexInt(numBlks);
  DEBUG_printString("\r\n");

  // Start in block 1 (leave block 0 alone)
  blockNum = 1;

  // Unprotect all blocks of the device
	if (NAND_unProtectBlocks(hNandInfo, blockNum, (hNandInfo->numBlocks-1)) != E_PASS)
	{
		blockNum++;
		DEBUG_printString("Unprotect failed.\r\n");
    return E_FAIL;
	}

  while (blockNum < hNandInfo->numBlocks)
  {
    // Find first good block
    while (NAND_badBlockCheck(hNandInfo,blockNum) != E_PASS)
    {
      blockNum++;
    }

    // Erase the current block
    NAND_eraseBlocks(hNandInfo,blockNum,1);

	  // Start writing in page 0 of current block
    pageNum = 0;
    pageCnt = 0;

    // Setup data pointer
    dataPtr = srcBuf;

    // Start page writing loop
    do
    {
      DEBUG_printString((Uint8 *)"Writing image data to block ");
      DEBUG_printHexInt(blockNum);
      DEBUG_printString((Uint8 *)", page ");
      DEBUG_printHexInt(pageNum);
      DEBUG_printString((Uint8 *)"\r\n");

		  // Write the AIS image data to the NAND device
      if (NAND_writePage(hNandInfo, blockNum,  pageNum, dataPtr) != E_PASS)
      {
        DEBUG_printString("Write failed. Marking block as bad...\n");
        NAND_reset(hNandInfo);
        NAND_badBlockMark(hNandInfo,blockNum);
        dataPtr -=  pageNum * hNandInfo->dataBytesPerPage;
        blockNum++;
		    continue;
      }
    
      UTIL_waitLoop(200);
		
      // Verify the page just written
      if (NAND_verifyPage(hNandInfo, blockNum, pageNum, dataPtr, gNandRx) != E_PASS)
      {
        DEBUG_printString("Verify failed. Marking block as bad...\n");
        NAND_reset(hNandInfo);
        NAND_badBlockMark(hNandInfo,blockNum);
        dataPtr -=  pageNum * hNandInfo->dataBytesPerPage;
        blockNum++;
		    continue;
      }
		
      pageNum++;
      pageCnt++;
      dataPtr +=  hNandInfo->dataBytesPerPage;
  
      if (pageNum == hNandInfo->pagesPerBlock)
      {
        // A block transition needs to take place; go to next good block
        do
        {
          blockNum++;
        }
        while (NAND_badBlockCheck(hNandInfo,blockNum) != E_PASS);

        // Erase the current block
        NAND_eraseBlocks(hNandInfo,blockNum,1);

        pageNum = 0;
		  }
	  } while (pageCnt < totalPageCnt);

    NAND_protectBlocks(hNandInfo);
    break;
  }
  return E_PASS;
}
Beispiel #13
0
static Uint32 norwriter()
{
  NOR_InfoHandle hNorInfo;

  FILE	*fPtr;
  Uint8	*appPtr;
  Int32	appFileSize = 0;
  Int8	fileName[256];
  Uint32  baseAddress = 0;

  DEBUG_printString( "Starting NORWriter.\r\n");

  // Initialize NOR Flash
  hNorInfo = NOR_open((Uint32)&NORStart, (Uint8)DEVICE_emifBusWidth() );
  if (hNorInfo == NULL)
  {
    DEBUG_printString( "\tERROR: NOR Initialization failed.\r\n" );
    return E_FAIL;
  }

  // Set base address to start putting data at
  baseAddress = hNorInfo->flashBase;

  // Read the UBL file from host
  DEBUG_printString("Enter the binary AIS application file name (enter 'none' to skip): \r\n");

#ifndef INPUT_FILE
  DEBUG_readString(fileName);
  fflush(stdin);
#else
  strcpy(fileName, "../../../../../proj/ais/tcas_decoder.ais");
#endif
  
  if (strcmp(fileName,"none") != 0)
  {
    // Open an File from the hard drive
    fPtr = fopen(fileName, "rb");
    if(fPtr == NULL)
    {
      DEBUG_printString("\tERROR: File ");
      DEBUG_printString(fileName);
      DEBUG_printString(" open failed.\r\n");
      return E_FAIL;
    }

    // Initialize the pointer
    appFileSize = 0;

    // Read file size
    fseek(fPtr,0,SEEK_END);
    appFileSize = ftell(fPtr);

    // Check to make sure image was read correctly
    if(appFileSize == 0)
    {
      DEBUG_printString("\tERROR: File read failed.\r\n");
      fclose (fPtr);
      return E_FAIL;
    }
    // Check to make sure the app image will fit 
    else if ( appFileSize > hNorInfo->flashSize )
    {
      DEBUG_printString("\tERROR: File too big.. Closing program.\r\n");
      fclose (fPtr);
    }

    // Setup pointer in RAM
    appPtr = (Uint8 *) UTIL_allocMem(appFileSize);

    fseek(fPtr,0,SEEK_SET);

    if (appFileSize != fread(appPtr, 1, appFileSize, fPtr))
    {
      DEBUG_printString("\tWARNING: File Size mismatch.\r\n");
    }

    fclose (fPtr);

    // Erase the NOR flash to accomadate the file size
    if (NOR_erase( hNorInfo, baseAddress, appFileSize ) != E_PASS)
    {
      DEBUG_printString("\tERROR: Erasing NOR failed.\r\n");
      return E_FAIL;
    }

    // Write the application data to the flash
    if (NOR_writeBytes( hNorInfo, baseAddress, appFileSize, (Uint32)appPtr) != E_PASS)
    {
      DEBUG_printString("\tERROR: Writing NOR failed.\r\n");
      return E_FAIL;
    }
  }
  return E_PASS;
}
static Uint32 nandreader_ROM()
{

#if (1)
  Uint32 i,j, status;
  NAND_InfoHandle  hNandInfo = &gMyNandInfo;
#else
  Uint32 numPagesUBL;
  Uint32 numPagesAPP;

  Uint32 status;

  NANDWRITER_Boot  gNandBoot;
  NAND_InfoHandle  hNandInfo = &gMyNandInfo;

  FILE	*fPtr;
  Uint8	*ublPtr, *appPtr;
  Int32	ublFileSize = 0,ublAllocSize = 0, appFileSize = 0,appAllocSize = 0;
  Int8  fileName[256];
  Int8  answer[24];
#endif

  DEBUG_printString("Starting NANDReader_ROM.\r\n");

  // Initialize NAND Flash (ROM init routine)
  status = NANDInit();
  
  if (status != E_PASS)
  {
    DEBUG_printString( "\tERROR: NAND Initialization failed.\r\n" );
    return E_FAIL;
  }

  hNandInfo->dataBytesPerPage = NANDFLASH_PAGESIZE(gNandInfo.page_size);
  hNandInfo->CSOffset = 0;
  hNandInfo->busWidth = (gNandInfo.nand_width==0)?BUS_8BIT:BUS_16BIT;
  hNandInfo->dataBytesPerOp = 512;
  hNandInfo->devID = gNandInfo.dev_code;
  hNandInfo->flashBase = 0x02000000;
  hNandInfo->spareBytesPerOp = 16;
  hNandInfo->pagesPerBlock = 0x1 << (gNandInfo.blk_shift - gNandInfo.page_shift);
  hNandInfo->isLargePage = gNandInfo.big_block;
  hNandInfo->numColAddrBytes = gNandInfo.page_shift >> 3;
  hNandInfo->numRowAddrBytes = gNandInfo.addr_cycles - hNandInfo->numColAddrBytes;

#if (0)
  // Read the file from host
  DEBUG_printString("Enter the binary UBL file Name (enter 'none' to skip) :\r\n");
  DEBUG_readString(fileName);
  fflush(stdin);

  if (strcmp(fileName,"none") != 0)
  {
	  // Open an File from the hard drive
	  fPtr = fopen(fileName, "rb");
	  if(fPtr == NULL)
	  {
      DEBUG_printString("\tERROR: File ");
      DEBUG_printString(fileName);
      DEBUG_printString(" open failed.\r\n");
      return E_FAIL;
	  }

    // Read file size
    fseek(fPtr,0,SEEK_END);
    ublFileSize = ftell(fPtr);

    if(ublFileSize == 0)
    {
      DEBUG_printString("\tERROR: File read failed.. Closing program.\r\n");
      fclose (fPtr);
      return E_FAIL;
    }

    numPagesUBL = 0;
    while ( (numPagesUBL *  hNandInfo->dataBytesPerPage)  < ublFileSize )
    {
      numPagesUBL++;
    }

    //We want to allocate an even number of pages.
    ublAllocSize = numPagesUBL *  hNandInfo->dataBytesPerPage;

    // Setup pointer in RAM
    ublPtr = (Uint8 *) UTIL_allocMem(ublAllocSize);


    for (i=0; i<ublAllocSize; i++)
      ublPtr[i]=0x00;

    fseek(fPtr,0,SEEK_SET);

    if (ublFileSize != fread(ublPtr, 1, ublFileSize, fPtr))
    {
      DEBUG_printString("\tWARNING: File Size mismatch.\r\n");
    }

    fclose (fPtr);

    gNandBoot.magicNum    = UBL_MAGIC_SAFE;
    gNandBoot.block       = DEVICE_NAND_RBL_SEARCH_START_BLOCK;
    gNandBoot.page        = 0;
    gNandBoot.numPage     = numPagesUBL;
    gNandBoot.entryPoint  = 0x0100;       // This fixed entry point will work with the UBLs
    gNandBoot.ldAddress   = 0;            // This doesn't matter for the UBL

    if (LOCAL_readHeaderAndData(hNandInfo,&gNandBoot,ublPtr) != E_PASS)
    {
      printf("\tERROR: Read failed.\r\n");
      return E_FAIL;
    }
  }

  // Read the file from host
  DEBUG_printString("Enter the U-boot or application file name (enter 'none' to skip):\r\n");
  DEBUG_readString(fileName);
  fflush(stdin);

  if (strcmp(fileName,"none") != 0)
  {
    // Open an File from the hard drive
    fPtr = fopen(fileName, "rb");
    if(fPtr == NULL)
    {
      DEBUG_printString("\tERROR: File ");
      DEBUG_printString(fileName);
      DEBUG_printString(" open failed.\r\n");
      return E_FAIL;
    }

    // Read file size
    fseek(fPtr,0,SEEK_END);
    appFileSize = ftell(fPtr);

    if(appFileSize == 0)
    {
      DEBUG_printString("\tERROR: File read failed.. Closing program.\r\n");
      fclose (fPtr);
      return E_FAIL;
    }

    numPagesAPP = 0;
    while ( (numPagesAPP * hNandInfo->dataBytesPerPage)  < (appFileSize) )
    {
      numPagesAPP++;
    }

    // We want to allocate an even number of pages.
    appAllocSize = numPagesAPP * hNandInfo->dataBytesPerPage;
     
    // Setup pointer in RAM
    appPtr = (Uint8 *) UTIL_allocMem(appAllocSize);

    fseek(fPtr,0,SEEK_SET);

    if (appFileSize != fread(appPtr, 1, appFileSize, fPtr))
    {
      DEBUG_printString("\tWARNING: File Size mismatch\n");
    }

    fclose(fPtr);

    // Get the entry point and load addresses
    DEBUG_printString("Enter the U-boot or application entry point (in hex): \n");
    DEBUG_readString(answer);
    gNandBoot.entryPoint = strtoul(answer, NULL, 16);
    fflush(stdin);

    if ( (gNandBoot.entryPoint < DEVICE_DDR2_START_ADDR) || (gNandBoot.entryPoint >= DEVICE_DDR2_END_ADDR) )
    {
      DEBUG_printString("\tWARNING: Entry point not in acceptable range - using default 0x81080000.\r\n");
      gNandBoot.entryPoint = 0x81080000;
    }
    else
    {
      DEBUG_printString("Selected entry point is ");
      DEBUG_printHexInt(gNandBoot.entryPoint);
      DEBUG_printString("\r\n");
    }

    DEBUG_printString("Enter the U-boot or application load address (in hex): \r\n");
    DEBUG_readString(answer);
    gNandBoot.ldAddress = strtoul(answer, NULL, 16);

    if ( (gNandBoot.ldAddress < DEVICE_DDR2_START_ADDR) || (gNandBoot.ldAddress >= DEVICE_DDR2_END_ADDR) )
    {
      DEBUG_printString("\tWARNING: Load address not in acceptable range - using default 0x81080000.\r\n");
      gNandBoot.ldAddress = 0x81080000;
    }

    gNandBoot.magicNum = UBL_MAGIC_BIN_IMG;
    gNandBoot.block = DEVICE_NAND_UBL_SEARCH_START_BLOCK;
    gNandBoot.page = 0;
    gNandBoot.numPage = numPagesAPP;

    if (LOCAL_readHeaderAndData(hNandInfo, &gNandBoot, appPtr) != E_PASS)
    {
      DEBUG_printString("\tERROR: Write Failed\n");
      return E_FAIL;
    }
  }
#else
  for (i = 1; i <= 5; i++)
  { 
    for (j=0; j < hNandInfo->pagesPerBlock; j++)
    {

      DEBUG_printString("Block ");
      DEBUG_printHexInt(i);
      DEBUG_printString(", Page ");
      DEBUG_printHexInt(j);

      if (NANDReadPage(i,j,gNandRx) != E_PASS)
      {
        DEBUG_printString("\r\n\tRead failed\r\n");
        break;
      }

      DEBUG_printString("\r\n\t1st Word = ");
      DEBUG_printHexInt(((Uint32 *)gNandRx)[0]);
      DEBUG_printString("\r\n\t2nd Word = ");
      DEBUG_printHexInt(((Uint32 *)gNandRx)[1]);
      DEBUG_printString("\r\n\t3rd Word = ");
      DEBUG_printHexInt(((Uint32 *)gNandRx)[2]);
      DEBUG_printString("\r\n\t4th Word = ");
      DEBUG_printHexInt(((Uint32 *)gNandRx)[3]);
      DEBUG_printString("\r\n");
    }
  }
#endif

  return E_PASS;
}
Beispiel #15
0
static Uint32 LOCAL_GetAndWriteFileData(SPI_MEM_InfoHandle hSpiMemInfo, String fileName, Uint32 destAddr, Bool useHeader)
{
  FILE	*fPtr;
  Uint8	*appPtr, *appPtr2;
  Int32	fileSize = 0;
  SPI_MEM_BOOT_HeaderObj spiMemBoot;

  if (strcmp(fileName,"none") != 0)
  {
    // Open an File from the hard drive
    fPtr = fopen(fileName, "rb");
    if(fPtr == NULL)
    {
      DEBUG_printString("\tERROR: File ");
      DEBUG_printString(fileName);
      DEBUG_printString(" open failed.\r\n");
      return E_FAIL;
    }

    // Initialize the pointer
    fileSize = 0;

    // Read file size
    fseek(fPtr,0,SEEK_END);
    fileSize = ftell(fPtr);

    // Check to make sure image was read correctly
    if(fileSize == 0)
    {
      DEBUG_printString("\tERROR: File read failed.\r\n");
      fclose (fPtr);
      return E_FAIL;
    }
    // Check to make sure the app image will fit 
    else if ( fileSize > hSpiMemInfo->hMemParams->memorySize )
    {
      DEBUG_printString("\tERROR: File too big.. Closing program.\r\n");
      fclose (fPtr);
      exit(0);
    }

    // Setup pointer in RAM
    appPtr = (Uint8 *) UTIL_allocMem(fileSize);

    fseek(fPtr,0,SEEK_SET);

    if (fileSize != fread(appPtr, 1, fileSize, fPtr))
    {
      DEBUG_printString("\tWARNING: File Size mismatch.\r\n");
    }

    fclose (fPtr);
    
    DEBUG_printString("\tINFO: File read complete.\r\n");
    
    if (useHeader)
    {
      Uint8 *tempPtr = (Uint8 *) UTIL_allocMem(fileSize + sizeof(SPI_MEM_BOOT_HeaderObj));
      DEBUG_printString("Enter the app image load address (in hex): \r\n");
      DEBUG_readHexInt(&(spiMemBoot.ldAddress));  
      DEBUG_printString("Enter the app image entry point address (in hex): \r\n");
      DEBUG_readHexInt(&(spiMemBoot.entryPoint));

      spiMemBoot.appSize = fileSize;
      spiMemBoot.magicNum = UBL_MAGIC_BINARY_BOOT;
      spiMemBoot.memAddress = destAddr + sizeof(SPI_MEM_BOOT_HeaderObj); 
      
      UTIL_memcpy(tempPtr, &spiMemBoot, sizeof(SPI_MEM_BOOT_HeaderObj));
      tempPtr += sizeof(SPI_MEM_BOOT_HeaderObj);
      UTIL_memcpy(tempPtr, appPtr, fileSize);
      fileSize += sizeof(SPI_MEM_BOOT_HeaderObj);
      appPtr = tempPtr;
      appPtr -= sizeof(SPI_MEM_BOOT_HeaderObj);
    }
    
    // Create spare buffer for erase and write verify
    appPtr2 = (Uint8 *) UTIL_allocMem(fileSize);

    // Erase the SPI flash to accomodate the file size
    if (SPI_MEM_eraseBytes( hSpiMemInfo, destAddr, fileSize ) != E_PASS)
    {
      DEBUG_printString("\tERROR: Erasing SPI failed.\r\n");
      return E_FAIL;
    }
    
    // Verify the SPI was actually erased
    if (SPI_MEM_verifyErase(hSpiMemInfo, destAddr, fileSize, appPtr2) != E_PASS)
    {
      DEBUG_printString("\tERROR: Verifying SPI data failed.\r\n");
      return E_FAIL;
    }
    
    // Make copy of the file data to compare against after the write
    memcpy(appPtr2, appPtr, fileSize);

    // Write the application data to the flash (note that writes are destructive)
    if (SPI_MEM_writeBytes( hSpiMemInfo, destAddr, fileSize, appPtr) != E_PASS)
    {
      DEBUG_printString("\tERROR: Writing SPI failed.\r\n");
      return E_FAIL;
    }

    // Verify the memory contents 
    if (SPI_MEM_verifyBytes(hSpiMemInfo, destAddr, fileSize, appPtr2, appPtr) != E_PASS)
    {
      DEBUG_printString("\tERROR: Verifying SPI data failed.\r\n");
      return E_FAIL;
    }
  }
  return E_PASS;
}
Beispiel #16
0
static Uint32 LOCAL_NANDWriteHeaderAndData(NAND_InfoHandle hNandInfo, NANDBOOT_HeaderHandle nandBoot, Uint8 *srcBuf)
{
    Uint32    endBlockNum;
    Uint32    *ptr;
    Uint32    blockNum,pageNum,pageCnt,i;
    Uint32    numBlks;

    Uint8     *hNandWriteBuf,*hNandReadBuf;

    // Allocate mem for write and read buffers
    hNandWriteBuf = UTIL_allocMem(hNandInfo->dataBytesPerPage);
    hNandReadBuf  = UTIL_allocMem(hNandInfo->dataBytesPerPage);

    // Clear buffers
    for (i=0; i < hNandInfo->dataBytesPerPage; i++)
    {
        hNandWriteBuf[i] = 0xFF;
        hNandReadBuf[i] = 0xFF;
    }

    // Get total number of blocks needed
    numBlks = 0;
    while ( (numBlks * hNandInfo->pagesPerBlock)  < (nandBoot->numPage + 1) )
    {
        numBlks++;
    }
    DEBUG_printString("Number of blocks needed for header and data: 0x");
    DEBUG_printHexInt(numBlks);
    DEBUG_printString("\r\n");

    // Check whether writing UBL or APP (based on destination block)
    blockNum = nandBoot->block;
    if (blockNum == DEVICE_NAND_RBL_SEARCH_START_BLOCK)
        endBlockNum = DEVICE_NAND_RBL_SEARCH_END_BLOCK;
    else if (blockNum == DEVICE_NAND_UBL_SEARCH_START_BLOCK)
        endBlockNum = DEVICE_NAND_UBL_SEARCH_END_BLOCK;
    else
        return E_FAIL; // Block number is out of range

NAND_WRITE_RETRY:
    if (blockNum > endBlockNum)
        return E_FAIL;

    // Go to first good block
    if (NAND_badBlockCheck(hNandInfo,blockNum) != E_PASS)
    {
        blockNum++;
        goto NAND_WRITE_RETRY;
    }

    DEBUG_printString("Attempting to start in block number 0x");
    DEBUG_printHexInt(blockNum);
    DEBUG_printString(".\n");

    // Unprotect all needed blocks of the Flash
    if (NAND_unProtectBlocks(hNandInfo,blockNum,numBlks) != E_PASS)
    {
        blockNum++;
        DEBUG_printString("Unprotect failed\r\n");
        goto NAND_WRITE_RETRY;
    }

    // Erase the block where the header goes and the data starts
    if (NAND_eraseBlocks(hNandInfo,blockNum,numBlks) != E_PASS)
    {
        blockNum++;
        DEBUG_printString("Erase failed\r\n");
        goto NAND_WRITE_RETRY;
    }

    // Setup header to be written
    ptr = (Uint32 *) hNandWriteBuf;
    ptr[0] = nandBoot->magicNum;
    ptr[1] = nandBoot->entryPoint;
    ptr[2] = nandBoot->numPage;
    ptr[3] = blockNum;  //always start data in current block
    ptr[4] = 1;      //always start data in page 1 (this header goes in page 0)
    ptr[5] = nandBoot->ldAddress;

    // Write the header to page 0 of the current blockNum
    DEBUG_printString("Writing header data to Block ");
    DEBUG_printHexInt(blockNum);
    DEBUG_printString(", Page ");
    DEBUG_printHexInt(0);
    DEBUG_printString("\r\n");

    if (NAND_writePage(hNandInfo, blockNum, 0, hNandWriteBuf) != E_PASS)
    {
        blockNum++;
        DEBUG_printString("Write failed!\r\n");
        goto NAND_WRITE_RETRY;
    }

    UTIL_waitLoop(200);

    // Verify the page just written
    if (NAND_verifyPage(hNandInfo, blockNum, 0, hNandWriteBuf, hNandReadBuf) != E_PASS)
    {
        blockNum++;
        DEBUG_printString("Write verify failed!\r\n");
        goto NAND_WRITE_RETRY;
    }

    pageCnt = 1;
    pageNum = 1;

    do
    {
        DEBUG_printString("Writing image data to Block ");
        DEBUG_printHexInt(blockNum);
        DEBUG_printString(", Page ");
        DEBUG_printHexInt(pageNum);
        DEBUG_printString("\r\n");

        // Write the UBL or APP data on a per page basis
        if (NAND_writePage(hNandInfo, blockNum, pageNum, srcBuf) != E_PASS)
        {
            blockNum++;
            DEBUG_printString("Write failed!\r\n");
            goto NAND_WRITE_RETRY;
        }

        UTIL_waitLoop(200);

        // Verify the page just written
        if (NAND_verifyPage(hNandInfo, blockNum, pageNum, srcBuf, hNandReadBuf) != E_PASS)
        {
            blockNum++;
            DEBUG_printString("Write verify failed!\r\n");
            goto NAND_WRITE_RETRY;
        }

        srcBuf += hNandInfo->dataBytesPerPage;
        pageCnt++;
        pageNum++;

        if (pageNum == hNandInfo->pagesPerBlock)
        {
            blockNum++;
            pageNum = 0;
        }

    }
    while (pageCnt < (nandBoot->numPage+1));

    NAND_protectBlocks(hNandInfo);

    return E_PASS;
}
Beispiel #17
0
void main(void)
{
  Uint8       regValue;

  // Init the memory alloc routines
  UTIL_setCurrMemPtr(0);

  // System init
  if (DEVICE_init() != E_PASS)
  {
    DEBUG_printString("Device initialization failed.\r\n");
    return;
  }

  // Give some time for I2C bus to settle (power-supply issue?)
  UTIL_waitLoop(4000000);

  // Make sure our board and chip can read the NOR via EMIF
  if (I2C_ECP_write(I2C_ECP_VMX_REG,0x20) != E_PASS)
  {
    DEBUG_printString("Write to ECP EMIF/VP control register has failed.\r\n");
    return;
  }
  DEVICE_pinmuxControl( 0, DEVICE_PINMUX_EMIF_MASK, DEVICE_PINMUX_EMIF_EN );


  // Start body of UBL
  DEBUG_printString("Starting UBL - ");
  DEBUG_printString(UBL_FLASH_TYPE); 
  DEBUG_printString(" Flash, v");
  DEBUG_printString( UBL_VERSION_STRING );
  DEBUG_printString("\r\n");

  // Find and copy the application image from the NOR flash
  if (NORBOOT_copy() != E_PASS)
  {
    DEBUG_printString( "\tERROR: Application boot failed.\r\n" );
    return;
  }
  
  // Modify board-level and chip-level settings to prep for application run

  // Set board-level muxes for video ports
  if (I2C_ECP_write(I2C_ECP_VMX_REG,0x44) != E_PASS)
  {
    DEBUG_printString("Write to ECP VP control register appears to have failed.");
    return;
  }

  // Set video port capture clocks for SD capture
  if (I2C_ECP_write(I2C_ECP_CMD_REG,0x08) != E_PASS)
  {
    DEBUG_printString("Write to ECP command register appears to have failed.");
    return;
  }

  // Set board-level muxes for audio codecs(AIC33s)
  if (I2C_ECP_write(I2C_ECP_McASP_MUX_CTRL_REG,0x19) != E_PASS)
  {
    DEBUG_printString("Write to ECP McASP control register appears to have failed.");
    return;
  }

  // Do one read to force the last write to complete
  I2C_ECP_read(I2C_ECP_McASP_MUX_CTRL_REG,&regValue);

  DEBUG_printString("Board-level setup complete.\r\n");


  // Set chip-level pin muxes for audio ports
  DEVICE_pinmuxControl( 0,
                        DEVICE_PINMUX_MCASP_MASK,
                        DEVICE_PINMUX_MCASP_EN );
  // Set chip-level pin muxes for video ports
  DEVICE_pinmuxControl( 0,
                        DEVICE_PINMUX_VP0_MASK  |
                        DEVICE_PINMUX_VP1_MASK  |
                        DEVICE_PINMUX_VP34_MASK |
                        DEVICE_PINMUX_VP2_MASK,
                        DEVICE_PINMUX_VP0_EN  |
                        DEVICE_PINMUX_VP1_EN  |
                        DEVICE_PINMUX_VP34_EN |
                        DEVICE_PINMUX_VP2_EN );

  DEBUG_printString("Chip-level setup complete.\r\n");

  // Pass control to the entry point in RAM
  DEBUG_printString("Passing control to entry point at ");
  DEBUG_printHexInt(gEntryPoint);
  DEBUG_printString(".\r\n");
  bootFunction = (AIS_fxnPtr) gEntryPoint;
  (*bootFunction)();
}
static Uint32 nandwriter()
{
  Uint32 numPagesAIS;

  NAND_InfoHandle  hNandInfo;

  FILE	*fPtr;
  Uint8	*aisPtr;
  Int32	aisFileSize = 0,aisAllocSize = 0;
  Int8  fileName[256];
  Int32 i=0;

  DEBUG_printString("Starting OMAP-L137 NANDWriter.\r\n");

  // Initialize NAND Flash
  hNandInfo = NAND_open((Uint32)&NANDStart, DEVICE_emifBusWidth() );
  
  if (hNandInfo == NULL)
  {
    DEBUG_printString( "\tERROR: NAND Initialization failed.\r\n" );
    return E_FAIL;
  }

  // Read the file from host
  DEBUG_printString("Enter the binary AIS file name to flash (enter 'none' to skip) :\r\n");
  DEBUG_readString(fileName);
	fflush(stdin);

  if (strcmp(fileName,"none") != 0)
  {
	  // Open an File from the hard drive
	  fPtr = fopen(fileName, "rb");
	  if(fPtr == NULL)
	  {
      DEBUG_printString("\tERROR: File ");
      DEBUG_printString(fileName);
      DEBUG_printString(" open failed.\r\n");
		  return E_FAIL;
	  }

    // Read file size
    fseek(fPtr,0,SEEK_END);
    aisFileSize = ftell(fPtr);

    if(aisFileSize == 0)
    {
      DEBUG_printString("\tERROR: File read failed.. Closing program.\r\n");
      fclose (fPtr);
      return E_FAIL;
	  }

	  numPagesAIS = 0;
	  while ( (numPagesAIS * hNandInfo->dataBytesPerPage)  < aisFileSize )
	  {
		  numPagesAIS++;
	  }

    //We want to allocate an even number of pages.
    aisAllocSize = numPagesAIS * hNandInfo->dataBytesPerPage;

    // Setup pointer in RAM
    aisPtr = (Uint8 *) UTIL_allocMem(aisAllocSize);

    // Clear memory
	  for (i=0; i<aisAllocSize; i++)
	    aisPtr[i]=0xFF;

    // Go to start of file
    fseek(fPtr,0,SEEK_SET);

    // Read file data
    if (aisFileSize != fread(aisPtr, 1, aisFileSize, fPtr))
    {
      DEBUG_printString("\tWARNING: File Size mismatch.\r\n");
    }

    // Close file
	  fclose (fPtr);

    // Write the file data to the NAND flash
	  if (LOCAL_writeData(hNandInfo, aisPtr, numPagesAIS) != E_PASS)
	  {
		  printf("\tERROR: Write failed.\r\n");
		  return E_FAIL;
	  }

  }



	return E_PASS;
}
// Generic function to write a UBL or Application header and the associated data
static Uint32 LOCAL_writeHeaderAndData(NAND_InfoHandle hNandInfo, NANDWRITER_Boot *nandBoot, Uint8 *srcBuf)
{
  Uint32    endBlockNum;
  Uint32    *headerPtr;
  Uint32    blockNum;
  Uint32    count;
  Uint32    countMask;
  Uint32    numBlks;
  Uint32    pageNum;
  Uint32    i;
  Uint8     *dataPtr;


  gNandTx = (Uint8 *) UTIL_allocMem(NAND_MAX_PAGE_SIZE);
  gNandRx = (Uint8 *) UTIL_allocMem(NAND_MAX_PAGE_SIZE);

  for (i=0; i<NAND_MAX_PAGE_SIZE; i++)  
  {
    gNandTx[i]=0xff;
    gNandRx[i]=0xff;
  }  
  
  // Get total number of blocks needed
  numBlks = 0;
  while ( (numBlks * hNandInfo->pagesPerBlock)  < (nandBoot->numPage + 1) )
  {
    numBlks++;
  }
  DEBUG_printString("Number of blocks needed for header and data: ");
  DEBUG_printHexInt(numBlks);
  DEBUG_printString("\r\n");

  // Check whether writing UBL or APP (based on destination block)
  blockNum = nandBoot->block;
  if (blockNum == DEVICE_NAND_RBL_SEARCH_START_BLOCK)
  {
    endBlockNum = DEVICE_NAND_RBL_SEARCH_END_BLOCK;
  }
  else if (blockNum == DEVICE_NAND_UBL_SEARCH_START_BLOCK)
  {
    endBlockNum = DEVICE_NAND_UBL_SEARCH_END_BLOCK;
  }
  else
  {
    // Block number is out of range
    return E_FAIL; 
  }

NAND_WRITE_RETRY:
  if (blockNum > endBlockNum)
  {
    return E_FAIL;
  }
  DEBUG_printString("Attempting to start write in block number ");
  DEBUG_printHexInt(blockNum);
  DEBUG_printString(".\r\n");

  // Unprotect all needed blocks of the Flash 
  if (NAND_unProtectBlocks(hNandInfo,blockNum,numBlks) != E_PASS)
  {
    blockNum++;
    DEBUG_printString("Unprotect failed.\r\n");
    goto NAND_WRITE_RETRY;
  }
  
  // Setup header to be written
  headerPtr = (Uint32 *) gNandTx;
  headerPtr[0] = nandBoot->magicNum;          //Magic Number
  headerPtr[1] = nandBoot->entryPoint;        //Entry Point
  headerPtr[2] = nandBoot->numPage;           //Number of Pages
  headerPtr[3] = blockNum;                    //Starting Block Number 
  headerPtr[4] = 1;                           //Starting Page Number - always start data in page 1 (this header goes in page 0)

  if ( (blockNum>=DEVICE_NAND_RBL_SEARCH_START_BLOCK) &&  (blockNum <= DEVICE_NAND_RBL_SEARCH_END_BLOCK) )
  {
    headerPtr[5] = 0;                           //nandBoot->ldAddress;  
  }
  else if ( (blockNum>=DEVICE_NAND_UBL_SEARCH_START_BLOCK) &&  (blockNum<=DEVICE_NAND_UBL_SEARCH_END_BLOCK) )
  {
    headerPtr[5] = nandBoot->ldAddress;         //nandBoot->ldAddress;
  }
  else
  {
    // Block number is out of range
    return E_FAIL; 
  }
  pageNum = 0;
    
  // Erase the block where the header goes and the data starts
  if (NAND_eraseBlocks(hNandInfo,blockNum,numBlks) != E_PASS)
  {
    blockNum++;
    DEBUG_printString("Erase failed\n");
    goto NAND_WRITE_RETRY;
  }

  DEBUG_printString("Writing header data to Block ");
  DEBUG_printHexInt(blockNum);
  DEBUG_printString(", Page ");
  DEBUG_printHexInt(pageNum);
  DEBUG_printString("\r\n");

  if (NAND_writePage(hNandInfo, blockNum, pageNum, gNandTx) != E_PASS)
  {
    blockNum++;
    DEBUG_printString("Write failed\n");
    NAND_reset(hNandInfo);
    goto NAND_WRITE_RETRY;
  }
    
  UTIL_waitLoop(200);

  // Verify the page just written
  if (NAND_verifyPage(hNandInfo, blockNum, pageNum, gNandTx, gNandRx) != E_PASS)
  {
    DEBUG_printString("Verify failed. Attempting to clear page\n");
    NAND_reset(hNandInfo);
    NAND_eraseBlocks(hNandInfo,blockNum,numBlks);
    
    blockNum++;
    NAND_reset(hNandInfo);

    goto NAND_WRITE_RETRY;
  }

  // Start writing in page 1 of current block (header was in page 0)
  count = 1;

  // The following assumes power of 2 pagesPerBlock -  *should* always be valid 
  countMask = (Uint32) hNandInfo->pagesPerBlock - 1;
  dataPtr = srcBuf;

  do
  {
    DEBUG_printString((Uint8 *)"Writing image data to Block ");
    DEBUG_printHexInt(blockNum);
    DEBUG_printString((Uint8 *)", Page ");
    DEBUG_printHexInt(count & countMask);
    DEBUG_printString((Uint8 *)"\r\n");

    // Write the UBL or APP data on a per page basis
    if (NAND_writePage(hNandInfo, blockNum,  (count & countMask), dataPtr) != E_PASS)
    {
      blockNum++;
      DEBUG_printString("Write failed\n");
      goto NAND_WRITE_RETRY;
    }
    
    UTIL_waitLoop(200);
    
    // Verify the page just written
    if (NAND_verifyPage(hNandInfo, blockNum, (count & countMask), dataPtr, gNandRx) != E_PASS)
    {
      DEBUG_printString("Verify failed. Attempting to clear page\n");
      NAND_reset(hNandInfo);
      NAND_eraseBlocks(hNandInfo,blockNum,numBlks);
      blockNum++;
      goto NAND_WRITE_RETRY;
    }
    
    count++;
    dataPtr +=  hNandInfo->dataBytesPerPage;
    if (!(count & countMask))
    {
      do
      {
        blockNum++;
      }
      while (NAND_badBlockCheck(hNandInfo,blockNum) != E_PASS);
    }
  } while (count <= nandBoot->numPage);

  NAND_protectBlocks(hNandInfo);

  return E_PASS;
}
Uint32 UARTBOOT_copy(void)
{

#if defined(UBL_NAND)
  NANDBOOT_HeaderObj  nandBoot;
  NAND_InfoHandle     hNandInfo;
#elif defined(UBL_NOR)
  NORBOOT_HeaderObj   norBoot;
  NOR_InfoHandle      hNorInfo;
#endif  
  UARTBOOT_HeaderObj  ackHeader;
  Uint32              bootCmd;

UART_tryAgain:
  DEBUG_printString("Starting UART Boot...\r\n");

  // UBL Sends 'BOOTUBL/0'
  if (LOCAL_sendSequence("BOOTUBL") != E_PASS)
    goto UART_tryAgain;

  // Receive the BOOT command
  if(LOCAL_recvCommand(&bootCmd) != E_PASS)
    goto UART_tryAgain;
    
  // Send ^^^DONE\0 to indicate command was accepted
  if ( LOCAL_sendSequence("   DONE") != E_PASS )
    goto UART_tryAgain;

  switch(bootCmd)
  {
#if defined(UBL_NOR)
    case UBL_MAGIC_NOR_FLASH_NO_UBL:
    {
      // Initialize the NOR Flash
      hNorInfo = NOR_open((Uint32)&EMIFStart, (Uint8)DEVICE_emifBusWidth());
      if (hNorInfo == NULL)
      {
        DEBUG_printString("NOR_open() failed!");
        goto UART_tryAgain;    
      }
    
      // Get the APP (should be u-boot) into binary form
      if ( LOCAL_recvHeaderAndData(&ackHeader) != E_PASS )
        goto UART_tryAgain;
      
      // Erasing the Flash
      if ( NOR_erase(hNorInfo,hNorInfo->flashBase, ackHeader.byteCnt) != E_PASS )
        goto UART_tryAgain;

      // Write the actual application to the flash
      if ( NOR_writeBytes(hNorInfo,hNorInfo->flashBase, ackHeader.byteCnt, (Uint32)ackHeader.imageBuff) != E_PASS )
        goto UART_tryAgain;
          
      // Return DONE when UBL flash operation has been completed
      if ( LOCAL_sendSequence("   DONE") != E_PASS )
        return E_FAIL;

      // Set the entry point for code execution
      gEntryPoint = hNorInfo->flashBase;
      break;
    }
    case UBL_MAGIC_NOR_FLASH:
    {
      Uint32 blockSize, blockAddr;
    
      // Initialize the NAND Flash
      hNorInfo = NOR_open((Uint32)&EMIFStart, (Uint8)DEVICE_emifBusWidth());
      if ( hNorInfo ==  NULL )
      {
        DEBUG_printString("NOR_open() failed!");
        goto UART_tryAgain;
      }
    
      // ------ Get UBL Data and Write it to Flash ------       
      // Get the UBL header and data
      if (LOCAL_recvHeaderAndData(&ackHeader) != E_PASS)
        goto UART_tryAgain;

      // Erasing the Flash
      if ( NOR_erase(hNorInfo,hNorInfo->flashBase, ackHeader.byteCnt) != E_PASS )
        goto UART_tryAgain;
	        
      // Write the UBL data to the start of the NOR flash
      DEBUG_printString("Writing UBL to NOR flash\r\n");
      if (NOR_writeBytes(hNorInfo,hNorInfo->flashBase, ackHeader.byteCnt, (Uint32)ackHeader.imageBuff) != E_PASS )
        goto UART_tryAgain;
          
      // Return DONE when UBL flash operation has been completed
      if ( LOCAL_sendSequence("   DONE") != E_PASS )
        return E_FAIL;
        
      // Get block size and base of block where UBL was written
      NOR_getBlockInfo(hNorInfo,hNorInfo->flashBase+ackHeader.byteCnt,&blockSize,&blockAddr);

      // Get the application header and data
      if (LOCAL_recvHeaderAndData(&ackHeader) != E_PASS)
        goto UART_tryAgain;
        
      // Setup the NORBOOT header that will be stored in flash
      norBoot.magicNum = ackHeader.magicNum;
      norBoot.entryPoint = ackHeader.startAddr;
      norBoot.appSize = ackHeader.byteCnt;
      norBoot.ldAddress = ackHeader.loadAddr;

      // Erasing the Flash
      if ( NOR_erase(hNorInfo,(blockAddr + blockSize), (ackHeader.byteCnt + sizeof(NORBOOT_HeaderObj))) != E_PASS )
        goto UART_tryAgain;
	        
      // Write the NORBOOT header to the flash
      DEBUG_printString("Writing APP to NOR flash\r\n");
      if (NOR_writeBytes(hNorInfo,(blockAddr + blockSize), sizeof(NORBOOT_HeaderObj), (Uint32)&norBoot) != E_PASS )
        goto UART_tryAgain;
      
      // Write the application data to the flash
      if ( NOR_writeBytes(hNorInfo,(blockAddr + blockSize + sizeof(NORBOOT_HeaderObj)), norBoot.appSize, (Uint32)ackHeader.imageBuff) != E_PASS )
        goto UART_tryAgain;
          
      // Return DONE when UBL flash operation has been completed
      if ( LOCAL_sendSequence("   DONE") != E_PASS )
        return E_FAIL;

      // Set the entry point to nowhere, since there isn't an appropriate binary image to run */
      gEntryPoint = 0x0;
      break;
    }  
    case UBL_MAGIC_NOR_ERASE:
    {
      // Initialize the NOR Flash
      hNorInfo = NOR_open((Uint32)&EMIFStart, (Uint8)DEVICE_emifBusWidth()) ;
      if (hNorInfo == NULL)
      {
        DEBUG_printString("NOR_open() failed!");
        goto UART_tryAgain;    
      }

      // Erasing the Flash
      if (NOR_globalErase(hNorInfo) != E_PASS)
      {
        DEBUG_printString("\r\nErase failed.\r\n");
      }
      else
      {
        DEBUG_printString("\r\nErase completed successfully.\r\n");
      }
      
      // Return DONE when erase operation has been completed
      if ( LOCAL_sendSequence("   DONE") != E_PASS )
        return E_FAIL;

      // Set the entry point for code execution
      // Go to reset in this case since no code was downloaded
      gEntryPoint = 0x0; 

      break;
    }
#elif defined(UBL_NAND)
    case UBL_MAGIC_NAND_FLASH:
    {
      Uint32 i;
    
      // Initialize the NAND Flash
      hNandInfo = NAND_open((Uint32)&EMIFStart, (Uint8) DEVICE_emifBusWidth() );
      if ( hNandInfo ==  NULL )
      {
        DEBUG_printString("NAND_open() failed!");
        goto UART_tryAgain;
      }
      
      // Allocate mem for write and read buffers (only once)
      hNandWriteBuf = UTIL_allocMem(hNandInfo->dataBytesPerPage);
      hNandReadBuf  = UTIL_allocMem(hNandInfo->dataBytesPerPage);
     	trvx(hNandWriteBuf); 
     	trvx(hNandReadBuf); 
      // Clear buffers
      for (i=0; i < hNandInfo->dataBytesPerPage; i++)
      {
        hNandWriteBuf[i] = 0xFF;
        hNandReadBuf[i] = 0xFF;
      }
    
      // ------ Get UBL Data and Write it to Flash ------       
      // Get the UBL header and data
      if (LOCAL_recvHeaderAndData(&ackHeader) != E_PASS)
        goto UART_tryAgain;
       
      // Setup fixed elements of the NANDBOOT header that will be stored in flash for UBL
      nandBoot.magicNum = ackHeader.magicNum;
      nandBoot.entryPoint = ackHeader.startAddr;
      nandBoot.page = 1;                          // The page is always page 0 for the UBL header, so we use page 1 for data        
      nandBoot.ldAddress = ackHeader.loadAddr;    // This field doesn't matter for the UBL header      
      nandBoot.forceContigImage = TRUE;
      nandBoot.startBlock = DEVICE_NAND_RBL_SEARCH_START_BLOCK;
      nandBoot.endBlock = DEVICE_NAND_RBL_SEARCH_END_BLOCK;
        
      // Calculate the number of NAND pages needed to store the UBL image
      nandBoot.numPage = 0;
      while ( (nandBoot.numPage * hNandInfo->dataBytesPerPage) < (ackHeader.byteCnt))
      {
        nandBoot.numPage++;
      }     
        
      // Write multiple copies of the UBL to the appropriate RBL search blocks
      DEBUG_printString("Writing UBL to NAND flash\r\n");
      if (LOCAL_NANDWriteHeaderAndData(hNandInfo, &nandBoot, ackHeader.imageBuff) != E_PASS)
      {
        DEBUG_printString("Writing failed!");
        goto UART_tryAgain;
      }
              
      // Return DONE when UBL flash operation has been completed
      if ( LOCAL_sendSequence("   DONE") != E_PASS )
        return E_FAIL;

      // ------ Get Application Data and Write it to Flash ------       
      // Get the application header and data
      if (LOCAL_recvHeaderAndData(&ackHeader) != E_PASS)
        goto UART_tryAgain;
      
      // Setup fixed elements of the NANDBOOT header that will be stored in flash for APP
      nandBoot.magicNum         = ackHeader.magicNum;         // Rely on the host applciation to send over the right magic number (safe or bin)
      nandBoot.entryPoint       = ackHeader.startAddr;      // Use the entrypoint received in ACK header
      nandBoot.page             = 1;                              // The page is always page 0 for the header, so we use page 1 for data
      nandBoot.ldAddress        = ackHeader.loadAddr;        // The load address is only important if this is a binary image
      nandBoot.forceContigImage = FALSE;
      nandBoot.startBlock       = DEVICE_NAND_UBL_SEARCH_START_BLOCK;
      nandBoot.endBlock         = DEVICE_NAND_UBL_SEARCH_END_BLOCK;      
      
      // Calculate the number of NAND pages needed to store the APP image
      nandBoot.numPage = 0;
      while ( (nandBoot.numPage * hNandInfo->dataBytesPerPage) < ackHeader.byteCnt )
      {
        nandBoot.numPage++;
      }

      // Write multiple copies of the APP to the appropriate UBL search blocks
      DEBUG_printString("Writing APP to NAND flash\r\n");
      if (LOCAL_NANDWriteHeaderAndData(hNandInfo, &nandBoot, ackHeader.imageBuff) != E_PASS)
      {
        DEBUG_printString("Writing failed!");
        goto UART_tryAgain;
      }

      // Return DONE when UBL flash operation has been completed
      if ( LOCAL_sendSequence("   DONE") != E_PASS )
        return E_FAIL;

      // Set the entry point to nowhere, since there isn't an appropriate binary image to run */
      gEntryPoint = 0x0;
      break;
    }  
    case UBL_MAGIC_NAND_ERASE:
    {
      // Initialize the NAND Flash
      hNandInfo = NAND_open((Uint32)&EMIFStart, (Uint8) DEVICE_emifBusWidth() );
      if ( hNandInfo ==  NULL )
      {
        DEBUG_printString("NAND_open() failed!");
        goto UART_tryAgain;
      }   

      // Unprotect the NAND Flash
      NAND_unProtectBlocks(hNandInfo, DEVICE_NAND_RBL_SEARCH_START_BLOCK, DEVICE_NAND_UBL_SEARCH_END_BLOCK-1);

      // Erase all the pages of the device
      if (NAND_eraseBlocks(hNandInfo, DEVICE_NAND_RBL_SEARCH_START_BLOCK, DEVICE_NAND_UBL_SEARCH_END_BLOCK-1) != E_PASS)
      {
        DEBUG_printString("Erase failed.\r\n");
        goto UART_tryAgain;
      }
      else
      {
        DEBUG_printString("Erase completed successfully.\r\n");
      }
                  
      // Protect the device
      NAND_protectBlocks(hNandInfo);
      
      // Return DONE when erase operation has been completed
      if ( LOCAL_sendSequence("   DONE") != E_PASS )
        return E_FAIL;

      // Set the entry point for code execution
      // Go to reset in this case since no code was downloaded 
      gEntryPoint = 0x0; 
      break;
    }
#elif defined(UBL_SDMMC)
    case UBL_MAGIC_SDMMC_FLASH:
    {
      break;
    }
    case UBL_MAGIC_SDMMC_ERASE:
    {
      break;
    }
#endif
    default:
    {
      DEBUG_printString("Boot command not supported!");
      return E_FAIL;
    }
  }
  
  LOCAL_sendSequence("   DONE");

  return E_PASS;
}
Uint32 LOCAL_NANDWriteHeaderAndData(NAND_InfoHandle hNandInfo, NANDBOOT_HeaderHandle hNandBoot, Uint8 *srcBuf)
{
	Uint32    *ptr;
	Uint32    currBlockNum,currPageNum,pageCnt,i;
	Uint32    numBlks, numBlksRemaining;
	trl_();
	trvx_(hNandBoot->startBlock);
	trvx(hNandBoot->endBlock);
	trvx(srcBuf);
	hNandWriteBuf = UTIL_allocMem(hNandInfo->dataBytesPerPage);
	hNandReadBuf = UTIL_allocMem(hNandInfo->dataBytesPerPage);
	extern __FAR__ Uint32 EXTERNAL_RAM_START, EXTERNAL_RAM_END;
	trvx(&EXTERNAL_RAM_START); 
	trvx(hNandWriteBuf);
	trvx(hNandReadBuf);
	// Unprotect all needed blocks of the flash 
	if (NAND_unProtectBlocks(hNandInfo,hNandBoot->startBlock,hNandBoot->endBlock-hNandBoot->startBlock+1) != E_PASS)
	{
		DEBUG_printString("Unprotect failed\r\n");
		return E_FAIL;
	}

	// Check if device is write protected
	if (NAND_isWriteProtected(hNandInfo))
	{
		DEBUG_printString("NAND is write protected!\r\n");
		return E_FAIL;
	}

	// Get total number of blocks needed for each copy
	numBlks = 0;
	while ( (numBlks * hNandInfo->pagesPerBlock)  < (hNandBoot->numPage + 1) )
	{
		numBlks++;
	}
	DEBUG_printString("Number of blocks needed for header and data: 0x");
	DEBUG_printHexInt(numBlks);
	DEBUG_printString("\r\n");

	// Init internal current block number counter
	currBlockNum = hNandBoot->startBlock; 

	// Go to first good block
	while (NAND_badBlockCheck(hNandInfo,currBlockNum) != E_PASS)
	{
		DEBUG_printString("NAND block ");
		DEBUG_printHexInt(currBlockNum);
		DEBUG_printString(" is bad!!!\r\n");
		currBlockNum++;
		// Now check to make sure we aren't already out of space
		if (currBlockNum > (hNandBoot->endBlock + numBlks - 1 ))
		{
			DEBUG_printString("No good blocks in allowed range!!!\r\n");
			return E_FAIL;
		}
	}

	DEBUG_printString("Attempting to start in block number 0x");
	DEBUG_printHexInt(currBlockNum);
	DEBUG_printString(".\r\n");

	// Keep going while we have room to place another copy
	do
	{
		numBlksRemaining = numBlks;

		// Erase the block where the header goes and the data starts
		if (NAND_eraseBlocks(hNandInfo,currBlockNum,numBlks) != E_PASS)
		{
			// Attempt to mark block bad
			NAND_badBlockMark(hNandInfo, currBlockNum);
			currBlockNum++;
			DEBUG_printString("Erase failed\r\n");
			continue;
		}
		trl();  
		// Clear write buffer
		ptr = (Uint32 *) hNandWriteBuf;
		for (i=0; i < hNandInfo->dataBytesPerPage >> 2; i++)
		{
			ptr[i] = 0xFFFFFFFF;
		}
		trl();  

		// Setup header to be written
		ptr[0] = hNandBoot->magicNum;
		ptr[1] = hNandBoot->entryPoint;
		ptr[2] = hNandBoot->numPage;
		ptr[3] = currBlockNum;  //always start data in current block
		ptr[4] = 1;      //always start data in page 1 (this header goes in page 0)
		ptr[5] = hNandBoot->ldAddress;

		// Write the header to page 0 of the current blockNum
		DEBUG_printString("Writing header and image data to Block ");
		DEBUG_printHexInt(currBlockNum);
		DEBUG_printString(", Page ");
		DEBUG_printHexInt(0);
		DEBUG_printString("\r\n");
		trl();  

#ifdef DM35X_REVB
#define DM35X_REVC
#endif

#ifdef DM35X_REVC
		if (NAND_writePage_ubl_header(hNandInfo, currBlockNum, 0, hNandWriteBuf) != E_PASS)
		{
			// Attempt to mark block bad
			NAND_badBlockMark(hNandInfo, currBlockNum);
			currBlockNum++;
			DEBUG_printString("Write failed!\r\n");
			continue;
		}
#else
		if (NAND_writePage(hNandInfo, currBlockNum, 0, hNandWriteBuf) != E_PASS)
		{
			// Attempt to mark block bad
			NAND_badBlockMark(hNandInfo, currBlockNum);
			currBlockNum++;
			DEBUG_printString("Write failed!\r\n");
			continue;
		}
#endif

		UTIL_waitLoop(200);

		// Verify the page just written
		if (NAND_verifyPage(hNandInfo, currBlockNum, 0, hNandWriteBuf, hNandReadBuf) != E_PASS)
		{
			// Attempt to mark block bad
			NAND_badBlockMark(hNandInfo, currBlockNum);
			currBlockNum++;
			DEBUG_printString("Write verify failed!\r\n");
			continue;
		}

		pageCnt = 1;
		currPageNum = 1;
		do
		{
			// Write the UBL or APP data on a per page basis
			if (NAND_writePage(hNandInfo, currBlockNum, currPageNum, srcBuf) != E_PASS)
			{
				// Attempt to mark block bad
				NAND_badBlockMark(hNandInfo, currBlockNum);
				currBlockNum++;
				DEBUG_printString("Write failed, skipping block!\r\n");
				if ( (numBlksRemaining == numBlks) || (hNandBoot->forceContigImage) )
					break;    // If we are still in the first block, we have to go rewrite the header too
				else
				{
					srcBuf -= (hNandInfo->dataBytesPerPage * currPageNum);
					trvx(srcBuf);
					pageCnt -= currPageNum;
					currPageNum = 0;        
					continue;
				}
			}

			UTIL_waitLoop(200);

			// Verify the page just written
			if (NAND_verifyPage(hNandInfo, currBlockNum, currPageNum, srcBuf, hNandReadBuf) != E_PASS)
			{
				// Attempt to mark block bad
				NAND_badBlockMark(hNandInfo, currBlockNum);
				currBlockNum++;
				DEBUG_printString(RED"Write verify failed, skipping block!\r\n"NOCOLOR);
				if ( (numBlksRemaining == numBlks) || (hNandBoot->forceContigImage) )
					break;    // If we are still in the first block, we have to go rewrite the header too
				else
				{
					srcBuf -= (hNandInfo->dataBytesPerPage * currPageNum);
					trvx(srcBuf);
					pageCnt -= currPageNum;
					currPageNum = 0;
					continue;
				}
			}

			srcBuf += hNandInfo->dataBytesPerPage;
			pageCnt++;
			currPageNum++;

			// If we need to go the next block, or our image is complete, increment current block num
			if ( (currPageNum == hNandInfo->pagesPerBlock) || (pageCnt >= (hNandBoot->numPage+1)) )
			{
				trvi(currPageNum);
				currBlockNum++;
				numBlksRemaining--;
				srcBuf -= hNandInfo->dataBytesPerPage * currPageNum;
				currPageNum = 0;
			}
		}
		while ( (pageCnt < (hNandBoot->numPage+1)) && ((currBlockNum + numBlksRemaining - 1)<=hNandBoot->endBlock) );
		trvi(pageCnt);
	} 
	while( (currBlockNum + numBlks - 1)<=hNandBoot->endBlock );

	// Protect all blocks
	NAND_protectBlocks(hNandInfo);

	// We succeeded in writing all copies that would fit
	return E_PASS;
}
Beispiel #22
0
Uint32 UARTBOOT_copy(void)
{

#if defined(UBL_NAND)
    NANDBOOT_HeaderObj  nandBoot;
    NAND_InfoHandle     hNandInfo;
#elif defined(UBL_NOR)
    NOR_InfoHandle      hNorInfo;
#endif
    UARTBOOT_HeaderObj  ackHeader;
    Uint32              bootCmd;

UART_tryAgain:
    DEBUG_printString("Starting UART Boot...\r\n");

    // UBL Sends 'BOOTUBL/0'
    if (LOCAL_sendSequence("BOOTUBL") != E_PASS)
        goto UART_tryAgain;

    // Receive the BOOT command
    if(LOCAL_recvCommand(&bootCmd) != E_PASS)
        goto UART_tryAgain;

    // Send ^^^DONE\0 to indicate command was accepted
    if ( LOCAL_sendSequence("   DONE") != E_PASS )
        goto UART_tryAgain;

    switch(bootCmd)
    {
#if defined(UBL_NOR)
    case UBL_MAGIC_NOR_BIN_BURN:
    {
        // Initialize the NOR Flash
        hNorInfo = NOR_open((Uint32)&EMIFStart, (Uint8)DEVICE_emifBusWidth()) ;
        if (hNorInfo == NULL)
        {
            DEBUG_printString("NOR_open() failed!");
            goto UART_tryAgain;
        }

        // Get the APP (should be u-boot) into binary form
        if ( LOCAL_recvHeaderAndData(&ackHeader) != E_PASS )
            goto UART_tryAgain;

        // Erasing the Flash
        if ( NOR_erase(hNorInfo,hNorInfo->flashBase, ackHeader.byteCnt) != E_PASS )
            goto UART_tryAgain;

        // Write the actual application to the flash
        if ( NOR_writeBytes(hNorInfo,hNorInfo->flashBase, ackHeader.byteCnt, (Uint32)ackHeader.imageBuff) != E_PASS )
            goto UART_tryAgain;

        // Return DONE when UBL flash operation has been completed
        if ( LOCAL_sendSequence("   DONE") != E_PASS )
            return E_FAIL;

        // Set the entry point for code execution
        gEntryPoint = hNorInfo->flashBase;
        break;
    }
    case UBL_MAGIC_NOR_GLOBAL_ERASE:
    {
        // Initialize the NOR Flash
        hNorInfo = NOR_open((Uint32)&EMIFStart, (Uint8)DEVICE_emifBusWidth()) ;
        if (hNorInfo == NULL)
        {
            DEBUG_printString("NOR_open() failed!");
            goto UART_tryAgain;
        }

        // Erasing the Flash
        if (NOR_globalErase(hNorInfo) != E_PASS)
        {
            DEBUG_printString("\r\nErase failed.\r\n");
        }
        else
        {
            DEBUG_printString("\r\nErase completed successfully.\r\n");
        }

        // Return DONE when erase operation has been completed
        if ( LOCAL_sendSequence("   DONE") != E_PASS )
            return E_FAIL;

        // Set the entry point for code execution
        // Go to reset in this case since no code was downloaded
        gEntryPoint = 0x0;

        break;
    }
#elif defined(UBL_NAND)
    case UBL_MAGIC_NAND_BIN_BURN:
    {
        // Initialize the NAND Flash
        hNandInfo = NAND_open((Uint32)&EMIFStart);
        if ( hNandInfo ==  NULL )
        {
            DEBUG_printString("NAND_open() failed!");
            goto UART_tryAgain;
        }

        // ------ Get UBL Data and Write it to Flash ------
        // Get the UBL header and data
        if (LOCAL_recvHeaderAndData(&ackHeader) != E_PASS)
            goto UART_tryAgain;

        // Setup the NANDBOOT header that will be stored in flash
        nandBoot.magicNum = ackHeader.magicNum;
        nandBoot.entryPoint = ackHeader.startAddr;
        nandBoot.page = 1;                          // The page is always page 0 for the UBL header, so we use page 1 for data
        nandBoot.block = DEVICE_NAND_RBL_SEARCH_START_BLOCK;       // Set starting block to begin the write attempts
        nandBoot.ldAddress = ackHeader.loadAddr;    // This field doesn't matter for the UBL header

        // Calculate the number of NAND pages needed to store the UBL image
        nandBoot.numPage = 0;
        while ( (nandBoot.numPage * hNandInfo->dataBytesPerPage) < (ackHeader.byteCnt))
        {
            nandBoot.numPage++;
        }

        // Write header to page 0 of block 1(or up to block 5)
        // Write the UBL to the same block, starting at page 1
        DEBUG_printString("Writing UBL to NAND flash\r\n");
        if (LOCAL_NANDWriteHeaderAndData(hNandInfo, &nandBoot, ackHeader.imageBuff) != E_PASS)
            goto UART_tryAgain;

        // Return DONE when UBL flash operation has been completed
        if ( LOCAL_sendSequence("   DONE") != E_PASS )
            return E_FAIL;

        // ------ Get Application Data and Write it to Flash ------
        // Get the application header and data
        if (LOCAL_recvHeaderAndData(&ackHeader) != E_PASS)
            goto UART_tryAgain;

        // Setup the NANDBOOT header that will be stored in flash
        nandBoot.magicNum = ackHeader.magicNum;         // Rely on the host applciation to send over the right magic number (safe or bin)
        nandBoot.entryPoint = ackHeader.startAddr;      // Use the entrypoint received in ACK header
        nandBoot.page = 1;                              // The page is always page 0 for the header, so we use page 1 for data
        nandBoot.block = DEVICE_NAND_UBL_SEARCH_START_BLOCK;           // Set the starting block for application
        nandBoot.ldAddress = ackHeader.loadAddr;        // The load address is only important if this is a binary image

        // Calculate the number of NAND pages needed to store the APP image
        nandBoot.numPage = 0;
        while ( (nandBoot.numPage * hNandInfo->dataBytesPerPage) < ackHeader.byteCnt )
        {
            nandBoot.numPage++;
        }

        // Write header to page 0 of block 1(or up to block 5)
        // Write the UBL to the same block, starting at page 1
        DEBUG_printString("Writing APP to NAND flash\r\n");
        if (LOCAL_NANDWriteHeaderAndData(hNandInfo,&nandBoot, ackHeader.imageBuff) != E_PASS)
            goto UART_tryAgain;

        // Return DONE when UBL flash operation has been completed
        if ( LOCAL_sendSequence("   DONE") != E_PASS )
            return E_FAIL;

        // Set the entry point to nowhere, since there isn't an appropriate binary image to run */
        gEntryPoint = 0x0;
        break;
    }  // end case UBL_MAGIC_NAND_BIN_BURN
    case UBL_MAGIC_NAND_GLOBAL_ERASE:
    {
        // Initialize the NAND Flash
        hNandInfo = NAND_open((Uint32)&EMIFStart);
        if ( hNandInfo ==  NULL )
        {
            DEBUG_printString("NAND_open() failed!");
            goto UART_tryAgain;
        }

        // Unprotect the NAND Flash
        NAND_unProtectBlocks(hNandInfo, DEVICE_NAND_RBL_SEARCH_START_BLOCK, DEVICE_NAND_UBL_SEARCH_END_BLOCK-1);

        // Erase all the pages of the device
        if (NAND_eraseBlocks(hNandInfo, DEVICE_NAND_RBL_SEARCH_START_BLOCK, DEVICE_NAND_UBL_SEARCH_END_BLOCK-1) != E_PASS)
        {
            DEBUG_printString("Erase failed.\r\n");
            goto UART_tryAgain;
        }
        else
        {
            DEBUG_printString("Erase completed successfully.\r\n");
        }

        // Protect the device
        NAND_protectBlocks(hNandInfo);

        // Return DONE when erase operation has been completed
        if ( LOCAL_sendSequence("   DONE") != E_PASS )
            return E_FAIL;

        // Set the entry point for code execution
        // Go to reset in this case since no code was downloaded
        gEntryPoint = 0x0;
        break;
    }
#endif
    default:
    {
        DEBUG_printString("Boot command not supported!");
        return E_FAIL;
    }
    }

    LOCAL_sendSequence("   DONE");

    return E_PASS;
}
Beispiel #23
0
static Uint32 LOCAL_recvHeaderAndData(UARTBOOT_HeaderHandle ackHeader)
{
    Uint32  error = E_PASS, recvLen;
    Bool    imageIsUBL;
    Uint32  maxImageSize,minStartAddr,maxStartAddr;

    // Issue command to host to send image
    if ( LOCAL_sendSequence("SENDIMG") != E_PASS)
    {
        return E_FAIL;
    }

    // Recv ACK command
    if(UART_checkSequence("    ACK", TRUE) != E_PASS)
    {
        return E_FAIL;
    }

    // Get the ACK header elements
    error =  UART_recvHexData( 4, (Uint32 *) &(ackHeader->magicNum)  );
    error |= UART_recvHexData( 4, (Uint32 *) &(ackHeader->startAddr) );
    error |= UART_recvHexData( 4, (Uint32 *) &(ackHeader->byteCnt)   );
    error |= UART_recvHexData( 4, (Uint32 *) &(ackHeader->loadAddr)  );
    error |= UART_checkSequence("0000", FALSE);
    if(error != E_PASS)
    {
        return E_FAIL;
    }

    // Check if this is a UBL or APP image
    if (ackHeader->loadAddr == 0x00000020)
    {
        imageIsUBL = TRUE;
        maxImageSize = UBL_IMAGE_SIZE;
        minStartAddr = 0x0100;
        maxStartAddr = UBL_IMAGE_SIZE;
    }
    else
    {
        imageIsUBL = FALSE;
        maxImageSize = APP_IMAGE_SIZE;
        minStartAddr = DEVICE_DDR2_START_ADDR;
        maxStartAddr = DEVICE_DDR2_END_ADDR;
    }


    // Verify that the data size is appropriate
    if((ackHeader->byteCnt == 0) || (ackHeader->byteCnt > maxImageSize))
    {
        LOCAL_sendSequence(" BADCNT");  // trailing /0 will come along
        return E_FAIL;
    }

    // Verify application start address is in RAM (lower 16bit of appStartAddr also used
    // to hold UBL entry point if this header describes a UBL)
    if( (ackHeader->startAddr < minStartAddr) || (ackHeader->startAddr > maxStartAddr) )
    {
        LOCAL_sendSequence("BADADDR");  // trailing /0 will come along
        return E_FAIL;
    }

    // Allocate space in DDR to store image
    ackHeader->imageBuff = (Uint8 *) UTIL_allocMem(ackHeader->byteCnt);

    // Send BEGIN command
    if (LOCAL_sendSequence("  BEGIN") != E_PASS)
        return E_FAIL;

    // Receive the data over UART
    recvLen = ackHeader->byteCnt;
    error = UART_recvStringN((String)ackHeader->imageBuff, &recvLen, FALSE );
    if ( (error != E_PASS) || (recvLen != ackHeader->byteCnt) )
    {
        DEBUG_printString("\r\nUART Receive Error\r\n");
        return E_FAIL;
    }

    // Return DONE when all data arrives
    if ( LOCAL_sendSequence("   DONE") != E_PASS )
        return E_FAIL;

    return E_PASS;
}
Beispiel #24
0
Uint32 UARTBOOT_copy(UART_InfoHandle hUartInfo)
{
	Uint32 status = E_FAIL;
	Uint32 descriptor[5];
	Uint32 magicNum;
	SDMMC_Boot sdMMCBootDesc;
	SDMMC_MEM_InfoHandle hSDMMCMemInfo;
	Uint32 dataBytesPerBlk;
	Uint32 len, bytes2read;

	do
	{
		hSDMMCMemInfo = SDMMC_MEM_open(0,NULL);
		if (hSDMMCMemInfo == NULL)
		{
			DEBUG_printString("Failed to initialize MMC\r\n");
		    break;
		}
		dataBytesPerBlk = hSDMMCMemInfo->hSDMMCInfo->dataBytesPerBlk;

		// read from the UART first 5 words
		len = sizeof(descriptor);
		status = UART_recvStringN(hUartInfo, (char*)descriptor, &len, 0);
		if ((status == E_FAIL) ||(len != sizeof(descriptor)))
		{
			DEBUG_printString("Failed to read descriptor\r\n");
			break;
		}

		magicNum = descriptor[0];
		if((magicNum & 0xFFFFFF00) != (UBL_MAGIC_BIN_IMG & 0xFFFFFF00))
		{
			DEBUG_printString("Magic number failed\r\n");
			break;
		}

		sdMMCBootDesc.magicNum = magicNum;
		sdMMCBootDesc.entryPoint = descriptor[1];
		sdMMCBootDesc.numBlock = descriptor[2];
		sdMMCBootDesc.startBlock = descriptor[3];
		sdMMCBootDesc.ldAddress = descriptor[4];

		DEBUG_printString("Got descriptor\r\n");

		bytes2read = dataBytesPerBlk*sdMMCBootDesc.numBlock;
		len = bytes2read;
		status = UART_recvStringN(hUartInfo, ((char*)&DDR_START), &len, 0);
		if ((status == E_FAIL) || (len != bytes2read))
		{
			DEBUG_printString("Failed to read data to the external RAM\r\n");
			break;
		}

		// all the data is in the RAM - program the MMC
		status = SDMMC_MEM_writeBytes (hSDMMCMemInfo, dataBytesPerBlk*sdMMCBootDesc.startBlock, bytes2read, (Uint8*)&DDR_START);
		if (status == E_FAIL)
		{
			DEBUG_printString("Failed to write MMC\r\n");
			break;
		}


		status = E_PASS;

	}
	while (0);


	return status;
}
static Uint32 i2cwriter()
{
  I2C_MemInfoHandle hI2cMemInfo;

  FILE	*fPtr;
  Uint8	*appPtr;
  Int32	appFileSize = 0;
  Int8	fileName[256];
  Uint32  baseAddress = 0;

  I2C_ConfigObj i2cCfg;
  I2C_MemConfigObj i2cMemCfg;

  DEBUG_printString( "Starting I2CWriter.\r\n");

  // Initialize I2C Config
  i2cCfg.ownAddr = 0x29;
  i2cCfg.prescalar = 14;
  i2cCfg.i2cclkl = 6;
  i2cCfg.i2cclkh = 6;
  i2cCfg.addrMode = I2C_ADDRESSING_7BIT;

  // Initialize I2C Memory Config
  i2cMemCfg.i2cMemAddr = 0x50;
  i2cMemCfg.addrWidth = 16;
  i2cMemCfg.pageSize = 64;
  i2cMemCfg.memorySize = 32 *1024;

  hI2cMemInfo = I2C_MEM_open(0,&i2cCfg,&i2cMemCfg);
  if (hI2cMemInfo == NULL)
  {
    DEBUG_printString( "\tERROR: I2C Initialization failed.\r\n" );
    return E_FAIL;
  }

  // Set base address to start putting data at
  baseAddress = 0x00;

  // Read the UBL file from host
  DEBUG_printString("Enter the binary AIS application file name (enter 'none' to skip): \r\n");
  DEBUG_readString(fileName);
  fflush(stdin);

  if (strcmp(fileName,"none") != 0)
  {
    // Open an File from the hard drive
    fPtr = fopen(fileName, "rb");
    if(fPtr == NULL)
    {
      DEBUG_printString("\tERROR: File ");
      DEBUG_printString(fileName);
      DEBUG_printString(" open failed.\r\n");
      return E_FAIL;
    }

    // Initialize the pointer
    appFileSize = 0;

    // Read file size
    fseek(fPtr,0,SEEK_END);
    appFileSize = ftell(fPtr);

    // Check to make sure image was read correctly
    if(appFileSize == 0)
    {
      DEBUG_printString("\tERROR: File read failed.\r\n");
      fclose (fPtr);
      return E_FAIL;
    }
    // Check to make sure the app image will fit 
    else if ( appFileSize > hI2cMemInfo->hI2CMemCfg->memorySize)
    {
      DEBUG_printString("\tERROR: File too big.. Closing program.\r\n");
      fclose (fPtr);
    }

    // Setup pointer in RAM
    appPtr = (Uint8 *) UTIL_allocMem(appFileSize);

    fseek(fPtr,0,SEEK_SET);

    if (appFileSize != fread(appPtr, 1, appFileSize, fPtr))
    {
      DEBUG_printString("\tWARNING: File Size mismatch.\r\n");
    }

    fclose (fPtr);

    // Erase the I2C flash to accomodate the file size
#if (0)
    if (I2C_MEM_eraseBytes( hI2cMemInfo, baseAddress, appFileSize ) != E_PASS)
    {
      DEBUG_printString("\tERROR: Erasing I2C failed.\r\n");
      return E_FAIL;
    }
#endif

    {
      Uint8 *verifyBuffer = UTIL_allocMem(appFileSize);

      // Write the application data to the flash
      if (I2C_MEM_writeBytes(hI2cMemInfo, baseAddress, appFileSize, appPtr) != E_PASS)
      {
        DEBUG_printString("\tERROR: Writing I2C memory failed.\r\n");
        return E_FAIL;
      }

      if (I2C_MEM_verifyBytes(hI2cMemInfo, baseAddress, appFileSize, appPtr, verifyBuffer) != E_PASS)
      {
        DEBUG_printString("\tERROR: Verifying I2C memory failed.\r\n");
        return E_FAIL;
      }
    }
  }
  return E_PASS;
}