// +FHDR------------------------------------------------------------
//                 Copyright (c) 2022 SmartLogic.
//                       ALL RIGHTS RESERVED
// -----------------------------------------------------------------
// Filename      : ucp_handshake.c
// Author        : xianfeng.du
// Created On    : 2022-06-25
// Last Modified :
// -----------------------------------------------------------------
// Description:
//
//
// -FHDR------------------------------------------------------------

#include "typedef.h"
#include "ucp_utility.h"
#include "ucp_printf.h"
//#include "ucp_handshake.h"
//#include "msg_transfer_queue.h"
#include "msg_transfer_mem.h"
#include "pet_sm_mgt.h"

UcpHandshake_t* get_handshake_info(void)
{
    PetSmLocalMgt_t* pPetSmLocalMgt = get_pet_sm_local_mgt();
    return  pPetSmLocalMgt->pHandshake;
}

int32_t get_host_core_id(void)
{
    int32_t core_id;

#ifndef PCIE_BACKHAUL
    /*ARM A72 will call msg_transfer_init on TMAC_BACKHAUL mode*/
    core_id = NPU_CORE_ID;
#else
    /*PET RFM SPU0 will call msg_transfer_init on PCIE_BACKHAUL mode*/
    core_id = PET_RFM_SPU0_CORE_ID;
#endif

    return core_id;
}

//host is the core which called msg_transfer_init
void handshake_request_from_host(int32_t core_id)
{
    volatile uint32_t request = 0;
    UcpHandshake_t* pHandshake = (UcpHandshake_t *)get_handshake_info();

    while(1) {
        request = do_read_volatile(&pHandshake->request[core_id]);
        if (request == (core_id + HANDSHKAE_REQ_VALUE)) {
            UCP_PRINT_EMPTY("Recieved handshake request message from core[0x%08x],value[0x%08x].",core_id,request);
            break;
        }
    }

    return;
}

//host is the core which called msg_transfer_init
void handshake_response_to_host(int32_t core_id)
{
    uint32_t response= (core_id + HANDSHKAE_RESP_VALUE);
    UcpHandshake_t* pHandshake = (UcpHandshake_t *)get_handshake_info();

    do_write(&pHandshake->response[core_id], response);
    UCP_PRINT_EMPTY("Sent handshake response message to core[0x%08x],value[0x%08x].",core_id,response);

    return;
}

//msgagent is the core which agented msg_transfer_init,PET_RFM_SPU1_CORE_ID
void handshake_response_to_msgagent(int32_t core_id)
{
    volatile uint32_t request = 0;
    volatile uint32_t response = core_id + HANDSHKAE_RESP_VALUE;
    UcpHandshake_t* pHandshake = (UcpHandshake_t *)get_handshake_info();

    while(1) {
        request = do_read_volatile(&pHandshake->request[core_id]);
        if (request == (core_id + HANDSHKAE_REQ_VALUE)) {
            UCP_PRINT_EMPTY("Recieved handshake request message from core[0x%08x],value[0x%08x].",core_id,request);

			do_write(&pHandshake->response[core_id], response);
			UCP_PRINT_EMPTY("Sent handshake response message to core[0x%08x],value[0x%08x].",core_id,response);
            break;
        }
    }

    return;
}

//master is the core which controlled the handshake flow
#if 0
void handshake_with_host(void)
{
    int32_t core_id = get_host_core_id();
    handshake_request_from_host(core_id);
    handshake_response_to_host(core_id);

    return;
}
#endif

//master is the core which controlled the handshake flow
void handshake_master_with_slave(uint32_t u32_core_mask)
{
    volatile uint32_t request = 0;
    uint32_t response;
    uint32_t core_id,coreReadyBitMap,coreMask;
    UcpHandshake_t* pHandshake  = (UcpHandshake_t *)get_handshake_info();
    uint32_t ape_core_mask      = u32_core_mask;
    uint32_t handshake_coremask = HANDSHKAE_MASK | ape_core_mask;

    core_id = get_core_id();
    coreReadyBitMap = 1 << core_id;
    debug_write(DBG_DDR_COMMON_IDX(core_id,90), handshake_coremask);

    //msgagent need to run before other cores.
    handshake_response_to_msgagent(PET_RFM_SPU1_CORE_ID);

    while(1) {
        for(uint32_t i = 0; i < MAX_NUM_SPU; i++) {
            coreMask = (handshake_coremask >> i) & 0x1;
            if (coreMask) {
                request = do_read_volatile(&pHandshake->request[i]);
                if (request == (i + HANDSHKAE_REQ_VALUE)) {
                    UCP_PRINT_EMPTY("Recieved handshake request message from core[0x%08x],value[0x%08x].",core_id,request);

                    response= (i + HANDSHKAE_RESP_VALUE);
                    do_write(&pHandshake->response[i], response);
                    UCP_PRINT_EMPTY("Sent handshake response message to core[0x%08x],value[0x%08x].",core_id,response);

                    coreReadyBitMap |= (1 << i);
                }
            }
        }

        if (handshake_coremask == (coreReadyBitMap & handshake_coremask)) {
            UCP_PRINT_EMPTY("all cores are ready.");
            break;
        }
    }

    return;
}

//master is the core which controlled the handshake flow
void handshake_slave_with_master(void)
{
    uint32_t core_id = get_core_id();
    uint32_t request= (core_id + HANDSHKAE_REQ_VALUE);
    volatile uint32_t response;
    UcpHandshake_t*	pHandshake = (UcpHandshake_t *)get_handshake_info();

    do_write(&pHandshake->request[core_id], request);
    UCP_PRINT_EMPTY("core[0x%08x] sent handshake request message,value[0x%08x].",core_id,request);

    while(1) {
        response = do_read_volatile(&pHandshake->response[core_id]);
        if (response == (core_id + HANDSHKAE_RESP_VALUE)) {
            UCP_PRINT_EMPTY("core[0x%08x] recieved handshake response message,value[0x%08x].",core_id,response);
            break;
        }
    }
    return;
}


