//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//------------------------------------------------------------------------------
//
//  File:  InitCache.c
//
//  This file implements OEMCacheRangeFlush function suitable for ARM CPU
//  with separate data and instruction caches.
//
#include <windows.h>
#include <ceddk.h>
#include <oal_log.h>
#include <oal_cache.h>

extern UINT32 OALReadCacheInfo(UINT32 cache_type);
extern UINT32 OALReadCP15Cntrl(void);
extern UINT32 OALReadCP15AUXCntrl(void);

#define CORTEXA8_CACHE_LINESIZE_MASK       0x00000007
#define CORTEXA8_CACHE_LINESIZE_SHIFT      0

#define CORTEXA8_CACHE_ASSOCIATIVITY_MASK  0x00001FF8
#define CORTEXA8_CACHE_ASSOCIATIVITY_SHIFT 3

#define CORTEXA8_CACHE_NUMSETS_MASK        0x0FFFE000
#define CORTEXA8_CACHE_NUMSETS_SHIFT       13

#define CORTEXA8_CACHE_DATA                0
#define CORTEXA8_CACHE_UNIFIED             0
#define CORTEXA8_CACHE_INSTRUCTION         1

#define CORTEXA8_CACHE_L1                  (0 << 1)
#define CORTEXA8_CACHE_L2                  (1 << 1)

/*
// cache info flags (applied to both L1 and L2
#define  CF_UNIFIED             0x01     // I and D caches unified, use ICache info fields
#define  CF_WRITETHROUGH        0x02     // writeback if not set
#define  CF_COHERENT            0x04     // no cache flush operations necessary
*/

//------------------------------------------------------------------------------
//
//  Function:  OALCacheGlobalsInit
//

