/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

/*-----------------------------------------------------------------------------
 *
 * $Author$
 * $Date$
 * $RCSfile: dmx_api.c,v $
 * $Revision$
 *
 *---------------------------------------------------------------------------*/

/** @file gcpu.h
 *  gcpu driver - common definitions
 */

#ifndef GCPU_H
#define GCPU_H

//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------
#include "x_lint.h"
#include "x_stl_lib.h"
#include "x_assert.h"
#include "x_printf.h"
#include "x_hal_5381.h"
#include "x_hal_arm.h"
#include "drv_common.h"

#include "gcpu_if.h"

#include "x_printf.h"
#include "x_ckgen.h"
#include "x_os.h"

#ifndef CC_SECURE_WORLD
#include "x_common.h"
#include "x_debug.h"
#include "gcpu_debug.h"
#include "x_typedef.h"
#endif
//-----------------------------------------------------------------------------
// Configurations
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Constant definitions
//-----------------------------------------------------------------------------
#define GCPU_BASE           (AES_BASE)
#if defined(CC_MT5863) || defined(CC_MT5893) || defined(CC_MT5895)
#define IOMMU_GCPU_BASE     (IO_VIRT + 0x68080)
#else
#define IOMMU_GCPU_BASE     (IO_VIRT + 0x68040)
#endif

#ifdef CC_MT5863
#define GCPU_RSA_BASE       (IO_VIRT + 0x015000)
#else
#define GCPU_RSA_BASE       (IO_VIRT + 0x03E000)
#endif

#define GCPU_DMEM_BASE      (IO_VIRT + 0x16C00)

//IC Verify config addr in apollo\linux_core\kernel\linux-3.18\arch\arm\mach-mt53xx\core.c
#if defined(CC_MT5893) || defined(CC_MT5895)
#define GCPU_SECU_BASE      (IO_VIRT + 0x4121000) // husky
#define GCPU_DMX_BASE       (IO_VIRT + 0x4100000) // husky
#else
#define GCPU_SECU_BASE      (IO_VIRT + 0xB021000) //
#define GCPU_DMX_BASE       (IO_VIRT + 0xB000000) //
#endif

#define GCPU_DMX_SRAM_CFG   (IO_VIRT + 0x170C0)
//
// GCPU Registers
//
#define GCPU_REG_CTL                0 //(0x0)
#define GCPU_REG_MSC                1 //(0x4)

#define GCPU_REG_PC_CTL             256 //(0x400)
#define GCPU_REG_MEM_ADDR           257 //(0x404)
#define GCPU_REG_MEM_DATA           258 //(0x408)

#define GCPU_REG_MON                260 //(0x410)
#define GCPU_REG_MONCTL             261 //(0x414)

#define GCPU_REG_DRAM_INST_BASE     264 //(0x420)

#define GCPU_REG_TRAP_START         272 // (0x440)
#define GCPU_REG_TRAP_END           286 // (0x478)
#define GCPU_REG_OFFSET_CK          304 // (0x478)

#define GCPU_REG_INT_SET            512 //(0x800)
#define GCPU_REG_INT_CLR            513 //(0x804)
#define GCPU_REG_INT_EN             514 //(0x808)

#define GCPU_RSA_MMPRO_R1_CON       713 //(0xB24)
#define GCPU_RSA_MMPRO_PS_CON       720 //(0xB40)

#define GCPU_REG_MEM_CMD            768 //(0xC00)
#define GCPU_REG_MEM_P0             769 //(0xC04)
#define GCPU_REG_MEM_P1             770 //(0xC08)
#define GCPU_REG_MEM_P2             771 //(0xC0C)
#define GCPU_REG_MEM_P3             772 //(0xC10)
#define GCPU_REG_MEM_P4             773 //(0xC14)
#define GCPU_REG_MEM_P5             774 //(0xC18)
#define GCPU_REG_MEM_P6             775 //(0xC1C)
#define GCPU_REG_MEM_P7             776 //(0xC20)
#define GCPU_REG_MEM_P8             777 //(0xC24)
#define GCPU_REG_MEM_P9             778 //(0xC28)
#define GCPU_REG_MEM_P10            779 //(0xC2C)
#define GCPU_REG_MEM_P11            780 //(0xC30)
#define GCPU_REG_MEM_P12            781 //(0xC34)
#define GCPU_REG_MEM_P13            782 //(0xC38)
#define GCPU_REG_MEM_P14            783 //(0xC3C)
#define GCPU_REG_MEM_Slot           784 //(0xC40)

