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