eeb10c4e41c8dfe9800eb5a2744194cf1ee41cbf
[akaros.git] / kern / arch / sparc / sparc.h
1 #ifndef ROS_INC_SPARC_H
2 #define ROS_INC_SPARC_H
3
4 #define CORE_ID_REG     %asr15
5 #define NUM_CORES_REG   %asr14
6 #define MEMSIZE_MB_REG  %asr13
7
8 #define PSR_CWP         0x0000001F
9 #define PSR_ET          0x00000020
10 #define PSR_PS          0x00000040
11 #define PSR_S           0x00000080
12 #define PSR_PIL         0x00000F00
13 #define PSR_EF          0x00001000
14 #define PSR_EC          0x00002000
15 #define PSR_RESERVED    0x000FC000
16 #define PSR_ICC         0x00F00000
17 #define PSR_VER         0x0F000000
18 #define PSR_IMPL        0xF0000000
19
20 #ifndef __ASSEMBLER__
21
22 #define STR(arg) #arg
23 #define XSTR(arg) STR(arg)
24
25 #include <ros/common.h>
26
27 static __inline uint32_t read_psr(void) __attribute__((always_inline));
28 static __inline uint32_t read_wim(void) __attribute__((always_inline));
29 static __inline uint32_t read_tbr(void) __attribute__((always_inline));
30 static __inline uint32_t read_mmu_reg(uint32_t which) __attribute__((always_inline));
31 static __inline uint32_t read_y(void) __attribute__((always_inline));
32 static __inline uint32_t read_fsr(void) __attribute__((always_inline));
33 static __inline uint64_t read_perfctr(uint32_t core, uint32_t which) __attribute__((always_inline));
34 static __inline void write_psr(uint32_t val) __attribute__((always_inline));
35 static __inline void write_wim(uint32_t val) __attribute__((always_inline));
36 static __inline void write_tbr(uint32_t val) __attribute__((always_inline));
37 static __inline void write_mmu_reg(uint32_t which, uint32_t val) __attribute__((always_inline));
38 static __inline void write_y(uint32_t val) __attribute__((always_inline));
39 static __inline void write_fsr(uint32_t val) __attribute__((always_inline));
40 static __inline uint32_t memsize_mb(void) __attribute__((always_inline));
41 static __inline uint32_t mmu_probe(uint32_t va) __attribute__((always_inline));
42 static __inline uint32_t send_ipi(uint32_t dst) __attribute__((always_inline));
43
44 void flush_windows();
45
46 #define store_alternate(addr,asi,data) ({ uint32_t __my_addr = (addr); uint32_t __my_data = (data); __asm__ __volatile__ ("sta %0,[%1] %2" : : "r"(__my_data),"r"(__my_addr),"i"(asi)); })
47 #define load_alternate(addr,asi) ({ uint32_t __my_addr = (addr); uint32_t __my_data; __asm__ __volatile__ ("lda [%1] %2,%0" : "=r"(__my_data) : "r"(__my_addr),"i"(asi)); __my_data; })
48
49 static __inline uint32_t
50 read_psr(void)
51 {
52         uint32_t reg;
53         asm volatile ("mov %%psr,%0" : "=r"(reg));
54         return reg;
55 }
56
57 static __inline uint32_t
58 read_wim(void)
59 {
60         uint32_t reg;
61         asm volatile ("mov %%wim,%0" : "=r"(reg));
62         return reg;
63 }
64
65 static __inline uint32_t
66 read_tbr(void)
67 {
68         uint32_t reg;
69         asm volatile ("mov %%tbr,%0" : "=r"(reg));
70         return reg;
71 }
72
73 static __inline uint32_t
74 read_mmu_reg(uint32_t which)
75 {
76         return load_alternate(which,4);
77 }
78
79 static __inline uint32_t
80 read_y(void)
81 {
82         uint32_t reg;
83         asm volatile ("mov %%y,%0" : "=r"(reg));
84         return reg;
85 }
86
87 static __inline uint32_t
88 read_fsr(void)
89 {
90         uint32_t reg;
91         asm volatile ("st %%fsr,%0" : "=m"(reg));
92         return reg;
93 }
94
95 static __inline uint64_t
96 read_perfctr(uint32_t cpu, uint32_t which)
97 {
98         register uint32_t hi asm("o0"), lo asm("o1");
99         intptr_t addr = cpu<<10 | which<<3;
100         #ifdef ROS_KERNEL
101                 hi = load_alternate(addr,2);
102                 lo = load_alternate(addr+4,2);
103         #else
104                 asm volatile("mov %2,%%o0; ta 9"
105                              : "=r"(hi),"=r"(lo) : "r"(addr));
106         #endif
107         return (((uint64_t)hi) << 32) | lo;
108 }
109
110 static __inline void
111 write_psr(uint32_t val)
112 {
113         asm volatile ("mov %0,%%psr; nop;nop;nop" : : "r"(val) : "memory");
114 }
115
116 static __inline void
117 write_wim(uint32_t val)
118 {
119         asm volatile ("mov %0,%%wim; nop;nop;nop" : : "r"(val) : "memory");
120 }
121
122 static __inline void
123 write_tbr(uint32_t val)
124 {
125         asm volatile ("mov %0,%%tbr; nop;nop;nop" : : "r"(val) : "memory");
126 }
127
128 static __inline void
129 write_mmu_reg(uint32_t which, uint32_t val)
130 {
131         store_alternate(which,4,val);
132 }
133
134 static __inline void
135 write_y(uint32_t val)
136 {
137         asm volatile ("mov %0,%%y; nop;nop;nop" : : "r"(val) : "memory");
138 }
139
140 static __inline void
141 write_fsr(uint32_t val)
142 {
143         asm volatile ("ld %0,%%fsr; nop;nop;nop" : : "m"(val) : "memory");
144 }
145
146 static __inline uint32_t
147 memsize_mb(void)
148 {
149         uint32_t reg;
150         __asm__ __volatile__("mov %" XSTR(MEMSIZE_MB_REG) ",%0" : "=r"(reg));
151         return reg;
152 }
153
154 static __inline uint32_t
155 num_cores(void)
156 {
157         uint32_t reg;
158         __asm__ __volatile__("mov %" XSTR(NUM_CORES_REG) ",%0" : "=r"(reg));
159         return reg;
160 }
161
162 static __inline uint32_t
163 mmu_probe(uint32_t va)
164 {
165         return load_alternate((va & ~0xFFF) | 0x400, 3);
166 }
167
168 static __inline void
169 store_iobus(uint32_t device, uint32_t addr, uint32_t data)
170 {
171         store_alternate(device << 16 | addr, 2, data);
172 }
173
174 static __inline uint32_t
175 send_ipi(uint32_t dst)
176 {
177         store_iobus(2,dst<<10,0);
178         return 0;
179 }
180
181 // arm the calling core's interrupt timer.
182 // enable must be 1 or 0; clocks must be a power of 2
183 static __inline void
184 sparc_set_timer(uint32_t clocks, uint32_t enable)
185 {
186         store_iobus(1,0,enable << 24 | (clocks-1));
187 }
188
189 #endif /* !__ASSEMBLER__ */
190
191 #endif /* !ROS_INC_X86_H */