#define REG_IOMMU_CFG0              0x0//0x000        // basic setting
#define REG_IOMMU_CFG1              0x1//0x004        // page table index
#define REG_IOMMU_CFG2              0x2//0x008        // agnet_0~1 setting
#define REG_IOMMU_CFG4              0x4//0x010        // interrupt, monitor and debug
#define REG_IOMMU_CFG5              0x5//0x010
#define REG_IOMMU_CFG6              0x6//0x010
#define REG_IOMMU_CFG7              0x7//0x010
#define REG_IOMMU_CFG8              0x8//0x010
#define REG_IOMMU_CFG9              0x9//0x010
#define REG_IOMMU_CFGA              0xA//0x010
#define REG_IOMMU_CFGB              0xb//0x010
#define REG_IOMMU_CFGC              0xc//0x010
#define REG_IOMMU_CFGD              0xd//0x010
#define REG_IOMMU_CFG11             0x11

#define REG_IOMMU_CFG13             0x13
#define REG_IOMMU_CFG14             0x14
//
// Interrupt masks
//
#define GCPU_INT_MASK               (0x80000001)

//
// GCPU command
//
#define CSS_DEC_DK                  (0x00)         // CSS Disk Key Decryption
#define CSS_DEC_TK                  (0x01)         // CSS Title Key Decryption
#define CSS_DSC_AV                  (0x02)         // CSS AV Descramble
#define CSS_AUTH_DRV                (0x03)         // CSS Drive Authentication
#define CSS_AUTH_DEC                (0x04)         // CSS Decoder Authentication
#define CSS_AUTH_BK                 (0x05)         // CSS Key Share Authentication

#define C2_D                        (0x08)         // CPPM/CPRM C2 Decryption
#define C2_E                        (0x09)         // CPPM/CPRM C2 Encryption
#define C2_G                        (0x0A)         // CPPM/CPRM C2 Generating Function
#define C2_H                        (0x0B)         // CPPM/CPRM C2 Hash Function
#define CPPM_DPAK                   (0x0C)         // CPPM Packet Decryption
#define CPRM_DPAK                   (0x0D)         // CPRM Packet Decryption
#define CPRM_EPAK                   (0x0E)         // CPRM Packet Encryption
#define CPRM_DCI_VFY                (0x0F)         // CPRM DCI CCI Verify

#define AES_DXTS                    (0x17)         // AES XTS Encryption
#define AES_EXTS                    (0x18)         // AES XTS Decryption
#define AES_CTR                     (0x1E)         // AES CTR Function
#define AES_OFB                     (0x1F)         // AES OFB Function
#define AES_D                       (0x20)         // AES Decryption Function
#define AES_E                       (0x21)         // AES Encryption Function
#define AES_G                       (0x22)         // AES Generating Function
#define AES_DPAK                    (0x23)         // AES Packet Decryption
#define AES_EPAK                    (0x24)         // AES Packet Encryption
#define AES_CMAC                    (0x25)         // AES CMAC Algorithm
#define AES_DCBC                    (0x26)         // AES Cipher Block Chaining Decryption
#define AES_ECBC                    (0x27)         // AES Cipher Block Chaining Encryption
#define AES_H                       (0x28)         // AES Hash

#define AES_D_CMP                   (0x36)         // AES Decryption Function with Result Compare

#define AES_GCM_E					(0x38)
#define AES_GCM_D					(0x39)

#define KEY_LADR                    (0x3A)

