Main Page | Directories | File List | Globals

timer.c

Go to the documentation of this file.
00001 /*
00002  * kernel_arch/i386/kernel/timer.c
00003  *
00004  * Copyright (c) 2003-2004 Lukasz Dembinski <dembol@nasa.com.pl>
00005  * All Rights Reserved
00006  * 
00007  * Date:        2004/01
00008  * Author:      Lukasz Dembinski
00009  * Info:        timer.c core file
00010  * Contact:     mailto: <dembol@nasa.com.pl>
00011  *
00012  */
00013 
00014 #include <agnix/agnix.h>
00015 #include <agnix/irq.h>
00016 #include <agnix/tasks.h>
00017 #include <agnix/timer.h>
00018 #include <agnix/memory.h>
00019 #include <agnix/adi/adi.h>
00020 #include <agnix/spinlock.h>
00021 #include <agnix/timers.h>
00022 #include <agnix/counters.h>
00023 #include <agnix/console.h>
00024 
00025 #define TIMER_INC_VAL   (1e6 / TIMER_HZ)        /* usec */
00026 #define USEC_IN_SEC     1000000
00027 
00028 struct timeval_s current_time;
00029 extern struct chip_s rtc_chip;
00030 extern struct chip_s i8254_chip;
00031 extern int counter_jiffies_desc;
00032 
00033 spinlock_t current_time_lock;
00034 
00035 void timer_usec_overflow(void)
00036 {
00037     do {
00038         current_time.tv_usec -= USEC_IN_SEC;
00039         current_time.tv_sec++;
00040     } while (current_time.tv_usec > USEC_IN_SEC);
00041 }
00042 
00043 void timer_actualize(void)
00044 {
00045     current_time.tv_usec += TIMER_INC_VAL;
00046     
00047     if (current_time.tv_usec > USEC_IN_SEC)
00048         timer_usec_overflow();
00049 }
00050 
00051 void timer_irq(u32 i)
00052 {
00053     if (--current_task->t_count <= 0) {
00054         current_task->t_resched = 1;
00055     }
00056     else
00057         current_task->t_resched = 0;
00058     
00059     timer_actualize();
00060     counter_inc(counter_jiffies_desc);
00061     run_timers();
00062 }
00063 
00064 struct irq_routine_s irq_timer = { timer_irq, 0, 0, };
00065 
00066 int __init timer_init(void)
00067 {
00068     spin_lock_init(&current_time_lock);
00069 
00070     rtc_ops(&rtc_chip)->gettime(&rtc_chip, &current_time);
00071     install_irq(0, &irq_timer);
00072 
00073     return 0;
00074 }
00075 
00076 int timer_gettimeofday(struct timeval_s *tv)
00077 {
00078     u16 count;
00079     u32 flags;
00080 
00081     spin_lock_irqsave(&current_time_lock, flags);
00082     
00083     memcpy(tv, &current_time, sizeof(struct timeval_s));
00084     count = pit_ops(&i8254_chip)->read_count(&i8254_chip, 0);
00085     tv->tv_usec += (int)(count);
00086     
00087     spin_unlock_irqrestore(&current_time_lock, flags);
00088 
00089     return 0;
00090 }
00091 
00092 int timer_settimeofday(struct timeval_s *tv)
00093 {
00094     u16 count;
00095     u32 flags;
00096 
00097     spin_lock_irqsave(&current_time_lock, flags);
00098     
00099     memcpy(&current_time, tv, sizeof(struct timeval_s));
00100     count = (u16)(tv->tv_usec % 1000);
00101     pit_ops(&i8254_chip)->write_count(&i8254_chip, 0, count);
00102     
00103     spin_unlock_irqrestore(&current_time_lock, flags);
00104 
00105     return 0;
00106 }
Dokumentacje wygenerowano programem Doxygen 1.4.2 dla projektu Agnix