Skip to content

Commit 8632e61

Browse files
committed
SoC/evalsoc: reorder _premain_init to init L2/SMP before L1 I/D Cache
Move L1 I/D Cache, LDSPEC_EN, and fence barrier initialization after L2 Cache and SMP/IOCP EN enable in _premain_init() to ensure correct cache coherency setup sequence. Signed-off-by: Huaqi Fang <578567190@qq.com>
1 parent 2b7778a commit 8632e61

2 files changed

Lines changed: 46 additions & 45 deletions

File tree

SoC/evalsoc/Common/Source/system_evalsoc.c

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,50 +1484,6 @@ void _premain_init(void)
14841484
}
14851485
#endif
14861486

1487-
#if defined(RUNMODE_LDSPEC_EN)
1488-
#if RUNMODE_LDSPEC_EN == 1
1489-
__RV_CSR_SET(CSR_MMISC_CTL, MMISC_CTL_LDSPEC_ENABLE);
1490-
#else
1491-
__RV_CSR_CLEAR(CSR_MMISC_CTL, MMISC_CTL_LDSPEC_ENABLE);
1492-
#endif
1493-
#endif
1494-
1495-
/* __ICACHE_PRESENT and __DCACHE_PRESENT are defined in evalsoc.h */
1496-
// For our internal cpu testing, they want to set evalsoc __ICACHE_PRESENT/__DCACHE_PRESENT to be 1
1497-
// __CCM_PRESENT is still default to 0 in evalsoc.h, since it is used in core_feature_eclic.h to register interrupt, if set to 1, it might cause exception
1498-
// but in the cpu, icache or dcache might not exist due to cpu configuration, so here
1499-
// we need to check whether icache/dcache really exist, if yes, then turn on it
1500-
#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1)
1501-
if (ICachePresent()) { // Check whether icache real present or not
1502-
#if defined(RUNMODE_ECC_EN)
1503-
#if RUNMODE_ECC_EN == 0
1504-
__RV_CSR_CLEAR(CSR_MCACHE_CTL, MCACHE_CTL_IC_ECC_EN | MCACHE_CTL_IC_ECC_EXCP_EN | MCACHE_CTL_IC_ECC_CHK_EN);
1505-
#else
1506-
__RV_CSR_SET(CSR_MCACHE_CTL, MCACHE_CTL_IC_ECC_EN | MCACHE_CTL_IC_ECC_EXCP_EN | MCACHE_CTL_IC_ECC_CHK_EN);
1507-
#endif
1508-
#endif
1509-
EnableICache();
1510-
// Enable canceling previous accesses in icache e1 stage when change flow happens
1511-
__RV_CSR_SET(CSR_MCACHE_CTL, MCACHE_CTL_IC_PF_EN);
1512-
}
1513-
#endif
1514-
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1)
1515-
if (DCachePresent()) { // Check whether dcache real present or not
1516-
#if defined(RUNMODE_ECC_EN)
1517-
#if RUNMODE_ECC_EN == 0
1518-
__RV_CSR_CLEAR(CSR_MCACHE_CTL, MCACHE_CTL_DC_ECC_EN | MCACHE_CTL_DC_ECC_EXCP_EN | MCACHE_CTL_DC_ECC_CHK_EN);
1519-
#else
1520-
__RV_CSR_SET(CSR_MCACHE_CTL, MCACHE_CTL_DC_ECC_EN | MCACHE_CTL_DC_ECC_EXCP_EN | MCACHE_CTL_DC_ECC_CHK_EN);
1521-
#endif
1522-
#endif
1523-
EnableDCache();
1524-
}
1525-
#endif
1526-
1527-
/* Do fence and fence.i to make sure previous ilm/dlm/icache/dcache control done */
1528-
__RWMB();
1529-
__FENCE_I();
1530-
15311487
#if defined(CFG_IREGION_BASE_ADDR) && (CFG_IREGION_BASE_ADDR == 0)
15321488
/*
15331489
* How to add the compiler option `-fno-delete-null-pointer-checks`:
@@ -1565,6 +1521,7 @@ void _premain_init(void)
15651521
}
15661522
#endif
15671523

1524+
/* NOTE: Initialize L2 Cache and SMP/IOCP EN before L1 I/D Cache */
15681525
if ( (hartid == BOOT_HARTID) && ((mcfginfo & (0x1 << 11)) && (SMP_CTRLREG(__SMPCC_BASEADDR, 0x4) & 0x1)) ) { // L2 Cache present
15691526
// NOTE: Enable L2 Cache by default when L2 Cache Present
15701527
#if !(defined(RUNMODE_L2_EN) && RUNMODE_L2_EN == 0)
@@ -1582,6 +1539,50 @@ void _premain_init(void)
15821539
__SMP_RWMB();
15831540
}
15841541