#define AESEK_D                     (0x74)         // AES Decryption with Enc key
#define AESEK_E                     (0x75)         // AES Encryption with Enc key
#define AESPK_EK_D                  (0x76)         // AES Decryption with Predetermined/Encrypted key
#define AESPK_EK_E                  (0x77)         // AES Encryption with Predetermined/Encrypted key
#define AESPK_D                     (0x78)         // AES Decryption with Predetermined Key
#define AESPK_E                     (0x79)         // AES Encryption with Predetermined Key
#define AESPK_DPAK                  (0x7A)         // AES Packet Decryption with Predetermined Key
#define AESPK_EPAK                  (0x7B)         // AES Packet Encryption with Predetermined Key
#define AESPK_DCBC                  (0x7C)         // AES Cipher Block Chaining Decryption with Predetermined Key
#define AESPK_ECBC                  (0x7D)         // AES Cipher Block Chaining Encryption with Predetermined Key
#define AESPK_EK_DCBC               (0x7E)         // AES Cipher Block Chaining Decryption with Predetermined/Encrypted Key

#define VCPS_H                      (0x28)         // VCPS Hash Function
#define VCPS_DPAK                   (0x29)         // VCPS Packet Decryption
#define VCPS_EPAK                   (0x2A)         // VCPS Packet Encryption
#define VCPS_DKBH                   (0x2B)         // VCPS DKB Hash Function
#define VCPS_DHDK                   (0x2C)         // VCPS Hardware Device Key Decryption
#define VCPS_DCBC                   (0x2D)         // VCPS AES Cipher Block Chaining Decryption
#define VCPS_ECBC                   (0x2E)         // VCPS AES Cipher Block Chaining Encryption

#define AACS_DBD                    (0x30)         // AACS Blu-ray AV Packet Decryption
#define AACS_EBD                    (0x31)         // AACS Blu-ray AV Packet Encryption
#define AACS_DTN                    (0x32)         // AACS Blu-ray Thumbnail Packet Decryption
#define AACS_ETN                    (0x33)         // AACS Blu-ray Thumbnail Packet Encryption
#define AACS_DHD                    (0x34)         // AACS HD-DVD Packet Decryption
#define AACS_EHD                    (0x35)         // AACS HD-DVD Packet Encryption
#define AACS_DV_CALC                (0x37)         // AACS DV Calculation

#define TDES_D                      (0x50)         // T-DES Decryption
#define TDES_E                      (0x51)         // T-DES Encryption
#define TDES_DMA_D                  (0x52)         // T-DES DMA Decryption
#define TDES_DMA_E                  (0x53)         // T-DES DMA Encryption
#define TDES_CBC_D                  (0x54)         // T-DES Cipher Block Chaining Decryption
#define TDES_CBC_E                  (0x55)         // T-DES Cipher Block Chaining Encryption

#define BDRE_DBD                    (0x58)         // BDRE AV Packet Decryption
#define BDRE_EBD                    (0x59)         // BDRE AV Packet Encryption
#define BDRE_DTN                    (0x5A)         // BDRE Thumbnail Packet Decryption
#define BDRE_ETN                    (0x5B)         // BDRE Thumbnail Packet Encryption
#define BDRE_BE                     (0x5C)         // BDRE BytePerm and ExtendKey

#define GCPU_WRITE                  (0x6e)
#define GCPU_READ                   (0x6f)

#define MEMCPY                      (0x10)         // DRAM Data Moving
#define DMA                         (0x11)         // DRAM Direct Memory Access
#define RSA                         (0x12)
#define DMX                         (0x13)
#define SECU                        (0x14)         // Secure SRAM direct Memory Access
#define SLOTDM						(0x16)		   //slot power off save dmem to slot sram,  resume, recover from slot to dmem.

#define SHA_1                       (0x40)         // SHA-1 Algorithm
#define SHA_256                     (0x41)         // SHA-256 Algorithm
#define MD5                         (0x42)         // MD5 Algorithm
#define SHA_224                     (0x43)         // SHA-224 Algorithm
#define HMAC_SHA_256				(0x44)		   // HMAC-SHA256 Algorithm
#define ROM_BIST                    (0x5E)
#define RNG                         (0x6B)
#define MEM_XOR                     (0x71)         // Memory XOR
#define TS_DESC                     (0x81)         // TS descramble
#define PTX                         (0x8c)
#define RC4DPAK                     (0x87)
#define RC4KSA                      (0x88)

