VMM: Clean up per-cpu VMCS state
[akaros.git] / kern / arch / riscv / arch.h
1 #pragma once
2
3 #include <ros/arch/arch.h>
4 #include <arch/mmu.h>
5 #include <ros/common.h>
6 #include <ros/arch/membar.h>
7 #include <arch/riscv.h>
8 #include <arch/time.h>
9
10 /* Arch Constants */
11 #define ARCH_CL_SIZE 64
12
13 void print_cpuinfo(void);
14 void show_mapping(pgdir_t pgdir, uintptr_t start, size_t size);
15 void backtrace(void);
16
17 static __inline void breakpoint(void)
18 {
19         asm volatile ("break");
20 }
21
22 static __inline void tlbflush(void)
23 {
24         lcr3(rcr3());
25 }
26
27 static __inline void invlpg(void *addr)
28
29         tlbflush();
30 }
31
32 static __inline void icache_flush_page(void* va, void* kva)
33 {
34         asm volatile ("fence.i");
35 }
36
37 static __inline uint64_t read_tsc(void)
38 {
39         unsigned long t;
40         asm volatile ("rdtime %0" : "=r"(t));
41         return t;
42 }
43
44 /* Continuing the poor tradition of x86 opcode functions... */
45 static __inline uint64_t read_tscp(void)
46 {
47         return read_tsc();
48 }
49
50 static __inline uint64_t read_tsc_serialized(void)
51 {
52         mb();
53         return read_tsc();
54 }
55
56 static __inline uintptr_t enable_fp(void)
57 {
58         return setpcr(PCR_SR, SR_EF);
59 }
60
61 static __inline uintptr_t enable_irq(void)
62 {
63         return setpcr(PCR_SR, SR_ET);
64 }
65
66 static __inline uintptr_t disable_irq(void)
67 {
68         return clearpcr(PCR_SR, SR_ET);
69 }
70
71 static __inline void restore_irq(uintptr_t val)
72 {
73         mtpcr(PCR_SR, val);
74 }
75
76 static __inline int irq_is_enabled(void)
77 {
78         return mfpcr(PCR_SR) & SR_ET;
79 }
80
81 static __inline void enable_irqsave(int8_t* state)
82 {
83         // *state tracks the number of nested enables and disables
84         // initial value of state: 0 = first run / no favorite
85         // > 0 means more enabled calls have been made
86         // < 0 means more disabled calls have been made
87         // Mostly doing this so we can call disable_irqsave first if we want
88
89         // one side or another "gets a point" if interrupts were already the
90         // way it wanted to go.  o/w, state stays at 0.  if the state was not 0
91         // then, enabling/disabling isn't even an option.  just increment/decrement
92
93         // if enabling is winning or tied, make sure it's enabled
94         if ((*state == 0) && !irq_is_enabled())
95                 enable_irq();
96         else
97                 (*state)++;
98 }
99
100 static __inline void disable_irqsave(int8_t* state)
101 {
102         if ((*state == 0) && irq_is_enabled())
103                 disable_irq();
104         else 
105                 (*state)--;
106 }
107
108 static __inline void cpu_relax(void)
109 {
110         // compute and use 0/0, which stalls Rocket for dozens of cycles
111         long scratch;
112         asm volatile ("div %0, zero, zero; move %0, %0" : "=r"(scratch));
113 }
114
115 static __inline void clflush(uintptr_t* addr)
116 {
117 }
118
119 /* os_coreid -> hw_coreid */
120 static __inline int get_hw_coreid(int coreid)
121 {
122         return coreid;
123 }
124
125 static __inline int hw_core_id(void)
126 {
127         return mfpcr(PCR_COREID);
128 }
129
130 /* hw_coreid -> os_coreid */
131 static __inline int get_os_coreid(int hw_coreid)
132 {
133         return hw_coreid;
134 }
135
136 /* core_id() returns the OS core number, not to be confused with the
137  * hardware-specific core identifier (such as the lapic id) returned by
138  * hw_core_id() */
139 static __inline int core_id(void)
140 {
141         return get_os_coreid(hw_core_id());
142 }
143
144 static __inline int core_id_early(void)
145 {
146         return core_id();
147 }
148
149 static __inline void cache_flush(void)
150 {
151 }
152
153 static __inline void reboot(void)
154 {
155         extern void cputchar(int ch);
156         cputchar(0);
157 }
158
159 extern void cpu_halt(void);
160
161 static inline void prefetch(void *addr)
162 {
163 }
164
165 static inline void prefetchw(void *addr)
166 {
167 }