# HG changeset patch # User John Tsiombikas # Date 1307491362 -10800 # Node ID 373a9f50b4e6cbe81bf9d1d466185ff398a8e82f # Parent 3ed041d07ae13f95883e5ba43ee18bb58ff27b50 8254 timer code diff -r 3ed041d07ae1 -r 373a9f50b4e6 src/config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/config.h Wed Jun 08 03:02:42 2011 +0300 @@ -0,0 +1,7 @@ +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +/* frequency of generated timer ticks in hertz */ +#define TICK_FREQ_HZ 250 + +#endif /* _CONFIG_H_ */ diff -r 3ed041d07ae1 -r 373a9f50b4e6 src/main.c --- a/src/main.c Fri May 27 13:08:23 2011 +0300 +++ b/src/main.c Wed Jun 08 03:02:42 2011 +0300 @@ -5,11 +5,10 @@ #include "asmops.h" #include "segm.h" #include "intr.h" +#include "timer.h" #include "mem.h" #include "vm.h" -static void do_nothing(); - /* special keys */ enum { LALT, RALT, @@ -55,8 +54,7 @@ init_segm(); init_intr(); - /* silence the blasted timer interrupt */ - interrupt(32, do_nothing); + init_timer(); /* initialize the physical memory manager */ init_mem(mbinf); @@ -66,27 +64,6 @@ /* initialization complete, enable interrupts */ enable_intr(); - dbg_print_vm(MEM_USER); - dbg_print_vm(MEM_KERNEL); - - { - void *foo, *bar, *xyzzy, *koko, *lala; - - foo = malloc(128); - bar = malloc(32 * 1024); - xyzzy = malloc(8000); - - free(bar); - - koko = malloc(700); - lala = malloc(6 * 1024 * 1024); - - free(xyzzy); - free(foo); - free(koko); - free(lala); - } - for(;;) { char c, keypress; do { @@ -98,7 +75,3 @@ } } } - -static void do_nothing() -{ -} diff -r 3ed041d07ae1 -r 373a9f50b4e6 src/timer.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/timer.c Wed Jun 08 03:02:42 2011 +0300 @@ -0,0 +1,78 @@ +#include +#include "intr.h" +#include "asmops.h" +#include "config.h" + +/* frequency of the oscillator driving the 8254 timer */ +#define OSC_FREQ_HZ 1193182 + +/* macro to divide and round to the nearest integer */ +#define DIV_ROUND(a, b) ((a) / (b) + ((a) % (b)) / ((b) / 2)) + +/* I/O ports connected to the 8254 */ +#define PORT_DATA0 0x40 +#define PORT_DATA1 0x41 +#define PORT_DATA2 0x42 +#define PORT_CMD 0x43 + +/* command bits */ +#define CMD_CHAN0 0 +#define CMD_CHAN1 (1 << 6) +#define CMD_CHAN2 (2 << 6) +#define CMD_RDBACK (3 << 6) + +#define CMD_LATCH 0 +#define CMD_ACCESS_LOW (1 << 4) +#define CMD_ACCESS_HIGH (2 << 4) +#define CMD_ACCESS_BOTH (3 << 4) + +#define CMD_OP_INT_TERM 0 +#define CMD_OP_ONESHOT (1 << 1) +#define CMD_OP_RATE (2 << 1) +#define CMD_OP_SQWAVE (3 << 1) +#define CMD_OP_SOFT_STROBE (4 << 1) +#define CMD_OP_HW_STROBE (5 << 1) + +#define CMD_MODE_BIN 0 +#define CMD_MODE_BCD 1 + + +static void intr_handler(); + +static unsigned long nticks; + + +void init_timer(void) +{ + /* calculate the reset count: round(osc / freq) */ + int reset_count = DIV_ROUND(OSC_FREQ_HZ, TICK_FREQ_HZ); + + /* set the mode to square wave for channel 0, both low + * and high reset count bytes will follow... + */ + outb(CMD_CHAN0 | CMD_ACCESS_BOTH | CMD_OP_SQWAVE, PORT_CMD); + + /* write the low and high bytes of the reset count to the + * port for channel 0 + */ + outb(reset_count & 0xff, PORT_DATA0); + outb((reset_count >> 8) & 0xff, PORT_DATA0); + + nticks = 0; + + /* set the timer interrupt handler */ + interrupt(32, intr_handler); +} + +/* This will be called by the interrupt dispatcher approximately + * every 1/250th of a second, so it must be extremely fast. + * For now, just increasing a tick counter will suffice. + */ +static void intr_handler() +{ + nticks++; + + if(nticks % TICK_FREQ_HZ == 0) { + printf("%lu sec\n", nticks / TICK_FREQ_HZ); + } +} diff -r 3ed041d07ae1 -r 373a9f50b4e6 src/timer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/timer.h Wed Jun 08 03:02:42 2011 +0300 @@ -0,0 +1,8 @@ +#ifndef _TIMER_H_ +#define _TIMER_H_ + +unsigned long nticks; + +void init_timer(void); + +#endif /* _TIMER_H_ */ diff -r 3ed041d07ae1 -r 373a9f50b4e6 src/vm.c --- a/src/vm.c Fri May 27 13:08:23 2011 +0300 +++ b/src/vm.c Wed Jun 08 03:02:42 2011 +0300 @@ -259,7 +259,7 @@ void pgfree(int start, int num) { - int i, area, end, intr_state; + int i, area, intr_state; struct page_range *node, *new, *prev, *next; intr_state = get_intr_state(); @@ -276,7 +276,7 @@ panic("pgfree: can't allocate new page_range node to add the freed pages\n"); } new->start = start; - end = new->end = start + num; + new->end = start + num; area = PAGE_TO_ADDR(start) >= KMEM_START ? MEM_KERNEL : MEM_USER;