Beispiel #1
0
/**
 * BootLoader_State_Machine
 *
 * The state machine for the boot loader which performs certain tasks
 * based on the current state of the boot loader. The current state must
 * be changed appropriately before calling this fuction.
 *
 */
void BootLoader_State_Machine ()
{
  switch (CurrentState)
  {
    case NORMAL:
      /*FIXME Move the code from main and post the state machine*/
    break;
    case CPY_TO_BOOT:
    {
      uint8_t buffer [61];
      Read_Attribute_Value(BL_ATTR_TYP_PRIMARY_IMG_LOCATION, &GImgAddr);
      Read_Attribute_Value(BL_ATTR_TYP_PRIMARY_IMG_CRC, &GImgCrc);
      Read_Attribute_Value(BL_ATTR_TYP_PRIMARY_IMG_SIZE, &GImgSize);
      __nesc_atomic_t atomic = __nesc_atomic_start();
      if (Move_Image_To_Boot_Loc (CurrImageAddr, CurrImageSize) == FAIL)
        Reboot_Device (); 
      __nesc_atomic_end (atomic);

      TOGGLE_LED (YELLOW);

      if(Change_BootLoader_State_Attribute (SET_LOADED_TO_GOLDEN) == SUCCESS)
      {
        sprintf (buffer, "Successfully copied image to boot location.\n");
        Send_USB_Command_Packet (CMD_BOOTLOADER_MSG, 61, buffer);
        TOS_post (&BootLoader_State_Machine);
      }
      else
      {
        /**
         * If we cant switch state then its hard to determine the problem
         * So let reboot and try to recover.
         */
        sprintf (buffer, "Could not switch to SET_LOADED_TO_GOLDEN. Rebooting\n");
        Send_USB_Error_Packet (ERR_FATAL_ERROR_ABORT, 60, buffer);	   
        Reboot_Device ();
      }
    }
    break;
    case SET_LOADED_TO_GOLDEN:
    {
      uint8_t buffer [61];
      result_t ret = SUCCESS;
      /*It may not be required, but still we dont want an interrupt to stop us*/
      TOGGLE_LED (GREEN);
      __nesc_atomic_t atomic = __nesc_atomic_start();
        ret = Map_Loaded_To_Golden ();
      __nesc_atomic_end (atomic);
      TOGGLE_LED (GREEN);
      if (ret == SUCCESS)
      {
        sprintf (buffer, "Mapped Boot Image to golden. Booting New Image.\n");
        Send_USB_Command_Packet (CMD_CREATED_GOLDEN_IMG, 61, buffer);
        Reboot_Device ();
      }
      else
      {
        /* Very Bad, We dont know exactly where we failed. I Guess the
         * best way is reset the whole primary to secondary switch and
         * reboot.
         */
        sprintf (buffer, "Mark loaded to golden failed. Trying to recover\n");
        Send_USB_Error_Packet (ERR_FATAL_ERROR_ABORT, 60, buffer);
        Reboot_Device ();
      }
    }
    break;
    case SET_BOOT_TO_GOLDEN:
    {
      Change_BootLoader_State_Attribute (NORMAL);
      Reboot_Device ();
    }
    break;
    case BOOT_IMAGE:
    break;
    case CODE_LOAD:
      switch (CLoaderState)
      {
        case REQUEST_IMAGE_DETAIL:
        {
          USBCommand cmd;
          if (!MMU_ENABLED)
          {
            MMU_ENABLED = TRUE;
      	    Enable_MMU ();
          }
          cmd.type = CMD_GET_IMAGE_DETAILS;
          Send_Command_Packet (&cmd, sizeof (USBCommand));
        }
        break;
        case REQUEST_USB_PACKETS:
#ifdef MMU_ENABLE
          Request_Next_Binary_Chunk ();
#else
          Request_Next_Binary_Packet ();
#endif
          break;
        case VERIFY_CURRENT_BUFFER:
          break;
        case VERIFY_CURRENT_IMAGE:
          Send_USB_Command_Packet (CMD_IMG_UPLOAD_COMPLETE, 0, NULL);
          break;
        default:
          break;
      }
    break;
    case VERIFY_IMAGE:
    break;
    case VERIFY_SELF_TEST:
      /*Implemented in Recovery State Machine*/
    break;
    default:
      /* This is fatal, It is very essential to investigate why
       * this might have happened but at the same time we dont
       * want to panic. The best is to go back and try normal
       * operation.
       */
      CurrentState = NORMAL;
    break;
  }
}
/* ===========================================================================
 *  @func   ARM926_user_swi_handler()
 *
 *  @desc   This function is a C level SWI handler.
 *          .
 *  @param  int swi_numberNone.
 *
 *  @param  int *args - For future expansion
 *
 *  @return None
 *
 *  @note   None
 * ===========================================================================
 */
void ARM926_user_swi_handler (int swi_number, int *args)
{
    /* The SWI number is used to switch to different functions to perform
     * the desired action  */
    switch (swi_number)
    {
		case 0:
			/* Enable the MMU */
			Enable_MMU();
			break;
		case 1:
            /* Disable the MMU */
			Disable_MMU();
			break;
		case 2:
			/* Set the MMU base address */
			Set_MMU_Base(MMU_BASE);
			break;
		case 3:
			/* Set the MMU domain register to Full permission */
			Set_Domains(0xFFFFFFFF);
			break;
        case 4: 
            /* Enable the FIQ */
            enable_FIQ();
            break;
		case 5:
            /* Enable I-cache */
			Icache_Enable();
			break;
		case 6:
            /* Disable I-cache */
			Icache_Disable();
			break;
		case 7:
            /* set round robin cache replacement strategy */
			Cache_Set_RoundRobin();
			break;
		case 8:
            /* set random cache replacement strategy */
			Cache_Set_Random();
			break;
		case 9:
            /* Enable D-cache */
			Dcache_Enable();
			break;
		case 10:
            /* Disable D-cache */
			Dcache_Disable();
			break;
		case 11:
            /* Flush I-cache */
			Flush_Icache();
			break;
		case 12:
            /* Invalidate D-cache */
			Flush_Dcache();
			break;
		case 13:
            /* Clean  D-cache */
			cache_low_data_clean();
			break;
		case 14:
            /* clean and Invalidate D-cache */
			cache_low_data_clean_flush();
			break;
		default:
            break;
    } /* end switch */ 
} /* ARM926_user_swi_handler() */