blob: 492b6245b405d72d9899979f6f494eb4974ebb11 [file] [log] [blame]
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +08001/*
2 * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <unistd.h>
11
12#include "n200_func.h"
13#include "register.h"
14#include "common.h"
15#include "n200_timer.h"
xiaohu.huang38262102022-05-06 22:21:48 +080016#include "gcc_compiler_attributes.h"
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +080017#include "riscv_encoding.h"
18
19// Configure PMP to make all the address space accesable and executable
xiaohu.huang38262102022-05-06 22:21:48 +080020void pmp_open_all_space(void)
21{
22 // Config entry0 addr to all 1s to make the range cover all space
23 asm volatile("li x6, 0xffffffff" ::: "x6");
24 asm volatile("csrw pmpaddr0, x6" :::);
25 // Config entry0 cfg to make it NAPOT address mode, and R/W/X okay
26 asm volatile("li x6, 0x7f" ::: "x6");
27 asm volatile("csrw pmpcfg0, x6" :::);
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +080028}
29
xiaohu.huang38262102022-05-06 22:21:48 +080030void switch_m2u_mode(void)
31{
32 clear_csr(mstatus, MSTATUS_MPP);
33 //printf("\nIn the m2u function, the mstatus is 0x%x\n", read_csr(mstatus));
34 //printf("\nIn the m2u function, the mepc is 0x%x\n", read_csr(mepc));
35 asm volatile("la x6, 1f " ::: "x6");
36 asm volatile("csrw mepc, x6" :::);
37 asm volatile("mret" :::);
38 asm volatile("1:" :::);
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +080039}
40
41uint32_t mtime_lo(void)
42{
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080043#ifdef configSOC_TIMER_AS_TICK
xiaohu.huang38262102022-05-06 22:21:48 +080044 return *(volatile uint32_t *)TIMERE_LOW_REG;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080045#else
xiaohu.huang38262102022-05-06 22:21:48 +080046 return *(volatile uint32_t *)(TIMER_CTRL_ADDR + TIMER_MTIME);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080047#endif
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +080048}
49
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +080050uint32_t mtime_hi(void)
51{
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080052#ifdef configSOC_TIMER_AS_TICK
xiaohu.huang38262102022-05-06 22:21:48 +080053 return *(volatile uint32_t *)TIMERE_HIG_REG;
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080054#else
xiaohu.huang38262102022-05-06 22:21:48 +080055 return *(volatile uint32_t *)(TIMER_CTRL_ADDR + TIMER_MTIME + 4);
Xiaohu.Huanga2c5a042022-03-12 22:41:09 +080056#endif
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +080057}
58
59uint64_t get_timer_value(void)
60{
xiaohu.huang38262102022-05-06 22:21:48 +080061 while (1) {
62 uint32_t hi = mtime_hi();
63 uint32_t lo = mtime_lo();
64
65 if (hi == mtime_hi())
66 return ((uint64_t)hi << 32) | lo;
67 }
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +080068}
69
70uint32_t get_timer_freq(void)
71{
xiaohu.huang38262102022-05-06 22:21:48 +080072 return TIMER_FREQ;
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +080073}
74
75uint64_t get_instret_value(void)
76{
xiaohu.huang38262102022-05-06 22:21:48 +080077 while (1) {
78 uint32_t hi = read_csr(minstreth);
79 uint32_t lo = read_csr(minstret);
80
81 if (hi == read_csr(minstreth))
82 return ((uint64_t)hi << 32) | lo;
83 }
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +080084}
85
86uint64_t get_cycle_value(void)
87{
xiaohu.huang38262102022-05-06 22:21:48 +080088 while (1) {
89 uint32_t hi = read_csr(mcycleh);
90 uint32_t lo = read_csr(mcycle);
91
92 if (hi == read_csr(mcycleh))
93 return ((uint64_t)hi << 32) | lo;
94 }
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +080095}
96
97unsigned long interrupt_status_get(void)
98{
99 return read_csr(mstatus) >> 0x3;
100}
101
102void interrupt_disable(void)
103{
104 clear_csr(mstatus, MSTATUS_MIE);
105}
106
107void interrupt_enable(void)
108{
109 set_csr(mstatus, MSTATUS_MIE);
110}
111
112#ifndef CONFIG_N200_REVA
113
xiaohu.huang38262102022-05-06 22:21:48 +0800114uint32_t __noinline measure_cpu_freq(size_t n)
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +0800115{
xiaohu.huang38262102022-05-06 22:21:48 +0800116 uint32_t start_mtime, delta_mtime;
117 uint32_t mtime_freq = get_timer_freq();
118 // Don't start measuruing until we see an mtime tick
119 uint32_t tmp = mtime_lo();
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +0800120
xiaohu.huang38262102022-05-06 22:21:48 +0800121 do {
122 start_mtime = mtime_lo();
123 } while (start_mtime == tmp);
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +0800124
xiaohu.huang38262102022-05-06 22:21:48 +0800125 uint32_t start_mcycle = read_csr(mcycle);
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +0800126
xiaohu.huang38262102022-05-06 22:21:48 +0800127 do {
128 delta_mtime = mtime_lo() - start_mtime;
129 } while (delta_mtime < n);
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +0800130
xiaohu.huang38262102022-05-06 22:21:48 +0800131 uint32_t delta_mcycle = read_csr(mcycle) - start_mcycle;
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +0800132
xiaohu.huang38262102022-05-06 22:21:48 +0800133 return (delta_mcycle / delta_mtime) * mtime_freq +
134 ((delta_mcycle % delta_mtime) * mtime_freq) / delta_mtime;
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +0800135}
136
137uint32_t get_cpu_freq(void)
138{
xiaohu.huang38262102022-05-06 22:21:48 +0800139 uint32_t cpu_freq;
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +0800140
xiaohu.huang38262102022-05-06 22:21:48 +0800141 // warm up
142 measure_cpu_freq(1);
143 // measure for real
144 cpu_freq = measure_cpu_freq(100);
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +0800145
xiaohu.huang38262102022-05-06 22:21:48 +0800146 return cpu_freq;
Xiaohu.Huangf78b48b2022-01-17 10:41:38 +0800147}
148
149unsigned int xPortIsIsrContext(void)
150{
151 return (read_csr_msubmode & 0xff);
152}
153
154#else
155
156unsigned int xPortIsIsrContext(void)
157{
158 return read_csr_msubmode;
159}
160
161#endif