]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Drivers/PL310L2Cache/PL310L2Cache.c
Sync up ArmPkg with patch from mailing list. Changed name of BdsLib.h to BdsUnixLib...
[mirror_edk2.git] / ArmPkg / Drivers / PL310L2Cache / PL310L2Cache.c
diff --git a/ArmPkg/Drivers/PL310L2Cache/PL310L2Cache.c b/ArmPkg/Drivers/PL310L2Cache/PL310L2Cache.c
new file mode 100644 (file)
index 0000000..6cc6cc6
--- /dev/null
@@ -0,0 +1,130 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  \r
+*  This program and the accompanying materials                          \r
+*  are licensed and made available under the terms and conditions of the BSD License         \r
+*  which accompanies this distribution.  The full text of the license may be found at        \r
+*  http://opensource.org/licenses/bsd-license.php                                            \r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*\r
+**/\r
+\r
+#include <Library/IoLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/ArmLib.h>\r
+#include <Library/L2X0CacheLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+#define L2x0WriteReg(reg,val)               MmioWrite32(PcdGet32(PcdL2x0ControllerBase) + reg, val)\r
+#define L2x0ReadReg(reg)                    MmioRead32(PcdGet32(PcdL2x0ControllerBase) + reg)\r
+\r
+// Initialize PL320 L2 Cache Controller\r
+VOID L2x0CacheInit(UINTN L2x0Base, BOOLEAN CacheEnabled) {\r
+    UINT32 Data;\r
+    UINT32 Revision;\r
+    UINT32 Aux;\r
+    UINT32 PfCtl;\r
+    UINT32 PwrCtl;\r
+\r
+    // Check if L2x0 is present and is an ARM implementation\r
+    Data = L2x0ReadReg(L2X0_CACHEID);\r
+    if ((Data >> 24) != L2X0_CACHEID_IMPLEMENTER_ARM) {\r
+        ASSERT(0);\r
+        return;\r
+    }\r
+\r
+    // Check if L2x0 is PL310\r
+    if (((Data >> 6) & 0xF) != L2X0_CACHEID_PARTNUM_PL310) {\r
+        ASSERT(0);\r
+        return;\r
+    }\r
+\r
+    // RTL release\r
+    Revision = Data & 0x3F;\r
+\r
+    // Check if L2x0 is already enabled then we disable it\r
+    Data = L2x0ReadReg(L2X0_CTRL);\r
+    if (Data & L2X0_CTRL_ENABLED) {\r
+        L2x0WriteReg(L2X0_CTRL, L2X0_CTRL_DISABLED);\r
+    }\r
+\r
+    //\r
+    // Set up global configurations\r
+    //\r
+\r
+    // Auxiliary register: Non-secure interrupt access Control + Event monitor bus enable + SBO\r
+    Aux = L2X0_AUXCTRL_NSAC | L2X0_AUXCTRL_EM | L2X0_AUXCTRL_SBO;\r
+    // Use AWCACHE attributes for WA\r
+    Aux |= L2x0_AUXCTRL_AW_AWCACHE;\r
+    // Use default Size\r
+    Data = L2x0ReadReg(L2X0_AUXCTRL);\r
+    Aux |= Data & (0x7 << 17);\r
+    // Use default associativity\r
+    Aux |= Data & (0x1 << 16);\r
+    // Enabled I & D Prefetch\r
+    Aux |= L2x0_AUXCTRL_IPREFETCH | L2x0_AUXCTRL_DPREFETCH;\r
+    \r
+    if (Revision >= 5) {\r
+        // Prefetch Offset Register\r
+        PfCtl = L2x0ReadReg(L2X0_PFCTRL);\r
+        // - Prefetch increment set to 0\r
+        // - Prefetch dropping off\r
+        // - Double linefills off\r
+        L2x0WriteReg(L2X0_PFCTRL, PfCtl);\r
+\r
+        // Power Control Register - L2X0_PWRCTRL\r
+        PwrCtl = L2x0ReadReg(L2X0_PWRCTRL);\r
+        // - Standby when idle off\r
+        // - Dynamic clock gating off\r
+        // - Nc,NC-shared dropping off\r
+        L2x0WriteReg(L2X0_PWRCTRL, PwrCtl);\r
+    }\r
+\r
+    if (Revision >= 4) {\r
+        // Tag RAM Latency register\r
+        // - Use default latency\r
+    \r
+        // Data RAM Latency Control register\r
+        // - Use default latency\r
+    } else if (Revision >= 2) {\r
+        L2x0WriteReg(L230_TAG_LATENCY,\r
+            (L2_TAG_ACCESS_LATENCY << 8)\r
+            | (L2_TAG_ACCESS_LATENCY << 4)\r
+            | L2_TAG_SETUP_LATENCY\r
+        );\r
+        \r
+        L2x0WriteReg(L230_DATA_LATENCY,\r
+            (L2_DATA_ACCESS_LATENCY << 8)\r
+            | (L2_DATA_ACCESS_LATENCY << 4)\r
+            | L2_DATA_SETUP_LATENCY\r
+        );\r
+    } else {\r
+        Aux |= (L2_TAG_ACCESS_LATENCY << 6)\r
+               | (L2_DATA_ACCESS_LATENCY << 3)\r
+               | L2_DATA_ACCESS_LATENCY;\r
+    }\r
+\r
+    // Write Auxiliary value\r
+    L2x0WriteReg(L2X0_AUXCTRL, Aux);\r
+\r
+    //\r
+    // Invalidate all entries in cache\r
+    //\r
+    L2x0WriteReg(L2X0_INVWAY, 0xffff);\r
+    // Poll cache maintenance register until invalidate operation is complete\r
+    while(L2x0ReadReg(L2X0_INVWAY) & 0xffff);\r
+\r
+    // Write to the Lockdown D and Lockdown I Register 9 if required\r
+    // - Not required\r
+\r
+    // Clear any residual raw interrupts\r
+    L2x0WriteReg(L2X0_INTCLEAR, 0x1FF);\r
+\r
+    // Enable the cache\r
+    if (CacheEnabled) {\r
+        L2x0WriteReg(L2X0_CTRL, L2X0_CTRL_ENABLED);\r
+    }\r
+}\r