Cleanup in elf.c with .bss section clean; adm command mounts cdrom instead of floppy...
[ZeXOS.git] / kernel / arch / x86_64 / timer.c
blobbcddc9cc13f9db7a27b4162a1d3a2d4215aeca27
1 /*
2 * ZeX/OS
3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <system.h>
21 #include <arch/io.h>
22 #include <string.h>
24 /* This will keep track of how many ticks that the system
25 * has been running for */
26 unsigned long timer_ticks = 0;
28 /* Software timer - ticks count to 1ms */
29 unsigned long timer_swticks = 0;
31 /* Handles the timer. In this case, it's very simple: We
32 * increment the 'timer_ticks' variable every time the
33 * timer fires. By default, the timer fires 18.222 times
34 * per second. Why 18.222Hz? Some engineer at IBM must've
35 * been smoking something funky */
36 void timer_handler (struct regs *r)
38 /* Increment our 'tick count' */
39 timer_ticks ++;
42 /* This will continuously loop until the given time has
43 * been reached */
44 void timer_wait (int ticks)
46 int eticks;
48 eticks = timer_ticks + ticks;
50 while (timer_ticks < eticks)
51 kprintf("");;
54 char *time_tostring (unsigned long s)
56 static char buffer[512];
57 unsigned int weeks, days, hours, minutes, seconds, total;
59 seconds = s % 60;
60 minutes = s / 60;
61 hours = minutes / 60;
62 days = hours / 24;
63 weeks = days / 7;
64 minutes = minutes % 60;
65 hours = hours % 24;
66 days = days % 7;
68 total = 0;
70 if (weeks)
71 total += sprintf (buffer, "%u week%s, ", weeks, (weeks > 1) ? "s" : "");
72 if (days)
73 total += sprintf (buffer + total, "%u day%s, ", days, (days > 1) ? "s" : "");
75 if ((hours || minutes || seconds) || (!(weeks || days)))
76 total += sprintf (buffer + total, "%2uh %2umin %2usec", hours, minutes, seconds);
78 return buffer;
81 void uptime (void)
83 printf ("Uptime: %s\n", time_tostring (timer_ticks/((3579545L / 3) / HZ)));
86 void calc_freqency ()
88 /* Kernel with 1000Hz timer dont need it */
89 if (kernel_attr & KERNEL_18HZ) {
90 int eticks;
92 eticks = timer_ticks + 18;
94 while (timer_ticks < eticks) {
95 ctps ++;
96 kprintf("");;
99 kprintf ("Freqency: %lluHz\n", ctps);
103 void calc_swtimer ()
105 unsigned long timer = timer_ticks;
107 while ((timer_ticks - timer) >= 1)
108 timer_swticks ++;
111 void usleep (unsigned len)
113 if (kernel_attr & KERNEL_18HZ) {
114 unsigned long long t = ctps * len;
115 unsigned long long i = 0;
117 while (t > i) {
118 i += 1000;
119 kprintf("");;
121 } else
122 timer_wait (1);
125 void init_8253 ()
127 if (kernel_attr & KERNEL_18HZ) { // Dont set new timer frequency, when is setted KERNEL_18HZ
128 kprintf ("Warning -> kernel is set to 18HZ timer frequency !\n");
129 #undef HZ
130 #define HZ 18
131 return;
134 unsigned foo = (3579545L / 3) / HZ;
136 /* reprogram the 8253 timer chip to run at 'HZ', instead of 18 Hz */
137 outb (0x43, 0x36); /* channel 0, LSB/MSB, mode 3, binary */
138 outb (0x40, (unsigned short) foo & 0xFF); /* LSB */
139 outb (0x40, (unsigned short) foo >> 8); /* MSB */
142 /* Sets up the system clock by installing the timer handler into IRQ0 */
143 unsigned int timer_install ()
145 /* set hw timer (irq0) to HZ frequency */
146 init_8253 ();
148 /* Installs 'timer_handler' to IRQ0 */
149 // TODO: irq_install_handler (0, timer_handler);
151 return 1;