|
@@ -168,6 +168,15 @@ static inline bool slc_exists(void)
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+static inline bool slc_data_bypass(void)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * If L1 data cache is disabled SL$ is bypassed and all load/store
|
|
|
+ * requests are sent directly to main memory.
|
|
|
+ */
|
|
|
+ return !dcache_enabled();
|
|
|
+}
|
|
|
+
|
|
|
static inline bool ioc_exists(void)
|
|
|
{
|
|
|
if (is_isa_arcv2()) {
|
|
@@ -412,7 +421,13 @@ void invalidate_icache_all(void)
|
|
|
{
|
|
|
__ic_entire_invalidate();
|
|
|
|
|
|
- if (is_isa_arcv2())
|
|
|
+ /*
|
|
|
+ * If SL$ is bypassed for data it is used only for instructions,
|
|
|
+ * so we need to invalidate it too.
|
|
|
+ * TODO: HS 3.0 supports SLC disable so we need to check slc
|
|
|
+ * enable/disable status here.
|
|
|
+ */
|
|
|
+ if (is_isa_arcv2() && slc_data_bypass())
|
|
|
__slc_entire_op(OP_INV);
|
|
|
}
|
|
|
|
|
@@ -520,14 +535,15 @@ void invalidate_dcache_range(unsigned long start, unsigned long end)
|
|
|
return;
|
|
|
|
|
|
/*
|
|
|
- * ARCv1 -> call __dc_line_op
|
|
|
- * ARCv2 && no IOC -> call __dc_line_op; call __slc_rgn_op
|
|
|
- * ARCv2 && IOC enabled -> nothing
|
|
|
+ * ARCv1 -> call __dc_line_op
|
|
|
+ * ARCv2 && L1 D$ disabled -> nothing
|
|
|
+ * ARCv2 && L1 D$ enabled && IOC enabled -> nothing
|
|
|
+ * ARCv2 && L1 D$ enabled && no IOC -> call __dc_line_op; call __slc_rgn_op
|
|
|
*/
|
|
|
if (!is_isa_arcv2() || !ioc_enabled())
|
|
|
__dc_line_op(start, end - start, OP_INV);
|
|
|
|
|
|
- if (is_isa_arcv2() && !ioc_enabled())
|
|
|
+ if (is_isa_arcv2() && !ioc_enabled() && !slc_data_bypass())
|
|
|
__slc_rgn_op(start, end - start, OP_INV);
|
|
|
}
|
|
|
|
|
@@ -537,14 +553,15 @@ void flush_dcache_range(unsigned long start, unsigned long end)
|
|
|
return;
|
|
|
|
|
|
/*
|
|
|
- * ARCv1 -> call __dc_line_op
|
|
|
- * ARCv2 && no IOC -> call __dc_line_op; call __slc_rgn_op
|
|
|
- * ARCv2 && IOC enabled -> nothing
|
|
|
+ * ARCv1 -> call __dc_line_op
|
|
|
+ * ARCv2 && L1 D$ disabled -> nothing
|
|
|
+ * ARCv2 && L1 D$ enabled && IOC enabled -> nothing
|
|
|
+ * ARCv2 && L1 D$ enabled && no IOC -> call __dc_line_op; call __slc_rgn_op
|
|
|
*/
|
|
|
if (!is_isa_arcv2() || !ioc_enabled())
|
|
|
__dc_line_op(start, end - start, OP_FLUSH);
|
|
|
|
|
|
- if (is_isa_arcv2() && !ioc_enabled())
|
|
|
+ if (is_isa_arcv2() && !ioc_enabled() && !slc_data_bypass())
|
|
|
__slc_rgn_op(start, end - start, OP_FLUSH);
|
|
|
}
|
|
|
|
|
@@ -563,7 +580,7 @@ void flush_n_invalidate_dcache_all(void)
|
|
|
{
|
|
|
__dc_entire_op(OP_FLUSH_N_INV);
|
|
|
|
|
|
- if (is_isa_arcv2())
|
|
|
+ if (is_isa_arcv2() && !slc_data_bypass())
|
|
|
__slc_entire_op(OP_FLUSH_N_INV);
|
|
|
}
|
|
|
|
|
@@ -571,6 +588,6 @@ void flush_dcache_all(void)
|
|
|
{
|
|
|
__dc_entire_op(OP_FLUSH);
|
|
|
|
|
|
- if (is_isa_arcv2())
|
|
|
+ if (is_isa_arcv2() && !slc_data_bypass())
|
|
|
__slc_entire_op(OP_FLUSH);
|
|
|
}
|