#define GCPU_AACS_BDMV_PACKET_SIZE  (6144)
#define GCPU_AACS_BDTHUMB_PACKET_SIZE   (2048)
#define GCPU_AACS_HDVD_PACKET_SIZE  (2048)
#define GCPU_BDRE_PACKET_SIZE       (6144)
#define GCPU_BDRE_THUMB_PACKET_SIZE (2048)
#define GCPU_DES_PACKET_SIZE        (8)
#define GCPU_CSS_PACKET_SIZE        (2048)
#define GCPU_C2H_PACKET_SIZE        (8)
#define GCPU_CPPM_PACKET_SIZE       (2048)
#define GCPU_CPRM_PACKET_SIZE       (2048)
#define GCPU_VCPS_PACKET_SIZE       (2048)
#define GCPU_SHA_1_PACKET_SIZE      (64) //(512bits)
#define GCPU_MD_5_PACKET_SIZE       (64) //(512bits)
#define GCPU_TSDESC_WORKBUF_SIZE    (192 * 3)

#define GCPU_TRAP_NUM               (14)
#define GCPU_INTR_NUM               (1)

#define GCPU_DMEM_SIZE              (48)    // dmem (Command memory 0x16C00) size: 64x128 bits
#define GCPU_IMEM_RAM_SIZE          (512)   // iram (0x16408) size: 128x88 bits
#define GCPU_IMEM_ROM_SIZE          (4096)

#define GCPU_SECURESLOT_PTR         (48)
#define GCPU_SECURESLOT_NUM         (48)

#define GCPU_PARAM_NUM              (48)
#define GCPU_S_SLOT_NUM             (48)

#define GCPU_PARAM_PTR              (32)
#define GCPU_PARAM_RET_PTR          (32)
#define GCPU_PARAM_RET_NUM          (GCPU_PARAM_NUM - GCPU_PARAM_RET_PTR)

// CPRM
#define GCPU_PARAM_CPRM_KEY_NUM      (2)      //key 2 slots
#define GCPU_PARAM_CPRM_KEY_PTR      (GCPU_PARAM_PTR)
#define GCPU_PARAM_CPRM_DAT_PTR      (GCPU_PARAM_PTR + GCPU_PARAM_CPRM_KEY_NUM)
#define GCPU_PARAM_CPRM_RET_PTR      (GCPU_PARAM_RET_PTR)

// AES
#define GCPU_PARAM_AES_KEY_NUM      (8)      //key 8 slots
#define GCPU_PARAM_AES_MAC_KEY_NUM  (4)      //key 8 slots
#define GCPU_PARAM_AES_IV_NUM       (4)      //iv 4 slots
#define GCPU_PARAM_AES_KEY_PTR      (32)//(GCPU_PARAM_PTR)
#define GCPU_PARAM_AES_IV_PTR       (40)//(GCPU_PARAM_PTR + GCPU_PARAM_AES_KEY_NUM)
#define GCPU_PARAM_AES_RET_IV_PTR   (44)//(GCPU_PARAM_RET_PTR)

// VCPS
#define GCPU_PARAM_VPCS_KEY_NUM      (4)      //key 2 slots
#define GCPU_PARAM_VPCS_KEY_PTR      (GCPU_PARAM_PTR)
#define GCPU_PARAM_VPCS_DAT_PTR      (GCPU_PARAM_PTR + GCPU_PARAM_VPCS_KEY_NUM)
#define GCPU_PARAM_VPCS_RET_PTR      (GCPU_PARAM_RET_PTR)

// AACS
#define GCPU_PARAM_AACS_KEY_NUM      (4)      //key 4 slots
#define GCPU_PARAM_AACS_IV_NUM       (4)      //iv 4 slots
#define GCPU_PARAM_AACS_KEY_PTR      (GCPU_PARAM_PTR)
#define GCPU_PARAM_AACS_IV_PTR      (GCPU_PARAM_PTR + GCPU_PARAM_AACS_KEY_NUM)

// BDRE
#define GCPU_PARAM_BDRE_KEY_NUM      (4)      //key 2 slots
#define GCPU_PARAM_BDRE_KEY_PTR      (GCPU_PARAM_PTR)
#define GCPU_PARAM_BDRE_RET_PTR      (GCPU_PARAM_RET_PTR)

