| /* | 
 |  *	Machine specific setup for generic | 
 |  */ | 
 |  | 
 | #include <linux/init.h> | 
 | #include <linux/interrupt.h> | 
 | #include <asm/arch_hooks.h> | 
 | #include <asm/voyager.h> | 
 | #include <asm/e820.h> | 
 | #include <asm/io.h> | 
 | #include <asm/setup.h> | 
 |  | 
 | void __init pre_intr_init_hook(void) | 
 | { | 
 | 	init_ISA_irqs(); | 
 | } | 
 |  | 
 | /* | 
 |  * IRQ2 is cascade interrupt to second interrupt controller | 
 |  */ | 
 | static struct irqaction irq2 = { | 
 | 	.handler = no_action, | 
 | 	.mask = CPU_MASK_NONE, | 
 | 	.name = "cascade", | 
 | }; | 
 |  | 
 | void __init intr_init_hook(void) | 
 | { | 
 | #ifdef CONFIG_SMP | 
 | 	smp_intr_init(); | 
 | #endif | 
 |  | 
 | 	setup_irq(2, &irq2); | 
 | } | 
 |  | 
 | void __init pre_setup_arch_hook(void) | 
 | { | 
 | 	/* Voyagers run their CPUs from independent clocks, so disable | 
 | 	 * the TSC code because we can't sync them */ | 
 | 	setup_clear_cpu_cap(X86_FEATURE_TSC); | 
 | } | 
 |  | 
 | void __init trap_init_hook(void) | 
 | { | 
 | } | 
 |  | 
 | static struct irqaction irq0 = { | 
 | 	.handler = timer_interrupt, | 
 | 	.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, | 
 | 	.mask = CPU_MASK_NONE, | 
 | 	.name = "timer" | 
 | }; | 
 |  | 
 | void __init time_init_hook(void) | 
 | { | 
 | 	irq0.mask = cpumask_of_cpu(safe_smp_processor_id()); | 
 | 	setup_irq(0, &irq0); | 
 | } | 
 |  | 
 | /* Hook for machine specific memory setup. */ | 
 |  | 
 | char *__init machine_specific_memory_setup(void) | 
 | { | 
 | 	char *who; | 
 |  | 
 | 	who = "NOT VOYAGER"; | 
 |  | 
 | 	if (voyager_level == 5) { | 
 | 		__u32 addr, length; | 
 | 		int i; | 
 |  | 
 | 		who = "Voyager-SUS"; | 
 |  | 
 | 		e820.nr_map = 0; | 
 | 		for (i = 0; voyager_memory_detect(i, &addr, &length); i++) { | 
 | 			add_memory_region(addr, length, E820_RAM); | 
 | 		} | 
 | 		return who; | 
 | 	} else if (voyager_level == 4) { | 
 | 		__u32 tom; | 
 | 		__u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT) << 8; | 
 | 		/* select the DINO config space */ | 
 | 		outb(VOYAGER_DINO, VOYAGER_CAT_CONFIG_PORT); | 
 | 		/* Read DINO top of memory register */ | 
 | 		tom = ((inb(catbase + 0x4) & 0xf0) << 16) | 
 | 		    + ((inb(catbase + 0x5) & 0x7f) << 24); | 
 |  | 
 | 		if (inb(catbase) != VOYAGER_DINO) { | 
 | 			printk(KERN_ERR | 
 | 			       "Voyager: Failed to get DINO for L4, setting tom to EXT_MEM_K\n"); | 
 | 			tom = (boot_params.screen_info.ext_mem_k) << 10; | 
 | 		} | 
 | 		who = "Voyager-TOM"; | 
 | 		add_memory_region(0, 0x9f000, E820_RAM); | 
 | 		/* map from 1M to top of memory */ | 
 | 		add_memory_region(1 * 1024 * 1024, tom - 1 * 1024 * 1024, | 
 | 				  E820_RAM); | 
 | 		/* FIXME: Should check the ASICs to see if I need to | 
 | 		 * take out the 8M window.  Just do it at the moment | 
 | 		 * */ | 
 | 		add_memory_region(8 * 1024 * 1024, 8 * 1024 * 1024, | 
 | 				  E820_RESERVED); | 
 | 		return who; | 
 | 	} | 
 |  | 
 | 	who = "BIOS-e820"; | 
 |  | 
 | 	/* | 
 | 	 * Try to copy the BIOS-supplied E820-map. | 
 | 	 * | 
 | 	 * Otherwise fake a memory map; one section from 0k->640k, | 
 | 	 * the next section from 1mb->appropriate_mem_k | 
 | 	 */ | 
 | 	sanitize_e820_map(boot_params.e820_map, &boot_params.e820_entries); | 
 | 	if (copy_e820_map(boot_params.e820_map, boot_params.e820_entries) | 
 | 	    < 0) { | 
 | 		unsigned long mem_size; | 
 |  | 
 | 		/* compare results from other methods and take the greater */ | 
 | 		if (boot_params.alt_mem_k < boot_params.screen_info.ext_mem_k) { | 
 | 			mem_size = boot_params.screen_info.ext_mem_k; | 
 | 			who = "BIOS-88"; | 
 | 		} else { | 
 | 			mem_size = boot_params.alt_mem_k; | 
 | 			who = "BIOS-e801"; | 
 | 		} | 
 |  | 
 | 		e820.nr_map = 0; | 
 | 		add_memory_region(0, LOWMEMSIZE(), E820_RAM); | 
 | 		add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); | 
 | 	} | 
 | 	return who; | 
 | } |