void OALGetCacheInfo(VOID)
{
    ULONG dwCacheInfo;
    
    OALMSG(OAL_CACHE, (L"+OALGetCacheInfo\r\n"));

    // Read cache ID&Selection registers

    // L1 Cache
    g_oalCacheInfo.L1Flags = 0x0;
//    g_oalCacheInfo.L1Flags = (CF_WRITETHROUGH|CF_COHERENT); // test for PA tag, na9da, 2008.11.14

    // L1 ICache
    dwCacheInfo = OALReadCacheInfo(CORTEXA8_CACHE_L1|CORTEXA8_CACHE_INSTRUCTION);
    OALMSG(OAL_CACHE, (L"L1I:CachSizeIDReg   = 0x%x\r\n", dwCacheInfo));
    g_oalCacheInfo.L1ILineSize    = 1 << (((dwCacheInfo & CORTEXA8_CACHE_LINESIZE_MASK) >> CORTEXA8_CACHE_LINESIZE_SHIFT) + 4);
    g_oalCacheInfo.L1INumWays     = ((dwCacheInfo & CORTEXA8_CACHE_ASSOCIATIVITY_MASK) >> CORTEXA8_CACHE_ASSOCIATIVITY_SHIFT) + 1;
    g_oalCacheInfo.L1ISetsPerWay  = ((dwCacheInfo & CORTEXA8_CACHE_NUMSETS_MASK) >> CORTEXA8_CACHE_NUMSETS_SHIFT) + 1;
    g_oalCacheInfo.L1ISize        = g_oalCacheInfo.L1ILineSize * g_oalCacheInfo.L1INumWays * g_oalCacheInfo.L1ISetsPerWay;

    // L1 DCache
    dwCacheInfo = OALReadCacheInfo(CORTEXA8_CACHE_L1|CORTEXA8_CACHE_DATA);
    OALMSG(OAL_CACHE, (L"L1D:CachSizeIDReg   = 0x%x\r\n", dwCacheInfo));
    g_oalCacheInfo.L1DLineSize    = 1 << (((dwCacheInfo & CORTEXA8_CACHE_LINESIZE_MASK) >> CORTEXA8_CACHE_LINESIZE_SHIFT) + 4);
    g_oalCacheInfo.L1DNumWays     = ((dwCacheInfo & CORTEXA8_CACHE_ASSOCIATIVITY_MASK) >> CORTEXA8_CACHE_ASSOCIATIVITY_SHIFT) + 1;
    g_oalCacheInfo.L1DSetsPerWay  = ((dwCacheInfo & CORTEXA8_CACHE_NUMSETS_MASK) >> CORTEXA8_CACHE_NUMSETS_SHIFT) + 1;
    g_oalCacheInfo.L1DSize        = g_oalCacheInfo.L1DLineSize * g_oalCacheInfo.L1DNumWays * g_oalCacheInfo.L1DSetsPerWay;

    // L2 Cache (unified)
    g_oalCacheInfo.L2Flags = CF_UNIFIED; // CF_UNIFIED in pkfuncs.h

    dwCacheInfo = OALReadCacheInfo(CORTEXA8_CACHE_L2|CORTEXA8_CACHE_UNIFIED);
    OALMSG(OAL_CACHE, (L"L2U:CachSizeIDReg   = 0x%x\r\n", dwCacheInfo));
    g_oalCacheInfo.L2ILineSize    = 1 << (((dwCacheInfo & CORTEXA8_CACHE_LINESIZE_MASK) >> CORTEXA8_CACHE_LINESIZE_SHIFT) + 4);
    g_oalCacheInfo.L2INumWays     = ((dwCacheInfo & CORTEXA8_CACHE_ASSOCIATIVITY_MASK) >> CORTEXA8_CACHE_ASSOCIATIVITY_SHIFT) + 1;
    g_oalCacheInfo.L2ISetsPerWay  = ((dwCacheInfo & CORTEXA8_CACHE_NUMSETS_MASK) >> CORTEXA8_CACHE_NUMSETS_SHIFT) + 1;
    g_oalCacheInfo.L2ISize        = g_oalCacheInfo.L2ILineSize * g_oalCacheInfo.L2INumWays * g_oalCacheInfo.L2ISetsPerWay;
    
    // If g_oalCacheInfo.L2Flags was set as CF_UNIFIED, OS read the value of I-Cache
    // But I-Cache variable will be set as D-Cache to comform. na9da, 2008.11.12
    g_oalCacheInfo.L2DLineSize    = g_oalCacheInfo.L2ILineSize;
    g_oalCacheInfo.L2DNumWays     = g_oalCacheInfo.L2INumWays;
    g_oalCacheInfo.L2DSetsPerWay  = g_oalCacheInfo.L2ISetsPerWay;
    g_oalCacheInfo.L2DSize        = g_oalCacheInfo.L2ISize;

    {
        UINT32 value = 0;
        value = OALReadCP15Cntrl();
        OALMSG(OAL_CACHE, (L"Control Reg     = 0x%x, 0x%x\r\n", value, value&(1<<12|1<<2)));
        value = OALReadCP15AUXCntrl();
        OALMSG(OAL_CACHE, (L"AUX Control Reg = 0x%x\r\n", value));
    }

    OALMSG(OAL_CACHE, (L"L1ILineSize     = %d\r\n", g_oalCacheInfo.L1ILineSize));
    OALMSG(OAL_CACHE, (L"L1INumWays      = %d\r\n", g_oalCacheInfo.L1INumWays));
    OALMSG(OAL_CACHE, (L"L1IISetsPerWay  = %d\r\n", g_oalCacheInfo.L1ISetsPerWay));
    OALMSG(OAL_CACHE, (L"L1IISize        = %d\r\n", g_oalCacheInfo.L1ISize));
    OALMSG(OAL_CACHE, (L"L1DLineSize     = %d\r\n", g_oalCacheInfo.L1DLineSize));
    OALMSG(OAL_CACHE, (L"L1DNumWays      = %d\r\n", g_oalCacheInfo.L1DNumWays));
    OALMSG(OAL_CACHE, (L"L1DISetsPerWay  = %d\r\n", g_oalCacheInfo.L1DSetsPerWay));
    OALMSG(OAL_CACHE, (L"L1DISize        = %d\r\n", g_oalCacheInfo.L1DSize));
    OALMSG(OAL_CACHE, (L"L2LineSize      = %d\r\n", g_oalCacheInfo.L2ILineSize));
    OALMSG(OAL_CACHE, (L"L2NumWays       = %d\r\n", g_oalCacheInfo.L2INumWays));
    OALMSG(OAL_CACHE, (L"L2ISetsPerWay   = %d\r\n", g_oalCacheInfo.L2ISetsPerWay));
    OALMSG(OAL_CACHE, (L"L2ISize         = %d\r\n", g_oalCacheInfo.L2ISize));

    OALMSG(OAL_CACHE, (L"-OALGetCacheInfo\r\n"));

}


//------------------------------------------------------------------------------