// DES
#define GCPU_PARAM_DES_KEY_NUM      (6)      //key 6 slots
#define GCPU_PARAM_DES_IV_NUM       (2)      //iv 2 slots
#define GCPU_PARAM_DES_KEY_PTR      (GCPU_PARAM_PTR)
#define GCPU_PARAM_DES_IV_PTR       (6)
#define GCPU_PARAM_DES_DAT_PTR      (GCPU_PARAM_PTR + GCPU_PARAM_DES_KEY_NUM)
#define GCPU_PARAM_DES_RET_PTR      (GCPU_PARAM_RET_PTR)

// RC4
#define GCPU_PARAM_RC4_KEY_NUM      (2)
#define GCPU_PARAM_S_KEY_NUM        (64)
#define GCPU_PARAM_RC4_KEY_PTR      (16)
#define GCPU_PARAM_RC4_S_PTR        (GCPU_PARAM_RC4_KEY_PTR + GCPU_PARAM_RC4_KEY_NUM)

//HMAC
#define GCPU_PARAM_HMAC_KEY_PTR		(32)
#define GCPU_PARAM_HMAC_KEY_NUM		(16)

//AES GCM
#define GCPU_PARAM_AES_GCM_KEY_NUM      	(8) 
#define GCPU_PARAM_AES_GCM_KEY_PTR			(18)//(32)
#define GCPU_PARAM_AES_GCM_CTRUPDATE_PTR	(26)//(40)
#define GCPU_PARAM_AES_GCM_TAG_PTR			(30)//(44)

// IF
#define GCPU_PARAM_IF_PTR           (4)

//TS Scramble/Descramble
#define TSDESC_PARAM_PTR 			(40)

// TS DESC
#define GCPU_PARAM_TSDESC_EVEN      (22)
#define GCPU_PARAM_TSDESC_ODD       (30)

#define GCPU_PARAM_TSDESC_EVEN_EX   (22)    // with AES mode
#define GCPU_PARAM_TSDESC_ODD_EX    (31)    // with AES mode

#define GCPU_PARAM_TSSCRM_EVEN      (22)
#define GCPU_PARAM_TSSCRM_ODD       (31)

#define GCPU_HWCMD_FLAG_NONE            (0x0)
#define GCPU_HWCMD_FLAG_IOMMU           (0x1)
#define GCPU_HWCMD_FLAG_CLEAR_CACHE     (0x2)
#define GCPU_HWCMD_FLAG_DMA_BUF         (0x4)

#define LOADER_AES_KEY_PTR  (48)
#define LOADER_AES_IV_PTR  (52)

#define GCPU_KEY_MEM_PTR			(0x100)
#define GCPU_KEY_MEM_SIZE			(512) //512*32bit 

#define GCPU_RSA_KEY_EXPO_PTR       (0x100)
#define GCPU_RSA_KEY_MODU_PTR       (0x140)
#define GCPU_RSA_KEY_C_ARRAY_PTR    (0x180)

#define GCPU_RSA_KEY_MMPRO_MODU_PTR (0x700)
#define GCPU_RSA_KEY_MMPRO_C_PTR    (0x7C0)

#ifdef CC_MT5886
#define GCPU_DMX_SRAM_SIZE          (48 * 1024)   //48K
#else
#define GCPU_DMX_SRAM_SIZE          (40 * 1024)   //41K (40k for GCPU & CPU, 1k for CPU)
#endif

#define GCPU_SECU_SRAM_SIZE   (140 * 1024)  //140k
#define DMEM_SZIE_BYTE        (832)         //0x330~0x3FF

#define GCPU_SLOT_SRAM_SIZE   (512)    //32*128bit

#ifdef CC_GCPU_EMULATION
#define WHILE_LOOP while(1)
#endif
//-----------------------------------------------------------------------------
// Type definitions
//-----------------------------------------------------------------------------

// GCPU HW CMD Struct
typedef struct
{
    UINT32 u4Param[GCPU_PARAM_NUM];
//  UINT32 u4NonSecureSlot[GCPU_NS_SLOT_NUM];
//  UINT32 u4NonSecureSlotSetMask;
} GCPU_HW_CMD_T;

// Slot information
typedef struct
{
    BOOL fgUsed;             // used or not
    UINT8 u1Size;            // Slot size, unit: 32bits
} GCPU_SECURE_SLOT_INFO;

typedef enum
{
	IOMMU_32BIT,
	IOMMU_39BIT_4K,
	IOMMU_39BIT_64K,
}IOMMU_MODE;

