/***********************************************************************
*                    SEGGER Microcontroller GmbH                       *
*                        The Embedded Experts                          *
************************************************************************
*                                                                      *
*                  (c) SEGGER Microcontroller GmbH                     *
*                        All rights reserved                           *
*                          www.segger.com                              *
*                                                                      *
************************************************************************
*                                                                      *
************************************************************************
*                                                                      *
*                                                                      *
*  Licensing terms                                                     *
*                                                                      *
* This software may be distributed to your customers free of charge.   *
* This grant of redistribution does not entitle YOU or enduser to      *
* receive from SEGGER hard-copy documentation, technical support,      *
* phone assistance, or enhancements or updates to the Software unless  *
* a specific agreement clearly states otherwise.                       *
*                                                                      *
*                                                                      *
* THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER "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 COPYRIGHT HOLDER 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.                                                              *
*                                                                      *
************************************************************************

-------------------------- END-OF-HEADER -----------------------------
Purpose: Demonstration of AP selection for SoC-600
---------------------------------------------------------
*/

/*********************************************************************
*
*       Constants (similar to defines)
*
**********************************************************************
*/

//
// CoreSight DAP generic
//   AXI-CSW bit descriptions:
//    [30:28] Prot  (Reset = 3)
//    [27:24] Cache (xxx)
//    [23:23] SPIStatus (Read-only. 0 == secure AXI accesses are not performed)
//    [14:13] Domain (0 == Non-shareable, 1 == Shareable, inner domain, includes add. masters, 2 == Shareable, outer domain, includes inner/additional masters, 3 == Shareable, system domain, all masters included)
//    [12:12] DbgStatus/ACEEnable (1 == Enable ACE transactions, including barriers) 
//    [11:8] Mode (0 == Normal download/upload, 1 == Barrier transaction)
//    [7:7] TrInProg (Read-only, 1 == Transfer in progress)
//    [6:6] DbgStatus (Read-only, 1 == AXI transactions are allowed/enabled)
//    [5:4] AddrInc (1 == Auto-inc address)
//    [2:0] Size (0 == 8-bit, 1 == 16-bit, 2 == 32-bit, 2 == 64-bit)
//
__constant U32 _AHB_ACC_32BIT_AUTO_INC          = (1 << 29) | (1 << 25) | (1 << 24) | (1 << 4) | (2 << 0);  // HMASTER = DEBUG, Private access, Auto-increment, Access size: word;
__constant U32 _AHB_ACC_32BIT_NO_AUTO_INC       = (1 << 29) | (1 << 25) | (1 << 24) | (0 << 4) | (2 << 0);
__constant U32 _APB_AP_32BIT_ACCESS_NO_INC      = ((2 << 0) | (0 << 4) | (1 << 31));  // [1:0] = Access width, [4:4] = Auto-inc, [31:31] = Enable software access to APB-AP
__constant U32 _APB_AP_32BIT_ACCESS_AUTO_INC    = ((2 << 0) | (1 << 4) | (1 << 31));  // [1:0] = Access width, [4:4] = Auto-inc, [31:31] = Enable software access to APB-AP
__constant U32 _AXI_ACC_32BIT_NO_AUTO_INC       = ((3 << 28) | (0 << 24) | (3 << 13) | (0 << 12) | (0 << 8) | (0 << 4) | (2 << 0));
__constant U32 _AXI_ACC_32BIT_AUTO_INC          = ((3 << 28) | (0 << 24) | (3 << 13) | (0 << 12) | (0 << 8) | (1 << 4) | (2 << 0));
__constant U32 _AXI_ACC_64BIT_NO_AUTO_INC       = ((3 << 28) | (0 << 24) | (3 << 13) | (0 << 12) | (0 << 8) | (0 << 4) | (3 << 0));
__constant U32 _AXI_ACC_64BIT_AUTO_INC          = ((3 << 28) | (0 << 24) | (3 << 13) | (0 << 12) | (0 << 8) | (1 << 4) | (3 << 0));
__constant U32 _CSW_REG_OFF                     = 0xD00;  // The offset to be written to DP.SELECT[11:0] to specify the CSW register of the AP 
//
// Device specific
//
__constant U32 _AXI_BASE_ADDR                    = 0x7C004000;  // See "CoreSight AP map (CoreSight SoC-600 based)" in header of this file
__constant U32 _AP0_BASE_ADDR                    = 0x7C002000;  // Base address for AP0 

