source: trunk/hal/tsar_mips32/core/hal_special.c

Last change on this file was 686, checked in by alain, 6 years ago

cosmetic

File size: 8.7 KB
Line 
1/*
2 * hal_special.c - implementation of Generic Special Register Access API for TSAR-MIPS32
3 *
4 * Author Alain Greiner (2016,2017,2018,2019,2020)
5 *
6 * Copyright (c) UPMC Sorbonne Universites
7 *
8 * This file is part of ALMOS-MKH..
9 *
10 * ALMOS-MKH. is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
14 * ALMOS-MKH. is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ALMOS-MKH.; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24
25#include <hal_kernel_types.h>
26#include <hal_special.h>
27#include <hal_exception.h>
28#include <core.h>
29#include <thread.h>
30
31/**** Forward declarations ****/
32
33struct thread_s;
34
35
36//////////////////////////////////////////////////////////////////////////////////
37// Extern global variables
38//////////////////////////////////////////////////////////////////////////////////
39
40extern cxy_t local_cxy;
41extern void hal_kentry_enter( void );
42
43////////////////////////////////////////////////////////////////////////////////
44// For the TSAR architecture, this function registers the address of the
45// hal_kentry_enter() function in the MIPS32 cp0_ebase register.
46////////////////////////////////////////////////////////////////////////////////
47void hal_set_kentry( void )
48{
49 uint32_t kentry = (uint32_t)(&hal_kentry_enter);
50
51 asm volatile("mtc0 %0, $15, 1" : : "r" (kentry) );
52}
53
54/////////////////////////////////////////////////////////////////////////////////
55// For the TSAR architecture, this function register the physical address of
56// the first level page table (PT1) in the PTPR register.
57// It activates the intructions MMU, and de-activates the data MMU, that is NOT
58// used by the kernel for 32 bits architectures.
59/////////////////////////////////////////////////////////////////////////////////
60void hal_mmu_init( gpt_t * gpt )
61{
62 // set PT1 base address in cp2_ptpr register
63 uint32_t ptpr = (((uint32_t)gpt->ptr) >> 13) | (local_cxy << 19);
64 asm volatile ( "mtc2 %0, $0 \n" : : "r" (ptpr) );
65
66 // set ITLB | ICACHE | DCACHE bits in cp2_mode register
67 asm volatile ( "ori $26, $0, 0xB \n"
68 "mtc2 $26, $1 \n" );
69}
70
71////////////////////////////////////////////////////////////////////////////////
72// For the TSAR architecture, this function returns the current value
73// of the 32 bits c0_sr register
74////////////////////////////////////////////////////////////////////////////////
75inline reg_t hal_get_sr( void )
76{
77 reg_t sr;
78
79 asm volatile ("mfc0 %0, $12" : "=&r" (sr));
80
81 return sr;
82}
83
84////////////////////////////////////////////////////////////////////////////////
85// For the TSAR architecture, this function returns the 10 LSB bits
86// of the 32 bits c0_ebase register : Y (4 bits) | Y (4 bits) | LID (2 bits)
87////////////////////////////////////////////////////////////////////////////////
88inline gid_t hal_get_gid( void )
89{
90 uint32_t proc_id;
91
92 asm volatile ("mfc0 %0, $15, 1" : "=&r" (proc_id));
93
94 return (proc_id & 0x3FF); // 4/4/2 format for TSAR
95}
96
97////////////////////////////////////////////////////////////////////////////////
98// For the TSAR architecture, this function returns the current value
99// of the 32 bits c0_count cycle counter.
100////////////////////////////////////////////////////////////////////////////////
101inline reg_t hal_time_stamp( void )
102{
103 reg_t count;
104
105 asm volatile ("mfc0 %0, $9" : "=&r" (count));
106
107 return count;
108}
109
110///////////////////////////////
111uint64_t hal_get_cycles( void )
112{
113 uint64_t cycles; // absolute time to be returned
114 uint32_t last_count; // last registered cycles count
115 uint32_t current_count; // current cycles count
116 uint32_t elapsed;
117
118 core_t * core = CURRENT_THREAD->core;
119
120 // get last registered time stamp
121 last_count = core->time_stamp;
122
123 // get current time stamp from hardware register
124 current_count = hal_time_stamp();
125
126 // compute number of elapsed cycles, taking into account 32 bits register wrap
127 if(current_count < last_count) elapsed = (0xFFFFFFFF - last_count) + current_count;
128 else elapsed = current_count - last_count;
129
130 // compute absolute time
131 cycles = core->cycles + elapsed;
132
133 // update core time
134 core->time_stamp = current_count;
135 core->cycles = cycles;
136
137 hal_fence();
138
139 return cycles;
140}
141
142////////////////////////////////////////////////////////////////////////////////
143// For the TSAR architecture, this function returns the current value
144// of the 32 bits c0_th register.
145////////////////////////////////////////////////////////////////////////////////
146inline struct thread_s * hal_get_current_thread( void )
147{
148 void * thread_ptr;
149
150 asm volatile ("mfc0 %0, $4, 2" : "=&r" (thread_ptr));
151
152 return thread_ptr;
153}
154
155////////////////////////////////////////////////////////////////////////////////
156// For the TSAR architecture, this function set a new value
157// to the 32 bits c0_th register.
158////////////////////////////////////////////////////////////////////////////////
159void hal_set_current_thread( struct thread_s * thread )
160{
161 asm volatile ("mtc0 %0, $4, 2" : : "r" (thread));
162}
163
164///////////////////////////
165void hal_fpu_enable( void )
166{
167 // set CU1 bit (FPU enable) in c0_sr
168 asm volatile
169 ( ".set noat \n"
170 "lui $27, 0x2000 \n"
171 "mfc0 $1, $12 \n"
172 "or $27, $1, $27 \n"
173 "mtc0 $27, $12 \n"
174 ".set at \n" );
175
176 // set CU1 bit in calling thread UZONE
177 uint32_t * uzone = CURRENT_THREAD->uzone_current;
178 uzone[34] |= 0x20000000;
179}
180
181////////////////////////////
182void hal_fpu_disable( void )
183{
184 // reset CU1 bit (FPU enable) in c0_sr
185 asm volatile
186 ( ".set noat \n"
187 "lui $27, 0xDFFF \n"
188 "ori $27, $27, 0xFFFF \n"
189 "mfc0 $1, $12 \n"
190 "and $27, $1, $27 \n"
191 "mtc0 $27, $12 \n"
192 ".set at \n");
193
194 // reset CU1 bit in calling thread UZONE
195 uint32_t * uzone = CURRENT_THREAD->uzone_current;
196 uzone[34] &= 0xDFFFFFFF;
197}
198
199////////////////////////////////////////////////////////////////////////////////
200// For the TSAR architecture, this function returns the current value
201// of the 32 bits sp_29 register.
202////////////////////////////////////////////////////////////////////////////////
203reg_t hal_get_sp( void )
204{
205 register uint32_t sp;
206
207 asm volatile ("or %0, $0, $29" : "=&r" (sp));
208
209 return sp;
210}
211
212//////////////////////////////////
213uint32_t hal_get_bad_vaddr( void )
214{
215 register uint32_t bad_va;
216
217 asm volatile
218 ( "mfc0 %0, $8 \n"
219 : "=&r" (bad_va) );
220
221 return bad_va;
222}
223
224////////////////////////////////////////////
225uint32_t hal_uncached_read( uint32_t * ptr )
226{
227 register uint32_t val;
228
229 asm volatile
230 ( "ll %0, (%1) \n"
231 : "=&r"(val) : "r" (ptr) );
232
233 return val;
234}
235
236//////////////////////////////////////////
237void hal_invalid_dcache_line( void * ptr )
238{
239 asm volatile
240 ( "cache %0, (%1) \n"
241 "sync \n"
242 : : "i" (0x11) , "r" (ptr) );
243}
244
245/////////////////////////////
246inline void hal_fence( void )
247{
248 asm volatile ("sync");
249}
250
251/////////////////////////////
252inline void hal_rdbar( void )
253{
254 asm volatile( "" ::: "memory" );
255}
256
257///////////////////////////
258void hal_core_sleep( void )
259{
260 while( 1 ) asm volatile ("wait");
261}
262
263//////////////////////////////////////
264void hal_fixed_delay( uint32_t delay )
265{
266 asm volatile
267 ( ".set noreorder \n"
268 "or $27, %0, $0 \n"
269 "1: \n"
270 "addi $27, $27, -1 \n"
271 "nop \n"
272 "bne $27, $0, 1b \n"
273 "nop \n"
274 ".set reorder \n"
275 : : "r" (delay>>2) : "$27" );
276}
277
278//////////////////////////////////////////////////
279void hal_get_mmu_excp( intptr_t * mmu_ins_excp_code,
280 intptr_t * mmu_ins_bad_vaddr,
281 intptr_t * mmu_dat_excp_code,
282 intptr_t * mmu_dat_bad_vaddr )
283{
284 asm volatile
285 ( "mfc2 %0, $11 \n"
286 "mfc2 %1, $13 \n"
287 "mfc2 %2, $12 \n"
288 "mfc2 %3, $14 \n"
289 : "=&r"(*mmu_ins_excp_code),
290 "=&r"(*mmu_ins_bad_vaddr),
291 "=&r"(*mmu_dat_excp_code),
292 "=&r"(*mmu_dat_bad_vaddr) );
293}
294
295
Note: See TracBrowser for help on using the repository browser.