// Make size be the multiple of 32 bytes (cache line)
typedef struct
{
	IOMMU_MODE eIommuMode;
    UINT32 u4InitRam;
    UINT32 u4InitDram;
    UINT64 u4RamCodeAddr;
    UINT32 u4RamCodeSize;
    UINT64 u4TrappingAddr;
    UINT32 u4TrapSize;
    UINT64 u4PhyDramCodeAddr;
    UINT32 u4ReturnedValue;
    UINT64 u4MmuSrc1Start;
    UINT64 u4MmuSrc1End;
    UINT64 u4MmuSrc2Start;
    UINT64 u4MmuSrc2End;
    UINT64 u4MmuTblAddr;
    UINT32 u4SlotIdx;
    UINT32 u4SlotData;
} GCPU_TZ_PARAM_T;

typedef struct
{
    UPTR u4IommuSrc1Start;
    UPTR u4IommuSrc1End;
    UPTR u4IommuSrc2Start;
    UPTR u4IommuSrc2End;

    UPTR u4InBufStart;
    UPTR u4InBufEnd;
    UINT32 u4InBufSize;
    UPTR u4InAddr;
    UINT32 u4InDataSize;

    UPTR u4OutBufStart;
    UPTR u4OutBufEnd;
    UINT32 u4OutBufSize;
    UPTR u4OutAddr;
    UINT32 u4OutDataSize;
    UINT32 u4MmuTblAddr;
} GCPU_IO_BUF_T;

//-----------------------------------------------------------------------------
// Macro definitions
//-----------------------------------------------------------------------------
///
/// GCPU register access commands
///
#define GCPUCMD_READ32(offset)          IO_READ32(GCPU_BASE, ((offset) * 4))
#define GCPUCMD_WRITE32(offset, value)  IO_WRITE32(GCPU_BASE, ((offset) * 4), (value))
#define IOMMU_GCPU_READ32(offset)           IO_READ32(IOMMU_GCPU_BASE, ((offset) * 4))
#define IOMMU_GCPU_WRITE32(offset, value)   IO_WRITE32(IOMMU_GCPU_BASE, ((offset) * 4), (value))

#define GCPU_RSA_READ32(offset)             IO_READ32(GCPU_RSA_BASE, ((offset) * 4))
#define GCPU_RSA_WRITE32(offset, value)     IO_WRITE32(GCPU_RSA_BASE, ((offset) * 4), (value))

#define GCPU_SECU_READ32(offset)            IO_READ32(GCPU_SECU_BASE, ((offset) * 4))
#define GCPU_SECU_WRITE32(offset, value)    IO_WRITE32(GCPU_SECU_BASE, ((offset) * 4), (value))

#define GCPU_SECU_READ8(offset)             IO_READ8(GCPU_SECU_BASE, (offset))
#define GCPU_SECU_WRITE8(offset, value)     IO_WRITE8(GCPU_SECU_BASE, (offset), (value))

#define GCPU_DMX_READ32(offset)             IO_READ32(GCPU_DMX_BASE, ((offset) * 4))
#define GCPU_DMX_WRITE32(offset, value)     IO_WRITE32(GCPU_DMX_BASE, ((offset) * 4), (value))

#define GCPU_DMX_READ8(offset)             IO_READ8(GCPU_DMX_BASE, (offset))
#define GCPU_DMX_WRITE8(offset, value)     IO_WRITE8(GCPU_DMX_BASE, (offset), (value))

#define SwitchValue(u4Value) \
              (((u4Value) << 24) & 0xFF000000) + (((u4Value) << 8) & 0x00FF0000) + \
              (((u4Value) >> 8) & 0x0000FF00) + (((u4Value) >> 24) & 0x000000FF)

#define _GCPU_IsInRegion(u4Addr, u4BufStart, u4BufEnd) \
    (((u4Addr >= u4BufStart) && (u4Addr < u4BufEnd))?TRUE:FALSE)

#define ADDR_INCR_IN_RING(addr, incr, ringstart, ringend)      \
    ((((addr) + (incr)) < (ringend)) ? ((addr) + (incr)) : (((addr) + (incr)) - ((ringend) - (ringstart))))

