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