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

📄 time.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
		}		if ((year += 1900) < 1970)			year += 100;	}	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);	xtime.tv_usec = 0;	if (mregs) {		tmp = mostek_read(mregs + MOSTEK_CREG);		tmp &= ~MSTK_CREG_READ;		mostek_write(mregs + MOSTEK_CREG, tmp);		spin_unlock_irq(&mostek_lock);	}}void __init clock_probe(void){	struct linux_prom_registers clk_reg[2];	char model[128];	int node, busnd = -1, err;	unsigned long flags;#ifdef CONFIG_PCI	struct linux_ebus *ebus = NULL;	struct isa_bridge *isa_br = NULL;#endif	static int invoked = 0;	if (invoked)		return;	invoked = 1;	if (this_is_starfire) {		/* davem suggests we keep this within the 4M locked kernel image */		static char obp_gettod[256];		static u32 unix_tod;		sprintf(obp_gettod, "h# %08x unix-gettod",			(unsigned int) (long) &unix_tod);		prom_feval(obp_gettod);		xtime.tv_sec = unix_tod;		xtime.tv_usec = 0;		return;	}	__save_and_cli(flags);	if(central_bus != NULL) {		busnd = central_bus->child->prom_node;	}#ifdef CONFIG_PCI	else if (ebus_chain != NULL) {		ebus = ebus_chain;		busnd = ebus->prom_node;	} else if (isa_chain != NULL) {		isa_br = isa_chain;		busnd = isa_br->prom_node;	}#endif	else if (sbus_root != NULL) {		busnd = sbus_root->prom_node;	}	if (busnd == -1) {		prom_printf("clock_probe: problem, cannot find bus to search.\n");		prom_halt();	}	node = prom_getchild(busnd);	while (1) {		if (!node)			model[0] = 0;		else			prom_getstring(node, "model", model, sizeof(model));		if (strcmp(model, "mk48t02") &&		    strcmp(model, "mk48t08") &&		    strcmp(model, "mk48t59") &&		    strcmp(model, "m5819") &&		    strcmp(model, "ds1287")) {		   	if (node)				node = prom_getsibling(node);#ifdef CONFIG_PCI			while ((node == 0) && ebus != NULL) {				ebus = ebus->next;				if (ebus != NULL) {					busnd = ebus->prom_node;					node = prom_getchild(busnd);				}			}			while ((node == 0) && isa_br != NULL) {				isa_br = isa_br->next;				if (isa_br != NULL) {					busnd = isa_br->prom_node;					node = prom_getchild(busnd);				}			}#endif			if (node == 0) {				prom_printf("clock_probe: Cannot find timer chip\n");				prom_halt();			}			continue;		}		err = prom_getproperty(node, "reg", (char *)clk_reg,				       sizeof(clk_reg));		if(err == -1) {			prom_printf("clock_probe: Cannot get Mostek reg property\n");			prom_halt();		}		if(central_bus) {			apply_fhc_ranges(central_bus->child, clk_reg, 1);			apply_central_ranges(central_bus, clk_reg, 1);		}#ifdef CONFIG_PCI		else if (ebus_chain != NULL) {			struct linux_ebus_device *edev;			for_each_ebusdev(edev, ebus)				if (edev->prom_node == node)					break;			if (edev == NULL) {				if (isa_chain != NULL)					goto try_isa_clock;				prom_printf("%s: Mostek not probed by EBUS\n",					    __FUNCTION__);				prom_halt();			}			if (!strcmp(model, "ds1287") ||			    !strcmp(model, "m5819")) {				ds1287_regs = edev->resource[0].start;			} else {				mstk48t59_regs = edev->resource[0].start;				mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;			}			break;		} else if (isa_chain != NULL) {			struct isa_device *isadev;try_isa_clock:			for_each_isadev(isadev, isa_br)				if (isadev->prom_node == node)					break;			if (isadev == NULL) {				prom_printf("%s: Mostek not probed by ISA\n");				prom_halt();			}			if (!strcmp(model, "ds1287") ||			    !strcmp(model, "m5819")) {				ds1287_regs = isadev->resource.start;			} else {				mstk48t59_regs = isadev->resource.start;				mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;			}			break;		}#endif		else {			if (sbus_root->num_sbus_ranges) {				int nranges = sbus_root->num_sbus_ranges;				int rngc;				for (rngc = 0; rngc < nranges; rngc++)					if (clk_reg[0].which_io ==					    sbus_root->sbus_ranges[rngc].ot_child_space)						break;				if (rngc == nranges) {					prom_printf("clock_probe: Cannot find ranges for "						    "clock regs.\n");					prom_halt();				}				clk_reg[0].which_io =					sbus_root->sbus_ranges[rngc].ot_parent_space;				clk_reg[0].phys_addr +=					sbus_root->sbus_ranges[rngc].ot_parent_base;			}		}		if(model[5] == '0' && model[6] == '2') {			mstk48t02_regs = (((u64)clk_reg[0].phys_addr) |					  (((u64)clk_reg[0].which_io)<<32UL));		} else if(model[5] == '0' && model[6] == '8') {			mstk48t08_regs = (((u64)clk_reg[0].phys_addr) |					  (((u64)clk_reg[0].which_io)<<32UL));			mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;		} else {			mstk48t59_regs = (((u64)clk_reg[0].phys_addr) |					  (((u64)clk_reg[0].which_io)<<32UL));			mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;		}		break;	}	if (mstk48t02_regs != 0UL) {		/* Report a low battery voltage condition. */		if (has_low_battery())			prom_printf("NVRAM: Low battery voltage!\n");		/* Kick start the clock if it is completely stopped. */		if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)			kick_start_clock();	}	set_system_time();		__restore_flags(flags);}extern void init_timers(void (*func)(int, void *, struct pt_regs *),			unsigned long *);void __init time_init(void){	/* clock_probe() is now done at end of [se]bus_init on sparc64	 * so that sbus, fhc and ebus bus information is probed and	 * available.	 */	unsigned long clock;	init_timers(timer_interrupt, &clock);	timer_ticks_per_usec_quotient = ((1UL<<32) / (clock / 1000020));}static __inline__ unsigned long do_gettimeoffset(void){	unsigned long ticks;	if (!SPARC64_USE_STICK) {	__asm__ __volatile__(	"	rd	%%tick, %%g1\n"	"	add	%1, %%g1, %0\n"	"	sub	%0, %2, %0\n"		: "=r" (ticks)		: "r" (timer_tick_offset), "r" (timer_tick_compare)		: "g1", "g2");	} else {	__asm__ __volatile__("rd	%%asr24, %%g1\n\t"			     "add	%1, %%g1, %0\n\t"			     "sub	%0, %2, %0\n\t"			     : "=&r" (ticks)			     : "r" (timer_tick_offset), "r" (timer_tick_compare)			     : "g1");	}	return (ticks * timer_ticks_per_usec_quotient) >> 32UL;}void do_settimeofday(struct timeval *tv){	if (this_is_starfire)		return;	write_lock_irq(&xtime_lock);	tv->tv_usec -= do_gettimeoffset();	if(tv->tv_usec < 0) {		tv->tv_usec += 1000000;		tv->tv_sec--;	}	xtime = *tv;	time_adjust = 0;		/* stop active adjtime() */	time_status |= STA_UNSYNC;	time_maxerror = NTP_PHASE_LIMIT;	time_esterror = NTP_PHASE_LIMIT;	write_unlock_irq(&xtime_lock);}static int set_rtc_mmss(unsigned long nowtime){	int real_seconds, real_minutes, chip_minutes;	unsigned long mregs = mstk48t02_regs;#ifdef CONFIG_PCI	unsigned long dregs = ds1287_regs;#else	unsigned long dregs = 0UL;#endif	unsigned long flags;	u8 tmp;	/* 	 * Not having a register set can lead to trouble.	 * Also starfire doesnt have a tod clock.	 */	if (!mregs && !dregs) 		return -1;	if (mregs) {		spin_lock_irqsave(&mostek_lock, flags);		/* Read the current RTC minutes. */		tmp = mostek_read(mregs + MOSTEK_CREG);		tmp |= MSTK_CREG_READ;		mostek_write(mregs + MOSTEK_CREG, tmp);		chip_minutes = MSTK_REG_MIN(mregs);		tmp = mostek_read(mregs + MOSTEK_CREG);		tmp &= ~MSTK_CREG_READ;		mostek_write(mregs + MOSTEK_CREG, tmp);		/*		 * since we're only adjusting minutes and seconds,		 * don't interfere with hour overflow. This avoids		 * messing with unknown time zones but requires your		 * RTC not to be off by more than 15 minutes		 */		real_seconds = nowtime % 60;		real_minutes = nowtime / 60;		if (((abs(real_minutes - chip_minutes) + 15)/30) & 1)			real_minutes += 30;	/* correct for half hour time zone */		real_minutes %= 60;		if (abs(real_minutes - chip_minutes) < 30) {			tmp = mostek_read(mregs + MOSTEK_CREG);			tmp |= MSTK_CREG_WRITE;			mostek_write(mregs + MOSTEK_CREG, tmp);			MSTK_SET_REG_SEC(mregs,real_seconds);			MSTK_SET_REG_MIN(mregs,real_minutes);			tmp = mostek_read(mregs + MOSTEK_CREG);			tmp &= ~MSTK_CREG_WRITE;			mostek_write(mregs + MOSTEK_CREG, tmp);			spin_unlock_irqrestore(&mostek_lock, flags);			return 0;		} else {			spin_unlock_irqrestore(&mostek_lock, flags);			return -1;		}	} else {		int retval = 0;		unsigned char save_control, save_freq_select;		/* Stolen from arch/i386/kernel/time.c, see there for		 * credits and descriptive comments.		 */		spin_lock_irqsave(&rtc_lock, flags);		save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */		CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);		save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */		CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);		chip_minutes = CMOS_READ(RTC_MINUTES);		if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)			BCD_TO_BIN(chip_minutes);		real_seconds = nowtime % 60;		real_minutes = nowtime / 60;		if (((abs(real_minutes - chip_minutes) + 15)/30) & 1)			real_minutes += 30;		real_minutes %= 60;		if (abs(real_minutes - chip_minutes) < 30) {			if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {				BIN_TO_BCD(real_seconds);				BIN_TO_BCD(real_minutes);			}			CMOS_WRITE(real_seconds,RTC_SECONDS);			CMOS_WRITE(real_minutes,RTC_MINUTES);		} else {			printk(KERN_WARNING			       "set_rtc_mmss: can't update from %d to %d\n",			       chip_minutes, real_minutes);			retval = -1;		}		CMOS_WRITE(save_control, RTC_CONTROL);		CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);		spin_unlock_irqrestore(&rtc_lock, flags);		return retval;	}}

⌨️ 快捷键说明

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