Mon 14 Oct 23:06:38 CEST 2024
This commit is contained in:
		
							parent
							
								
									5b0f5cf2c2
								
							
						
					
					
						commit
						39561050f8
					
				
							
								
								
									
										80
									
								
								kernel/clock.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								kernel/clock.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,80 @@ | ||||||
|  | /*
 | ||||||
|  | Copyright (C) 2015-2019 The University of Notre Dame | ||||||
|  | This software is distributed under the GNU General Public License. | ||||||
|  | See the file LICENSE for details. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include "interrupt.h" | ||||||
|  | #include "clock.h" | ||||||
|  | #include "ioports.h" | ||||||
|  | #include "process.h" | ||||||
|  | 
 | ||||||
|  | // Minimum PIT frequency is 18.2Hz.
 | ||||||
|  | #define CLICKS_PER_SECOND 20 | ||||||
|  | 
 | ||||||
|  | #define TIMER0		0x40 | ||||||
|  | #define TIMER_MODE	0x43 | ||||||
|  | #define SQUARE_WAVE     0x36 | ||||||
|  | #define TIMER_FREQ	1193182 | ||||||
|  | #define TIMER_COUNT	(((unsigned)TIMER_FREQ)/CLICKS_PER_SECOND) | ||||||
|  | 
 | ||||||
|  | static uint32_t clicks = 0; | ||||||
|  | static uint32_t seconds = 0; | ||||||
|  | 
 | ||||||
|  | static struct list queue = { 0, 0 }; | ||||||
|  | 
 | ||||||
|  | static void clock_interrupt(int i, int code) | ||||||
|  | { | ||||||
|  | 	clicks++; | ||||||
|  | 	process_wakeup_all(&queue); | ||||||
|  | 	if(clicks >= CLICKS_PER_SECOND) { | ||||||
|  | 		clicks = 0; | ||||||
|  | 		seconds++; | ||||||
|  | 		process_preempt(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | clock_t clock_read() | ||||||
|  | { | ||||||
|  | 	clock_t result; | ||||||
|  | 	result.seconds = seconds; | ||||||
|  | 	result.millis = 1000 * clicks / CLICKS_PER_SECOND; | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | clock_t clock_diff(clock_t start, clock_t stop) | ||||||
|  | { | ||||||
|  | 	clock_t result; | ||||||
|  | 	if(stop.millis < start.millis) { | ||||||
|  | 		stop.millis += 1000; | ||||||
|  | 		stop.seconds -= 1; | ||||||
|  | 	} | ||||||
|  | 	result.seconds = stop.seconds - start.seconds; | ||||||
|  | 	result.millis = stop.millis - start.millis; | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void clock_wait(uint32_t millis) | ||||||
|  | { | ||||||
|  | 	clock_t start, elapsed; | ||||||
|  | 	uint32_t total; | ||||||
|  | 
 | ||||||
|  | 	start = clock_read(); | ||||||
|  | 	do { | ||||||
|  | 		process_wait(&queue); | ||||||
|  | 		elapsed = clock_diff(start, clock_read()); | ||||||
|  | 		total = elapsed.millis + elapsed.seconds * 1000; | ||||||
|  | 	} while(total < millis); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void clock_init() | ||||||
|  | { | ||||||
|  | 	outb(SQUARE_WAVE, TIMER_MODE); | ||||||
|  | 	outb((TIMER_COUNT & 0xff), TIMER0); | ||||||
|  | 	outb((TIMER_COUNT >> 8) & 0xff, TIMER0); | ||||||
|  | 
 | ||||||
|  | 	interrupt_register(32, clock_interrupt); | ||||||
|  | 	interrupt_enable(32); | ||||||
|  | 
 | ||||||
|  | 	printf("clock: ticking\n"); | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user