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

📄 prep_setup.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
/* We use the NVRAM RTC to time a second to calibrate the decrementer, * the RTC registers have just been set up in the right state by the * preceding routine. */static void __initmk48t59_calibrate_decr(void){	unsigned long freq;	unsigned long t1;	unsigned char save_control;	long i;	unsigned char sec; 			/* Make sure the time is not stopped. */	save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLB);		ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA,			(save_control & (~MK48T59_RTC_CB_STOP)));	/* Now make sure the read bit is off so the value will change. */	save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLA);	save_control &= ~MK48T59_RTC_CA_READ;	ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, save_control);	/* Read the seconds value to see when it changes. */	sec = ppc_md.nvram_read_val(MK48T59_RTC_SECONDS);	/* Actually this is bad for precision, we should have a loop in	 * which we only read the seconds counter. nvram_read_val writes	 * the address bytes on every call and this takes a lot of time.	 * Perhaps an nvram_wait_change method returning a time	 * stamp with a loop count as parameter would be the  solution.	 */	for (i = 0 ; i < 1000000 ; i++)	{ /* may take up to 1 second... */		t1 = get_tbl();		if (ppc_md.nvram_read_val(MK48T59_RTC_SECONDS) != sec) {			break;		}	}	sec = ppc_md.nvram_read_val(MK48T59_RTC_SECONDS);	for (i = 0 ; i < 1000000 ; i++)	{ /* Should take up 1 second... */		freq = get_tbl()-t1;		if (ppc_md.nvram_read_val(MK48T59_RTC_SECONDS) != sec)			break;	}	printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",		 freq/1000000, freq%1000000);	tb_ticks_per_jiffy = freq / HZ;	tb_to_us = mulhwu_scale_factor(freq, 1000000);}static void __prepprep_restart(char *cmd){	unsigned long i = 10000;	__cli();	/* set exception prefix high - to the prom */	_nmask_and_or_msr(0, MSR_IP);	/* make sure bit 0 (reset) is a 0 */	outb( inb(0x92) & ~1L , 0x92 );	/* signal a reset to system control port A - soft reset */	outb( inb(0x92) | 1 , 0x92 );	while ( i != 0 ) i++;	panic("restart failed\n");}static void __prepprep_halt(void){	unsigned long flags;	__cli();	/* set exception prefix high - to the prom */	save_flags( flags );	restore_flags( flags|MSR_IP );	/* make sure bit 0 (reset) is a 0 */	outb( inb(0x92) & ~1L , 0x92 );	/* signal a reset to system control port A - soft reset */	outb( inb(0x92) | 1 , 0x92 );	while ( 1 ) ;	/*	 * Not reached	 */}/* * On IBM PReP's, power management is handled by a Signetics 87c750 behind the * Utah component on the ISA bus. To access the 750 you must write a series of * nibbles to port 0x82a (decoded by the Utah). This is described somewhat in * the IBM Carolina Technical Specification. * -Hollis */static void __preputah_sig87c750_setbit(unsigned int bytenum, unsigned int bitnum, int value){	/*	 * byte1: 0 0 0 1 0  d  a5 a4	 * byte2: 0 0 0 1 a3 a2 a1 a0	 *	 * d = the bit's value, enabled or disabled	 * (a5 a4 a3) = the byte number, minus 20	 * (a2 a1 a0) = the bit number	 *	 * example: set the 5th bit of byte 21 (21.5)	 *     a5 a4 a3 = 001 (byte 1)	 *     a2 a1 a0 = 101 (bit 5)	 *	 *     byte1 = 0001 0100 (0x14)	 *     byte2 = 0001 1101 (0x1d)	 */	unsigned char byte1=0x10, byte2=0x10;	const unsigned int pm_reg_1=0x82a; /* ISA address */	/* the 750's '20.0' is accessed as '0.0' through Utah (which adds 20) */	bytenum -= 20;	byte1 |= (!!value) << 2;		/* set d */	byte1 |= (bytenum >> 1) & 0x3;	/* set a5, a4 */	byte2 |= (bytenum & 0x1) << 3;	/* set a3 */	byte2 |= bitnum & 0x7;			/* set a2, a1, a0 */	outb(byte1, pm_reg_1);		/* first nibble */	mb();	udelay(100);				/* important: let controller recover */	outb(byte2, pm_reg_1);		/* second nibble */	mb();	udelay(100);				/* important: let controller recover */}static void __prepprep_power_off(void){	if ( _prep_type == _PREP_IBM) {		/* tested on:		 * 		Carolina's: 7248-43P, 6070 (PowerSeries 850)		 * should work on:		 * 		Carolina: 6050 (PowerSeries 830)		 * 		7043-140 (Tiger 1)		 */		unsigned long flags;		__cli();		/* set exception prefix high - to the prom */		save_flags( flags );		restore_flags( flags|MSR_IP );		utah_sig87c750_setbit(21, 5, 1); /* set bit 21.5, "PMEXEC_OFF" */		while ( 1 ) ;		/* not reached */	} else {		prep_halt();	}}static unsigned int __prepprep_irq_cannonicalize(u_int irq){	if (irq == 2)	{		return 9;	}	else	{		return irq;	}}static int __prepprep_get_irq(struct pt_regs *regs){	return i8259_irq();}		static void __initprep_init_IRQ(void){	int i;	if (OpenPIC_Addr != NULL)		openpic_init(1, NUM_8259_INTERRUPTS, 0, -1);	for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ )		irq_desc[i].handler = &i8259_pic;	i8259_init(0xbffffff0); /* PCI interrupt ack address for MPC105 and 106 */}#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)/* * IDE stuff. */static int __prepprep_ide_default_irq(ide_ioreg_t base){	switch (base) {		case 0x1f0: return 13;		case 0x170: return 13;		case 0x1e8: return 11;		case 0x168: return 10;		case 0xfff0: return 14;		/* MCP(N)750 ide0 */		case 0xffe0: return 15;		/* MCP(N)750 ide1 */		default: return 0;	}}static ide_ioreg_t __prepprep_ide_default_io_base(int index){	switch (index) {		case 0: return 0x1f0;		case 1: return 0x170;		case 2: return 0x1e8;		case 3: return 0x168;		default:			return 0;	}}static int __prepprep_ide_check_region(ide_ioreg_t from, unsigned int extent){	return check_region(from, extent);}static void __prepprep_ide_request_region(ide_ioreg_t from,			unsigned int extent,			const char *name){	request_region(from, extent, name);}static void __prepprep_ide_release_region(ide_ioreg_t from,			unsigned int extent){	release_region(from, extent);}static void __initprep_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq){	ide_ioreg_t reg = data_port;	int i;	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {		hw->io_ports[i] = reg;		reg += 1;	}	if (ctrl_port) {		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;	} else {		hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;	}	if (irq != NULL)		*irq = 0;}#endif#ifdef CONFIG_SMP/* PReP (MTX) support */static int __initsmp_prep_probe(void){	extern int mot_multi;	if (mot_multi) {		openpic_request_IPIs();		smp_hw_index[1] = 1;		return 2;	}	return 1;}static void __initsmp_prep_kick_cpu(int nr){	*(unsigned long *)KERNELBASE = nr;	asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");	printk("CPU1 reset, waiting\n");}static void __initsmp_prep_setup_cpu(int cpu_nr){	if (OpenPIC_Addr)		do_openpic_setup_cpu();}static struct smp_ops_t prep_smp_ops __prepdata = {	smp_openpic_message_pass,	smp_prep_probe,	smp_prep_kick_cpu,	smp_prep_setup_cpu,};#endif /* CONFIG_SMP *//* * This finds the amount of physical ram and does necessary * setup for prep.  This is pretty architecture specific so * this will likely stay separate from the pmac. * -- Cort */static unsigned long __initprep_find_end_of_memory(void){	unsigned long total = 0;	extern unsigned int boot_mem_size;#ifdef CONFIG_PREP_RESIDUAL		total = res->TotalMemory;#endif		if (total == 0 && boot_mem_size != 0)		total = boot_mem_size;	else if (total == 0) {		/*		 * I need a way to probe the amount of memory if the residual		 * data doesn't contain it. -- Cort		 */		total = 0x02000000;		printk(KERN_INFO "Ramsize from residual data was 0"			 " -- defaulting to %ldM\n", total>>20);	}	return (total);}/* * Setup the bat mappings we're going to load that cover * the io areas.  RAM was mapped by mapin_ram(). * -- Cort */static void __initprep_map_io(void){	io_block_mapping(0x80000000, PREP_ISA_IO_BASE, 0x10000000, _PAGE_IO);	io_block_mapping(0xf0000000, PREP_ISA_MEM_BASE, 0x08000000, _PAGE_IO);}static void __initprep_init2(void){#ifdef CONFIG_NVRAM	request_region(PREP_NVRAM_AS0, 0x8, "nvram");#endif	request_region(0x20,0x20,"pic1");	request_region(0xa0,0x20,"pic2");	request_region(0x00,0x20,"dma1");	request_region(0x40,0x20,"timer");	request_region(0x80,0x10,"dma page reg");	request_region(0xc0,0x20,"dma2");}void __initprep_init(unsigned long r3, unsigned long r4, unsigned long r5,		unsigned long r6, unsigned long r7){#ifdef CONFIG_PREP_RESIDUAL		/* make a copy of residual data */	if ( r3 ) {		memcpy((void *)res,(void *)(r3+KERNELBASE),			 sizeof(RESIDUAL));	}#endif#ifdef CONFIG_BLK_DEV_INITRD	if ( r4 )	{		initrd_start = r4 + KERNELBASE;		initrd_end = r5 + KERNELBASE;	}#endif /* CONFIG_BLK_DEV_INITRD */	/* Copy cmd_line parameters */	if ( r6 )	{		*(char *)(r7 + KERNELBASE) = 0;		strcpy(cmd_line, (char *)(r6 + KERNELBASE));	}		isa_io_base = PREP_ISA_IO_BASE;	isa_mem_base = PREP_ISA_MEM_BASE;	pci_dram_offset = PREP_PCI_DRAM_OFFSET;	ISA_DMA_THRESHOLD = 0x00ffffff;	DMA_MODE_READ = 0x44;	DMA_MODE_WRITE = 0x48;	/* figure out what kind of prep workstation we are */#ifdef CONFIG_PREP_RESIDUAL		if ( res->ResidualLength != 0 )	{		if ( !strncmp(res->VitalProductData.PrintableModel,"IBM",3) )			_prep_type = _PREP_IBM;		else			_prep_type = _PREP_Motorola;	}	else /* assume motorola if no residual (netboot?) */#endif	{		_prep_type = _PREP_Motorola;	}	ppc_md.setup_arch     = prep_setup_arch;	ppc_md.show_percpuinfo = prep_show_percpuinfo;	ppc_md.show_cpuinfo   = prep_show_cpuinfo;	ppc_md.irq_cannonicalize = prep_irq_cannonicalize;	ppc_md.init_IRQ       = prep_init_IRQ;	/* this gets changed later on if we have an OpenPIC -- Cort */	ppc_md.get_irq        = prep_get_irq;	ppc_md.init           = prep_init2;	ppc_md.restart        = prep_restart;	ppc_md.power_off      = prep_power_off;	ppc_md.halt           = prep_halt;	ppc_md.time_init      = NULL;	if (_prep_type == _PREP_IBM) {		ppc_md.set_rtc_time   = mc146818_set_rtc_time;		ppc_md.get_rtc_time   = mc146818_get_rtc_time;		ppc_md.calibrate_decr = prep_calibrate_decr;	} else {		ppc_md.set_rtc_time   = mk48t59_set_rtc_time;		ppc_md.get_rtc_time   = mk48t59_get_rtc_time;		ppc_md.calibrate_decr = mk48t59_calibrate_decr;		ppc_md.time_init      = mk48t59_init;	}	ppc_md.find_end_of_memory = prep_find_end_of_memory;	ppc_md.setup_io_mappings = prep_map_io;#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)	ppc_ide_md.default_irq = prep_ide_default_irq;	ppc_ide_md.default_io_base = prep_ide_default_io_base;	ppc_ide_md.ide_check_region = prep_ide_check_region;	ppc_ide_md.ide_request_region = prep_ide_request_region;	ppc_ide_md.ide_release_region = prep_ide_release_region;	ppc_ide_md.ide_init_hwif = prep_ide_init_hwif_ports;#endif#ifdef CONFIG_VT	ppc_md.kbd_setkeycode    = pckbd_setkeycode;	ppc_md.kbd_getkeycode    = pckbd_getkeycode;	ppc_md.kbd_translate     = pckbd_translate;	ppc_md.kbd_unexpected_up = pckbd_unexpected_up;	ppc_md.kbd_leds          = pckbd_leds;	ppc_md.kbd_init_hw       = pckbd_init_hw;#ifdef CONFIG_MAGIC_SYSRQ	ppc_md.ppc_kbd_sysrq_xlate	 = pckbd_sysrq_xlate;	SYSRQ_KEY = 0x54;#endif#endif#ifdef CONFIG_SMP	ppc_md.smp_ops		 = &prep_smp_ops;#endif /* CONFIG_SMP */}

⌨️ 快捷键说明

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