1542+
#if defined(RUNMODE_LDSPEC_EN)
1543+
#if RUNMODE_LDSPEC_EN == 1
1544+
__RV_CSR_SET(CSR_MMISC_CTL, MMISC_CTL_LDSPEC_ENABLE);
1545+
#else
1546+
__RV_CSR_CLEAR(CSR_MMISC_CTL, MMISC_CTL_LDSPEC_ENABLE);
1547+
#endif
1548+
#endif
1549+
1550+
/* NOTE: L2 Cache and SMP EN initialized above, now initialize L1 I/D Cache */
1551+
// For our internal cpu testing, they want to set evalsoc __ICACHE_PRESENT/__DCACHE_PRESENT to be 1
1552+
// __CCM_PRESENT is still default to 0 in evalsoc.h, since it is used in core_feature_eclic.h to register interrupt, if set to 1, it might cause exception
1553+
// but in the cpu, icache or dcache might not exist due to cpu configuration, so here
1554+
// we need to check whether icache/dcache really exist, if yes, then turn on it
1555+
#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1)
1556+
if (ICachePresent()) { // Check whether icache real present or not
1557+
#if defined(RUNMODE_ECC_EN)
1558+
#if RUNMODE_ECC_EN == 0
1559+
__RV_CSR_CLEAR(CSR_MCACHE_CTL, MCACHE_CTL_IC_ECC_EN | MCACHE_CTL_IC_ECC_EXCP_EN | MCACHE_CTL_IC_ECC_CHK_EN);
1560+
#else
1561+
__RV_CSR_SET(CSR_MCACHE_CTL, MCACHE_CTL_IC_ECC_EN | MCACHE_CTL_IC_ECC_EXCP_EN | MCACHE_CTL_IC_ECC_CHK_EN);
1562+
#endif
1563+
#endif
1564+
EnableICache();
1565+
// Enable canceling previous accesses in icache e1 stage when change flow happens
1566+
__RV_CSR_SET(CSR_MCACHE_CTL, MCACHE_CTL_IC_PF_EN);
1567+
}
1568+
#endif
1569+
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1)
1570+
if (DCachePresent()) { // Check whether dcache real present or not
1571+
#if defined(RUNMODE_ECC_EN)
1572+
#if RUNMODE_ECC_EN == 0
1573+
__RV_CSR_CLEAR(CSR_MCACHE_CTL, MCACHE_CTL_DC_ECC_EN | MCACHE_CTL_DC_ECC_EXCP_EN | MCACHE_CTL_DC_ECC_CHK_EN);
1574+
#else
1575+
__RV_CSR_SET(CSR_MCACHE_CTL, MCACHE_CTL_DC_ECC_EN | MCACHE_CTL_DC_ECC_EXCP_EN | MCACHE_CTL_DC_ECC_CHK_EN);
1576+
#endif
1577+
#endif
1578+
EnableDCache();
1579+
}
1580+
#endif
1581+
1582+
/* Ensure previous L2/SMP/ILM/DLM/I-Cache/D-Cache configurations take effect */
1583+
__RWMB();
1584+
__FENCE_I();
1585+
15851586
#if defined(RUNMODE_BPU_EN)
15861587
#if RUNMODE_BPU_EN == 1
15871588
__RV_CSR_SET(CSR_MMISC_CTL, MMISC_CTL_BPU);

doc/source/changelog.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ This is release version of ``1.0.0`` of Nuclei SDK, which is still under develop
1212

1313
- Warn when ``CFG_IREGION_BASE_ADDR`` is defined as ``0`` and document the required compiler option.
1414
- Fix EvalSoC UART stop-bit and FIFO watermark configuration to update the intended control-register fields.
15-
- Enable SMP_ENB register of SMPCC with ``0xFFFFFFFF`` after L2 Cache enable to ensure SMP and IOCP consistency across cluster cores in ``system_evalsoc.c``.
15+
- Reorder ``_premain_init()`` cache initialization in ``system_evalsoc.c``: L2 Cache and SMP/IOCP EN are now initialized before L1 I/D Cache to ensure correct SMP coherency setup sequence.
1616

1717
V0.9.0
1818
------

0 commit comments

Comments
 (0)