source: trunk/kernel/kern/core.c @ 46

Last change on this file since 46 was 23, checked in by alain, 8 years ago

Introduce syscalls.

File size: 5.9 KB
RevLine 
[1]1/*
2 * core.c - core descriptor access function.
[19]3 *
[1]4 * Author  Ghassan Almaless (2008,2009,2010,2011,2012)
5 *         Mohamed Lamine Karaoui (2015)
6 *         Alain Greiner (2016)
7 *
8 * Copyright (c) UPMC Sorbonne Universites
9 *
10 * This file is part of ALMOS-MKH.
11 *
12 * ALMOS-MKH.is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; version 2.0 of the License.
15 *
16 * ALMOS-MKH is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
23 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
[14]26#include <kernel_config.h>
[1]27#include <hal_types.h>
28#include <hal_special.h>
29#include <errno.h>
30#include <printk.h>
31#include <thread.h>
[5]32#include <chdev.h>
[1]33#include <dev_icu.h>
34#include <rpc.h>
35#include <cluster.h>
36#include <kmem.h>
37#include <dqdt.h>
38#include <core.h>
39
40/////////////////////////////////
[19]41void core_init( core_t    * core,
42                lid_t       lid,
[5]43                gid_t       gid )
[1]44{
45        core->lid               = lid;
46        core->gid               = gid;
47        core->cycles            = 0;
48        core->time_stamp        = 0;
49        core->ticks_nr          = 0;
50        core->ticks_period      = CONFIG_SCHED_TICK_PERIOD;
51        core->usage             = 0;
52        core->spurious_irqs     = 0;
[19]53        core->rpc_threads       = 0;
[1]54
55        rpc_fifo_init( &core->rpc_fifo );
56
[19]57        list_root_init( &core->rpc_free_list );
[1]58
[19]59        core->thread_rpc        = NULL;
60        core->thread_idle       = NULL;
61        core->fpu_owner         = NULL;
[1]62        core->rand_last         =  hal_time_stamp() & 0xFFF;
63
64        sched_init( core );
65}
66
67//////////////////////////////////////////////
68inline uint32_t core_get_rand( core_t * core )
69{
[19]70        uint32_t value  = ((core->rand_last * CONFIG_RDNG_PARAM_A) +
71                            CONFIG_RDNG_PARAM_C) ^ (hal_time_stamp() & 0xFFF);
72        core->rand_last = value;
73        return value;
[1]74}
75
76////////////////////////////////////////////////
77inline uint64_t core_get_cycles( core_t * core )
78{
[19]79        uint32_t elapsed;
80        uint64_t cycles;
[1]81        uint32_t time_stamp = core->time_stamp;
82        uint32_t time_now   = hal_time_stamp();
[19]83
[1]84        // compute number of elapsed cycles, taking into account 32 bits register wrap
85        if(time_now < time_stamp) elapsed = (0xFFFFFFFF - time_stamp) + time_now;
86        else                      elapsed = (time_now - time_stamp);
87
[19]88        cycles = core->cycles + elapsed;
[1]89
[19]90        // update core time
91        core->time_stamp = time_now;
92        core->cycles     = cycles;
[1]93        hal_wbflush();
94
95        return cycles;
96}
97
98////////////////////////////////////
99void core_get_time( core_t   * core,
[23]100                    uint32_t * tm_s, 
[1]101                    uint32_t * tm_us )
102{
103        // uint64_t cycles = core_get_cycles( core );
104
[19]105        // TODO ces deux ligne ne compilent pas : "undefined referenc to __udivdi3"
[1]106
107        // *tm_ms = (cycles / CONFIG_CYCLES_PER_MS);
108        // *tm_us = (cycles % CONFIG_CYCLES_PER_MS) / (CONFIG_CYCLES_PER_MS / 1000000);
109
[19]110        printk("\n[PANIC] in %s : not implemented yet\n", __FUNCTION__ );
[1]111}
112
113//////////////////////////////////////
114void core_time_update( core_t * core )
115{
[19]116        uint32_t elapsed;
[1]117        uint32_t ticks_nr   = core->ticks_nr;
118        uint64_t cycles     = core->cycles;
119        uint32_t time_stamp = core->time_stamp;
120        uint32_t time_now   = hal_time_stamp();
121
[19]122        // compute number of elapsed cycles taking into account 32 bits register wrap
[1]123        if( time_now < time_stamp ) elapsed = (0xFFFFFFFF - time_stamp) + time_now;
124        else                        elapsed = time_now - time_stamp;
[19]125
[1]126        cycles  += elapsed;
127        ticks_nr = elapsed / core->ticks_period;
128
129        core->time_stamp     = time_now;
130        core->cycles         = cycles + elapsed;
131        core->ticks_nr       = ticks_nr + (elapsed / core->ticks_period);
132        hal_wbflush();
133}
134
135////////////////////////////////
136void core_clock( core_t * core )
137{
138        uint32_t ticks;
139
[19]140        // update cycles and ticks counter
[1]141        core_time_update( core );
142
[19]143        // get current ticks number
[1]144        ticks = core->ticks_nr;
145
[19]146        // handle pending alarms TODO ??? [AG]
[1]147        // alarm_clock( &core->alarm_mgr , ticks );
148
[19]149        // handle scheduler TODO  improve the scheduling condition ... AG
150        if( (ticks % 10) == 0 ) sched_yield();
151
152        // update DQDT TODO  This update should depend on the cluster identifier,
153        // to avoid simultaneous updates from various clusters ... AG
[1]154        if( ((ticks % CONFIG_DQDT_PERIOD) == 0) && (core->lid == 0) ) dqdt_global_update();
155}
156
157////////////////////////////////////////
[19]158void core_compute_stats( core_t * core )
[1]159{
160        thread_t * idle  = core->thread_idle;
161        uint32_t   ticks = core->ticks_nr;
162
163        uint32_t   idle_percent;
164        uint32_t   busy_percent;
165        uint32_t   usage;
166
[19]167        // compute cumulated usage
[1]168        ticks         = (ticks) ? ticks : 1;
169        idle_percent  = (idle->ticks_nr * 100) / ticks;
170        idle_percent  = (idle_percent > 100) ? 100 : idle_percent;
171        busy_percent  = 100 - idle_percent;
172        usage         = (busy_percent + core->usage) / 2;
173
[19]174        // update core descriptor
[1]175        core->usage = usage;
176        hal_wbflush();
177
178#if CONFIG_SHOW_CPU_USAGE
179        printk(INFO, "INFO: core %d in cluster %x : busy_percent = %d / cumulated_usage = %d\n",
180               core->lid, local_cxy , busy_percent , usage );
181#endif
182
183        core->ticks_nr = 0;
184        idle->ticks_nr = 0;
185}
186
187/////////////////////////////////////
188void core_reset_stats( core_t * core )
189{
190        core_time_update(core);
191
192        core->ticks_nr              = 0;
193        core->usage                 = 0;
194        core->thread_idle->ticks_nr = 0;
195        hal_wbflush();
196}
197
198///////////////////////////////////////////////////
[5]199void core_set_irq_vector_entry( core_t   * core,
[1]200                                uint32_t   irq_type,
201                                uint32_t   irq_id,
[5]202                                chdev_t  * chdev )
[1]203{
[19]204        if     ( irq_type == WTI_TYPE ) core->wti_vector[irq_id] = chdev;
205        else if( irq_type == HWI_TYPE ) core->hwi_vector[irq_id] = chdev;
206        else                            core->pti_vector[irq_id] = chdev;
[1]207}
Note: See TracBrowser for help on using the repository browser.