khypervisor  v1
timer.c
Go to the documentation of this file.
00001 /* 
00002  * timer.c
00003  * --------------------------------------
00004  * Implementation of ARMv7 Generic Timer
00005  * Responsible: Inkyu Han
00006  */
00007 #include "timer.h"
00008 #include "generic_timer.h"
00009 
00010 #include <config/cfg_platform.h>
00011 #include <k-hypervisor-config.h>
00012 
00013 static struct timer_channel _channels[TIMER_NUM_MAX_CHANNELS];
00014 
00015 static void _timer_each_callback_channel( timer_channel_t channel, void *param)
00016 {
00017     int i;
00018     for( i = 0; i < TIMER_MAX_CHANNEL_CALLBACKS; i++ ) {
00019         if( _channels[channel].callbacks[i] ) _channels[channel].callbacks[i](param);
00020     }
00021 }
00022 
00023 static int _timer_channel_num_callbacks( timer_channel_t channel )
00024 {
00025     int i, count = 0;
00026     for( i = 0; i < TIMER_MAX_CHANNEL_CALLBACKS; i++) {
00027         if( _channels[channel].callbacks[i] ) count++;
00028     }
00029     return count;
00030 }
00031 
00032 static void _timer_hw_callback(void *pdata)
00033 {
00034     generic_timer_disable_int(GENERIC_TIMER_HYP);
00035 
00036     _timer_each_callback_channel(timer_sched, pdata);
00037 
00038     generic_timer_set_tval(GENERIC_TIMER_HYP, _channels[timer_sched].interval_us);
00039     
00040     generic_timer_enable_int(GENERIC_TIMER_HYP);
00041 }
00042 
00043 hvmm_status_t timer_init(timer_channel_t channel)
00044 {   
00045     int i;
00046     for( i = 0; i < TIMER_MAX_CHANNEL_CALLBACKS; i++ ) {
00047         _channels[channel].callbacks[i] = 0;
00048     }
00049 
00050     generic_timer_init();
00051     return HVMM_STATUS_SUCCESS;
00052 }
00053     
00054 hvmm_status_t timer_start(timer_channel_t channel)
00055 {
00056     if ( _timer_channel_num_callbacks( channel ) > 0 ) {
00057 
00058         generic_timer_set_callback(GENERIC_TIMER_HYP, &_timer_hw_callback );
00059     
00060         generic_timer_set_tval(GENERIC_TIMER_HYP, _channels[channel].interval_us);
00061     
00062         generic_timer_enable_irq(GENERIC_TIMER_HYP);
00063 
00064         generic_timer_enable_int(GENERIC_TIMER_HYP);
00065     }
00066 
00067     return HVMM_STATUS_SUCCESS;
00068 }
00069 
00070 hvmm_status_t timer_stop(timer_channel_t channel)
00071 {
00072     generic_timer_disable_int(GENERIC_TIMER_HYP);
00073     return HVMM_STATUS_SUCCESS;
00074 }
00075 
00076 hvmm_status_t timer_set_interval(timer_channel_t channel, uint32_t interval_us)
00077 {
00078     _channels[channel].interval_us = timer_t2c(interval_us);
00079     return HVMM_STATUS_SUCCESS;
00080 }
00081 
00082 uint32_t timer_get_interval(timer_channel_t channel)
00083 {
00084     return _channels[channel].interval_us;
00085 }
00086 
00087 hvmm_status_t timer_add_callback(timer_channel_t channel, timer_callback_t callback)
00088 {
00089     int i;
00090     hvmm_status_t result = HVMM_STATUS_BUSY;
00091     for( i = 0; i < TIMER_MAX_CHANNEL_CALLBACKS; i++ ) {
00092         if( _channels[channel].callbacks[i] == 0 ) {
00093             _channels[channel].callbacks[i] = callback;
00094             result = HVMM_STATUS_SUCCESS;
00095             break;
00096         }
00097     }
00098     return result;
00099 }
00100 
00101 hvmm_status_t timer_remove_callback(timer_channel_t channel, timer_callback_t callback)
00102 {
00103     int i;
00104     hvmm_status_t result = HVMM_STATUS_NOT_FOUND;
00105     for( i = 0; i < TIMER_MAX_CHANNEL_CALLBACKS; i++ ) {
00106         if ( _channels[channel].callbacks[i] == callback ) {
00107             _channels[channel].callbacks[i] = 0;
00108             result = HVMM_STATUS_SUCCESS;
00109             break;
00110         }
00111     }
00112     return result;
00113 }
00114 
00115 uint64_t timer_t2c(uint64_t time_us)
00116 {
00117     return time_us * COUNT_PER_USEC;
00118 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines