blob: d2d3d160d64e5c30c8ca2cdddd7f6435f16b5a48 [file] [log] [blame]
Xiaohu.Huangbe565062021-10-15 17:29:19 +08001// See LICENSE for license details.
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <unistd.h>
7
8#include "riscv_encoding.h"
9#include "n200_func.h"
10#include "register.h"
11#include "common.h"
12#include "n200_timer.h"
13#include "FreeRTOS.h"
14
15 // Configure PMP to make all the address space accesable and executable
16void pmp_open_all_space(void){
17 // Config entry0 addr to all 1s to make the range cover all space
18 asm volatile ("li x6, 0xffffffff":::"x6");
19 asm volatile ("csrw pmpaddr0, x6":::);
20 // Config entry0 cfg to make it NAPOT address mode, and R/W/X okay
21 asm volatile ("li x6, 0x7f":::"x6");
22 asm volatile ("csrw pmpcfg0, x6":::);
23}
24
25void switch_m2u_mode(void){
26 clear_csr (mstatus,MSTATUS_MPP);
27 //printf("\nIn the m2u function, the mstatus is 0x%x\n", read_csr(mstatus));
28 //printf("\nIn the m2u function, the mepc is 0x%x\n", read_csr(mepc));
29 asm volatile ("la x6, 1f ":::"x6");
30 asm volatile ("csrw mepc, x6":::);
31 asm volatile ("mret":::);
32 asm volatile ("1:":::);
33}
34
35uint32_t mtime_lo(void)
36{
37 return *(volatile uint32_t *)(TIMER_CTRL_ADDR + TIMER_MTIME);
38}
39
40
41uint32_t mtime_hi(void)
42{
43 return *(volatile uint32_t *)(TIMER_CTRL_ADDR + TIMER_MTIME + 4);
44}
45
46uint64_t get_timer_value(void)
47{
48 while (1) {
49 uint32_t hi = mtime_hi();
50 uint32_t lo = mtime_lo();
51 if (hi == mtime_hi())
52 return ((uint64_t)hi << 32) | lo;
53 }
54}
55
56uint32_t get_timer_freq(void)
57{
58 return TIMER_FREQ;
59}
60
61uint64_t get_instret_value(void)
62{
63 while (1) {
64 uint32_t hi = read_csr(minstreth);
65 uint32_t lo = read_csr(minstret);
66 if (hi == read_csr(minstreth))
67 return ((uint64_t)hi << 32) | lo;
68 }
69}
70
71uint64_t get_cycle_value(void)
72{
73 while (1) {
74 uint32_t hi = read_csr(mcycleh);
75 uint32_t lo = read_csr(mcycle);
76 if (hi == read_csr(mcycleh))
77 return ((uint64_t)hi << 32) | lo;
78 }
79}
80
81unsigned long interrupt_status_get(void)
82{
83 return read_csr(mstatus) >> 0x3;
84}
85
86void interrupt_disable(void)
87{
88 clear_csr(mstatus, MSTATUS_MIE);
89}
90
91void interrupt_enable(void)
92{
93 set_csr(mstatus, MSTATUS_MIE);
94}
95
96#ifndef N200_REVA
97
98uint32_t __attribute__((noinline)) measure_cpu_freq(size_t n)
99{
100 uint32_t start_mtime, delta_mtime;
101 uint32_t mtime_freq = get_timer_freq();
102
103 // Don't start measuruing until we see an mtime tick
104 uint32_t tmp = mtime_lo();
105 do {
106 start_mtime = mtime_lo();
107 } while (start_mtime == tmp);
108
109 uint32_t start_mcycle = read_csr(mcycle);
110
111 do {
112 delta_mtime = mtime_lo() - start_mtime;
113 } while (delta_mtime < n);
114
115 uint32_t delta_mcycle = read_csr(mcycle) - start_mcycle;
116
117 return (delta_mcycle / delta_mtime) * mtime_freq
118 + ((delta_mcycle % delta_mtime) * mtime_freq) / delta_mtime;
119}
120
121uint32_t get_cpu_freq(void)
122{
123 uint32_t cpu_freq;
124
125 // warm up
126 measure_cpu_freq(1);
127 // measure for real
128 cpu_freq = measure_cpu_freq(100);
129
130 return cpu_freq;
131}
132
133unsigned int xPortIsIsrContext(void)
134{
135 return (read_csr_msubmode & 0xff);
136}
137
138#else
139
140unsigned int xPortIsIsrContext(void)
141{
142 return read_csr_msubmode;
143}
144
145#endif