config.c

来自「linux 内核源代码」· C语言 代码 · 共 981 行 · 第 1/2 页

C
981
字号
#define TICK_SIZE 10000/* This is always executed with interrupts disabled.  */static unsigned long amiga_gettimeoffset(void){	unsigned short hi, lo, hi2;	unsigned long ticks, offset = 0;	/* read CIA B timer A current value */	hi  = ciab.tahi;	lo  = ciab.talo;	hi2 = ciab.tahi;	if (hi != hi2) {		lo = ciab.talo;		hi = hi2;	}	ticks = hi << 8 | lo;	if (ticks > jiffy_ticks / 2)		/* check for pending interrupt */		if (cia_set_irq(&ciab_base, 0) & CIA_ICR_TA)			offset = 10000;	ticks = jiffy_ticks - ticks;	ticks = (10000 * ticks) / jiffy_ticks;	return ticks + offset;}static int a3000_hwclk(int op, struct rtc_time *t){	tod_3000.cntrl1 = TOD3000_CNTRL1_HOLD;	if (!op) { /* read */		t->tm_sec  = tod_3000.second1 * 10 + tod_3000.second2;		t->tm_min  = tod_3000.minute1 * 10 + tod_3000.minute2;		t->tm_hour = tod_3000.hour1   * 10 + tod_3000.hour2;		t->tm_mday = tod_3000.day1    * 10 + tod_3000.day2;		t->tm_wday = tod_3000.weekday;		t->tm_mon  = tod_3000.month1  * 10 + tod_3000.month2 - 1;		t->tm_year = tod_3000.year1   * 10 + tod_3000.year2;		if (t->tm_year <= 69)			t->tm_year += 100;	} else {		tod_3000.second1 = t->tm_sec / 10;		tod_3000.second2 = t->tm_sec % 10;		tod_3000.minute1 = t->tm_min / 10;		tod_3000.minute2 = t->tm_min % 10;		tod_3000.hour1   = t->tm_hour / 10;		tod_3000.hour2   = t->tm_hour % 10;		tod_3000.day1    = t->tm_mday / 10;		tod_3000.day2    = t->tm_mday % 10;		if (t->tm_wday != -1)			tod_3000.weekday = t->tm_wday;		tod_3000.month1  = (t->tm_mon + 1) / 10;		tod_3000.month2  = (t->tm_mon + 1) % 10;		if (t->tm_year >= 100)			t->tm_year -= 100;		tod_3000.year1   = t->tm_year / 10;		tod_3000.year2   = t->tm_year % 10;	}	tod_3000.cntrl1 = TOD3000_CNTRL1_FREE;	return 0;}static int a2000_hwclk(int op, struct rtc_time *t){	int cnt = 5;	tod_2000.cntrl1 = TOD2000_CNTRL1_HOLD;	while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) {		tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;		udelay(70);		tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;	}	if (!cnt)		printk(KERN_INFO "hwclk: timed out waiting for RTC (0x%x)\n",			tod_2000.cntrl1);	if (!op) { /* read */		t->tm_sec  = tod_2000.second1     * 10 + tod_2000.second2;		t->tm_min  = tod_2000.minute1     * 10 + tod_2000.minute2;		t->tm_hour = (tod_2000.hour1 & 3) * 10 + tod_2000.hour2;		t->tm_mday = tod_2000.day1        * 10 + tod_2000.day2;		t->tm_wday = tod_2000.weekday;		t->tm_mon  = tod_2000.month1      * 10 + tod_2000.month2 - 1;		t->tm_year = tod_2000.year1       * 10 + tod_2000.year2;		if (t->tm_year <= 69)			t->tm_year += 100;		if (!(tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE)) {			if (!(tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour == 12)				t->tm_hour = 0;			else if ((tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour != 12)				t->tm_hour += 12;		}	} else {		tod_2000.second1 = t->tm_sec / 10;		tod_2000.second2 = t->tm_sec % 10;		tod_2000.minute1 = t->tm_min / 10;		tod_2000.minute2 = t->tm_min % 10;		if (tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE)			tod_2000.hour1 = t->tm_hour / 10;		else if (t->tm_hour >= 12)			tod_2000.hour1 = TOD2000_HOUR1_PM +				(t->tm_hour - 12) / 10;		else			tod_2000.hour1 = t->tm_hour / 10;		tod_2000.hour2   = t->tm_hour % 10;		tod_2000.day1    = t->tm_mday / 10;		tod_2000.day2    = t->tm_mday % 10;		if (t->tm_wday != -1)			tod_2000.weekday = t->tm_wday;		tod_2000.month1  = (t->tm_mon + 1) / 10;		tod_2000.month2  = (t->tm_mon + 1) % 10;		if (t->tm_year >= 100)			t->tm_year -= 100;		tod_2000.year1   = t->tm_year / 10;		tod_2000.year2   = t->tm_year % 10;	}	tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;	return 0;}static int amiga_set_clock_mmss(unsigned long nowtime){	short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;	if (AMIGAHW_PRESENT(A3000_CLK)) {		tod_3000.cntrl1 = TOD3000_CNTRL1_HOLD;		tod_3000.second1 = real_seconds / 10;		tod_3000.second2 = real_seconds % 10;		tod_3000.minute1 = real_minutes / 10;		tod_3000.minute2 = real_minutes % 10;		tod_3000.cntrl1 = TOD3000_CNTRL1_FREE;	} else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ {		int cnt = 5;		tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;		while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) {			tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;			udelay(70);			tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;		}		if (!cnt)			printk(KERN_INFO "set_clock_mmss: timed out waiting for RTC (0x%x)\n", tod_2000.cntrl1);		tod_2000.second1 = real_seconds / 10;		tod_2000.second2 = real_seconds % 10;		tod_2000.minute1 = real_minutes / 10;		tod_2000.minute2 = real_minutes % 10;		tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;	}	return 0;}static unsigned int amiga_get_ss(void){	unsigned int s;	if (AMIGAHW_PRESENT(A3000_CLK)) {		tod_3000.cntrl1 = TOD3000_CNTRL1_HOLD;		s = tod_3000.second1 * 10 + tod_3000.second2;		tod_3000.cntrl1 = TOD3000_CNTRL1_FREE;	} else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ {		s = tod_2000.second1 * 10 + tod_2000.second2;	}	return s;}static NORET_TYPE void amiga_reset(void)    ATTRIB_NORET;static void amiga_reset(void){	unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040);	unsigned long jmp_addr = virt_to_phys(&&jmp_addr_label);	local_irq_disable();	if (CPU_IS_040_OR_060)		/* Setup transparent translation registers for mapping		 * of 16 MB kernel segment before disabling translation		 */		asm volatile ("\n"			"	move.l	%0,%%d0\n"			"	and.l	#0xff000000,%%d0\n"			"	or.w	#0xe020,%%d0\n"   /* map 16 MB, enable, cacheable */			"	.chip	68040\n"			"	movec	%%d0,%%itt0\n"			"	movec	%%d0,%%dtt0\n"			"	.chip	68k\n"			"	jmp	%0@\n"			: /* no outputs */			: "a" (jmp_addr040)			: "d0");	else		/* for 680[23]0, just disable translation and jump to the physical		 * address of the label		 */		asm volatile ("\n"			"	pmove	%%tc,%@\n"			"	bclr	#7,%@\n"			"	pmove	%@,%%tc\n"			"	jmp	%0@\n"			: /* no outputs */			: "a" (jmp_addr));jmp_addr_label040:	/* disable translation on '040 now */	asm volatile ("\n"		"	moveq	#0,%%d0\n"		"	.chip	68040\n"		"	movec	%%d0,%%tc\n"	/* disable MMU */		"	.chip	68k\n"		: /* no outputs */		: /* no inputs */		: "d0");	jmp_addr_label:	/* pickup reset address from AmigaOS ROM, reset devices and jump	 * to reset address	 */	asm volatile ("\n"		"	move.w	#0x2700,%sr\n"		"	lea	0x01000000,%a0\n"		"	sub.l	%a0@(-0x14),%a0\n"		"	move.l	%a0@(4),%a0\n"		"	subq.l	#2,%a0\n"		"	jra	1f\n"		/* align on a longword boundary */		"	" __ALIGN_STR "\n"		"1:\n"		"	reset\n"		"	jmp   %a0@");	for (;;)		;}    /*     *  Debugging     */#define SAVEKMSG_MAXMEM		128*1024#define SAVEKMSG_MAGIC1		0x53415645	/* 'SAVE' */#define SAVEKMSG_MAGIC2		0x4B4D5347	/* 'KMSG' */struct savekmsg {	unsigned long magic1;		/* SAVEKMSG_MAGIC1 */	unsigned long magic2;		/* SAVEKMSG_MAGIC2 */	unsigned long magicptr;		/* address of magic1 */	unsigned long size;	char data[0];};static struct savekmsg *savekmsg;static void amiga_mem_console_write(struct console *co, const char *s,				    unsigned int count){	if (savekmsg->size + count <= SAVEKMSG_MAXMEM-sizeof(struct savekmsg)) {		memcpy(savekmsg->data + savekmsg->size, s, count);		savekmsg->size += count;	}}static int __init amiga_savekmsg_setup(char *arg){	static struct resource debug_res = { .name = "Debug" };	if (!MACH_IS_AMIGA || strcmp(arg, "mem"))		goto done;	if (!AMIGAHW_PRESENT(CHIP_RAM)) {		printk("Warning: no chipram present for debugging\n");		goto done;	}	savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res);	savekmsg->magic1 = SAVEKMSG_MAGIC1;	savekmsg->magic2 = SAVEKMSG_MAGIC2;	savekmsg->magicptr = ZTWO_PADDR(savekmsg);	savekmsg->size = 0;	amiga_console_driver.write = amiga_mem_console_write;	register_console(&amiga_console_driver);done:	return 0;}early_param("debug", amiga_savekmsg_setup);static void amiga_serial_putc(char c){	amiga_custom.serdat = (unsigned char)c | 0x100;	while (!(amiga_custom.serdatr & 0x2000))		;}void amiga_serial_console_write(struct console *co, const char *s,				unsigned int count){	while (count--) {		if (*s == '\n')			amiga_serial_putc('\r');		amiga_serial_putc(*s++);	}}#ifdef CONFIG_SERIAL_CONSOLEvoid amiga_serial_puts(const char *s){	amiga_serial_console_write(NULL, s, strlen(s));}int amiga_serial_console_wait_key(struct console *co){	int ch;	while (!(amiga_custom.intreqr & IF_RBF))		barrier();	ch = amiga_custom.serdatr & 0xff;	/* clear the interrupt, so that another character can be read */	amiga_custom.intreq = IF_RBF;	return ch;}void amiga_serial_gets(struct console *co, char *s, int len){	int ch, cnt = 0;	while (1) {		ch = amiga_serial_console_wait_key(co);		/* Check for backspace. */		if (ch == 8 || ch == 127) {			if (cnt == 0) {				amiga_serial_putc('\007');				continue;			}			cnt--;			amiga_serial_puts("\010 \010");			continue;		}		/* Check for enter. */		if (ch == 10 || ch == 13)			break;		/* See if line is too long. */		if (cnt >= len + 1) {			amiga_serial_putc(7);			cnt--;			continue;		}		/* Store and echo character. */		s[cnt++] = ch;		amiga_serial_putc(ch);	}	/* Print enter. */	amiga_serial_puts("\r\n");	s[cnt] = 0;}#endifstatic int __init amiga_debug_setup(char *arg){	if (MACH_IS_AMIGA && !strcmp(arg, "ser")) {		/* no initialization required (?) */		amiga_console_driver.write = amiga_serial_console_write;		register_console(&amiga_console_driver);	}	return 0;}early_param("debug", amiga_debug_setup);#ifdef CONFIG_HEARTBEATstatic void amiga_heartbeat(int on){	if (on)		ciaa.pra &= ~2;	else		ciaa.pra |= 2;}#endif    /*     *  Amiga specific parts of /proc     */static void amiga_get_model(char *model){	strcpy(model, amiga_model_name);}static int amiga_get_hardware_list(char *buffer){	int len = 0;	if (AMIGAHW_PRESENT(CHIP_RAM))		len += sprintf(buffer+len, "Chip RAM:\t%ldK\n", amiga_chip_size>>10);	len += sprintf(buffer+len, "PS Freq:\t%dHz\nEClock Freq:\t%ldHz\n",			amiga_psfreq, amiga_eclock);	if (AMIGAHW_PRESENT(AMI_VIDEO)) {		char *type;		switch (amiga_chipset) {		case CS_OCS:			type = "OCS";			break;		case CS_ECS:			type = "ECS";			break;		case CS_AGA:			type = "AGA";			break;		default:			type = "Old or Unknown";			break;		}		len += sprintf(buffer+len, "Graphics:\t%s\n", type);	}#define AMIGAHW_ANNOUNCE(name, str)			\	if (AMIGAHW_PRESENT(name))			\		len += sprintf (buffer+len, "\t%s\n", str)	len += sprintf (buffer + len, "Detected hardware:\n");	AMIGAHW_ANNOUNCE(AMI_VIDEO, "Amiga Video");	AMIGAHW_ANNOUNCE(AMI_BLITTER, "Blitter");	AMIGAHW_ANNOUNCE(AMBER_FF, "Amber Flicker Fixer");	AMIGAHW_ANNOUNCE(AMI_AUDIO, "Amiga Audio");	AMIGAHW_ANNOUNCE(AMI_FLOPPY, "Floppy Controller");	AMIGAHW_ANNOUNCE(A3000_SCSI, "SCSI Controller WD33C93 (A3000 style)");	AMIGAHW_ANNOUNCE(A4000_SCSI, "SCSI Controller NCR53C710 (A4000T style)");	AMIGAHW_ANNOUNCE(A1200_IDE, "IDE Interface (A1200 style)");	AMIGAHW_ANNOUNCE(A4000_IDE, "IDE Interface (A4000 style)");	AMIGAHW_ANNOUNCE(CD_ROM, "Internal CD ROM drive");	AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "Keyboard");	AMIGAHW_ANNOUNCE(AMI_MOUSE, "Mouse Port");	AMIGAHW_ANNOUNCE(AMI_SERIAL, "Serial Port");	AMIGAHW_ANNOUNCE(AMI_PARALLEL, "Parallel Port");	AMIGAHW_ANNOUNCE(A2000_CLK, "Hardware Clock (A2000 style)");	AMIGAHW_ANNOUNCE(A3000_CLK, "Hardware Clock (A3000 style)");	AMIGAHW_ANNOUNCE(CHIP_RAM, "Chip RAM");	AMIGAHW_ANNOUNCE(PAULA, "Paula 8364");	AMIGAHW_ANNOUNCE(DENISE, "Denise 8362");	AMIGAHW_ANNOUNCE(DENISE_HR, "Denise 8373");	AMIGAHW_ANNOUNCE(LISA, "Lisa 8375");	AMIGAHW_ANNOUNCE(AGNUS_PAL, "Normal/Fat PAL Agnus 8367/8371");	AMIGAHW_ANNOUNCE(AGNUS_NTSC, "Normal/Fat NTSC Agnus 8361/8370");	AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "Fat Hires PAL Agnus 8372");	AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "Fat Hires NTSC Agnus 8372");	AMIGAHW_ANNOUNCE(ALICE_PAL, "PAL Alice 8374");	AMIGAHW_ANNOUNCE(ALICE_NTSC, "NTSC Alice 8374");	AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick");	AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot");#ifdef CONFIG_ZORRO	if (AMIGAHW_PRESENT(ZORRO))		len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion "				"Device%s\n",				AMIGAHW_PRESENT(ZORRO3) ? "I" : "",				zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");#endif /* CONFIG_ZORRO */#undef AMIGAHW_ANNOUNCE	return len;}

⌨️ 快捷键说明

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