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

📄 prep_setup.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* vgacon.c needs to know where we mapped IO memory in io_block_mapping() */	vgacon_remap_base = 0xf0000000;	conswitchp = &vga_con;#elif defined(CONFIG_DUMMY_CONSOLE)	conswitchp = &dummy_con;#endif}/* * Determine the decrementer frequency from the residual data * This allows for a faster boot as we do not need to calibrate the * decrementer against another clock. This is important for embedded systems. */static int __initprep_res_calibrate_decr(void){#ifdef CONFIG_PREP_RESIDUAL	unsigned long freq, divisor = 4;	if ( res->VitalProductData.ProcessorBusHz ) {		freq = res->VitalProductData.ProcessorBusHz;		printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",				(freq/divisor)/1000000,				(freq/divisor)%1000000);		tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000);		tb_ticks_per_jiffy = freq / HZ / divisor;		return 0;	} else#endif			return 1;}/* * Uses the on-board timer to calibrate the on-chip decrementer register * for prep systems.  On the pmac the OF tells us what the frequency is * but on prep we have to figure it out. * -- Cort *//* Done with 3 interrupts: the first one primes the cache and the * 2 following ones measure the interval. The precision of the method * is still doubtful due to the short interval sampled. */static volatile int calibrate_steps __initdata = 3;static unsigned tbstamp __initdata = 0;static void __initprep_calibrate_decr_handler(int irq, void *dev, struct pt_regs *regs){	unsigned long t, freq;	int step=--calibrate_steps;	t = get_tbl();	if (step > 0) {		tbstamp = t;	} else {		freq = (t - tbstamp)*HZ;		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 __initprep_calibrate_decr(void){	int res;	/* Try and get this from the residual data. */	res = prep_res_calibrate_decr();	/* If we didn't get it from the residual data, try this. */	if ( res ) {		unsigned long flags;		save_flags(flags);#define TIMER0_COUNT 0x40#define TIMER_CONTROL 0x43		/* set timer to periodic mode */		outb_p(0x34,TIMER_CONTROL);/* binary, mode 2, LSB/MSB, ch 0 */		/* set the clock to ~100 Hz */		outb_p(LATCH & 0xff , TIMER0_COUNT);	/* LSB */		outb(LATCH >> 8 , TIMER0_COUNT);	/* MSB */		if (request_irq(0, prep_calibrate_decr_handler, 0, "timer", NULL) != 0)			panic("Could not allocate timer IRQ!");		__sti();		/* wait for calibrate */		while ( calibrate_steps )			;		restore_flags(flags);		free_irq( 0, NULL);	}}static long __initmk48t59_init(void) {	unsigned char tmp;	tmp = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLB);	if (tmp & MK48T59_RTC_CB_STOP) {		printk("Warning: RTC was stopped, date will be wrong.\n");		ppc_md.nvram_write_val(MK48T59_RTC_CONTROLB, 					 tmp & ~MK48T59_RTC_CB_STOP);		/* Low frequency crystal oscillators may take a very long		 * time to startup and stabilize. For now just ignore the		 * the issue, but attempting to calibrate the decrementer		 * from the RTC just after this wakeup is likely to be very 		 * inaccurate. Firmware should not allow to load		 * the OS with the clock stopped anyway...		 */	}	/* Ensure that the clock registers are updated */	tmp = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLA);	tmp &= ~(MK48T59_RTC_CA_READ | MK48T59_RTC_CA_WRITE);	ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, tmp);	return 0;}/* 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 unsigned int __prepprep_irq_cannonicalize(u_int irq){	if (irq == 2)	{		return 9;	}	else	{		return irq;	}}static void __initprep_init_IRQ(void){	int i;	unsigned int pci_viddid, pci_did;	if (OpenPIC_Addr != NULL) {		openpic_init(NUM_8259_INTERRUPTS);		/* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */		openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",				       i8259_irq);	}	for (i = 0; i < NUM_8259_INTERRUPTS; i++)		irq_desc[i].handler = &i8259_pic;	 /* If we have a Raven PCI bridge or a Hawk PCI bridge / Memory	  * controller, we poll (as they have a different int-ack address). */	early_read_config_dword(0, 0, 0, PCI_VENDOR_ID, &pci_viddid);	pci_did = (pci_viddid & 0xffff0000) >> 16;	if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA)			&& ((pci_did == PCI_DEVICE_ID_MOTOROLA_RAVEN)				|| (pci_did == PCI_DEVICE_ID_MOTOROLA_HAWK)))		i8259_init(0);	else		/* PCI interrupt ack address given in section 6.1.8 of the		 * PReP specification. */		i8259_init(0xbffffff0);}#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;	}}#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 released, 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 *//* * What ever boots us must pass in the ammount of memory. */static unsigned long __initprep_find_end_of_memory(void){	return boot_mem_size;}/* * 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(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	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   = NULL; /* set in prep_setup_arch() */	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        = i8259_irq;	ppc_md.init           = prep_init2;	ppc_md.restart        = prep_restart;	ppc_md.power_off      = NULL; /* set in prep_setup_arch() */	ppc_md.halt           = prep_halt;	ppc_md.nvram_read_val = prep_nvram_read_val;	ppc_md.nvram_write_val = prep_nvram_write_val;	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;#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 + -