فهرست منبع

SoC/evalsoc: make _premain_init more robust for n100 cpu

Signed-off-by: Huaqi Fang <578567190@qq.com>
Huaqi Fang 1 ماه پیش
والد
کامیت
95f4ee94d4

+ 4 - 0
SoC/evalsoc/Common/Source/GCC/startup_evalsoc.S

@@ -206,6 +206,7 @@ _start:
     la sp, _sp
 #endif
 
+#if !(defined(CPU_SERIES) && CPU_SERIES == 100)
     /*
      * Set the the NMI base mnvec to share
      * with mtvec by setting CSR_MMISC_CTL
@@ -222,6 +223,7 @@ _start:
     csrs CSR_MMISC_CTL, t0
 #else
     csrc CSR_MMISC_CTL, t0
+#endif
 #endif
 
     /*
@@ -370,9 +372,11 @@ __skip_init:
      */
     call _premain_init
 
+#if !(defined(CPU_SERIES) && CPU_SERIES == 100)
     /* BPU cold bringup need time, so enable BPU before enter to main */
     li t0, MMISC_CTL_BPU
     csrs CSR_MMISC_CTL, t0
+#endif
 
     // Interrupt is still disabled here
     /* ===== Call SMP Main Function  ===== */

+ 16 - 5
SoC/evalsoc/Common/Source/evalsoc_common.c

@@ -5,6 +5,17 @@ __STATIC_FORCEINLINE uint64_t get_timer_freq(void)
     return (uint64_t)SOC_TIMER_FREQ;
 }
 
+__STATIC_FORCEINLINE uint32_t get_time(void)
+{
+#if defined(CPU_SERIES) && CPU_SERIES == 100
+    // NOTE: when CSR_MIRGB_INFO CSR exist and not zero, it means eclic and systimer present
+    if (__RV_CSR_READ(CSR_MIRGB_INFO) == 0) {
+        return __RV_CSR_READ(CSR_MTIME);
+    }
+#endif
+    return (uint32_t)SysTimer_GetLoadValue();
+}
+
 // optimize measure_cpu_freq function with Os/O0
 // to get a correct cpu frequency, which
 // is important for flashxip linker script
@@ -22,14 +33,14 @@ uint32_t measure_cpu_freq(uint32_t n)
     uint64_t mtime_freq = get_timer_freq();
 
     // Don't start measuruing until we see an mtime tick
-    uint32_t tmp = (uint32_t)SysTimer_GetLoadValue();
+    uint32_t tmp = (uint32_t)get_time();
     do {
-        start_mtime = (uint32_t)SysTimer_GetLoadValue();
+        start_mtime = (uint32_t)get_time();
         start_mcycle = __RV_CSR_READ(CSR_MCYCLE);
     } while (start_mtime == tmp);
 
     do {
-        delta_mtime = (uint32_t)SysTimer_GetLoadValue() - start_mtime;
+        delta_mtime = (uint32_t)get_time() - start_mtime;
         delta_mcycle = __RV_CSR_READ(CSR_MCYCLE) - start_mcycle;
     } while (delta_mtime < n);
 
@@ -75,10 +86,10 @@ void delay_1ms(uint32_t count)
     uint64_t delay_ticks = (SOC_TIMER_FREQ * (uint64_t)count) / 1000;
 
 #if defined(__SYSTIMER_PRESENT) && (__SYSTIMER_PRESENT == 1)
-    start_mtime = SysTimer_GetLoadValue();
+    start_mtime = get_time();
 
     do {
-        delta_mtime = SysTimer_GetLoadValue() - start_mtime;
+        delta_mtime = get_time() - start_mtime;
     } while (delta_mtime < delay_ticks);
 #else
     #warning "delay_1ms function require system timer present, if you are using this, it will not work"

+ 8 - 7
SoC/evalsoc/Common/Source/system_evalsoc.c

@@ -880,15 +880,16 @@ void ECLIC_Interrupt_Init(void)
 {
 #if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1)
 #if defined(CPU_SERIES) && CPU_SERIES == 100
+    // NOTE: when CSR_MIRGB_INFO CSR exist and not zero, it means eclic and systimer present
+    if (__RV_CSR_READ(CSR_MIRGB_INFO)) {
 #if defined(__SYSTIMER_PRESENT) && (__SYSTIMER_PRESENT == 1)
-    // NOTE: Workaround to make n100 software able to run on qemu and xlmodel
-    // TIMECMPH in n100 is zero, so we need to manually set high 32b of TIMECMP to 0
-    SysTimer->RESERVED2 = 0;
-    // NOTE: Workaround for Nuclei Qemu 2025.10, need to read higher 32b then it can be really clear to 0
-    SysTimer->MTIMERCMP = SysTimer->RESERVED2;
-    __RWMB();
+        // NOTE: Workaround to make n100 software able to run on qemu and xlmodel
+        // TIMECMPH in n100 is zero, so we need to manually set high 32b of TIMECMP to 0
+        SysTimer->RESERVED2 = 0;
+        // NOTE: Workaround for Nuclei Qemu 2025.10, need to read higher 32b then it can be really clear to 0
+        SysTimer->MTIMERCMP = SysTimer->RESERVED2;
+        __RWMB();
 #endif
-    if (1) {
 #else
     unsigned long mcfg_info;
     mcfg_info = __RV_CSR_READ(CSR_MCFG_INFO);