aboutsummaryrefslogtreecommitdiff
path: root/platform/ext/target/arm/musca_s1/Native_Driver/cache_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ext/target/arm/musca_s1/Native_Driver/cache_drv.c')
-rw-r--r--platform/ext/target/arm/musca_s1/Native_Driver/cache_drv.c315
1 files changed, 315 insertions, 0 deletions
diff --git a/platform/ext/target/arm/musca_s1/Native_Driver/cache_drv.c b/platform/ext/target/arm/musca_s1/Native_Driver/cache_drv.c
new file mode 100644
index 0000000000..a44e6c1eff
--- /dev/null
+++ b/platform/ext/target/arm/musca_s1/Native_Driver/cache_drv.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2017-2020 Arm Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * \file cache_drv.c
+ * \brief Driver for L1 instruction cache based on SSE-200 version r1p0
+ */
+
+#include "cache_drv.h"
+
+/**
+ * \brief L1 cache register map structure
+ */
+struct _arm_cache_reg_map_t {
+ volatile uint32_t cacheichwparams;
+ /*!< Offset: 0x000 (R/ ) HW Parameters Register */
+ volatile uint32_t cacheicctrl;
+ /*!< Offset: 0x004 (R/W) Control Register */
+ volatile uint32_t reserved_0[62];
+ /*!< Offset: 0x00C-0x0FC Reserved */
+ volatile uint32_t cacheicirqstat;
+ /*!< Offset: 0x100 (R/ ) Interrupt Request Status Register */
+ volatile uint32_t cacheicirqsclr;
+ /*!< Offset: 0x104 ( /W) Interrupt Status Clear Register */
+ volatile uint32_t cacheicirqen;
+ /*!< Offset: 0x108 (R/W) Interrupt Enable Register */
+ volatile uint32_t cacheicdbgfillerr;
+ /*!< Offset: 0x10C (R/ ) Fill Error Address Register */
+ volatile uint32_t reserved_1[124];
+ /*!< Offset: 0x110-0x2FC Reserved */
+ volatile uint32_t cacheicsh;
+ /*!< Offset: 0x300 (R/ ) Cache Statistic Hit Register */
+ volatile uint32_t cacheicsm;
+ /*!< Offset: 0x304 (R/ ) Cache Statistic Miss Register */
+ volatile uint32_t cacheicsuc;
+ /*!< Offset: 0x308 (R/ ) Cache Statistic Uncached Register */
+ volatile uint32_t reserved_2[331];
+ /*!< Offset: 0x30C-0xFCC Reserved */
+ volatile uint32_t cachepidr4;
+ /*!< Offset: 0xFD0 (R/ ) Product ID Register 4 */
+ volatile uint32_t cachepidr5;
+ /*!< Offset: 0xFD4 (R/ ) Product ID Register 5 */
+ volatile uint32_t cachepidr6;
+ /*!< Offset: 0xFD8 (R/ ) Product ID Register 6 */
+ volatile uint32_t cachepidr7;
+ /*!< Offset: 0xFDC (R/ ) Product ID Register 7 */
+ volatile uint32_t cachepidr0;
+ /*!< Offset: 0xFE0 (R/ ) Product ID Register 0 */
+ volatile uint32_t cachepidr1;
+ /*!< Offset: 0xFE4 (R/ ) Product ID Register 1 */
+ volatile uint32_t cachepidr2;
+ /*!< Offset: 0xFE8 (R/ ) Product ID Register 2 */
+ volatile uint32_t cachepidr3;
+ /*!< Offset: 0xFEC (R/ ) Product ID Register 3 */
+ volatile uint32_t cachecidr0;
+ /*!< Offset: 0xFF0 (R/ ) Component ID Register 0 */
+ volatile uint32_t cachecidr1;
+ /*!< Offset: 0xFF4 (R/ ) Component ID Register 1 */
+ volatile uint32_t cachecidr2;
+ /*!< Offset: 0xFF8 (R/ ) Component ID Register 2 */
+ volatile uint32_t cachecidr3;
+ /*!< Offset: 0xFFC (R/ ) Component ID Register 3 */
+};
+
+#define ARM_CACHEICHWPARAMS_CSIZE_MASK (0xFu<<ARM_CACHEICHWPARAMS_CSIZE_OFF)
+#define ARM_CACHEICHWPARAMS_STATS_MASK (0x1u<<ARM_CACHEICHWPARAMS_STATS_OFF)
+#define ARM_CACHEICHWPARAMS_INVMAT_MASK (0x1u<<ARM_CACHEICHWPARAMS_INVMAT_OFF)
+
+#define ARM_CACHEICCTRL_CACHEEN_MASK (0x1u<<ARM_CACHEICCTRL_CACHEEN_OFF)
+#define ARM_CACHEICCTRL_PINV_MASK (0x1u<<ARM_CACHEICCTRL_PINV_OFF)
+#define ARM_CACHEICCTRL_FINV_MASK (0x1u<<ARM_CACHEICCTRL_FINV_OFF)
+#define ARM_CACHEICCTRL_STATEN_MASK (0x1u<<ARM_CACHEICCTRL_STATEN_OFF)
+#define ARM_CACHEICCTRL_STATC_MASK (0x1u<<ARM_CACHEICCTRL_STATC_OFF)
+#define ARM_CACHEICCTRL_HALLOC_MASK (0x1u<<ARM_CACHEICCTRL_HALLOC_OFF)
+
+enum arm_cache_size_t arm_cache_get_size(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ enum arm_cache_size_t val = (enum arm_cache_size_t)
+ (p_cache->cacheichwparams & ARM_CACHEICHWPARAMS_CSIZE_MASK);
+ /**
+ * 9: 512 byte
+ * 10: 1 KB
+ * 11: 2 KB
+ * 12: 4 KB
+ * 13: 8 KB
+ * 14: 16 KB
+ * Other values are reserved, returning error
+ */
+ if ((val < arm_cache_size_512B) || (val > arm_cache_size_16KB)) {
+ return arm_cache_size_err;
+ }
+
+ return val;
+}
+
+bool arm_cache_is_stat_func_available(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ return (p_cache->cacheichwparams & ARM_CACHEICHWPARAMS_STATS_MASK) != 0;
+}
+
+bool arm_cache_is_invalidate_cache_line_enabled(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ return (p_cache->cacheichwparams & ARM_CACHEICHWPARAMS_INVMAT_MASK) != 0;
+}
+
+void arm_cache_enable(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ p_cache->cacheicctrl |= ARM_CACHEICCTRL_CACHEEN_MASK;
+}
+
+void arm_cache_enable_blocking(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ p_cache->cacheicctrl |= ARM_CACHEICCTRL_CACHEEN_MASK;
+
+ while ((arm_cache_get_raw_intr_status(dev) & arm_cache_cec_intr_mask) == 0) {
+ }
+
+ arm_cache_clear_intr(dev, arm_cache_cec_intr_mask);
+}
+
+void arm_cache_disable(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ p_cache->cacheicctrl &= ~ARM_CACHEICCTRL_CACHEEN_MASK;
+}
+
+void arm_cache_disable_blocking(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ p_cache->cacheicctrl &= ~ARM_CACHEICCTRL_CACHEEN_MASK;
+
+ while ((arm_cache_get_raw_intr_status(dev) & arm_cache_cdc_intr_mask) == 0) {
+ }
+
+ arm_cache_clear_intr(dev, arm_cache_cdc_intr_mask);
+}
+
+bool arm_cache_is_enabled(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+ return (p_cache->cacheicctrl & ARM_CACHEICCTRL_CACHEEN_MASK) != 0;
+}
+
+void arm_cache_full_invalidate(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ p_cache->cacheicctrl |= ARM_CACHEICCTRL_FINV_MASK;
+}
+
+void arm_cache_full_invalidate_blocking(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ p_cache->cacheicctrl |= ARM_CACHEICCTRL_FINV_MASK;
+
+ while ((arm_cache_get_raw_intr_status(dev) & arm_cache_ic_intr_mask) == 0) {
+ }
+
+ arm_cache_clear_intr(dev, arm_cache_ic_intr_mask);
+}
+
+void arm_cache_statistic_enable(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ p_cache->cacheicctrl |= ARM_CACHEICCTRL_STATEN_MASK;
+}
+
+void arm_cache_statistic_disable(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ p_cache->cacheicctrl &= ~ARM_CACHEICCTRL_STATEN_MASK;
+}
+
+void arm_cache_clear_statistic_value(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ p_cache->cacheicctrl |= ARM_CACHEICCTRL_STATC_MASK;
+}
+
+void arm_cache_handler_alloc_enable(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ p_cache->cacheicctrl |= ARM_CACHEICCTRL_HALLOC_MASK;
+}
+
+void arm_cache_handler_alloc_disable(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ p_cache->cacheicctrl &= ~ARM_CACHEICCTRL_HALLOC_MASK;
+}
+
+void arm_cache_enable_intr(struct arm_cache_dev_t* dev,
+ enum arm_cache_intr_t mask)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ p_cache->cacheicirqen |= (uint32_t)(mask);
+
+}
+
+void arm_cache_disable_intr(struct arm_cache_dev_t* dev,
+ enum arm_cache_intr_t mask)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ p_cache->cacheicirqen &= ~(uint32_t)(mask);
+}
+
+void arm_cache_clear_intr(struct arm_cache_dev_t* dev,
+ enum arm_cache_intr_t mask)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ p_cache->cacheicirqsclr = (uint32_t)mask;
+}
+
+enum arm_cache_intr_t arm_cache_get_masked_intr_status(
+ struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ return (enum arm_cache_intr_t)
+ (p_cache->cacheicirqstat & p_cache->cacheicirqen);
+}
+
+enum arm_cache_intr_t arm_cache_get_raw_intr_status(
+ struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ return (enum arm_cache_intr_t)(p_cache->cacheicirqstat);
+}
+
+uint32_t arm_cache_get_debug_fill_address(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ return p_cache->cacheicdbgfillerr;
+}
+
+uint32_t arm_cache_get_hit_count(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ return p_cache->cacheicsh;
+}
+
+uint32_t arm_cache_get_miss_count(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ return p_cache->cacheicsm;
+}
+
+uint32_t arm_cache_get_uncached_count(struct arm_cache_dev_t* dev)
+{
+ struct _arm_cache_reg_map_t* p_cache =
+ (struct _arm_cache_reg_map_t*)dev->cfg->base;
+
+ return p_cache->cacheicsuc;
+}