/*********************************************************************
*
*       Local functions
*
**********************************************************************
*/

/*********************************************************************
*
*       _SelectAP32
*
*  Function description
*    Selects AP by address and access mask
*
*/
static int _SelectAP32 (U32 APAddress, U32 AccessMask) {
  JLINK_CORESIGHT_WriteDP(JLINK_CORESIGHT_DP_REG_SELECT, (APAddress + _CSW_REG_OFF));   // Select AP by Address for SOC-600 
  JLINK_CORESIGHT_WriteAP(JLINK_CORESIGHT_AP_REG_CTRL, AccessMask);                     // Set AP in default non-auto-inc state, 32 bit access
  return 0;
}

/*********************************************************************
*
*       Global functions
*
**********************************************************************
*/

/*********************************************************************
*
*       InitTarget()
*
*  Function description
*    If present, called right before performing generic connect sequence.
*    Usually used for targets which need a special connect sequence.
*    E.g.: TI devices with ICEPick TAP on them where core TAP needs to be enabled via specific ICEPick sequences first
*
*  Return value
*    >= 0:  O.K.
*     < 0:  Error
*
*  Notes
*    (1) Must not use high-level API functions like JLINK_MEM_ etc.
*    (2) For target interface JTAG, this device has to setup the JTAG chain + JTAG TAP Ids.
*    (3) This function is called before J-Link performed any communication with the device
*/
int InitTarget(void) {
  U32 Data;
  U32 DestAddr;
  //
  // Select AXI AP
  //
  _SelectAP32(_AXI_BASE_ADDR, _AXI_ACC_32BIT_NO_AUTO_INC);
  //
  // Write data via AHB-AP
  //
  JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, 1, DestAddr);
  JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_DATA, 1, 0xDEADBEEF);
  //
  // Read data via AHB-AP
  //
  JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, 1, DestAddr);
  JLINK_CORESIGHT_ReadDAP(JLINK_CORESIGHT_AP_REG_DATA, 1, &Data);  
  //
  // Select AP0
  //
  _SelectAP32(_AP0_BASE_ADDR, _APB_AP_32BIT_ACCESS_NO_INC);
  //
  // Write data via AHB-AP
  //
  JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, 1, DestAddr);
  JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_DATA, 1, 0xDEADBEEF);
  //
  // Read data via AHB-AP
  //
  JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_AP_REG_ADDR, 1, DestAddr);
  JLINK_CORESIGHT_ReadDAP(JLINK_CORESIGHT_AP_REG_DATA, 1, &Data);
  return 0;
}

/*********************************************************************
*
*       ConfigTargetSettings()
*
*  Function description
*    Called before InitTarget(). Mainly used to set some global DLL variables to customize the normal connect procedure.
*    For ARM CoreSight devices this may be specifying the base address of some CoreSight components (ETM, ...)
*    that cannot be automatically detected by J-Link due to erroneous ROM tables etc.
*    May also be used to specify the device name in case debugger does not pass it to the DLL.
*
*  Return value
*    >= 0  O.K.
*     < 0  Error
*
*  Notes
*    (1) May not, under absolutely NO circumstances, call any API functions that perform target communication.
*    (2) Should only set some global DLL variables
*/
int ConfigTargetSettings(void) {
  //
  // Specify AP map
  //
  JLINK_ExecCommand("CORESIGHT_AddAP BaseAddr = 0x7C002000 Index=0 Type=APB-AP");   // Has access to the Cortex-R52+ cores
  JLINK_ExecCommand("CORESIGHT_AddAP BaseAddr = 0x7C004000 Index=1 Type=AXI-AP");   // May be used for RTT because it has access to system memory
  JLINK_ExecCommand("CORESIGHT_SetIndexAHBAPToUse = 0");
  return 0;
}