//-----------------------------------------------------------------------------
// Prototype  of inter-file functions
//-----------------------------------------------------------------------------
EXTERN void _GCPU_Lock(void);
EXTERN void _GCPU_Unlock(void);
EXTERN UPTR _GCPU_CopyRingBuffer(UPTR u4Dst, UPTR u4DstStart, UPTR u4DstEnd,
                                   UPTR u4Src, UPTR u4SrcStart, UPTR u4SrcEnd, UINT32 u4Size);

EXTERN INT32 _GCPU_Init(UINT32 u4Mode);
EXTERN UINT32 _GCPU_AllocSecureSlot(UINT32 u4Size);
EXTERN INT32 _GCPU_FreeSecureSlot(UINT32 u4SlotPtr);
EXTERN INT32 _GCPU_SetSecureSlot(UINT32 u4SlotPtr, UINT8* pu1Data, UINT32 u4Size);
EXTERN INT32 _GCPU_Cmd(UPTR u4Handle, UINT32 u4Cmd, void* pvParam);
EXTERN INT32 _GCPU_CmdEx(UPTR u4Handle, UINT32 u4Cmd, void* pvParam, BOOL fgIOMMU);
EXTERN INT32 _GCPU_CmdSw(UPTR u4Handle, UINT32 u4Cmd, void* pvParam);

EXTERN INT32 _GCPU_EnableIOMMU(UPTR u4Src1Start, UPTR u4Src1End, UPTR u4Src2Start, UPTR u4Src2End, UINT32 u4MmuTblAddr);
EXTERN INT32 _GCPU_DisableIOMMU(void);
EXTERN INT32 _GCPU_GetRomCodeChecksum(void);
EXTERN INT32 _GCPU_Hw_Init(UINT32 u4Mode, BOOL fgIsLocked);
EXTERN INT32 _GCPU_Hw_SetSlot(UINT32 u4Idx, UINT32 u4Data);
EXTERN INT32 _GCPU_Hw_Cmd(GCPU_HW_CMD_T *prHwCmd);
EXTERN INT32 _GCPU_Hw_CmdEx(GCPU_HW_CMD_T *prHwCmd, const GCPU_IO_BUF_T *prBuf, UINT32 u4Flags);
EXTERN BOOL _GCPU_AES_SW_Ring(AES_PARAM_T *prLParam);

#if defined(CC_SUPPORT_STR) && !defined(CC_UBOOT) && !defined(CC_MTK_LOADER)
EXTERN void _GCPU_pm_str_suspend(void);
EXTERN void _GCPU_pm_str_resume(void);
#endif

EXTERN INT32 _GCPU_LoaderInit(UINT32 u4Mode);
EXTERN BOOL _GCPU_SetAesKey(UINT8 *pu1Key, KEY_BIT_LEN eKeyBitLen, UINT8 *pu1Iv);
EXTERN BOOL _GCPU_AesDecrypt(UINT32 u4InBufStart, UINT32 u4OutBufStart, UINT32 u4BufSize);
EXTERN BOOL _GCPU_AesEncrypt(UINT32 u4InBufStart, UINT32 u4OutBufStart, UINT32 u4BufSize);
EXTERN BOOL _GCPU_SHA256(UINT8 *pu1Buf, UINT32 u4Size, UINT8 Message_Digest[32]);

EXTERN BOOL _GCPU_SHA256_Init(UPTR u4Handle, BOOL fgIOMMU);
EXTERN BOOL _GCPU_SHA256_Update(UPTR u4Handle, UINT8 *pu1Buf, UINT32 u4Size, BOOL fgLastPacket, UINT32 u4MmuTblAddr);
EXTERN BOOL _GCPU_SHA256_Final(UPTR u4Handle, UINT8 au1Digest[32]);

EXTERN BOOL _GCPU_RSA_decrypt(UINT8 *pu1Signature, UINT8 *pu1PublicKey, UINT8 *pu1CheckSum, UINT32 e, UINT32 u4Len);
EXTERN INT32 _GCPU_AESGCM(UINT32 u4Handle, void* prParam, BOOL fgIOMMU);
EXTERN INT32 _GCPU_AESXTS(UINT32 u4Handle, AES_XTS_PARAM_T *prParam, BOOL fgIOMMU);

#endif  // GCPU_H

