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