⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arch_timer.c

📁 newos is new operation system
💻 C
字号:
/*** Copyright 2001-2004, Travis Geiselbrecht. All rights reserved.** Distributed under the terms of the NewOS License.*/#include <kernel/kernel.h>#include <boot/stage2.h>#include <arch/sh4/sh4.h>#include <kernel/int.h>#include <kernel/debug.h>#include <kernel/time.h>#include <kernel/timer.h>#include <kernel/arch/timer.h>#include <kernel/arch/cpu.h>#define timer_rate 12500000#define max_timer_interval ((bigtime_t)0xffffffff * 1000000 / timer_rate)#define min_timer_interval ((bigtime_t)0x1000)#define SYSTEM_TIME_TIMER_QUANTA 0xffffffffstatic const bigtime_t system_time_timer_period = (bigtime_t)SYSTEM_TIME_TIMER_QUANTA * timer_rate / 1000000;static volatile bigtime_t base_system_time = 0;#if 0bigtime_t system_time(){	bigtime_t outtime;	uint32 timer_val;	int_disable_interrupts();restart:	timer_val = SYSTEM_TIME_TIMER_QUANTA - *(uint32 *)TCNT1;	if(*(uint16 *)TCR1 & 0x0100) {		// underflow has occurred already		outtime = base_system_time + system_time_timer_period + (bigtime_t)timer_val * 1000000 / timer_rate;	} else {		outtime = base_system_time + (bigtime_t)timer_val * 1000000 / timer_rate;		if(*(uint16 *)TCR1 & 0x0100) {			// an underflow must have happened since we checked last, redo			goto restart;		}	}	int_restore_interrupts();	return outtime;}#endifstatic void start_timer(int timer){	uint8 old_val = *(uint8 *)TSTR;	*(uint8 *)TSTR = old_val | (0x1 << timer % 3);}static void stop_timer(int timer){	uint8 old_val = *(uint8 *)TSTR;	*(uint8 *)TSTR = old_val & ~(0x1 << timer %3);}static void setup_timer(int timer, bigtime_t relative_timeout){	uint32 timer_val;	if(relative_timeout < min_timer_interval) {		timer_val = min_timer_interval * timer_rate / 1000000;	} else if(relative_timeout < max_timer_interval) {		timer_val = relative_timeout * timer_rate / 1000000;	} else {		timer_val = 0xffffffff;	}	switch(timer) {		case 0:			*(uint16 *)TCR0 = 0x0020;        		*(uint32 *)TCNT0 = timer_val;        		*(uint32 *)TCOR0 = timer_val;			break;		case 1:			*(uint16 *)TCR1 = 0x0020;        		*(uint32 *)TCNT1 = timer_val;        		*(uint32 *)TCOR1 = timer_val;			break;		case 2:			*(uint16 *)TCR2 = 0x0020;        		*(uint32 *)TCNT2 = timer_val;        		*(uint32 *)TCOR2 = timer_val;			break;		default:			break;	}}void arch_timer_set_hardware_timer(bigtime_t timeout, int type){	PANIC_UNIMPLEMENTED();		stop_timer(0);	setup_timer(0, timeout);	start_timer(0);}void arch_timer_clear_hardware_timer(){	stop_timer(0);}static int timer_interrupt0(){	stop_timer(0);	return timer_interrupt();}static void setup_system_time_timer(){	*(uint16 *)TCR1 = 0x0020;	*(uint32 *)TCNT1 = SYSTEM_TIME_TIMER_QUANTA;	*(uint32 *)TCOR1 = SYSTEM_TIME_TIMER_QUANTA;}static int timer_interrupt1(){	base_system_time += system_time_timer_period;	*(uint16 *)TCR1 = 0x0020; // mask out the underflow bit	return INT_NO_RESCHEDULE;}int arch_init_timer(kernel_args *ka){	uint16 old_val16;	dprintf("arch_init_timer: entry\n");	int_set_io_interrupt_handler(32, &timer_interrupt0, NULL, "timer0");	int_set_io_interrupt_handler(33, &timer_interrupt1, NULL, "timer1");	// stop all of the timers	*(uint8 *)TSTR = 0;	// enable the interrupt on timer 0 & 1 & disable 2	old_val16 = *(uint16 *)IPRA;	*(uint16 *)IPRA = (old_val16 & 0x000f) | 0xef00;	// start timer 1 counting forever	base_system_time = 0;	setup_system_time_timer();	start_timer(1);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -