//#############################################################################
//
// FILE:    boot_ex3_cpu0_secure_flash.c
//
// TITLE:   Secure Flash Boot Example
//
// VERSION: 1.0.0
//
// DATE:    2025-01-15
//
//! \addtogroup driver_example_list
//! <h1> CPU0 Secure Flash Boot </h1>
//!
//! This example demonstrates how to use the secure flash boot mode for CPU0.
//!
//! Secure flash boot performs a CMAC authentication on the entry sector of
//! flash upon device boot up. If authentication passes, the application will
//! begin execution. Learn more on the secure flash boot mode in the user manual.
//!
//! This project shows how to use the Geehy CMAC Tool to generate a CMAC Tag
//! based on a user CMAC key and embed the value into the flash application.
//! Additionally, the example details the method to call the CMAC API from
//! the user application to calculate CMAC on other flash sectors beyond the 
//! application entry flash sector.
//!
//! Determining Pass/Fail without debugger connected:
//! - LED2 LED3 off = Secure Boot failed
//! - LED2 or LED3 Blinking = Secure Boot Passed, Full Flash CMAC failed
//! - LED2 and LED3 Blinking = Secure Boot Passed and Full Flash CMAC passed
//!
//! \b External \b Connections \n
//!  - None.
//!
//! \b Watch \b Variables \n
//!  - applicationCMACStatus - 0x00 : CPU0 full flash CMAC authentication passes
//!                            0xFFFFFFFF : CPU0 full flash CMAC authentication fails
//!                            Other Value: Other error
//!
//
//###########################################################################
// $Copyright:
// Copyright (C) 2024 Geehy Semiconductor - http://www.geehy.com/
//
// You may not use this file except in compliance with the
// GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
//
// The program is only for reference, which is distributed in the hope
// that it will be useful and instructional for customers to develop
// their software. Unless required by applicable law or agreed to in
// writing, the program is distributed on an "AS IS" BASIS, WITHOUT
// ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
// See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
// and limitations under the License.
// $
//###########################################################################


//
// Included Files
//
#include "driverlib.h"
#include "device.h"
#include "board.h"
#include "SecureROMAPIs.h"

//
// Defines
//
#define CMAC_AUTH_START_ADDRESS   0x08000000UL
#define CMAC_AUTH_END_ADDRESS     0x0800A000UL

//
// Note that the location 0x08008000UL can be set to anywhere as long 
// as it is within the specified CMAC authentication memory, and it must be 
// 4-byte aligned.
//
#define CMAC_AUTH_TAG_ADDRESS     0x08008000UL

//
// CMAC_ALL Golden Tag
//
// Reserves memory for storing the golden CMAC tag that gets
// generated by the G32R501 CMAC tool.
//
// The variable has no practical use in the program, it is just to occupy 4 word 
// flash memory for the Golden CMAC Tag.
//
#if defined (__ARMCC_VERSION) || defined (__CC_ARM) || defined (__ICCARM__)
    __attribute__((__used__, section(".ARM.__at_0x08008000")))
#elif defined (__GNUC__) && !defined (__ARMCC_VERSION)
    __attribute__((section(".cmac_all")))
#endif
const uint32_t cmac_all[] =
{
    0xFFFFFFFF,
    0xFFFFFFFF,
    0xFFFFFFFF,
    0xFFFFFFFF,
};

//
// Main
//
void example_main(void)
{
    uint32_t applicationCMACStatus = 0x12345678;

    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Initialize NVIC and clear NVIC registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initialize the NVIC vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    //
    // Board Initialization
    //
    Board_init();

    GPIO_writePin(myGPIOOutput_LED2, 0);
    GPIO_writePin(myGPIOOutput_LED3, 0);

    //
    // Enables CPU interrupts
    //
    Interrupt_enableMaster();

    //
    // Call CMAC Authentication API to verify the user-specified flash
    //
    applicationCMACStatus = CPU1BROM_calculateCMAC(CMAC_AUTH_START_ADDRESS, CMAC_AUTH_END_ADDRESS, CMAC_AUTH_TAG_ADDRESS);

    //
    // Loop.
    //
    for(;;)
    {
        if (applicationCMACStatus == 0)
        {
            //
            // CMAC verify successful
            //
            GPIO_togglePin(myGPIOOutput_LED2);
            GPIO_togglePin(myGPIOOutput_LED3);
        }
        else if (applicationCMACStatus == 0xFFFFFFFF)
        {
            //
            // CMAC verify fail
            //
            GPIO_togglePin(myGPIOOutput_LED2);
        }
        else
        {
            //
            // Other error
            //
            GPIO_togglePin(myGPIOOutput_LED3);
        }

        DEVICE_DELAY_US(500000);
    }
}

//
// End of File
//
