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

Last change on this file since 657 was 625, checked in by alain, 6 years ago

Fix a bug in the vmm_remove_vseg() function: the physical pages
associated to an user DATA vseg were released to the kernel when
the target process descriptor was in the reference cluster.
This physical pages release should be done only when the page
forks counter value is zero.
All other modifications are cosmetic.

File size: 8.6 KB
Line 
1/*
2 * hal_special.c - implementation of Generic Special Register Access API for TSAR-MIPS32
3 *
4 * Author    Alain Greiner (2016,2017)
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.
58/////////////////////////////////////////////////////////////////////////////////
59void hal_mmu_init( gpt_t * gpt )
60{
61    // set PT1 base address in cp2_ptpr register
62    uint32_t ptpr = (((uint32_t)gpt->ptr) >> 13) | (local_cxy << 19);
63    asm volatile ( "mtc2   %0,   $0         \n" : : "r" (ptpr) );
64
65    // set ITLB | ICACHE | DCACHE bits in cp2_mode register
66    asm volatile ( "ori    $26,  $0,  0xB   \n" 
67                   "mtc2   $26,  $1         \n" );
68}
69
70////////////////////////////////////////////////////////////////////////////////
71// For the TSAR architecture, this function returns the current value
72// of the 32 bits c0_sr register
73////////////////////////////////////////////////////////////////////////////////
74inline reg_t hal_get_sr( void )
75{
76    reg_t sr;
77
78        asm volatile ("mfc0    %0,    $12" : "=&r" (sr));
79
80        return sr;
81}
82
83////////////////////////////////////////////////////////////////////////////////
84// For the TSAR architecture, this function returns the 10 LSB bits
85// of the 32 bits c0_ebase register : Y (4 bits) | Y (4 bits) | LID (2 bits)
86////////////////////////////////////////////////////////////////////////////////
87inline gid_t hal_get_gid( void )
88{
89        uint32_t proc_id;
90
91        asm volatile ("mfc0    %0,  $15, 1" : "=&r" (proc_id));
92
93        return (proc_id & 0x3FF);  // 4/4/2 format for TSAR
94}
95
96////////////////////////////////////////////////////////////////////////////////
97// For the TSAR architecture, this function returns the current value
98// of the 32 bits c0_count cycle counter.
99////////////////////////////////////////////////////////////////////////////////
100inline reg_t hal_time_stamp( void )
101{
102    reg_t count;
103
104        asm volatile ("mfc0   %0,  $9" : "=&r" (count));
105
106    return count;
107}
108
109///////////////////////////////
110uint64_t hal_get_cycles( void )
111{
112        uint64_t cycles;                // absolute time to be returned
113    uint32_t last_count;            // last registered cycles count
114    uint32_t current_count;         // current cycles count
115        uint32_t elapsed;
116
117    core_t * core = CURRENT_THREAD->core;
118
119    // get last registered time stamp
120        last_count = core->time_stamp;
121
122    // get current time stamp from hardware register
123        current_count = hal_time_stamp();
124
125        // compute number of elapsed cycles, taking into account 32 bits register wrap
126        if(current_count < last_count) elapsed = (0xFFFFFFFF - last_count) + current_count;
127        else                           elapsed = current_count - last_count;
128
129    // compute absolute time
130        cycles = core->cycles + elapsed;
131
132        // update core time
133        core->time_stamp = current_count;
134        core->cycles     = cycles;
135
136        hal_fence();
137
138        return cycles;
139}
140
141////////////////////////////////////////////////////////////////////////////////
142// For the TSAR architecture, this function returns the current value
143// of the 32 bits c0_th register.
144////////////////////////////////////////////////////////////////////////////////
145inline struct thread_s * hal_get_current_thread( void )
146{
147        void * thread_ptr;
148 
149        asm volatile ("mfc0    %0,  $4,  2" : "=&r" (thread_ptr));
150
151        return thread_ptr;
152}
153
154////////////////////////////////////////////////////////////////////////////////
155// For the TSAR architecture, this function set a new value
156// to the 32 bits c0_th register.
157////////////////////////////////////////////////////////////////////////////////
158void hal_set_current_thread( struct thread_s * thread )
159{ 
160        asm volatile ("mtc0    %0,  $4,  2" : : "r" (thread));
161}
162
163///////////////////////////
164void hal_fpu_enable( void )
165{
166    // set CU1 bit (FPU enable) in c0_sr
167        asm volatile 
168        ( ".set noat                         \n"
169      "lui    $27,    0x2000             \n"
170      "mfc0   $1,     $12                \n"
171      "or     $27,    $1,    $27         \n"
172      "mtc0   $27,    $12                \n"
173      ".set at                           \n" );
174
175    // set CU1 bit in calling thread UZONE
176    uint32_t * uzone = CURRENT_THREAD->uzone_current;
177    uzone[34] |= 0x20000000;
178}
179
180////////////////////////////
181void hal_fpu_disable( void )
182{
183    // reset CU1 bit (FPU enable) in c0_sr
184        asm volatile 
185        ( ".set noat                         \n"
186      "lui    $27,    0xDFFF             \n"
187          "ori    $27,    $27,   0xFFFF      \n"
188      "mfc0   $1,     $12                \n"
189      "and    $27,    $1,    $27         \n"
190      "mtc0   $27,    $12                \n"
191          ".set at                           \n");
192
193    // reset CU1 bit in calling thread UZONE
194    uint32_t * uzone = CURRENT_THREAD->uzone_current;
195    uzone[34] &= 0xDFFFFFFF;
196}
197
198////////////////////////////////////////////////////////////////////////////////
199// For the TSAR architecture, this function returns the current value
200// of the 32 bits sp_29 register.
201////////////////////////////////////////////////////////////////////////////////
202reg_t hal_get_sp( void )
203{
204        register uint32_t sp;
205 
206        asm volatile ("or    %0,   $0,   $29" : "=&r" (sp));
207 
208        return sp;
209}
210
211//////////////////////////////////
212uint32_t hal_get_bad_vaddr( void )
213{
214        register uint32_t bad_va;
215
216        asm volatile
217    ( "mfc0    %0,  $8  \n"
218      : "=&r" (bad_va) );
219
220        return bad_va;
221}
222
223////////////////////////////////////////////
224uint32_t hal_uncached_read( uint32_t * ptr )
225{
226        register uint32_t val;
227
228        asm volatile
229        ( "ll    %0,     (%1)  \n"
230      : "=&r"(val) : "r" (ptr) );
231
232        return val;
233}
234
235//////////////////////////////////////////
236void hal_invalid_dcache_line( void * ptr )
237{
238        asm volatile
239        ( "cache    %0,     (%1)              \n"
240          "sync                               \n"
241          : : "i" (0x11) , "r" (ptr) );
242}
243
244/////////////////////////////
245inline void hal_fence( void )
246{
247        asm volatile ("sync");
248}
249
250/////////////////////////////
251inline void hal_rdbar( void )
252{
253        asm volatile( "" ::: "memory" );
254}
255
256///////////////////////////
257void hal_core_sleep( void )
258{
259        while( 1 ) asm volatile ("wait");
260}
261
262//////////////////////////////////////
263void hal_fixed_delay( uint32_t delay )
264{ 
265    asm volatile
266    ( ".set noreorder        \n"
267      "or    $27,  %0,  $0   \n"
268      "1:                    \n"
269      "addi  $27, $27,  -1   \n"
270      "nop                   \n"
271      "bne   $27,  $0,  1b   \n"
272      "nop                   \n"
273      ".set reorder          \n"
274      : : "r" (delay>>2) : "$27" );
275}
276
277//////////////////////////////////////////////////
278void hal_get_mmu_excp( intptr_t * mmu_ins_excp_code,
279                       intptr_t * mmu_ins_bad_vaddr,
280                       intptr_t * mmu_dat_excp_code,
281                       intptr_t * mmu_dat_bad_vaddr )
282{
283    asm volatile
284    ( "mfc2   %0,    $11        \n"
285      "mfc2   %1,    $13        \n"
286      "mfc2   %2,    $12        \n"
287      "mfc2   %3,    $14        \n"
288      : "=&r"(*mmu_ins_excp_code),
289        "=&r"(*mmu_ins_bad_vaddr),
290        "=&r"(*mmu_dat_excp_code),
291        "=&r"(*mmu_dat_bad_vaddr) );
292}
293
Note: See TracBrowser for help on using the repository browser.