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