kern
changeset 33:373a9f50b4e6
8254 timer code
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 08 Jun 2011 03:02:42 +0300 |
parents | 3ed041d07ae1 |
children | 17433fcaa563 |
files | src/config.h src/main.c src/timer.c src/timer.h src/vm.c |
diffstat | 5 files changed, 97 insertions(+), 31 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/config.h Wed Jun 08 03:02:42 2011 +0300 1.3 @@ -0,0 +1,7 @@ 1.4 +#ifndef _CONFIG_H_ 1.5 +#define _CONFIG_H_ 1.6 + 1.7 +/* frequency of generated timer ticks in hertz */ 1.8 +#define TICK_FREQ_HZ 250 1.9 + 1.10 +#endif /* _CONFIG_H_ */
2.1 --- a/src/main.c Fri May 27 13:08:23 2011 +0300 2.2 +++ b/src/main.c Wed Jun 08 03:02:42 2011 +0300 2.3 @@ -5,11 +5,10 @@ 2.4 #include "asmops.h" 2.5 #include "segm.h" 2.6 #include "intr.h" 2.7 +#include "timer.h" 2.8 #include "mem.h" 2.9 #include "vm.h" 2.10 2.11 -static void do_nothing(); 2.12 - 2.13 /* special keys */ 2.14 enum { 2.15 LALT, RALT, 2.16 @@ -55,8 +54,7 @@ 2.17 init_segm(); 2.18 init_intr(); 2.19 2.20 - /* silence the blasted timer interrupt */ 2.21 - interrupt(32, do_nothing); 2.22 + init_timer(); 2.23 2.24 /* initialize the physical memory manager */ 2.25 init_mem(mbinf); 2.26 @@ -66,27 +64,6 @@ 2.27 /* initialization complete, enable interrupts */ 2.28 enable_intr(); 2.29 2.30 - dbg_print_vm(MEM_USER); 2.31 - dbg_print_vm(MEM_KERNEL); 2.32 - 2.33 - { 2.34 - void *foo, *bar, *xyzzy, *koko, *lala; 2.35 - 2.36 - foo = malloc(128); 2.37 - bar = malloc(32 * 1024); 2.38 - xyzzy = malloc(8000); 2.39 - 2.40 - free(bar); 2.41 - 2.42 - koko = malloc(700); 2.43 - lala = malloc(6 * 1024 * 1024); 2.44 - 2.45 - free(xyzzy); 2.46 - free(foo); 2.47 - free(koko); 2.48 - free(lala); 2.49 - } 2.50 - 2.51 for(;;) { 2.52 char c, keypress; 2.53 do { 2.54 @@ -98,7 +75,3 @@ 2.55 } 2.56 } 2.57 } 2.58 - 2.59 -static void do_nothing() 2.60 -{ 2.61 -}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/timer.c Wed Jun 08 03:02:42 2011 +0300 3.3 @@ -0,0 +1,78 @@ 3.4 +#include <stdio.h> 3.5 +#include "intr.h" 3.6 +#include "asmops.h" 3.7 +#include "config.h" 3.8 + 3.9 +/* frequency of the oscillator driving the 8254 timer */ 3.10 +#define OSC_FREQ_HZ 1193182 3.11 + 3.12 +/* macro to divide and round to the nearest integer */ 3.13 +#define DIV_ROUND(a, b) ((a) / (b) + ((a) % (b)) / ((b) / 2)) 3.14 + 3.15 +/* I/O ports connected to the 8254 */ 3.16 +#define PORT_DATA0 0x40 3.17 +#define PORT_DATA1 0x41 3.18 +#define PORT_DATA2 0x42 3.19 +#define PORT_CMD 0x43 3.20 + 3.21 +/* command bits */ 3.22 +#define CMD_CHAN0 0 3.23 +#define CMD_CHAN1 (1 << 6) 3.24 +#define CMD_CHAN2 (2 << 6) 3.25 +#define CMD_RDBACK (3 << 6) 3.26 + 3.27 +#define CMD_LATCH 0 3.28 +#define CMD_ACCESS_LOW (1 << 4) 3.29 +#define CMD_ACCESS_HIGH (2 << 4) 3.30 +#define CMD_ACCESS_BOTH (3 << 4) 3.31 + 3.32 +#define CMD_OP_INT_TERM 0 3.33 +#define CMD_OP_ONESHOT (1 << 1) 3.34 +#define CMD_OP_RATE (2 << 1) 3.35 +#define CMD_OP_SQWAVE (3 << 1) 3.36 +#define CMD_OP_SOFT_STROBE (4 << 1) 3.37 +#define CMD_OP_HW_STROBE (5 << 1) 3.38 + 3.39 +#define CMD_MODE_BIN 0 3.40 +#define CMD_MODE_BCD 1 3.41 + 3.42 + 3.43 +static void intr_handler(); 3.44 + 3.45 +static unsigned long nticks; 3.46 + 3.47 + 3.48 +void init_timer(void) 3.49 +{ 3.50 + /* calculate the reset count: round(osc / freq) */ 3.51 + int reset_count = DIV_ROUND(OSC_FREQ_HZ, TICK_FREQ_HZ); 3.52 + 3.53 + /* set the mode to square wave for channel 0, both low 3.54 + * and high reset count bytes will follow... 3.55 + */ 3.56 + outb(CMD_CHAN0 | CMD_ACCESS_BOTH | CMD_OP_SQWAVE, PORT_CMD); 3.57 + 3.58 + /* write the low and high bytes of the reset count to the 3.59 + * port for channel 0 3.60 + */ 3.61 + outb(reset_count & 0xff, PORT_DATA0); 3.62 + outb((reset_count >> 8) & 0xff, PORT_DATA0); 3.63 + 3.64 + nticks = 0; 3.65 + 3.66 + /* set the timer interrupt handler */ 3.67 + interrupt(32, intr_handler); 3.68 +} 3.69 + 3.70 +/* This will be called by the interrupt dispatcher approximately 3.71 + * every 1/250th of a second, so it must be extremely fast. 3.72 + * For now, just increasing a tick counter will suffice. 3.73 + */ 3.74 +static void intr_handler() 3.75 +{ 3.76 + nticks++; 3.77 + 3.78 + if(nticks % TICK_FREQ_HZ == 0) { 3.79 + printf("%lu sec\n", nticks / TICK_FREQ_HZ); 3.80 + } 3.81 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/timer.h Wed Jun 08 03:02:42 2011 +0300 4.3 @@ -0,0 +1,8 @@ 4.4 +#ifndef _TIMER_H_ 4.5 +#define _TIMER_H_ 4.6 + 4.7 +unsigned long nticks; 4.8 + 4.9 +void init_timer(void); 4.10 + 4.11 +#endif /* _TIMER_H_ */
5.1 --- a/src/vm.c Fri May 27 13:08:23 2011 +0300 5.2 +++ b/src/vm.c Wed Jun 08 03:02:42 2011 +0300 5.3 @@ -259,7 +259,7 @@ 5.4 5.5 void pgfree(int start, int num) 5.6 { 5.7 - int i, area, end, intr_state; 5.8 + int i, area, intr_state; 5.9 struct page_range *node, *new, *prev, *next; 5.10 5.11 intr_state = get_intr_state(); 5.12 @@ -276,7 +276,7 @@ 5.13 panic("pgfree: can't allocate new page_range node to add the freed pages\n"); 5.14 } 5.15 new->start = start; 5.16 - end = new->end = start + num; 5.17 + new->end = start + num; 5.18 5.19 area = PAGE_TO_ADDR(start) >= KMEM_START ? MEM_KERNEL : MEM_USER; 5.20