소스 검색

Merge with rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

Steve French 20 년 전
부모
커밋
af6f5e3247
100개의 변경된 파일1663개의 추가작업 그리고 1285개의 파일을 삭제
  1. 1 2
      Documentation/cpusets.txt
  2. 3 0
      Documentation/x86_64/boot-options.txt
  3. 2 2
      MAINTAINERS
  4. 1 1
      Makefile
  5. 1 1
      arch/i386/Kconfig
  6. 6 3
      arch/i386/kernel/cpu/amd.c
  7. 1 4
      arch/i386/kernel/cpu/common.c
  8. 1 1
      arch/i386/kernel/cpu/intel_cacheinfo.c
  9. 4 1
      arch/i386/kernel/smpboot.c
  10. 8 9
      arch/i386/mach-voyager/voyager_smp.c
  11. 6 4
      arch/i386/mm/ioremap.c
  12. 0 5
      arch/i386/pci/irq.c
  13. 2 2
      arch/ia64/kernel/entry.S
  14. 2 2
      arch/ia64/kernel/mca.c
  15. 1 2
      arch/ia64/kernel/minstate.h
  16. 160 15
      arch/ia64/kernel/perfmon.c
  17. 17 3
      arch/ia64/kernel/ptrace.c
  18. 1 1
      arch/ia64/kernel/smpboot.c
  19. 0 7
      arch/ia64/kernel/sys_ia64.c
  20. 2 0
      arch/ia64/sn/kernel/setup.c
  21. 2 2
      arch/ppc/Kconfig
  22. 2 1
      arch/ppc/boot/images/Makefile
  23. 92 25
      arch/ppc/configs/mpc8555_cds_defconfig
  24. 9 6
      arch/ppc/kernel/head_44x.S
  25. 14 1
      arch/ppc/kernel/head_fsl_booke.S
  26. 1 1
      arch/ppc/kernel/setup.c
  27. 1 6
      arch/ppc/kernel/traps.c
  28. 5 2
      arch/ppc/lib/string.S
  29. 1 0
      arch/ppc/mm/init.c
  30. 0 1
      arch/ppc/platforms/83xx/mpc834x_sys.c
  31. 6 1
      arch/ppc/platforms/83xx/mpc834x_sys.h
  32. 3 0
      arch/ppc/platforms/85xx/mpc8540_ads.c
  33. 141 2
      arch/ppc/platforms/85xx/mpc85xx_cds_common.c
  34. 3 0
      arch/ppc/platforms/85xx/mpc85xx_cds_common.h
  35. 3 0
      arch/ppc/platforms/85xx/sbc8560.c
  36. 22 14
      arch/ppc/platforms/pmac_cpufreq.c
  37. 18 23
      arch/ppc/platforms/pq2ads.h
  38. 2 2
      arch/ppc/syslib/Makefile
  39. 1 1
      arch/ppc/syslib/ipic.c
  40. 0 193
      arch/ppc/syslib/m8260_pci.c
  41. 0 76
      arch/ppc/syslib/m8260_pci.h
  42. 5 5
      arch/ppc/syslib/m8260_pci_erratum9.c
  43. 9 2
      arch/ppc/syslib/m8260_setup.c
  44. 383 0
      arch/ppc/syslib/m82xx_pci.c
  45. 92 0
      arch/ppc/syslib/m82xx_pci.h
  46. 1 0
      arch/ppc/syslib/mpc83xx_devices.c
  47. 1 0
      arch/ppc/syslib/mpc85xx_devices.c
  48. 1 5
      arch/ppc/syslib/open_pic.c
  49. 28 0
      arch/ppc/syslib/ppc83xx_setup.c
  50. 16 0
      arch/ppc/syslib/ppc85xx_setup.c
  51. 65 20
      arch/ppc64/kernel/mf.c
  52. 21 7
      arch/ppc64/kernel/pmac_smp.c
  53. 49 1
      arch/ppc64/kernel/prom_init.c
  54. 1 38
      arch/ppc64/kernel/rtc.c
  55. 1 0
      arch/ppc64/kernel/time.c
  56. 67 100
      arch/sparc64/kernel/pci_iommu.c
  57. 23 8
      arch/sparc64/kernel/sbus.c
  58. 11 0
      arch/sparc64/kernel/setup.c
  59. 3 0
      arch/sparc64/kernel/smp.c
  60. 19 0
      arch/sparc64/kernel/traps.c
  61. 0 4
      arch/um/Kconfig.debug
  62. 4 0
      arch/um/Kconfig_x86_64
  63. 15 7
      arch/um/drivers/chan_kern.c
  64. 1 3
      arch/um/drivers/mcast_kern.c
  65. 15 32
      arch/um/drivers/mcast_user.c
  66. 11 5
      arch/um/drivers/random.c
  67. 0 1
      arch/um/drivers/ssl.c
  68. 0 1
      arch/um/drivers/stdio_console.c
  69. 6 297
      arch/um/drivers/ubd_kern.c
  70. 0 24
      arch/um/include/2_5compat.h
  71. 1 1
      arch/um/include/sysdep-i386/ptrace.h
  72. 10 16
      arch/um/include/sysdep-x86_64/checksum.h
  73. 26 36
      arch/um/include/sysdep-x86_64/ptrace.h
  74. 2 1
      arch/um/include/sysrq.h
  75. 1 1
      arch/um/kernel/Makefile
  76. 0 0
      arch/um/kernel/checksum.c
  77. 0 1
      arch/um/kernel/exec_kern.c
  78. 20 1
      arch/um/kernel/initrd.c
  79. 0 46
      arch/um/kernel/initrd_user.c
  80. 1 0
      arch/um/kernel/ksyms.c
  81. 21 19
      arch/um/kernel/main.c
  82. 31 9
      arch/um/kernel/mem.c
  83. 0 36
      arch/um/kernel/process_kern.c
  84. 6 19
      arch/um/kernel/ptrace.c
  85. 14 7
      arch/um/kernel/sysrq.c
  86. 4 33
      arch/um/kernel/trap_kern.c
  87. 1 0
      arch/um/kernel/tt/ksyms.c
  88. 1 7
      arch/um/kernel/tt/process_kern.c
  89. 0 6
      arch/um/kernel/um_arch.c
  90. 2 0
      arch/um/kernel/uml.lds.S
  91. 2 2
      arch/um/sys-i386/Makefile
  92. 12 4
      arch/um/sys-i386/delay.c
  93. 79 1
      arch/um/sys-i386/sysrq.c
  94. 1 13
      arch/um/sys-ppc/sysrq.c
  95. 2 4
      arch/um/sys-x86_64/Makefile
  96. 15 18
      arch/um/sys-x86_64/delay.c
  97. 1 2
      arch/um/sys-x86_64/ksyms.c
  98. 5 4
      arch/um/sys-x86_64/ptrace.c
  99. 11 6
      arch/um/sys-x86_64/syscalls.c
  100. 1 10
      arch/um/sys-x86_64/sysrq.c

+ 1 - 2
Documentation/cpusets.txt

@@ -252,8 +252,7 @@ in a tasks processor placement.
 There is an exception to the above.  If hotplug funtionality is used
 There is an exception to the above.  If hotplug funtionality is used
 to remove all the CPUs that are currently assigned to a cpuset,
 to remove all the CPUs that are currently assigned to a cpuset,
 then the kernel will automatically update the cpus_allowed of all
 then the kernel will automatically update the cpus_allowed of all
-tasks attached to CPUs in that cpuset with the online CPUs of the
-nearest parent cpuset that still has some CPUs online.  When memory
+tasks attached to CPUs in that cpuset to allow all CPUs.  When memory
 hotplug functionality for removing Memory Nodes is available, a
 hotplug functionality for removing Memory Nodes is available, a
 similar exception is expected to apply there as well.  In general,
 similar exception is expected to apply there as well.  In general,
 the kernel prefers to violate cpuset placement, over starving a task
 the kernel prefers to violate cpuset placement, over starving a task

+ 3 - 0
Documentation/x86_64/boot-options.txt

@@ -25,6 +25,9 @@ APICs
 
 
    noapictimer	 Don't set up the APIC timer
    noapictimer	 Don't set up the APIC timer
 
 
+   no_timer_check Don't check the IO-APIC timer. This can work around
+		 problems with incorrect timer initialization on some boards.
+
 Early Console
 Early Console
 
 
    syntax: earlyprintk=vga
    syntax: earlyprintk=vga

+ 2 - 2
MAINTAINERS

@@ -1023,8 +1023,8 @@ W:	http://www.ia64-linux.org/
 S:	Maintained
 S:	Maintained
 
 
 SN-IA64 (Itanium) SUB-PLATFORM
 SN-IA64 (Itanium) SUB-PLATFORM
-P:	Jesse Barnes
-M:	jbarnes@sgi.com
+P:	Greg Edwards
+M:	edwardsg@sgi.com
 L:	linux-altix@sgi.com
 L:	linux-altix@sgi.com
 L:	linux-ia64@vger.kernel.org
 L:	linux-ia64@vger.kernel.org
 W:	http://www.sgi.com/altix
 W:	http://www.sgi.com/altix

+ 1 - 1
Makefile

@@ -1,7 +1,7 @@
 VERSION = 2
 VERSION = 2
 PATCHLEVEL = 6
 PATCHLEVEL = 6
 SUBLEVEL = 12
 SUBLEVEL = 12
-EXTRAVERSION =-rc4
+EXTRAVERSION =-rc5
 NAME=Woozy Numbat
 NAME=Woozy Numbat
 
 
 # *DOCUMENTATION*
 # *DOCUMENTATION*

+ 1 - 1
arch/i386/Kconfig

@@ -1163,7 +1163,7 @@ config PCI_DIRECT
 
 
 config PCI_MMCONFIG
 config PCI_MMCONFIG
 	bool
 	bool
-	depends on PCI && (PCI_GOMMCONFIG || (PCI_GOANY && ACPI))
+	depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY)
 	select ACPI_BOOT
 	select ACPI_BOOT
 	default y
 	default y
 
 

+ 6 - 3
arch/i386/kernel/cpu/amd.c

@@ -195,7 +195,7 @@ static void __init init_amd(struct cpuinfo_x86 *c)
 			c->x86_num_cores = 1;
 			c->x86_num_cores = 1;
 	}
 	}
 
 
-#ifdef CONFIG_X86_SMP
+#ifdef CONFIG_X86_HT
 	/*
 	/*
 	 * On a AMD dual core setup the lower bits of the APIC id
 	 * On a AMD dual core setup the lower bits of the APIC id
 	 * distingush the cores.  Assumes number of cores is a power
 	 * distingush the cores.  Assumes number of cores is a power
@@ -203,8 +203,11 @@ static void __init init_amd(struct cpuinfo_x86 *c)
 	 */
 	 */
 	if (c->x86_num_cores > 1) {
 	if (c->x86_num_cores > 1) {
 		int cpu = smp_processor_id();
 		int cpu = smp_processor_id();
-		/* Fix up the APIC ID following AMD specifications. */
-		cpu_core_id[cpu] >>= hweight32(c->x86_num_cores - 1);
+		unsigned bits = 0;
+		while ((1 << bits) < c->x86_num_cores)
+			bits++;
+		cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<<bits)-1);
+		phys_proc_id[cpu] >>= bits;
 		printk(KERN_INFO "CPU %d(%d) -> Core %d\n",
 		printk(KERN_INFO "CPU %d(%d) -> Core %d\n",
 		       cpu, c->x86_num_cores, cpu_core_id[cpu]);
 		       cpu, c->x86_num_cores, cpu_core_id[cpu]);
 	}
 	}

+ 1 - 4
arch/i386/kernel/cpu/common.c

@@ -244,11 +244,8 @@ static void __init early_cpu_detect(void)
 
 
 	early_intel_workaround(c);
 	early_intel_workaround(c);
 
 
-#ifdef CONFIG_SMP
 #ifdef CONFIG_X86_HT
 #ifdef CONFIG_X86_HT
-	phys_proc_id[smp_processor_id()] =
-#endif
-	cpu_core_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff;
+	phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff;
 #endif
 #endif
 }
 }
 
 

+ 1 - 1
arch/i386/kernel/cpu/intel_cacheinfo.c

@@ -118,7 +118,7 @@ struct _cpuid4_info {
 };
 };
 
 
 #define MAX_CACHE_LEAVES		4
 #define MAX_CACHE_LEAVES		4
-static unsigned short __devinitdata	num_cache_leaves;
+static unsigned short			num_cache_leaves;
 
 
 static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
 static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
 {
 {

+ 4 - 1
arch/i386/kernel/smpboot.c

@@ -888,6 +888,7 @@ void *xquad_portio;
 
 
 cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
 cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
 cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
 cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
+EXPORT_SYMBOL(cpu_core_map);
 
 
 static void __init smp_boot_cpus(unsigned int max_cpus)
 static void __init smp_boot_cpus(unsigned int max_cpus)
 {
 {
@@ -1073,8 +1074,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
 			cpu_set(cpu, cpu_sibling_map[cpu]);
 			cpu_set(cpu, cpu_sibling_map[cpu]);
 		}
 		}
 
 
-		if (siblings != smp_num_siblings)
+		if (siblings != smp_num_siblings) {
 			printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings);
 			printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings);
+			smp_num_siblings = siblings;
+		}
 
 
 		if (c->x86_num_cores > 1) {
 		if (c->x86_num_cores > 1) {
 			for (i = 0; i < NR_CPUS; i++) {
 			for (i = 0; i < NR_CPUS; i++) {

+ 8 - 9
arch/i386/mach-voyager/voyager_smp.c

@@ -97,7 +97,6 @@ static void ack_vic_irq(unsigned int irq);
 static void vic_enable_cpi(void);
 static void vic_enable_cpi(void);
 static void do_boot_cpu(__u8 cpuid);
 static void do_boot_cpu(__u8 cpuid);
 static void do_quad_bootstrap(void);
 static void do_quad_bootstrap(void);
-static inline void wrapper_smp_local_timer_interrupt(struct pt_regs *);
 
 
 int hard_smp_processor_id(void);
 int hard_smp_processor_id(void);
 
 
@@ -125,6 +124,14 @@ send_QIC_CPI(__u32 cpuset, __u8 cpi)
 	}
 	}
 }
 }
 
 
+static inline void
+wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
+{
+	irq_enter();
+	smp_local_timer_interrupt(regs);
+	irq_exit();
+}
+
 static inline void
 static inline void
 send_one_CPI(__u8 cpu, __u8 cpi)
 send_one_CPI(__u8 cpu, __u8 cpi)
 {
 {
@@ -1249,14 +1256,6 @@ smp_vic_timer_interrupt(struct pt_regs *regs)
 	smp_local_timer_interrupt(regs);
 	smp_local_timer_interrupt(regs);
 }
 }
 
 
-static inline void
-wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
-{
-	irq_enter();
-	smp_local_timer_interrupt(regs);
-	irq_exit();
-}
-
 /* local (per CPU) timer interrupt.  It does both profiling and
 /* local (per CPU) timer interrupt.  It does both profiling and
  * process statistics/rescheduling.
  * process statistics/rescheduling.
  *
  *

+ 6 - 4
arch/i386/mm/ioremap.c

@@ -238,19 +238,21 @@ void iounmap(volatile void __iomem *addr)
 			addr < phys_to_virt(ISA_END_ADDRESS))
 			addr < phys_to_virt(ISA_END_ADDRESS))
 		return;
 		return;
 
 
-	p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
+	write_lock(&vmlist_lock);
+	p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
 	if (!p) { 
 	if (!p) { 
-		printk("__iounmap: bad address %p\n", addr);
-		return;
+		printk("iounmap: bad address %p\n", addr);
+		goto out_unlock;
 	}
 	}
 
 
 	if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) {
 	if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) {
-		/* p->size includes the guard page, but cpa doesn't like that */
 		change_page_attr(virt_to_page(__va(p->phys_addr)),
 		change_page_attr(virt_to_page(__va(p->phys_addr)),
 				 p->size >> PAGE_SHIFT,
 				 p->size >> PAGE_SHIFT,
 				 PAGE_KERNEL);
 				 PAGE_KERNEL);
 		global_flush_tlb();
 		global_flush_tlb();
 	} 
 	} 
+out_unlock:
+	write_unlock(&vmlist_lock);
 	kfree(p); 
 	kfree(p); 
 }
 }
 
 

+ 0 - 5
arch/i386/pci/irq.c

@@ -1029,7 +1029,6 @@ void pcibios_penalize_isa_irq(int irq)
 static int pirq_enable_irq(struct pci_dev *dev)
 static int pirq_enable_irq(struct pci_dev *dev)
 {
 {
 	u8 pin;
 	u8 pin;
-	extern int via_interrupt_line_quirk;
 	struct pci_dev *temp_dev;
 	struct pci_dev *temp_dev;
 
 
 	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
 	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
@@ -1084,10 +1083,6 @@ static int pirq_enable_irq(struct pci_dev *dev)
 		printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
 		printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
 		       'A' + pin, pci_name(dev), msg);
 		       'A' + pin, pci_name(dev), msg);
 	}
 	}
-	/* VIA bridges use interrupt line for apic/pci steering across
-	   the V-Link */
-	else if (via_interrupt_line_quirk)
-		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq & 15);
 	return 0;
 	return 0;
 }
 }
 
 

+ 2 - 2
arch/ia64/kernel/entry.S

@@ -1182,7 +1182,7 @@ ENTRY(notify_resume_user)
 	;;
 	;;
 (pNonSys) mov out2=0				// out2==0 => not a syscall
 (pNonSys) mov out2=0				// out2==0 => not a syscall
 	.fframe 16
 	.fframe 16
-	.spillpsp ar.unat, 16			// (note that offset is relative to psp+0x10!)
+	.spillsp ar.unat, 16
 	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
 	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
 	st8 [out1]=loc1,-8			// save ar.pfs, out1=&sigscratch
 	st8 [out1]=loc1,-8			// save ar.pfs, out1=&sigscratch
 	.body
 	.body
@@ -1208,7 +1208,7 @@ GLOBAL_ENTRY(sys_rt_sigsuspend)
 	adds out2=8,sp				// out2=&sigscratch->ar_pfs
 	adds out2=8,sp				// out2=&sigscratch->ar_pfs
 	;;
 	;;
 	.fframe 16
 	.fframe 16
-	.spillpsp ar.unat, 16			// (note that offset is relative to psp+0x10!)
+	.spillsp ar.unat, 16
 	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
 	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
 	st8 [out2]=loc1,-8			// save ar.pfs, out2=&sigscratch
 	st8 [out2]=loc1,-8			// save ar.pfs, out2=&sigscratch
 	.body
 	.body

+ 2 - 2
arch/ia64/kernel/mca.c

@@ -1390,8 +1390,7 @@ ia64_mca_init(void)
 	register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction);
 	register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction);
 
 
 #ifdef CONFIG_ACPI
 #ifdef CONFIG_ACPI
-	/* Setup the CPEI/P vector and handler */
-	cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI);
+	/* Setup the CPEI/P handler */
 	register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction);
 	register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction);
 #endif
 #endif
 
 
@@ -1436,6 +1435,7 @@ ia64_mca_late_init(void)
 
 
 #ifdef CONFIG_ACPI
 #ifdef CONFIG_ACPI
 	/* Setup the CPEI/P vector and handler */
 	/* Setup the CPEI/P vector and handler */
+	cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI);
 	init_timer(&cpe_poll_timer);
 	init_timer(&cpe_poll_timer);
 	cpe_poll_timer.function = ia64_mca_cpe_poll;
 	cpe_poll_timer.function = ia64_mca_cpe_poll;
 
 

+ 1 - 2
arch/ia64/kernel/minstate.h

@@ -41,7 +41,7 @@
 (pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;;							\
 (pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;;							\
 (pKStk) ld8 r3 = [r3];;										\
 (pKStk) ld8 r3 = [r3];;										\
 (pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;;						\
 (pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;;						\
-(pKStk) addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3;						\
+(pKStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3;						\
 (pUStk)	mov ar.rsc=0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
 (pUStk)	mov ar.rsc=0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
 (pUStk)	addl r22=IA64_RBS_OFFSET,r1;		/* compute base of register backing store */	\
 (pUStk)	addl r22=IA64_RBS_OFFSET,r1;		/* compute base of register backing store */	\
 	;;											\
 	;;											\
@@ -50,7 +50,6 @@
 (pUStk)	mov r23=ar.bspstore;				/* save ar.bspstore */			\
 (pUStk)	mov r23=ar.bspstore;				/* save ar.bspstore */			\
 (pUStk)	dep r22=-1,r22,61,3;			/* compute kernel virtual addr of RBS */	\
 (pUStk)	dep r22=-1,r22,61,3;			/* compute kernel virtual addr of RBS */	\
 	;;											\
 	;;											\
-(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1;		/* if in kernel mode, use sp (r12) */		\
 (pUStk)	mov ar.bspstore=r22;			/* switch to kernel RBS */			\
 (pUStk)	mov ar.bspstore=r22;			/* switch to kernel RBS */			\
 	;;											\
 	;;											\
 (pUStk)	mov r18=ar.bsp;										\
 (pUStk)	mov r18=ar.bsp;										\

+ 160 - 15
arch/ia64/kernel/perfmon.c

@@ -11,7 +11,7 @@
  * Version Perfmon-2.x is a rewrite of perfmon-1.x
  * Version Perfmon-2.x is a rewrite of perfmon-1.x
  * by Stephane Eranian, Hewlett Packard Co.
  * by Stephane Eranian, Hewlett Packard Co.
  *
  *
- * Copyright (C) 1999-2003, 2005  Hewlett Packard Co
+ * Copyright (C) 1999-2005  Hewlett Packard Co
  *               Stephane Eranian <eranian@hpl.hp.com>
  *               Stephane Eranian <eranian@hpl.hp.com>
  *               David Mosberger-Tang <davidm@hpl.hp.com>
  *               David Mosberger-Tang <davidm@hpl.hp.com>
  *
  *
@@ -497,6 +497,9 @@ typedef struct {
 static pfm_stats_t		pfm_stats[NR_CPUS];
 static pfm_stats_t		pfm_stats[NR_CPUS];
 static pfm_session_t		pfm_sessions;	/* global sessions information */
 static pfm_session_t		pfm_sessions;	/* global sessions information */
 
 
+static spinlock_t pfm_alt_install_check = SPIN_LOCK_UNLOCKED;
+static pfm_intr_handler_desc_t  *pfm_alt_intr_handler;
+
 static struct proc_dir_entry 	*perfmon_dir;
 static struct proc_dir_entry 	*perfmon_dir;
 static pfm_uuid_t		pfm_null_uuid = {0,};
 static pfm_uuid_t		pfm_null_uuid = {0,};
 
 
@@ -606,6 +609,7 @@ DEFINE_PER_CPU(unsigned long, pfm_syst_info);
 DEFINE_PER_CPU(struct task_struct *, pmu_owner);
 DEFINE_PER_CPU(struct task_struct *, pmu_owner);
 DEFINE_PER_CPU(pfm_context_t  *, pmu_ctx);
 DEFINE_PER_CPU(pfm_context_t  *, pmu_ctx);
 DEFINE_PER_CPU(unsigned long, pmu_activation_number);
 DEFINE_PER_CPU(unsigned long, pmu_activation_number);
+EXPORT_PER_CPU_SYMBOL_GPL(pfm_syst_info);
 
 
 
 
 /* forward declaration */
 /* forward declaration */
@@ -1325,7 +1329,7 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
 error_conflict:
 error_conflict:
 	DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n",
 	DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n",
   		pfm_sessions.pfs_sys_session[cpu]->pid,
   		pfm_sessions.pfs_sys_session[cpu]->pid,
-		smp_processor_id()));
+		cpu));
 abort:
 abort:
 	UNLOCK_PFS(flags);
 	UNLOCK_PFS(flags);
 
 
@@ -5555,26 +5559,32 @@ pfm_interrupt_handler(int irq, void *arg, struct pt_regs *regs)
 	int ret;
 	int ret;
 
 
 	this_cpu = get_cpu();
 	this_cpu = get_cpu();
-	min      = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min;
-	max      = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max;
+	if (likely(!pfm_alt_intr_handler)) {
+		min = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min;
+		max = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max;
 
 
-	start_cycles = ia64_get_itc();
+		start_cycles = ia64_get_itc();
 
 
-	ret = pfm_do_interrupt_handler(irq, arg, regs);
+		ret = pfm_do_interrupt_handler(irq, arg, regs);
 
 
-	total_cycles = ia64_get_itc();
+		total_cycles = ia64_get_itc();
 
 
-	/*
-	 * don't measure spurious interrupts
-	 */
-	if (likely(ret == 0)) {
-		total_cycles -= start_cycles;
+		/*
+		 * don't measure spurious interrupts
+		 */
+		if (likely(ret == 0)) {
+			total_cycles -= start_cycles;
 
 
-		if (total_cycles < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = total_cycles;
-		if (total_cycles > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = total_cycles;
+			if (total_cycles < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = total_cycles;
+			if (total_cycles > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = total_cycles;
 
 
-		pfm_stats[this_cpu].pfm_ovfl_intr_cycles += total_cycles;
+			pfm_stats[this_cpu].pfm_ovfl_intr_cycles += total_cycles;
+		}
+	}
+	else {
+		(*pfm_alt_intr_handler->handler)(irq, arg, regs);
 	}
 	}
+
 	put_cpu_no_resched();
 	put_cpu_no_resched();
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
@@ -6425,6 +6435,141 @@ static struct irqaction perfmon_irqaction = {
 	.name    = "perfmon"
 	.name    = "perfmon"
 };
 };
 
 
+static void
+pfm_alt_save_pmu_state(void *data)
+{
+	struct pt_regs *regs;
+
+	regs = ia64_task_regs(current);
+
+	DPRINT(("called\n"));
+
+	/*
+	 * should not be necessary but
+	 * let's take not risk
+	 */
+	pfm_clear_psr_up();
+	pfm_clear_psr_pp();
+	ia64_psr(regs)->pp = 0;
+
+	/*
+	 * This call is required
+	 * May cause a spurious interrupt on some processors
+	 */
+	pfm_freeze_pmu();
+
+	ia64_srlz_d();
+}
+
+void
+pfm_alt_restore_pmu_state(void *data)
+{
+	struct pt_regs *regs;
+
+	regs = ia64_task_regs(current);
+
+	DPRINT(("called\n"));
+
+	/*
+	 * put PMU back in state expected
+	 * by perfmon
+	 */
+	pfm_clear_psr_up();
+	pfm_clear_psr_pp();
+	ia64_psr(regs)->pp = 0;
+
+	/*
+	 * perfmon runs with PMU unfrozen at all times
+	 */
+	pfm_unfreeze_pmu();
+
+	ia64_srlz_d();
+}
+
+int
+pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl)
+{
+	int ret, i;
+	int reserve_cpu;
+
+	/* some sanity checks */
+	if (hdl == NULL || hdl->handler == NULL) return -EINVAL;
+
+	/* do the easy test first */
+	if (pfm_alt_intr_handler) return -EBUSY;
+
+	/* one at a time in the install or remove, just fail the others */
+	if (!spin_trylock(&pfm_alt_install_check)) {
+		return -EBUSY;
+	}
+
+	/* reserve our session */
+	for_each_online_cpu(reserve_cpu) {
+		ret = pfm_reserve_session(NULL, 1, reserve_cpu);
+		if (ret) goto cleanup_reserve;
+	}
+
+	/* save the current system wide pmu states */
+	ret = on_each_cpu(pfm_alt_save_pmu_state, NULL, 0, 1);
+	if (ret) {
+		DPRINT(("on_each_cpu() failed: %d\n", ret));
+		goto cleanup_reserve;
+	}
+
+	/* officially change to the alternate interrupt handler */
+	pfm_alt_intr_handler = hdl;
+
+	spin_unlock(&pfm_alt_install_check);
+
+	return 0;
+
+cleanup_reserve:
+	for_each_online_cpu(i) {
+		/* don't unreserve more than we reserved */
+		if (i >= reserve_cpu) break;
+
+		pfm_unreserve_session(NULL, 1, i);
+	}
+
+	spin_unlock(&pfm_alt_install_check);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pfm_install_alt_pmu_interrupt);
+
+int
+pfm_remove_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl)
+{
+	int i;
+	int ret;
+
+	if (hdl == NULL) return -EINVAL;
+
+	/* cannot remove someone else's handler! */
+	if (pfm_alt_intr_handler != hdl) return -EINVAL;
+
+	/* one at a time in the install or remove, just fail the others */
+	if (!spin_trylock(&pfm_alt_install_check)) {
+		return -EBUSY;
+	}
+
+	pfm_alt_intr_handler = NULL;
+
+	ret = on_each_cpu(pfm_alt_restore_pmu_state, NULL, 0, 1);
+	if (ret) {
+		DPRINT(("on_each_cpu() failed: %d\n", ret));
+	}
+
+	for_each_online_cpu(i) {
+		pfm_unreserve_session(NULL, 1, i);
+	}
+
+	spin_unlock(&pfm_alt_install_check);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pfm_remove_alt_pmu_interrupt);
+
 /*
 /*
  * perfmon initialization routine, called from the initcall() table
  * perfmon initialization routine, called from the initcall() table
  */
  */

+ 17 - 3
arch/ia64/kernel/ptrace.c

@@ -692,16 +692,30 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs  *pt,
 			unsigned long cfm)
 			unsigned long cfm)
 {
 {
 	struct unw_frame_info info, prev_info;
 	struct unw_frame_info info, prev_info;
-	unsigned long ip, pr;
+	unsigned long ip, sp, pr;
 
 
 	unw_init_from_blocked_task(&info, child);
 	unw_init_from_blocked_task(&info, child);
 	while (1) {
 	while (1) {
 		prev_info = info;
 		prev_info = info;
 		if (unw_unwind(&info) < 0)
 		if (unw_unwind(&info) < 0)
 			return;
 			return;
-		if (unw_get_rp(&info, &ip) < 0)
+
+		unw_get_sp(&info, &sp);
+		if ((long)((unsigned long)child + IA64_STK_OFFSET - sp)
+		    < IA64_PT_REGS_SIZE) {
+			dprintk("ptrace.%s: ran off the top of the kernel "
+				"stack\n", __FUNCTION__);
+			return;
+		}
+		if (unw_get_pr (&prev_info, &pr) < 0) {
+			unw_get_rp(&prev_info, &ip);
+			dprintk("ptrace.%s: failed to read "
+				"predicate register (ip=0x%lx)\n",
+				__FUNCTION__, ip);
 			return;
 			return;
-		if (ip < FIXADDR_USER_END)
+		}
+		if (unw_is_intr_frame(&info)
+		    && (pr & (1UL << PRED_USER_STACK)))
 			break;
 			break;
 	}
 	}
 
 

+ 1 - 1
arch/ia64/kernel/smpboot.c

@@ -624,7 +624,7 @@ static struct {
 	__u16   thread_id;
 	__u16   thread_id;
 	__u16   proc_fixed_addr;
 	__u16   proc_fixed_addr;
 	__u8    valid;
 	__u8    valid;
-}mt_info[NR_CPUS] __devinit;
+} mt_info[NR_CPUS] __devinitdata;
 
 
 #ifdef CONFIG_HOTPLUG_CPU
 #ifdef CONFIG_HOTPLUG_CPU
 static inline void
 static inline void

+ 0 - 7
arch/ia64/kernel/sys_ia64.c

@@ -182,13 +182,6 @@ do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, un
 		}
 		}
 	}
 	}
 
 
-	/*
-	 * A zero mmap always succeeds in Linux, independent of whether or not the
-	 * remaining arguments are valid.
-	 */
-	if (len == 0)
-		goto out;
-
 	/* Careful about overflows.. */
 	/* Careful about overflows.. */
 	len = PAGE_ALIGN(len);
 	len = PAGE_ALIGN(len);
 	if (!len || len > TASK_SIZE) {
 	if (!len || len > TASK_SIZE) {

+ 2 - 0
arch/ia64/sn/kernel/setup.c

@@ -271,6 +271,8 @@ void __init sn_setup(char **cmdline_p)
 	int major = sn_sal_rev_major(), minor = sn_sal_rev_minor();
 	int major = sn_sal_rev_major(), minor = sn_sal_rev_minor();
 	extern void sn_cpu_init(void);
 	extern void sn_cpu_init(void);
 
 
+	ia64_sn_plat_set_error_handling_features();
+
 	/*
 	/*
 	 * If the generic code has enabled vga console support - lets
 	 * If the generic code has enabled vga console support - lets
 	 * get rid of it again. This is a kludge for the fact that ACPI
 	 * get rid of it again. This is a kludge for the fact that ACPI

+ 2 - 2
arch/ppc/Kconfig

@@ -1143,12 +1143,12 @@ config PCI_QSPAN
 
 
 config PCI_8260
 config PCI_8260
 	bool
 	bool
-	depends on PCI && 8260 && !8272
+	depends on PCI && 8260
 	default y
 	default y
 
 
 config 8260_PCI9
 config 8260_PCI9
 	bool "  Enable workaround for MPC826x erratum PCI 9"
 	bool "  Enable workaround for MPC826x erratum PCI 9"
-	depends on PCI_8260
+	depends on PCI_8260 && !ADS8272
 	default y
 	default y
 
 
 choice
 choice

+ 2 - 1
arch/ppc/boot/images/Makefile

@@ -22,7 +22,8 @@ targets += uImage
 $(obj)/uImage: $(obj)/vmlinux.gz
 $(obj)/uImage: $(obj)/vmlinux.gz
 	$(Q)rm -f $@
 	$(Q)rm -f $@
 	$(call if_changed,uimage)
 	$(call if_changed,uimage)
-	@echo '  Image: $@' $(if $(wildcard $@),'is ready','not made')
+	@echo -n '  Image: $@ '
+	@if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi
 
 
 # Files generated that shall be removed upon make clean
 # Files generated that shall be removed upon make clean
 clean-files	:= sImage vmapus vmlinux* miboot* zImage* uImage
 clean-files	:= sImage vmapus vmlinux* miboot* zImage* uImage

+ 92 - 25
arch/ppc/configs/mpc8555_cds_defconfig

@@ -1,7 +1,7 @@
 #
 #
 # Automatically generated make config: don't edit
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc1
-# Thu Jan 20 01:25:35 2005
+# Linux kernel version: 2.6.12-rc4
+# Tue May 17 11:56:01 2005
 #
 #
 CONFIG_MMU=y
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -11,6 +11,7 @@ CONFIG_HAVE_DEC_LOCK=y
 CONFIG_PPC=y
 CONFIG_PPC=y
 CONFIG_PPC32=y
 CONFIG_PPC32=y
 CONFIG_GENERIC_NVRAM=y
 CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 
 
 #
 #
 # Code maturity level options
 # Code maturity level options
@@ -18,6 +19,7 @@ CONFIG_GENERIC_NVRAM=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 
 #
 #
 # General setup
 # General setup
@@ -29,12 +31,14 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_HOTPLUG is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_EMBEDDED=y
 CONFIG_EMBEDDED=y
 # CONFIG_KALLSYMS is not set
 # CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_FUTEX=y
 # CONFIG_EPOLL is not set
 # CONFIG_EPOLL is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -44,6 +48,7 @@ CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 
 #
 #
 # Loadable module support
 # Loadable module support
@@ -62,10 +67,12 @@ CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_E500=y
 CONFIG_E500=y
 CONFIG_BOOKE=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
 CONFIG_FSL_BOOKE=y
+# CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_SPE=y
 CONFIG_MATH_EMULATION=y
 CONFIG_MATH_EMULATION=y
 # CONFIG_CPU_FREQ is not set
 # CONFIG_CPU_FREQ is not set
 CONFIG_PPC_GEN550=y
 CONFIG_PPC_GEN550=y
+# CONFIG_PM is not set
 CONFIG_85xx=y
 CONFIG_85xx=y
 CONFIG_PPC_INDIRECT_PCI_BE=y
 CONFIG_PPC_INDIRECT_PCI_BE=y
 
 
@@ -76,6 +83,7 @@ CONFIG_PPC_INDIRECT_PCI_BE=y
 CONFIG_MPC8555_CDS=y
 CONFIG_MPC8555_CDS=y
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_SBC8560 is not set
 # CONFIG_SBC8560 is not set
+# CONFIG_STX_GP3 is not set
 CONFIG_MPC8555=y
 CONFIG_MPC8555=y
 CONFIG_85xx_PCI2=y
 CONFIG_85xx_PCI2=y
 
 
@@ -90,6 +98,7 @@ CONFIG_CPM2=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_CMDLINE_BOOL is not set
 # CONFIG_CMDLINE_BOOL is not set
+CONFIG_ISA_DMA_API=y
 
 
 #
 #
 # Bus options
 # Bus options
@@ -104,10 +113,6 @@ CONFIG_PCI_NAMES=y
 #
 #
 # CONFIG_PCCARD is not set
 # CONFIG_PCCARD is not set
 
 
-#
-# PC-card bridges
-#
-
 #
 #
 # Advanced setup
 # Advanced setup
 #
 #
@@ -180,7 +185,59 @@ CONFIG_IOSCHED_CFQ=y
 #
 #
 # ATA/ATAPI/MFM/RLL support
 # ATA/ATAPI/MFM/RLL support
 #
 #
-# CONFIG_IDE is not set
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
 
 
 #
 #
 # SCSI device support
 # SCSI device support
@@ -220,7 +277,6 @@ CONFIG_NET=y
 #
 #
 CONFIG_PACKET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_INET=y
@@ -369,14 +425,6 @@ CONFIG_INPUT=y
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 # CONFIG_INPUT_EVBUG is not set
 
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
 #
 #
 # Input Device Drivers
 # Input Device Drivers
 #
 #
@@ -386,6 +434,13 @@ CONFIG_SOUND_GAMEPORT=y
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 # CONFIG_INPUT_MISC is not set
 
 
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
 #
 #
 # Character devices
 # Character devices
 #
 #
@@ -406,6 +461,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_CPM is not set
 # CONFIG_SERIAL_CPM is not set
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_LEGACY_PTY_COUNT=256
@@ -433,6 +489,11 @@ CONFIG_GEN_RTC=y
 # CONFIG_DRM is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_RAW_DRIVER is not set
 
 
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
 #
 #
 # I2C support
 # I2C support
 #
 #
@@ -456,11 +517,11 @@ CONFIG_I2C_CHARDEV=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 # CONFIG_I2C_ISA is not set
 CONFIG_I2C_MPC=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
 # CONFIG_SCx200_ACB is not set
@@ -483,7 +544,9 @@ CONFIG_I2C_MPC=y
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
 # CONFIG_SENSORS_GL518SM is not set
 # CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
 # CONFIG_SENSORS_LM63 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM75 is not set
@@ -494,9 +557,11 @@ CONFIG_I2C_MPC=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83781D is not set
@@ -506,10 +571,12 @@ CONFIG_I2C_MPC=y
 #
 #
 # Other I2C Chip support
 # Other I2C Chip support
 #
 #
+# CONFIG_SENSORS_DS1337 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
 # CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_M41T00 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -538,7 +605,6 @@ CONFIG_I2C_MPC=y
 # Graphics support
 # Graphics support
 #
 #
 # CONFIG_FB is not set
 # CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 
 #
 #
 # Sound
 # Sound
@@ -548,13 +614,9 @@ CONFIG_I2C_MPC=y
 #
 #
 # USB support
 # USB support
 #
 #
-# CONFIG_USB is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
 
 
 #
 #
 # USB Gadget Support
 # USB Gadget Support
@@ -585,6 +647,10 @@ CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
 # CONFIG_XFS_FS is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -646,7 +712,6 @@ CONFIG_NFS_FS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -698,7 +763,9 @@ CONFIG_CRC32=y
 #
 #
 # Kernel hacking
 # Kernel hacking
 #
 #
+# CONFIG_PRINTK_TIME is not set
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_KGDB_CONSOLE is not set
 # CONFIG_KGDB_CONSOLE is not set
 # CONFIG_SERIAL_TEXT_DEBUG is not set
 # CONFIG_SERIAL_TEXT_DEBUG is not set
 
 

+ 9 - 6
arch/ppc/kernel/head_44x.S

@@ -330,8 +330,9 @@ interrupt_base:
 	/* If we are faulting a kernel address, we have to use the
 	/* If we are faulting a kernel address, we have to use the
 	 * kernel page tables.
 	 * kernel page tables.
 	 */
 	 */
-	andis.	r11, r10, 0x8000
-	beq	3f
+	lis	r11, TASK_SIZE@h
+	cmplw	r10, r11
+	blt+	3f
 	lis	r11, swapper_pg_dir@h
 	lis	r11, swapper_pg_dir@h
 	ori	r11, r11, swapper_pg_dir@l
 	ori	r11, r11, swapper_pg_dir@l
 
 
@@ -464,8 +465,9 @@ interrupt_base:
 	/* If we are faulting a kernel address, we have to use the
 	/* If we are faulting a kernel address, we have to use the
 	 * kernel page tables.
 	 * kernel page tables.
 	 */
 	 */
-	andis.	r11, r10, 0x8000
-	beq	3f
+	lis	r11, TASK_SIZE@h
+	cmplw	r10, r11
+	blt+	3f
 	lis	r11, swapper_pg_dir@h
 	lis	r11, swapper_pg_dir@h
 	ori	r11, r11, swapper_pg_dir@l
 	ori	r11, r11, swapper_pg_dir@l
 
 
@@ -533,8 +535,9 @@ interrupt_base:
 	/* If we are faulting a kernel address, we have to use the
 	/* If we are faulting a kernel address, we have to use the
 	 * kernel page tables.
 	 * kernel page tables.
 	 */
 	 */
-	andis.	r11, r10, 0x8000
-	beq	3f
+	lis	r11, TASK_SIZE@h
+	cmplw	r10, r11
+	blt+	3f
 	lis	r11, swapper_pg_dir@h
 	lis	r11, swapper_pg_dir@h
 	ori	r11, r11, swapper_pg_dir@l
 	ori	r11, r11, swapper_pg_dir@l
 
 

+ 14 - 1
arch/ppc/kernel/head_fsl_booke.S

@@ -232,7 +232,8 @@ skpinv:	addi	r6,r6,1				/* Increment */
 	tlbwe
 	tlbwe
 
 
 /* 7. Jump to KERNELBASE mapping */
 /* 7. Jump to KERNELBASE mapping */
-	li	r7,0
+	lis	r7,MSR_KERNEL@h
+	ori	r7,r7,MSR_KERNEL@l
 	bl	1f			/* Find our address */
 	bl	1f			/* Find our address */
 1:	mflr	r9
 1:	mflr	r9
 	rlwimi	r6,r9,0,20,31
 	rlwimi	r6,r9,0,20,31
@@ -293,6 +294,18 @@ skpinv:	addi	r6,r6,1				/* Increment */
 	mtspr	SPRN_HID0, r2
 	mtspr	SPRN_HID0, r2
 #endif
 #endif
 
 
+#if !defined(CONFIG_BDI_SWITCH)
+	/*
+	 * The Abatron BDI JTAG debugger does not tolerate others
+	 * mucking with the debug registers.
+	 */
+	lis	r2,DBCR0_IDM@h
+	mtspr	SPRN_DBCR0,r2
+	/* clear any residual debug events */
+	li	r2,-1
+	mtspr	SPRN_DBSR,r2
+#endif
+
 	/*
 	/*
 	 * This is where the main kernel code starts.
 	 * This is where the main kernel code starts.
 	 */
 	 */

+ 1 - 1
arch/ppc/kernel/setup.c

@@ -499,7 +499,7 @@ static int __init set_preferred_console(void)
 {
 {
 	struct device_node *prom_stdout;
 	struct device_node *prom_stdout;
 	char *name;
 	char *name;
-	int offset;
+	int offset = 0;
 
 
 	if (of_stdout_device == NULL)
 	if (of_stdout_device == NULL)
 		return -ENODEV;
 		return -ENODEV;

+ 1 - 6
arch/ppc/kernel/traps.c

@@ -408,12 +408,7 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword)
 
 
 	/* Early out if we are an invalid form of lswx */
 	/* Early out if we are an invalid form of lswx */
 	if ((instword & INST_STRING_MASK) == INST_LSWX)
 	if ((instword & INST_STRING_MASK) == INST_LSWX)
-		if ((rA >= rT) || (NB_RB >= rT) || (rT == rA) || (rT == NB_RB))
-			return -EINVAL;
-
-	/* Early out if we are an invalid form of lswi */
-	if ((instword & INST_STRING_MASK) == INST_LSWI)
-		if ((rA >= rT) || (rT == rA))
+		if ((rT == rA) || (rT == NB_RB))
 			return -EINVAL;
 			return -EINVAL;
 
 
 	EA = (rA == 0) ? 0 : regs->gpr[rA];
 	EA = (rA == 0) ? 0 : regs->gpr[rA];

+ 5 - 2
arch/ppc/lib/string.S

@@ -446,6 +446,7 @@ _GLOBAL(__copy_tofrom_user)
 #ifdef CONFIG_8xx
 #ifdef CONFIG_8xx
 	/* Don't use prefetch on 8xx */
 	/* Don't use prefetch on 8xx */
 	mtctr	r0
 	mtctr	r0
+	li	r0,0
 53:	COPY_16_BYTES_WITHEX(0)
 53:	COPY_16_BYTES_WITHEX(0)
 	bdnz	53b
 	bdnz	53b
 
 
@@ -564,7 +565,9 @@ _GLOBAL(__copy_tofrom_user)
 /* or write fault in cacheline loop */
 /* or write fault in cacheline loop */
 105:	li	r9,1
 105:	li	r9,1
 92:	li	r3,LG_CACHELINE_BYTES
 92:	li	r3,LG_CACHELINE_BYTES
-	b	99f
+	mfctr	r8
+	add	r0,r0,r8
+	b	106f
 /* read fault in final word loop */
 /* read fault in final word loop */
 108:	li	r9,0
 108:	li	r9,0
 	b	93f
 	b	93f
@@ -585,7 +588,7 @@ _GLOBAL(__copy_tofrom_user)
  * r5 + (ctr << r3), and r9 is 0 for read or 1 for write.
  * r5 + (ctr << r3), and r9 is 0 for read or 1 for write.
  */
  */
 99:	mfctr	r0
 99:	mfctr	r0
-	slw	r3,r0,r3
+106:	slw	r3,r0,r3
 	add.	r3,r3,r5
 	add.	r3,r3,r5
 	beq	120f			/* shouldn't happen */
 	beq	120f			/* shouldn't happen */
 	cmpwi	0,r9,0
 	cmpwi	0,r9,0

+ 1 - 0
arch/ppc/mm/init.c

@@ -179,6 +179,7 @@ void free_initmem(void)
 	if (!have_of)
 	if (!have_of)
 		FREESEC(openfirmware);
 		FREESEC(openfirmware);
  	printk("\n");
  	printk("\n");
+	ppc_md.progress = NULL;
 #undef FREESEC
 #undef FREESEC
 }
 }
 
 

+ 0 - 1
arch/ppc/platforms/83xx/mpc834x_sys.c

@@ -127,7 +127,6 @@ mpc834x_sys_map_io(void)
 {
 {
 	/* we steal the lowest ioremap addr for virt space */
 	/* we steal the lowest ioremap addr for virt space */
 	io_block_mapping(VIRT_IMMRBAR, immrbar, 1024*1024, _PAGE_IO);
 	io_block_mapping(VIRT_IMMRBAR, immrbar, 1024*1024, _PAGE_IO);
-	io_block_mapping(BCSR_VIRT_ADDR, BCSR_PHYS_ADDR, BCSR_SIZE, _PAGE_IO);
 }
 }
 
 
 int
 int

+ 6 - 1
arch/ppc/platforms/83xx/mpc834x_sys.h

@@ -26,9 +26,14 @@
 #define VIRT_IMMRBAR		((uint)0xfe000000)
 #define VIRT_IMMRBAR		((uint)0xfe000000)
 
 
 #define BCSR_PHYS_ADDR		((uint)0xf8000000)
 #define BCSR_PHYS_ADDR		((uint)0xf8000000)
-#define BCSR_VIRT_ADDR		((uint)0xfe100000)
 #define BCSR_SIZE		((uint)(32 * 1024))
 #define BCSR_SIZE		((uint)(32 * 1024))
 
 
+#define BCSR_MISC_REG2_OFF	0x07
+#define BCSR_MISC_REG2_PORESET	0x01
+
+#define BCSR_MISC_REG3_OFF	0x08
+#define BCSR_MISC_REG3_CNFLOCK	0x80
+
 #ifdef CONFIG_PCI
 #ifdef CONFIG_PCI
 /* PCI interrupt controller */
 /* PCI interrupt controller */
 #define PIRQA        MPC83xx_IRQ_IRQ4
 #define PIRQA        MPC83xx_IRQ_IRQ4

+ 3 - 0
arch/ppc/platforms/85xx/mpc8540_ads.c

@@ -210,6 +210,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
 #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
 	ppc_md.progress = gen550_progress;
 	ppc_md.progress = gen550_progress;
 #endif	/* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
 #endif	/* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
+#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB)
+	ppc_md.early_serial_map = mpc85xx_early_serial_map;
+#endif	/* CONFIG_SERIAL_8250 && CONFIG_KGDB */
 
 
 	if (ppc_md.progress)
 	if (ppc_md.progress)
 		ppc_md.progress("mpc8540ads_init(): exit", 0);
 		ppc_md.progress("mpc8540ads_init(): exit", 0);

+ 141 - 2
arch/ppc/platforms/85xx/mpc85xx_cds_common.c

@@ -44,6 +44,7 @@
 #include <asm/machdep.h>
 #include <asm/machdep.h>
 #include <asm/prom.h>
 #include <asm/prom.h>
 #include <asm/open_pic.h>
 #include <asm/open_pic.h>
+#include <asm/i8259.h>
 #include <asm/bootinfo.h>
 #include <asm/bootinfo.h>
 #include <asm/pci-bridge.h>
 #include <asm/pci-bridge.h>
 #include <asm/mpc85xx.h>
 #include <asm/mpc85xx.h>
@@ -181,6 +182,7 @@ void __init
 mpc85xx_cds_init_IRQ(void)
 mpc85xx_cds_init_IRQ(void)
 {
 {
 	bd_t *binfo = (bd_t *) __res;
 	bd_t *binfo = (bd_t *) __res;
+	int i;
 
 
 	/* Determine the Physical Address of the OpenPIC regs */
 	/* Determine the Physical Address of the OpenPIC regs */
 	phys_addr_t OpenPIC_PAddr = binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET;
 	phys_addr_t OpenPIC_PAddr = binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET;
@@ -198,6 +200,15 @@ mpc85xx_cds_init_IRQ(void)
 	 */
 	 */
 	openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET);
 	openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET);
 
 
+#ifdef CONFIG_PCI
+	openpic_hookup_cascade(PIRQ0A, "82c59 cascade", i8259_irq);
+
+	for (i = 0; i < NUM_8259_INTERRUPTS; i++)
+		irq_desc[i].handler = &i8259_pic;
+
+	i8259_init(0);
+#endif
+
 #ifdef CONFIG_CPM2
 #ifdef CONFIG_CPM2
 	/* Setup CPM2 PIC */
 	/* Setup CPM2 PIC */
         cpm2_init_IRQ();
         cpm2_init_IRQ();
@@ -231,7 +242,7 @@ mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
 			 * interrupt on slot */
 			 * interrupt on slot */
 		{
 		{
 			{ 0, 1, 2, 3 }, /* 16 - PMC */
 			{ 0, 1, 2, 3 }, /* 16 - PMC */
-			{ 3, 0, 0, 0 }, /* 17 P2P (Tsi320) */
+			{ 0, 1, 2, 3 }, /* 17 P2P (Tsi320) */
 			{ 0, 1, 2, 3 }, /* 18 - Slot 1 */
 			{ 0, 1, 2, 3 }, /* 18 - Slot 1 */
 			{ 1, 2, 3, 0 }, /* 19 - Slot 2 */
 			{ 1, 2, 3, 0 }, /* 19 - Slot 2 */
 			{ 2, 3, 0, 1 }, /* 20 - Slot 3 */
 			{ 2, 3, 0, 1 }, /* 20 - Slot 3 */
@@ -280,13 +291,135 @@ mpc85xx_exclude_device(u_char bus, u_char devfn)
 			return PCIBIOS_DEVICE_NOT_FOUND;
 			return PCIBIOS_DEVICE_NOT_FOUND;
 #endif
 #endif
 	/* We explicitly do not go past the Tundra 320 Bridge */
 	/* We explicitly do not go past the Tundra 320 Bridge */
-	if (bus == 1)
+	if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
 	if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	else
 	else
 		return PCIBIOS_SUCCESSFUL;
 		return PCIBIOS_SUCCESSFUL;
 }
 }
+
+void __init
+mpc85xx_cds_enable_via(struct pci_controller *hose)
+{
+	u32 pci_class;
+	u16 vid, did;
+
+	early_read_config_dword(hose, 0, 0x88, PCI_CLASS_REVISION, &pci_class);
+	if ((pci_class >> 16) != PCI_CLASS_BRIDGE_PCI)
+		return;
+
+	/* Configure P2P so that we can reach bus 1 */
+	early_write_config_byte(hose, 0, 0x88, PCI_PRIMARY_BUS, 0);
+	early_write_config_byte(hose, 0, 0x88, PCI_SECONDARY_BUS, 1);
+	early_write_config_byte(hose, 0, 0x88, PCI_SUBORDINATE_BUS, 0xff);
+
+	early_read_config_word(hose, 1, 0x10, PCI_VENDOR_ID, &vid);
+	early_read_config_word(hose, 1, 0x10, PCI_DEVICE_ID, &did);
+
+	if ((vid != PCI_VENDOR_ID_VIA) ||
+			(did != PCI_DEVICE_ID_VIA_82C686))
+		return;
+
+	/* Enable USB and IDE functions */
+	early_write_config_byte(hose, 1, 0x10, 0x48, 0x08);
+}
+
+void __init
+mpc85xx_cds_fixup_via(struct pci_controller *hose)
+{
+	u32 pci_class;
+	u16 vid, did;
+
+	early_read_config_dword(hose, 0, 0x88, PCI_CLASS_REVISION, &pci_class);
+	if ((pci_class >> 16) != PCI_CLASS_BRIDGE_PCI)
+		return;
+
+	/*
+	 * Force the backplane P2P bridge to have a window
+	 * open from 0x00000000-0x00001fff in PCI I/O space.
+	 * This allows legacy I/O (i8259, etc) on the VIA
+	 * southbridge to be accessed.
+	 */
+	early_write_config_byte(hose, 0, 0x88, PCI_IO_BASE, 0x00);
+	early_write_config_word(hose, 0, 0x88, PCI_IO_BASE_UPPER16, 0x0000);
+	early_write_config_byte(hose, 0, 0x88, PCI_IO_LIMIT, 0x10);
+	early_write_config_word(hose, 0, 0x88, PCI_IO_LIMIT_UPPER16, 0x0000);
+
+	early_read_config_word(hose, 1, 0x10, PCI_VENDOR_ID, &vid);
+	early_read_config_word(hose, 1, 0x10, PCI_DEVICE_ID, &did);
+	if ((vid != PCI_VENDOR_ID_VIA) ||
+			(did != PCI_DEVICE_ID_VIA_82C686))
+		return;
+
+	/*
+	 * Since the P2P window was forced to cover the fixed
+	 * legacy I/O addresses, it is necessary to manually
+	 * place the base addresses for the IDE and USB functions
+	 * within this window.
+	 */
+	/* Function 1, IDE */
+	early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_0, 0x1ff8);
+	early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_1, 0x1ff4);
+	early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_2, 0x1fe8);
+	early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_3, 0x1fe4);
+	early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_4, 0x1fd0);
+
+	/* Function 2, USB ports 0-1 */
+	early_write_config_dword(hose, 1, 0x12, PCI_BASE_ADDRESS_4, 0x1fa0);
+
+	/* Function 3, USB ports 2-3 */
+	early_write_config_dword(hose, 1, 0x13, PCI_BASE_ADDRESS_4, 0x1f80);
+
+	/* Function 5, Power Management */
+	early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_0, 0x1e00);
+	early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_1, 0x1dfc);
+	early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_2, 0x1df8);
+
+	/* Function 6, AC97 Interface */
+	early_write_config_dword(hose, 1, 0x16, PCI_BASE_ADDRESS_0, 0x1c00);
+}
+
+void __init
+mpc85xx_cds_pcibios_fixup(void)
+{
+        struct pci_dev *dev = NULL;
+	u_char		c;
+
+        if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+                                        PCI_DEVICE_ID_VIA_82C586_1, NULL))) {
+                /*
+                 * U-Boot does not set the enable bits
+                 * for the IDE device. Force them on here.
+                 */
+                pci_read_config_byte(dev, 0x40, &c);
+                c |= 0x03; /* IDE: Chip Enable Bits */
+                pci_write_config_byte(dev, 0x40, c);
+
+		/*
+		 * Since only primary interface works, force the
+		 * IDE function to standard primary IDE interrupt
+		 * w/ 8259 offset
+		 */
+                dev->irq = 14;
+                pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+        }
+
+	/*
+	 * Force legacy USB interrupt routing
+	 */
+        if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+                                        PCI_DEVICE_ID_VIA_82C586_2, NULL))) {
+                dev->irq = 10;
+                pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10);
+        }
+
+        if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+                                        PCI_DEVICE_ID_VIA_82C586_2, dev))) {
+                dev->irq = 11;
+                pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
+        }
+}
 #endif /* CONFIG_PCI */
 #endif /* CONFIG_PCI */
 
 
 TODC_ALLOC();
 TODC_ALLOC();
@@ -328,6 +461,9 @@ mpc85xx_cds_setup_arch(void)
 	loops_per_jiffy = freq / HZ;
 	loops_per_jiffy = freq / HZ;
 
 
 #ifdef CONFIG_PCI
 #ifdef CONFIG_PCI
+	/* VIA IDE configuration */
+        ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup;
+
 	/* setup PCI host bridges */
 	/* setup PCI host bridges */
 	mpc85xx_setup_hose();
 	mpc85xx_setup_hose();
 #endif
 #endif
@@ -459,6 +595,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
 #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
 	ppc_md.progress = gen550_progress;
 	ppc_md.progress = gen550_progress;
 #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
 #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
+#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB)
+	ppc_md.early_serial_map = mpc85xx_early_serial_map;
+#endif	/* CONFIG_SERIAL_8250 && CONFIG_KGDB */
 
 
 	if (ppc_md.progress)
 	if (ppc_md.progress)
 		ppc_md.progress("mpc85xx_cds_init(): exit", 0);
 		ppc_md.progress("mpc85xx_cds_init(): exit", 0);

+ 3 - 0
arch/ppc/platforms/85xx/mpc85xx_cds_common.h

@@ -77,4 +77,7 @@
 
 
 #define MPC85XX_PCI2_IO_SIZE         0x01000000
 #define MPC85XX_PCI2_IO_SIZE         0x01000000
 
 
+#define NR_8259_INTS		     16
+#define CPM_IRQ_OFFSET		     NR_8259_INTS
+
 #endif /* __MACH_MPC85XX_CDS_H__ */
 #endif /* __MACH_MPC85XX_CDS_H__ */

+ 3 - 0
arch/ppc/platforms/85xx/sbc8560.c

@@ -221,6 +221,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
 #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
 	ppc_md.progress = gen550_progress;
 	ppc_md.progress = gen550_progress;
 #endif	/* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
 #endif	/* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
+#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB)
+	ppc_md.early_serial_map = sbc8560_early_serial_map;
+#endif	/* CONFIG_SERIAL_8250 && CONFIG_KGDB */
 
 
 	if (ppc_md.progress)
 	if (ppc_md.progress)
 		ppc_md.progress("sbc8560_init(): exit", 0);
 		ppc_md.progress("sbc8560_init(): exit", 0);

+ 22 - 14
arch/ppc/platforms/pmac_cpufreq.c

@@ -85,14 +85,11 @@ static int no_schedule;
 static int has_cpu_l2lve;
 static int has_cpu_l2lve;
 
 
 
 
-#define PMAC_CPU_LOW_SPEED	1
-#define PMAC_CPU_HIGH_SPEED	0
-
 /* There are only two frequency states for each processor. Values
 /* There are only two frequency states for each processor. Values
  * are in kHz for the time being.
  * are in kHz for the time being.
  */
  */
-#define CPUFREQ_HIGH                  PMAC_CPU_HIGH_SPEED
-#define CPUFREQ_LOW                   PMAC_CPU_LOW_SPEED
+#define CPUFREQ_HIGH                  0
+#define CPUFREQ_LOW                   1
 
 
 static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
 static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
 	{CPUFREQ_HIGH, 		0},
 	{CPUFREQ_HIGH, 		0},
@@ -100,6 +97,11 @@ static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
 	{0,			CPUFREQ_TABLE_END},
 	{0,			CPUFREQ_TABLE_END},
 };
 };
 
 
+static struct freq_attr* pmac_cpu_freqs_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
 static inline void local_delay(unsigned long ms)
 static inline void local_delay(unsigned long ms)
 {
 {
 	if (no_schedule)
 	if (no_schedule)
@@ -269,6 +271,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
 #ifdef DEBUG_FREQ
 #ifdef DEBUG_FREQ
 	printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
 	printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
 #endif
 #endif
+	pmu_suspend();
+
 	/* Disable all interrupt sources on openpic */
 	/* Disable all interrupt sources on openpic */
  	pic_prio = openpic_get_priority();
  	pic_prio = openpic_get_priority();
 	openpic_set_priority(0xf);
 	openpic_set_priority(0xf);
@@ -343,6 +347,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
 	debug_calc_bogomips();
 	debug_calc_bogomips();
 #endif
 #endif
 
 
+	pmu_resume();
+
 	preempt_enable();
 	preempt_enable();
 
 
 	return 0;
 	return 0;
@@ -355,7 +361,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
 	static unsigned long prev_l3cr;
 	static unsigned long prev_l3cr;
 
 
 	freqs.old = cur_freq;
 	freqs.old = cur_freq;
-	freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
+	freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
 	freqs.cpu = smp_processor_id();
 	freqs.cpu = smp_processor_id();
 
 
 	if (freqs.old == freqs.new)
 	if (freqs.old == freqs.new)
@@ -363,7 +369,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
 
 
 	if (notify)
 	if (notify)
 		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-	if (speed_mode == PMAC_CPU_LOW_SPEED &&
+	if (speed_mode == CPUFREQ_LOW &&
 	    cpu_has_feature(CPU_FTR_L3CR)) {
 	    cpu_has_feature(CPU_FTR_L3CR)) {
 		l3cr = _get_L3CR();
 		l3cr = _get_L3CR();
 		if (l3cr & L3CR_L3E) {
 		if (l3cr & L3CR_L3E) {
@@ -371,8 +377,8 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
 			_set_L3CR(0);
 			_set_L3CR(0);
 		}
 		}
 	}
 	}
-	set_speed_proc(speed_mode == PMAC_CPU_LOW_SPEED);
-	if (speed_mode == PMAC_CPU_HIGH_SPEED &&
+	set_speed_proc(speed_mode == CPUFREQ_LOW);
+	if (speed_mode == CPUFREQ_HIGH &&
 	    cpu_has_feature(CPU_FTR_L3CR)) {
 	    cpu_has_feature(CPU_FTR_L3CR)) {
 		l3cr = _get_L3CR();
 		l3cr = _get_L3CR();
 		if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)
 		if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)
@@ -380,7 +386,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
 	}
 	}
 	if (notify)
 	if (notify)
 		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-	cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
+	cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
 
 
 	return 0;
 	return 0;
 }
 }
@@ -423,7 +429,8 @@ static int __pmac pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	policy->cpuinfo.transition_latency	= CPUFREQ_ETERNAL;
 	policy->cpuinfo.transition_latency	= CPUFREQ_ETERNAL;
 	policy->cur = cur_freq;
 	policy->cur = cur_freq;
 
 
-	return cpufreq_frequency_table_cpuinfo(policy, &pmac_cpu_freqs[0]);
+	cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
+	return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);
 }
 }
 
 
 static u32 __pmac read_gpio(struct device_node *np)
 static u32 __pmac read_gpio(struct device_node *np)
@@ -457,7 +464,7 @@ static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 state)
 	no_schedule = 1;
 	no_schedule = 1;
 	sleep_freq = cur_freq;
 	sleep_freq = cur_freq;
 	if (cur_freq == low_freq)
 	if (cur_freq == low_freq)
-		do_set_cpu_speed(PMAC_CPU_HIGH_SPEED, 0);
+		do_set_cpu_speed(CPUFREQ_HIGH, 0);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -473,8 +480,8 @@ static int __pmac pmac_cpufreq_resume(struct cpufreq_policy *policy)
 	 * is that we force a switch to whatever it was, which is
 	 * is that we force a switch to whatever it was, which is
 	 * probably high speed due to our suspend() routine
 	 * probably high speed due to our suspend() routine
 	 */
 	 */
-	do_set_cpu_speed(sleep_freq == low_freq ? PMAC_CPU_LOW_SPEED
-			 : PMAC_CPU_HIGH_SPEED, 0);
+	do_set_cpu_speed(sleep_freq == low_freq ?
+			 CPUFREQ_LOW : CPUFREQ_HIGH, 0);
 
 
 	no_schedule = 0;
 	no_schedule = 0;
 	return 0;
 	return 0;
@@ -488,6 +495,7 @@ static struct cpufreq_driver pmac_cpufreq_driver = {
 	.suspend	= pmac_cpufreq_suspend,
 	.suspend	= pmac_cpufreq_suspend,
 	.resume		= pmac_cpufreq_resume,
 	.resume		= pmac_cpufreq_resume,
 	.flags		= CPUFREQ_PM_NO_WARN,
 	.flags		= CPUFREQ_PM_NO_WARN,
+	.attr		= pmac_cpu_freqs_attr,
 	.name		= "powermac",
 	.name		= "powermac",
 	.owner		= THIS_MODULE,
 	.owner		= THIS_MODULE,
 };
 };

+ 18 - 23
arch/ppc/platforms/pq2ads.h

@@ -49,10 +49,10 @@
 /* PCI interrupt controller */
 /* PCI interrupt controller */
 #define PCI_INT_STAT_REG	0xF8200000
 #define PCI_INT_STAT_REG	0xF8200000
 #define PCI_INT_MASK_REG	0xF8200004
 #define PCI_INT_MASK_REG	0xF8200004
-#define PIRQA			(NR_SIU_INTS + 0)
-#define PIRQB			(NR_SIU_INTS + 1)
-#define PIRQC			(NR_SIU_INTS + 2)
-#define PIRQD			(NR_SIU_INTS + 3)
+#define PIRQA			(NR_CPM_INTS + 0)
+#define PIRQB			(NR_CPM_INTS + 1)
+#define PIRQC			(NR_CPM_INTS + 2)
+#define PIRQD			(NR_CPM_INTS + 3)
 
 
 /*
 /*
  * PCI memory map definitions for MPC8266ADS-PCI.
  * PCI memory map definitions for MPC8266ADS-PCI.
@@ -68,28 +68,23 @@
  *	0x00000000-0x1FFFFFFF	0x00000000-0x1FFFFFFF	MPC8266 local memory
  *	0x00000000-0x1FFFFFFF	0x00000000-0x1FFFFFFF	MPC8266 local memory
  */
  */
 
 
-/* window for a PCI master to access MPC8266 memory */
-#define PCI_SLV_MEM_LOCAL	0x00000000	/* Local base */
-#define PCI_SLV_MEM_BUS		0x00000000	/* PCI base */
+/* All the other PCI memory map definitions reside at syslib/m82xx_pci.h
+   Here we should redefine what is unique for this board */
+#define M82xx_PCI_SLAVE_MEM_LOCAL	0x00000000	/* Local base */
+#define M82xx_PCI_SLAVE_MEM_BUS		0x00000000	/* PCI base */
+#define M82xx_PCI_SLAVE_MEM_SIZE	0x10000000	/* 256 Mb */
 
 
-/* window for the processor to access PCI memory with prefetching */
-#define PCI_MSTR_MEM_LOCAL	0x80000000	/* Local base */
-#define PCI_MSTR_MEM_BUS	0x80000000	/* PCI base   */
-#define PCI_MSTR_MEM_SIZE	0x20000000	/* 512MB */
+#define M82xx_PCI_SLAVE_SEC_WND_SIZE	~(0x40000000 - 1U)	/* 2 x 512Mb  */
+#define M82xx_PCI_SLAVE_SEC_WND_BASE	0x80000000		/* PCI Memory base */
 
 
-/* window for the processor to access PCI memory without prefetching */
-#define PCI_MSTR_MEMIO_LOCAL	0xA0000000	/* Local base */
-#define PCI_MSTR_MEMIO_BUS	0xA0000000	/* PCI base   */
-#define PCI_MSTR_MEMIO_SIZE	0x20000000	/* 512MB */
+#if defined(CONFIG_ADS8272)
+#define PCI_INT_TO_SIU 	SIU_INT_IRQ2
+#elif defined(CONFIG_PQ2FADS)
+#define PCI_INT_TO_SIU 	SIU_INT_IRQ6
+#else
+#warning PCI Bridge will be without interrupts support
+#endif
 
 
-/* window for the processor to access PCI I/O */
-#define PCI_MSTR_IO_LOCAL	0xF4000000	/* Local base */
-#define PCI_MSTR_IO_BUS         0x00000000	/* PCI base   */
-#define PCI_MSTR_IO_SIZE        0x04000000	/* 64MB */
-
-#define _IO_BASE		PCI_MSTR_IO_LOCAL
-#define _ISA_MEM_BASE		PCI_MSTR_MEMIO_LOCAL
-#define PCI_DRAM_OFFSET		PCI_SLV_MEM_BUS
 #endif /* CONFIG_PCI */
 #endif /* CONFIG_PCI */
 
 
 #endif /* __MACH_ADS8260_DEFS */
 #endif /* __MACH_ADS8260_DEFS */

+ 2 - 2
arch/ppc/syslib/Makefile

@@ -81,7 +81,7 @@ obj-$(CONFIG_SBC82xx)		+= todc_time.o
 obj-$(CONFIG_SPRUCE)		+= cpc700_pic.o indirect_pci.o pci_auto.o \
 obj-$(CONFIG_SPRUCE)		+= cpc700_pic.o indirect_pci.o pci_auto.o \
 				   todc_time.o
 				   todc_time.o
 obj-$(CONFIG_8260)		+= m8260_setup.o
 obj-$(CONFIG_8260)		+= m8260_setup.o
-obj-$(CONFIG_PCI_8260)		+= m8260_pci.o indirect_pci.o
+obj-$(CONFIG_PCI_8260)		+= m82xx_pci.o indirect_pci.o pci_auto.o
 obj-$(CONFIG_8260_PCI9)		+= m8260_pci_erratum9.o
 obj-$(CONFIG_8260_PCI9)		+= m8260_pci_erratum9.o
 obj-$(CONFIG_CPM2)		+= cpm2_common.o cpm2_pic.o
 obj-$(CONFIG_CPM2)		+= cpm2_common.o cpm2_pic.o
 ifeq ($(CONFIG_PPC_GEN550),y)
 ifeq ($(CONFIG_PPC_GEN550),y)
@@ -97,7 +97,7 @@ obj-$(CONFIG_MPC10X_OPENPIC)	+= open_pic.o
 obj-$(CONFIG_40x)		+= dcr.o
 obj-$(CONFIG_40x)		+= dcr.o
 obj-$(CONFIG_BOOKE)		+= dcr.o
 obj-$(CONFIG_BOOKE)		+= dcr.o
 obj-$(CONFIG_85xx)		+= open_pic.o ppc85xx_common.o ppc85xx_setup.o \
 obj-$(CONFIG_85xx)		+= open_pic.o ppc85xx_common.o ppc85xx_setup.o \
-					ppc_sys.o mpc85xx_sys.o \
+					ppc_sys.o i8259.o mpc85xx_sys.o \
 					mpc85xx_devices.o
 					mpc85xx_devices.o
 ifeq ($(CONFIG_85xx),y)
 ifeq ($(CONFIG_85xx),y)
 obj-$(CONFIG_PCI)		+= indirect_pci.o pci_auto.o
 obj-$(CONFIG_PCI)		+= indirect_pci.o pci_auto.o

+ 1 - 1
arch/ppc/syslib/ipic.c

@@ -479,7 +479,7 @@ void __init ipic_init(phys_addr_t phys_addr,
 	temp = 0;
 	temp = 0;
 	for (i = 0 ; i < senses_count ; i++) {
 	for (i = 0 ; i < senses_count ; i++) {
 		if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) {
 		if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) {
-			temp |= 1 << (16 - i);
+			temp |= 1 << (15 - i);
 			if (i != 0)
 			if (i != 0)
 				irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0;
 				irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0;
 			else
 			else

+ 0 - 193
arch/ppc/syslib/m8260_pci.c

@@ -1,193 +0,0 @@
-/*
- * (C) Copyright 2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * (C) Copyright 2004 Red Hat, Inc.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <asm/immap_cpm2.h>
-#include <asm/mpc8260.h>
-
-#include "m8260_pci.h"
-
-
-/* PCI bus configuration registers.
- */
-
-static void __init m8260_setup_pci(struct pci_controller *hose)
-{
-	volatile cpm2_map_t *immap = cpm2_immr;
-	unsigned long pocmr;
-	u16 tempShort;
-
-#ifndef CONFIG_ATC 	/* already done in U-Boot */
-	/* 
-	 * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]), 
-	 * and local bus for PCI (SIUMCR [LBPC]).
-	 */
-	immap->im_siu_conf.siu_82xx.sc_siumcr = 0x00640000;
-#endif
-
-	/* Make PCI lowest priority */
-	/* Each 4 bits is a device bus request  and the MS 4bits 
-	   is highest priority */
-	/* Bus               4bit value 
-	   ---               ----------
-	   CPM high          0b0000
-	   CPM middle        0b0001
-	   CPM low           0b0010
-	   PCI reguest       0b0011
-	   Reserved          0b0100
-	   Reserved          0b0101
-	   Internal Core     0b0110
-	   External Master 1 0b0111
-	   External Master 2 0b1000
-	   External Master 3 0b1001
-	   The rest are reserved */
-	immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893;
-
-	/* Park bus on core while modifying PCI Bus accesses */
-	immap->im_siu_conf.siu_82xx.sc_ppc_acr = 0x6;
-
-	/* 
-	 * Set up master window that allows the CPU to access PCI space. This 
-	 * window is set up using the first SIU PCIBR registers.
-	 */
-	immap->im_memctl.memc_pcimsk0 = MPC826x_PCI_MASK;
-	immap->im_memctl.memc_pcibr0 =	MPC826x_PCI_BASE | PCIBR_ENABLE;
-
-	/* Disable machine check on no response or target abort */
-	immap->im_pci.pci_emr = cpu_to_le32(0x1fe7);
-	/* Release PCI RST (by default the PCI RST signal is held low)  */
-	immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN);
-
-	/* give it some time */
-	mdelay(1);
-
-	/* 
-	 * Set up master window that allows the CPU to access PCI Memory (prefetch) 
-	 * space. This window is set up using the first set of Outbound ATU registers.
-	 */
-	immap->im_pci.pci_potar0 = cpu_to_le32(MPC826x_PCI_LOWER_MEM >> 12);
-	immap->im_pci.pci_pobar0 = cpu_to_le32((MPC826x_PCI_LOWER_MEM - MPC826x_PCI_MEM_OFFSET) >> 12);
-	pocmr = ((MPC826x_PCI_UPPER_MEM - MPC826x_PCI_LOWER_MEM) >> 12) ^ 0xfffff;
-	immap->im_pci.pci_pocmr0 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PREFETCH_EN);
-
-	/* 
-	 * Set up master window that allows the CPU to access PCI Memory (non-prefetch) 
-	 * space. This window is set up using the second set of Outbound ATU registers.
-	 */
-	immap->im_pci.pci_potar1 = cpu_to_le32(MPC826x_PCI_LOWER_MMIO >> 12);
-	immap->im_pci.pci_pobar1 = cpu_to_le32((MPC826x_PCI_LOWER_MMIO - MPC826x_PCI_MMIO_OFFSET) >> 12);
-	pocmr = ((MPC826x_PCI_UPPER_MMIO - MPC826x_PCI_LOWER_MMIO) >> 12) ^ 0xfffff;
-	immap->im_pci.pci_pocmr1 = cpu_to_le32(pocmr | POCMR_ENABLE);
-
-	/* 
-	 * Set up master window that allows the CPU to access PCI IO space. This window
-	 * is set up using the third set of Outbound ATU registers.
-	 */
-	immap->im_pci.pci_potar2 = cpu_to_le32(MPC826x_PCI_IO_BASE >> 12);
-	immap->im_pci.pci_pobar2 = cpu_to_le32(MPC826x_PCI_LOWER_IO >> 12);
-	pocmr = ((MPC826x_PCI_UPPER_IO - MPC826x_PCI_LOWER_IO) >> 12) ^ 0xfffff;
-	immap->im_pci.pci_pocmr2 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PCI_IO);
-
-	/* 
-	 * Set up slave window that allows PCI masters to access MPC826x local memory. 
-	 * This window is set up using the first set of Inbound ATU registers
-	 */
-
-	immap->im_pci.pci_pitar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_LOCAL >> 12);
-	immap->im_pci.pci_pibar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_BUS >> 12);
-	pocmr = ((MPC826x_PCI_SLAVE_MEM_SIZE-1) >> 12) ^ 0xfffff;
-	immap->im_pci.pci_picmr0 = cpu_to_le32(pocmr | PICMR_ENABLE | PICMR_PREFETCH_EN);
-
-	/* See above for description - puts PCI request as highest priority */
-	immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567;
-
-	/* Park the bus on the PCI */
-	immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI;
-
-	/* Host mode - specify the bridge as a host-PCI bridge */
-	early_write_config_word(hose, 0, 0, PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_HOST);
-
-	/* Enable the host bridge to be a master on the PCI bus, and to act as a PCI memory target */
-	early_read_config_word(hose, 0, 0, PCI_COMMAND, &tempShort);
-	early_write_config_word(hose, 0, 0, PCI_COMMAND,
-				tempShort | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
-}
-
-void __init m8260_find_bridges(void)
-{
-	extern int pci_assign_all_busses;
-	struct pci_controller * hose;
-
-	pci_assign_all_busses = 1;
-
-	hose = pcibios_alloc_controller();
-
-	if (!hose)
-		return;
-
-	ppc_md.pci_swizzle = common_swizzle;
-
-	hose->first_busno = 0;
-	hose->bus_offset = 0;
-	hose->last_busno = 0xff;
-
-	setup_m8260_indirect_pci(hose, 
-				 (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr,
-				 (unsigned long)&cpm2_immr->im_pci.pci_cfg_data);
-
-	m8260_setup_pci(hose);
-        hose->pci_mem_offset = MPC826x_PCI_MEM_OFFSET;
-
-        hose->io_base_virt = ioremap(MPC826x_PCI_IO_BASE,
-                                        MPC826x_PCI_IO_SIZE);
-        isa_io_base = (unsigned long) hose->io_base_virt;
- 
-        /* setup resources */
-        pci_init_resource(&hose->mem_resources[0],
-			  MPC826x_PCI_LOWER_MEM,
-			  MPC826x_PCI_UPPER_MEM,
-			  IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory");
-
-        pci_init_resource(&hose->mem_resources[1],
-			  MPC826x_PCI_LOWER_MMIO,
-			  MPC826x_PCI_UPPER_MMIO,
-			  IORESOURCE_MEM, "PCI memory");
-
-        pci_init_resource(&hose->io_resource,
-			  MPC826x_PCI_LOWER_IO,
-			  MPC826x_PCI_UPPER_IO,
-			  IORESOURCE_IO, "PCI I/O");
-}

+ 0 - 76
arch/ppc/syslib/m8260_pci.h

@@ -1,76 +0,0 @@
-
-#ifndef _PPC_KERNEL_M8260_PCI_H
-#define _PPC_KERNEL_M8260_PCI_H
-
-#include <asm/m8260_pci.h>
-
-/*
- *   Local->PCI map (from CPU)                             controlled by
- *   MPC826x master window
- *
- *   0x80000000 - 0xBFFFFFFF    Total CPU2PCI space        PCIBR0
- *                       
- *   0x80000000 - 0x9FFFFFFF    PCI Mem with prefetch      (Outbound ATU #1)
- *   0xA0000000 - 0xAFFFFFFF    PCI Mem w/o  prefetch      (Outbound ATU #2)
- *   0xB0000000 - 0xB0FFFFFF    32-bit PCI IO              (Outbound ATU #3)
- *                      
- *   PCI->Local map (from PCI)
- *   MPC826x slave window                                  controlled by
- *
- *   0x00000000 - 0x07FFFFFF    MPC826x local memory       (Inbound ATU #1)
- */
-
-/* 
- * Slave window that allows PCI masters to access MPC826x local memory. 
- * This window is set up using the first set of Inbound ATU registers
- */
-
-#ifndef MPC826x_PCI_SLAVE_MEM_LOCAL
-#define MPC826x_PCI_SLAVE_MEM_LOCAL	(((struct bd_info *)__res)->bi_memstart)
-#define MPC826x_PCI_SLAVE_MEM_BUS	(((struct bd_info *)__res)->bi_memstart)
-#define MPC826x_PCI_SLAVE_MEM_SIZE	(((struct bd_info *)__res)->bi_memsize)
-#endif
-
-/* 
- * This is the window that allows the CPU to access PCI address space.
- * It will be setup with the SIU PCIBR0 register. All three PCI master
- * windows, which allow the CPU to access PCI prefetch, non prefetch,
- * and IO space (see below), must all fit within this window. 
- */
-#ifndef MPC826x_PCI_BASE
-#define MPC826x_PCI_BASE	0x80000000
-#define MPC826x_PCI_MASK	0xc0000000
-#endif
-
-#ifndef MPC826x_PCI_LOWER_MEM
-#define MPC826x_PCI_LOWER_MEM  0x80000000
-#define MPC826x_PCI_UPPER_MEM  0x9fffffff
-#define MPC826x_PCI_MEM_OFFSET 0x00000000
-#endif
-
-#ifndef MPC826x_PCI_LOWER_MMIO
-#define MPC826x_PCI_LOWER_MMIO  0xa0000000
-#define MPC826x_PCI_UPPER_MMIO  0xafffffff
-#define MPC826x_PCI_MMIO_OFFSET 0x00000000
-#endif
-
-#ifndef MPC826x_PCI_LOWER_IO
-#define MPC826x_PCI_LOWER_IO   0x00000000
-#define MPC826x_PCI_UPPER_IO   0x00ffffff
-#define MPC826x_PCI_IO_BASE    0xb0000000
-#define MPC826x_PCI_IO_SIZE    0x01000000
-#endif
-
-#ifndef _IO_BASE
-#define _IO_BASE isa_io_base
-#endif
-
-#ifdef CONFIG_8260_PCI9
-struct pci_controller;
-extern void setup_m8260_indirect_pci(struct pci_controller* hose,
-				     u32 cfg_addr, u32 cfg_data);
-#else
-#define setup_m8260_indirect_pci setup_indirect_pci
-#endif
-
-#endif /* _PPC_KERNEL_M8260_PCI_H */

+ 5 - 5
arch/ppc/syslib/m8260_pci_erratum9.c

@@ -31,7 +31,7 @@
 #include <asm/immap_cpm2.h>
 #include <asm/immap_cpm2.h>
 #include <asm/cpm2.h>
 #include <asm/cpm2.h>
 
 
-#include "m8260_pci.h"
+#include "m82xx_pci.h"
 
 
 #ifdef CONFIG_8260_PCI9
 #ifdef CONFIG_8260_PCI9
 /*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */
 /*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */
@@ -248,11 +248,11 @@ EXPORT_SYMBOL(idma_pci9_read_le);
 
 
 static inline int is_pci_mem(unsigned long addr)
 static inline int is_pci_mem(unsigned long addr)
 {
 {
-	if (addr >= MPC826x_PCI_LOWER_MMIO &&
-	    addr <= MPC826x_PCI_UPPER_MMIO)
+	if (addr >= M82xx_PCI_LOWER_MMIO &&
+		addr <= M82xx_PCI_UPPER_MMIO)
 		return 1;
 		return 1;
-	if (addr >= MPC826x_PCI_LOWER_MEM &&
-	    addr <= MPC826x_PCI_UPPER_MEM)
+	if (addr >= M82xx_PCI_LOWER_MEM &&
+		addr <= M82xx_PCI_UPPER_MEM)
 		return 1;
 		return 1;
 	return 0;
 	return 0;
 }
 }

+ 9 - 2
arch/ppc/syslib/m8260_setup.c

@@ -34,7 +34,8 @@
 unsigned char __res[sizeof(bd_t)];
 unsigned char __res[sizeof(bd_t)];
 
 
 extern void cpm2_reset(void);
 extern void cpm2_reset(void);
-extern void m8260_find_bridges(void);
+extern void pq2_find_bridges(void);
+extern void pq2pci_init_irq(void);
 extern void idma_pci9_init(void);
 extern void idma_pci9_init(void);
 
 
 /* Place-holder for board-specific init */
 /* Place-holder for board-specific init */
@@ -56,7 +57,7 @@ m8260_setup_arch(void)
 	idma_pci9_init();
 	idma_pci9_init();
 #endif
 #endif
 #ifdef CONFIG_PCI_8260
 #ifdef CONFIG_PCI_8260
-	m8260_find_bridges();
+	pq2_find_bridges();
 #endif
 #endif
 #ifdef CONFIG_BLK_DEV_INITRD
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
 	if (initrd_start)
@@ -173,6 +174,12 @@ m8260_init_IRQ(void)
 	 * in case the boot rom changed something on us.
 	 * in case the boot rom changed something on us.
 	 */
 	 */
 	cpm2_immr->im_intctl.ic_siprr = 0x05309770;
 	cpm2_immr->im_intctl.ic_siprr = 0x05309770;
+
+#if defined(CONFIG_PCI) && (defined(CONFIG_ADS8272) || defined(CONFIG_PQ2FADS))
+ 	/* Initialize stuff for the 82xx CPLD IC and install demux  */
+ 	pq2pci_init_irq();
+#endif
+
 }
 }
 
 
 /*
 /*

+ 383 - 0
arch/ppc/syslib/m82xx_pci.c

@@ -0,0 +1,383 @@
+/*
+ *
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2004 Red Hat, Inc.
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/immap_cpm2.h>
+#include <asm/mpc8260.h>
+#include <asm/cpm2.h>
+
+#include "m82xx_pci.h"
+
+/*
+ * Interrupt routing
+ */
+
+static inline int
+pq2pci_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] =
+	/*
+	 *	PCI IDSEL/INTPIN->INTLINE
+	 * 	  A      B      C      D
+	 */
+	{
+		{ PIRQA, PIRQB, PIRQC, PIRQD },	/* IDSEL 22 - PCI slot 0 */
+		{ PIRQD, PIRQA, PIRQB, PIRQC },	/* IDSEL 23 - PCI slot 1 */
+		{ PIRQC, PIRQD, PIRQA, PIRQB },	/* IDSEL 24 - PCI slot 2 */
+	};
+
+	const long min_idsel = 22, max_idsel = 24, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
+}
+
+static void
+pq2pci_mask_irq(unsigned int irq)
+{
+	int bit = irq - NR_CPM_INTS;
+
+	*(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit));
+	return;
+}
+
+static void
+pq2pci_unmask_irq(unsigned int irq)
+{
+	int bit = irq - NR_CPM_INTS;
+
+	*(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit));
+	return;
+}
+
+static void
+pq2pci_mask_and_ack(unsigned int irq)
+{
+	int bit = irq - NR_CPM_INTS;
+
+	*(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit));
+	return;
+}
+
+static void
+pq2pci_end_irq(unsigned int irq)
+{
+	int bit = irq - NR_CPM_INTS;
+
+	*(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit));
+	return;
+}
+
+struct hw_interrupt_type pq2pci_ic = {
+	"PQ2 PCI",
+	NULL,
+	NULL,
+	pq2pci_unmask_irq,
+	pq2pci_mask_irq,
+	pq2pci_mask_and_ack,
+	pq2pci_end_irq,
+	0
+};
+
+static irqreturn_t
+pq2pci_irq_demux(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long stat, mask, pend;
+	int bit;
+
+	for(;;) {
+		stat = *(volatile unsigned long *) PCI_INT_STAT_REG;
+		mask = *(volatile unsigned long *) PCI_INT_MASK_REG;
+		pend = stat & ~mask & 0xf0000000;
+		if (!pend)
+			break;
+		for (bit = 0; pend != 0; ++bit, pend <<= 1) {
+			if (pend & 0x80000000)
+				__do_IRQ(NR_CPM_INTS + bit, regs);
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction pq2pci_irqaction = {
+	.handler = pq2pci_irq_demux,
+	.flags 	 = SA_INTERRUPT,
+	.mask	 = CPU_MASK_NONE,
+	.name	 = "PQ2 PCI cascade",
+};
+
+
+void
+pq2pci_init_irq(void)
+{
+	int irq;
+	volatile cpm2_map_t *immap = cpm2_immr;
+#if defined CONFIG_ADS8272
+	/* configure chip select for PCI interrupt controller */
+	immap->im_memctl.memc_br3 = PCI_INT_STAT_REG | 0x00001801;
+	immap->im_memctl.memc_or3 = 0xffff8010;
+#elif defined CONFIG_PQ2FADS
+	immap->im_memctl.memc_br8 = PCI_INT_STAT_REG | 0x00001801;
+	immap->im_memctl.memc_or8 = 0xffff8010;
+#endif
+	for (irq = NR_CPM_INTS; irq < NR_CPM_INTS + 4; irq++)
+		irq_desc[irq].handler = &pq2pci_ic;
+
+	/* make PCI IRQ level sensitive */
+	immap->im_intctl.ic_siexr &=
+		~(1 << (14 - (PCI_INT_TO_SIU - SIU_INT_IRQ1)));
+
+	/* mask all PCI interrupts */
+	*(volatile unsigned long *) PCI_INT_MASK_REG |= 0xfff00000;
+
+	/* install the demultiplexer for the PCI cascade interrupt */
+	setup_irq(PCI_INT_TO_SIU, &pq2pci_irqaction);
+	return;
+}
+
+static int
+pq2pci_exclude_device(u_char bus, u_char devfn)
+{
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/* PCI bus configuration registers.
+ */
+static void
+pq2ads_setup_pci(struct pci_controller *hose)
+{
+	__u32 val;
+	volatile cpm2_map_t *immap = cpm2_immr;
+	bd_t* binfo = (bd_t*) __res;
+	u32 sccr = immap->im_clkrst.car_sccr;
+	uint pci_div,freq,time;
+		/* PCI int lowest prio */
+	/* Each 4 bits is a device bus request	and the MS 4bits
+	 is highest priority */
+	/* Bus                4bit value
+	   ---                ----------
+	   CPM high      	0b0000
+	   CPM middle           0b0001
+	   CPM low       	0b0010
+	   PCI reguest          0b0011
+	   Reserved      	0b0100
+	   Reserved      	0b0101
+	   Internal Core     	0b0110
+	   External Master 1 	0b0111
+	   External Master 2 	0b1000
+	   External Master 3 	0b1001
+	   The rest are reserved
+	 */
+	immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893;
+	/* park bus on core */
+	immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_CORE;
+	/*
+	 * Set up master windows that allow the CPU to access PCI space. These
+	 * windows are set up using the two SIU PCIBR registers.
+	 */
+
+	immap->im_memctl.memc_pcimsk0 = M82xx_PCI_PRIM_WND_SIZE;
+	immap->im_memctl.memc_pcibr0  = M82xx_PCI_PRIM_WND_BASE | PCIBR_ENABLE;
+
+#ifdef M82xx_PCI_SEC_WND_SIZE
+	immap->im_memctl.memc_pcimsk1 = M82xx_PCI_SEC_WND_SIZE;
+	immap->im_memctl.memc_pcibr1  = M82xx_PCI_SEC_WND_BASE | PCIBR_ENABLE;
+#endif
+
+#if defined CONFIG_ADS8272
+	immap->im_siu_conf.siu_82xx.sc_siumcr =
+		(immap->im_siu_conf.siu_82xx.sc_siumcr &
+		~(SIUMCR_BBD | SIUMCR_ESE | SIUMCR_PBSE |
+		SIUMCR_CDIS | SIUMCR_DPPC11 | SIUMCR_L2CPC11 |
+		SIUMCR_LBPC11 | SIUMCR_APPC11 |
+		SIUMCR_CS10PC11 | SIUMCR_BCTLC11 | SIUMCR_MMR11)) |
+		SIUMCR_DPPC11 | SIUMCR_L2CPC01 | SIUMCR_LBPC00 |
+		SIUMCR_APPC10 | SIUMCR_CS10PC00 |
+		SIUMCR_BCTLC00 | SIUMCR_MMR11 ;
+
+#elif defined CONFIG_PQ2FADS
+	/*
+	 * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]),
+	 * and local bus for PCI (SIUMCR [LBPC]).
+	 */
+	immap->im_siu_conf.siu_82xx.sc_siumcr = (immap->im_siu_conf.sc_siumcr &
+				~(SIUMCR_L2PC11 | SIUMCR_LBPC11 | SIUMCR_CS10PC11 | SIUMCR_APPC11) |
+				SIUMCR_BBD | SIUMCR_LBPC01 | SIUMCR_DPPC11 | SIUMCR_APPC10;
+#endif
+	/* Enable PCI  */
+	immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN);
+
+	pci_div = ( (sccr & SCCR_PCI_MODCK) ? 2 : 1) *
+			( ( (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT) + 1);
+	freq = (uint)((2*binfo->bi_cpmfreq)/(pci_div));
+	time = (int)666666/freq;
+	/* due to PCI Local Bus spec, some devices needs to wait such a long
+	time after RST 	deassertion. More specifically, 0.508s for 66MHz & twice more for 33 */
+	printk("%s: The PCI bus is %d Mhz.\nWaiting %s after deasserting RST...\n",__FILE__,freq,
+	(time==1) ? "0.5 seconds":"1 second" );
+
+	{
+		int i;
+		for(i=0;i<(500*time);i++)
+			udelay(1000);
+	}
+
+	/* setup ATU registers */
+	immap->im_pci.pci_pocmr0 = cpu_to_le32(POCMR_ENABLE | POCMR_PCI_IO |
+				((~(M82xx_PCI_IO_SIZE - 1U)) >> POTA_ADDR_SHIFT));
+	immap->im_pci.pci_potar0 = cpu_to_le32(M82xx_PCI_LOWER_IO >> POTA_ADDR_SHIFT);
+	immap->im_pci.pci_pobar0 = cpu_to_le32(M82xx_PCI_IO_BASE >> POTA_ADDR_SHIFT);
+
+	/* Set-up non-prefetchable window */
+	immap->im_pci.pci_pocmr1 = cpu_to_le32(POCMR_ENABLE | ((~(M82xx_PCI_MMIO_SIZE-1U)) >> POTA_ADDR_SHIFT));
+	immap->im_pci.pci_potar1 = cpu_to_le32(M82xx_PCI_LOWER_MMIO >> POTA_ADDR_SHIFT);
+	immap->im_pci.pci_pobar1 = cpu_to_le32((M82xx_PCI_LOWER_MMIO - M82xx_PCI_MMIO_OFFSET) >> POTA_ADDR_SHIFT);
+
+	/* Set-up prefetchable window */
+	immap->im_pci.pci_pocmr2 = cpu_to_le32(POCMR_ENABLE |POCMR_PREFETCH_EN |
+		(~(M82xx_PCI_MEM_SIZE-1U) >> POTA_ADDR_SHIFT));
+	immap->im_pci.pci_potar2 = cpu_to_le32(M82xx_PCI_LOWER_MEM >> POTA_ADDR_SHIFT);
+	immap->im_pci.pci_pobar2 = cpu_to_le32((M82xx_PCI_LOWER_MEM - M82xx_PCI_MEM_OFFSET) >> POTA_ADDR_SHIFT);
+
+ 	/* Inbound transactions from PCI memory space */
+	immap->im_pci.pci_picmr0 = cpu_to_le32(PICMR_ENABLE | PICMR_PREFETCH_EN |
+					((~(M82xx_PCI_SLAVE_MEM_SIZE-1U)) >> PITA_ADDR_SHIFT));
+	immap->im_pci.pci_pibar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_BUS  >> PITA_ADDR_SHIFT);
+	immap->im_pci.pci_pitar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_LOCAL>> PITA_ADDR_SHIFT);
+
+#if defined CONFIG_ADS8272
+	/* PCI int highest prio */
+	immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x01236745;
+#elif defined CONFIG_PQ2FADS
+	immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567;
+#endif
+	/* park bus on PCI */
+	immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI;
+
+	/* Enable bus mastering and inbound memory transactions */
+	early_read_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, &val);
+	val &= 0xffff0000;
+	val |= PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER;
+	early_write_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, val);
+
+}
+
+void __init pq2_find_bridges(void)
+{
+	extern int pci_assign_all_busses;
+	struct pci_controller * hose;
+	int host_bridge;
+
+	pci_assign_all_busses = 1;
+
+	hose = pcibios_alloc_controller();
+
+	if (!hose)
+		return;
+
+	ppc_md.pci_swizzle = common_swizzle;
+
+	hose->first_busno = 0;
+	hose->bus_offset = 0;
+	hose->last_busno = 0xff;
+
+#ifdef CONFIG_ADS8272
+	hose->set_cfg_type = 1;
+#endif
+
+	setup_m8260_indirect_pci(hose,
+				 (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr,
+				 (unsigned long)&cpm2_immr->im_pci.pci_cfg_data);
+
+	/* Make sure it is a supported bridge */
+	early_read_config_dword(hose,
+				0,
+				PCI_DEVFN(0,0),
+				PCI_VENDOR_ID,
+				&host_bridge);
+	switch (host_bridge) {
+		case PCI_DEVICE_ID_MPC8265:
+			break;
+		case PCI_DEVICE_ID_MPC8272:
+			break;
+		default:
+			printk("Attempting to use unrecognized host bridge ID"
+				" 0x%08x.\n", host_bridge);
+			break;
+	}
+
+	pq2ads_setup_pci(hose);
+
+	hose->io_space.start =	M82xx_PCI_LOWER_IO;
+	hose->io_space.end = M82xx_PCI_UPPER_IO;
+	hose->mem_space.start = M82xx_PCI_LOWER_MEM;
+	hose->mem_space.end = M82xx_PCI_UPPER_MMIO;
+	hose->pci_mem_offset = M82xx_PCI_MEM_OFFSET;
+
+	isa_io_base =
+	(unsigned long) ioremap(M82xx_PCI_IO_BASE,
+					M82xx_PCI_IO_SIZE);
+	hose->io_base_virt = (void *) isa_io_base;
+
+	/* setup resources */
+	pci_init_resource(&hose->mem_resources[0],
+			M82xx_PCI_LOWER_MEM,
+			M82xx_PCI_UPPER_MEM,
+			IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory");
+
+	pci_init_resource(&hose->mem_resources[1],
+			M82xx_PCI_LOWER_MMIO,
+			M82xx_PCI_UPPER_MMIO,
+			IORESOURCE_MEM, "PCI memory");
+
+	pci_init_resource(&hose->io_resource,
+			M82xx_PCI_LOWER_IO,
+			M82xx_PCI_UPPER_IO,
+			IORESOURCE_IO | 1, "PCI I/O");
+
+	ppc_md.pci_exclude_device = pq2pci_exclude_device;
+	hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
+
+	ppc_md.pci_map_irq = pq2pci_map_irq;
+	ppc_md.pcibios_fixup = NULL;
+	ppc_md.pcibios_fixup_bus = NULL;
+
+}

+ 92 - 0
arch/ppc/syslib/m82xx_pci.h

@@ -0,0 +1,92 @@
+
+#ifndef _PPC_KERNEL_M82XX_PCI_H
+#define _PPC_KERNEL_M82XX_PCI_H
+
+#include <asm/m8260_pci.h>
+/*
+ *   Local->PCI map (from CPU)                             controlled by
+ *   MPC826x master window
+ *
+ *   0xF6000000 - 0xF7FFFFFF    IO space
+ *   0x80000000 - 0xBFFFFFFF    CPU2PCI memory space       PCIBR0
+ *
+ *   0x80000000 - 0x9FFFFFFF    PCI Mem with prefetch      (Outbound ATU #1)
+ *   0xA0000000 - 0xBFFFFFFF    PCI Mem w/o  prefetch      (Outbound ATU #2)
+ *   0xF6000000 - 0xF7FFFFFF    32-bit PCI IO              (Outbound ATU #3)
+ *
+ *   PCI->Local map (from PCI)
+ *   MPC826x slave window                                  controlled by
+ *
+ *   0x00000000 - 0x07FFFFFF    MPC826x local memory       (Inbound ATU #1)
+ */
+
+/*
+ * Slave window that allows PCI masters to access MPC826x local memory.
+ * This window is set up using the first set of Inbound ATU registers
+ */
+
+#ifndef M82xx_PCI_SLAVE_MEM_LOCAL
+#define M82xx_PCI_SLAVE_MEM_LOCAL	(((struct bd_info *)__res)->bi_memstart)
+#define M82xx_PCI_SLAVE_MEM_BUS		(((struct bd_info *)__res)->bi_memstart)
+#define M82xx_PCI_SLAVE_MEM_SIZE	(((struct bd_info *)__res)->bi_memsize)
+#endif
+
+/*
+ * This is the window that allows the CPU to access PCI address space.
+ * It will be setup with the SIU PCIBR0 register. All three PCI master
+ * windows, which allow the CPU to access PCI prefetch, non prefetch,
+ * and IO space (see below), must all fit within this window.
+ */
+
+#ifndef M82xx_PCI_LOWER_MEM
+#define M82xx_PCI_LOWER_MEM		0x80000000
+#define M82xx_PCI_UPPER_MEM		0x9fffffff
+#define M82xx_PCI_MEM_OFFSET		0x00000000
+#define M82xx_PCI_MEM_SIZE		0x20000000
+#endif
+
+#ifndef M82xx_PCI_LOWER_MMIO
+#define M82xx_PCI_LOWER_MMIO		0xa0000000
+#define M82xx_PCI_UPPER_MMIO		0xafffffff
+#define M82xx_PCI_MMIO_OFFSET		0x00000000
+#define M82xx_PCI_MMIO_SIZE		0x20000000
+#endif
+
+#ifndef M82xx_PCI_LOWER_IO
+#define M82xx_PCI_LOWER_IO		0x00000000
+#define M82xx_PCI_UPPER_IO		0x01ffffff
+#define M82xx_PCI_IO_BASE		0xf6000000
+#define M82xx_PCI_IO_SIZE		0x02000000
+#endif
+
+#ifndef M82xx_PCI_PRIM_WND_SIZE
+#define M82xx_PCI_PRIM_WND_SIZE 	~(M82xx_PCI_IO_SIZE - 1U)
+#define M82xx_PCI_PRIM_WND_BASE		(M82xx_PCI_IO_BASE)
+#endif
+
+#ifndef M82xx_PCI_SEC_WND_SIZE
+#define M82xx_PCI_SEC_WND_SIZE 		~(M82xx_PCI_MEM_SIZE + M82xx_PCI_MMIO_SIZE - 1U)
+#define M82xx_PCI_SEC_WND_BASE 		(M82xx_PCI_LOWER_MEM)
+#endif
+
+#ifndef POTA_ADDR_SHIFT
+#define POTA_ADDR_SHIFT		12
+#endif
+
+#ifndef PITA_ADDR_SHIFT
+#define PITA_ADDR_SHIFT		12
+#endif
+
+#ifndef _IO_BASE
+#define _IO_BASE isa_io_base
+#endif
+
+#ifdef CONFIG_8260_PCI9
+struct pci_controller;
+extern void setup_m8260_indirect_pci(struct pci_controller* hose,
+					u32 cfg_addr, u32 cfg_data);
+#else
+#define setup_m8260_indirect_pci setup_indirect_pci
+#endif
+
+#endif /* _PPC_KERNEL_M8260_PCI_H */

+ 1 - 0
arch/ppc/syslib/mpc83xx_devices.c

@@ -61,6 +61,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 		.iotype		= UPIO_MEM,
 		.iotype		= UPIO_MEM,
 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
 	},
 	},
+	{ },
 };
 };
 
 
 struct platform_device ppc_sys_platform_devices[] = {
 struct platform_device ppc_sys_platform_devices[] = {

+ 1 - 0
arch/ppc/syslib/mpc85xx_devices.c

@@ -61,6 +61,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 		.iotype		= UPIO_MEM,
 		.iotype		= UPIO_MEM,
 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ,
 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ,
 	},
 	},
+	{ },
 };
 };
 
 
 struct platform_device ppc_sys_platform_devices[] = {
 struct platform_device ppc_sys_platform_devices[] = {

+ 1 - 5
arch/ppc/syslib/open_pic.c

@@ -275,7 +275,7 @@ static void __init openpic_enable_sie(void)
 }
 }
 #endif
 #endif
 
 
-#if defined(CONFIG_EPIC_SERIAL_MODE) || defined(CONFIG_PM)
+#if defined(CONFIG_EPIC_SERIAL_MODE)
 static void openpic_reset(void)
 static void openpic_reset(void)
 {
 {
 	openpic_setfield(&OpenPIC->Global.Global_Configuration0,
 	openpic_setfield(&OpenPIC->Global.Global_Configuration0,
@@ -557,12 +557,10 @@ static void __init openpic_initipi(u_int ipi, u_int pri, u_int vec)
  */
  */
 void openpic_cause_IPI(u_int ipi, cpumask_t cpumask)
 void openpic_cause_IPI(u_int ipi, cpumask_t cpumask)
 {
 {
-	cpumask_t phys;
 	DECL_THIS_CPU;
 	DECL_THIS_CPU;
 
 
 	CHECK_THIS_CPU;
 	CHECK_THIS_CPU;
 	check_arg_ipi(ipi);
 	check_arg_ipi(ipi);
-	phys = physmask(cpumask);
 	openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi),
 	openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi),
 		      cpus_addr(physmask(cpumask))[0]);
 		      cpus_addr(physmask(cpumask))[0]);
 }
 }
@@ -995,8 +993,6 @@ int openpic_resume(struct sys_device *sysdev)
 		return 0;
 		return 0;
 	}
 	}
 
 
-	openpic_reset();
-
 	/* OpenPIC sometimes seem to need some time to be fully back up... */
 	/* OpenPIC sometimes seem to need some time to be fully back up... */
 	do {
 	do {
 		openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
 		openpic_set_spurious(OPENPIC_VEC_SPURIOUS);

+ 28 - 0
arch/ppc/syslib/ppc83xx_setup.c

@@ -29,6 +29,7 @@
 #include <asm/mmu.h>
 #include <asm/mmu.h>
 #include <asm/ppc_sys.h>
 #include <asm/ppc_sys.h>
 #include <asm/kgdb.h>
 #include <asm/kgdb.h>
+#include <asm/delay.h>
 
 
 #include <syslib/ppc83xx_setup.h>
 #include <syslib/ppc83xx_setup.h>
 
 
@@ -117,7 +118,34 @@ mpc83xx_early_serial_map(void)
 void
 void
 mpc83xx_restart(char *cmd)
 mpc83xx_restart(char *cmd)
 {
 {
+	volatile unsigned char __iomem *reg;
+	unsigned char tmp;
+
+	reg = ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
+
 	local_irq_disable();
 	local_irq_disable();
+
+	/*
+	 * Unlock the BCSR bits so a PRST will update the contents.
+	 * Otherwise the reset asserts but doesn't clear.
+	 */
+	tmp = in_8(reg + BCSR_MISC_REG3_OFF);
+	tmp |= BCSR_MISC_REG3_CNFLOCK; /* low true, high false */
+	out_8(reg + BCSR_MISC_REG3_OFF, tmp);
+
+	/*
+	 * Trigger a reset via a low->high transition of the
+	 * PORESET bit.
+	 */
+	tmp = in_8(reg + BCSR_MISC_REG2_OFF);
+	tmp &= ~BCSR_MISC_REG2_PORESET;
+	out_8(reg + BCSR_MISC_REG2_OFF, tmp);
+
+	udelay(1);
+
+	tmp |= BCSR_MISC_REG2_PORESET;
+	out_8(reg + BCSR_MISC_REG2_OFF, tmp);
+
 	for(;;);
 	for(;;);
 }
 }
 
 

+ 16 - 0
arch/ppc/syslib/ppc85xx_setup.c

@@ -132,6 +132,12 @@ mpc85xx_halt(void)
 }
 }
 
 
 #ifdef CONFIG_PCI
 #ifdef CONFIG_PCI
+
+#if defined(CONFIG_MPC8555_CDS)
+extern void mpc85xx_cds_enable_via(struct pci_controller *hose);
+extern void mpc85xx_cds_fixup_via(struct pci_controller *hose);
+#endif
+
 static void __init
 static void __init
 mpc85xx_setup_pci1(struct pci_controller *hose)
 mpc85xx_setup_pci1(struct pci_controller *hose)
 {
 {
@@ -302,8 +308,18 @@ mpc85xx_setup_hose(void)
 
 
 	ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 	ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 
 
+#if defined(CONFIG_MPC8555_CDS)
+	/* Pre pciauto_bus_scan VIA init */
+	mpc85xx_cds_enable_via(hose_a);
+#endif
+
 	hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno);
 	hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno);
 
 
+#if defined(CONFIG_MPC8555_CDS)
+	/* Post pciauto_bus_scan VIA fixup */
+	mpc85xx_cds_fixup_via(hose_a);
+#endif
+
 #ifdef CONFIG_85xx_PCI2
 #ifdef CONFIG_85xx_PCI2
 	hose_b = pcibios_alloc_controller();
 	hose_b = pcibios_alloc_controller();
 
 

+ 65 - 20
arch/ppc64/kernel/mf.c

@@ -1,7 +1,7 @@
 /*
 /*
   * mf.c
   * mf.c
   * Copyright (C) 2001 Troy D. Armstrong  IBM Corporation
   * Copyright (C) 2001 Troy D. Armstrong  IBM Corporation
-  * Copyright (C) 2004 Stephen Rothwell  IBM Corporation
+  * Copyright (C) 2004-2005 Stephen Rothwell  IBM Corporation
   *
   *
   * This modules exists as an interface between a Linux secondary partition
   * This modules exists as an interface between a Linux secondary partition
   * running on an iSeries and the primary partition's Virtual Service
   * running on an iSeries and the primary partition's Virtual Service
@@ -36,10 +36,12 @@
 
 
 #include <asm/time.h>
 #include <asm/time.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
+#include <asm/paca.h>
 #include <asm/iSeries/vio.h>
 #include <asm/iSeries/vio.h>
 #include <asm/iSeries/mf.h>
 #include <asm/iSeries/mf.h>
 #include <asm/iSeries/HvLpConfig.h>
 #include <asm/iSeries/HvLpConfig.h>
 #include <asm/iSeries/ItSpCommArea.h>
 #include <asm/iSeries/ItSpCommArea.h>
+#include <asm/iSeries/ItLpQueue.h>
 
 
 /*
 /*
  * This is the structure layout for the Machine Facilites LPAR event
  * This is the structure layout for the Machine Facilites LPAR event
@@ -696,36 +698,23 @@ static void get_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
 	complete(&rtc->com);
 	complete(&rtc->com);
 }
 }
 
 
-int mf_get_rtc(struct rtc_time *tm)
+static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
 {
 {
-	struct ce_msg_comp_data ce_complete;
-	struct rtc_time_data rtc_data;
-	int rc;
-
-	memset(&ce_complete, 0, sizeof(ce_complete));
-	memset(&rtc_data, 0, sizeof(rtc_data));
-	init_completion(&rtc_data.com);
-	ce_complete.handler = &get_rtc_time_complete;
-	ce_complete.token = &rtc_data;
-	rc = signal_ce_msg_simple(0x40, &ce_complete);
-	if (rc)
-		return rc;
-	wait_for_completion(&rtc_data.com);
 	tm->tm_wday = 0;
 	tm->tm_wday = 0;
 	tm->tm_yday = 0;
 	tm->tm_yday = 0;
 	tm->tm_isdst = 0;
 	tm->tm_isdst = 0;
-	if (rtc_data.rc) {
+	if (rc) {
 		tm->tm_sec = 0;
 		tm->tm_sec = 0;
 		tm->tm_min = 0;
 		tm->tm_min = 0;
 		tm->tm_hour = 0;
 		tm->tm_hour = 0;
 		tm->tm_mday = 15;
 		tm->tm_mday = 15;
 		tm->tm_mon = 5;
 		tm->tm_mon = 5;
 		tm->tm_year = 52;
 		tm->tm_year = 52;
-		return rtc_data.rc;
+		return rc;
 	}
 	}
 
 
-	if ((rtc_data.ce_msg.ce_msg[2] == 0xa9) ||
-	    (rtc_data.ce_msg.ce_msg[2] == 0xaf)) {
+	if ((ce_msg[2] == 0xa9) ||
+	    (ce_msg[2] == 0xaf)) {
 		/* TOD clock is not set */
 		/* TOD clock is not set */
 		tm->tm_sec = 1;
 		tm->tm_sec = 1;
 		tm->tm_min = 1;
 		tm->tm_min = 1;
@@ -736,7 +725,6 @@ int mf_get_rtc(struct rtc_time *tm)
 		mf_set_rtc(tm);
 		mf_set_rtc(tm);
 	}
 	}
 	{
 	{
-		u8 *ce_msg = rtc_data.ce_msg.ce_msg;
 		u8 year = ce_msg[5];
 		u8 year = ce_msg[5];
 		u8 sec = ce_msg[6];
 		u8 sec = ce_msg[6];
 		u8 min = ce_msg[7];
 		u8 min = ce_msg[7];
@@ -765,6 +753,63 @@ int mf_get_rtc(struct rtc_time *tm)
 	return 0;
 	return 0;
 }
 }
 
 
+int mf_get_rtc(struct rtc_time *tm)
+{
+	struct ce_msg_comp_data ce_complete;
+	struct rtc_time_data rtc_data;
+	int rc;
+
+	memset(&ce_complete, 0, sizeof(ce_complete));
+	memset(&rtc_data, 0, sizeof(rtc_data));
+	init_completion(&rtc_data.com);
+	ce_complete.handler = &get_rtc_time_complete;
+	ce_complete.token = &rtc_data;
+	rc = signal_ce_msg_simple(0x40, &ce_complete);
+	if (rc)
+		return rc;
+	wait_for_completion(&rtc_data.com);
+	return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
+}
+
+struct boot_rtc_time_data {
+	int busy;
+	struct ce_msg_data ce_msg;
+	int rc;
+};
+
+static void get_boot_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
+{
+	struct boot_rtc_time_data *rtc = token;
+
+	memcpy(&rtc->ce_msg, ce_msg, sizeof(rtc->ce_msg));
+	rtc->rc = 0;
+	rtc->busy = 0;
+}
+
+int mf_get_boot_rtc(struct rtc_time *tm)
+{
+	struct ce_msg_comp_data ce_complete;
+	struct boot_rtc_time_data rtc_data;
+	int rc;
+
+	memset(&ce_complete, 0, sizeof(ce_complete));
+	memset(&rtc_data, 0, sizeof(rtc_data));
+	rtc_data.busy = 1;
+	ce_complete.handler = &get_boot_rtc_time_complete;
+	ce_complete.token = &rtc_data;
+	rc = signal_ce_msg_simple(0x40, &ce_complete);
+	if (rc)
+		return rc;
+	/* We need to poll here as we are not yet taking interrupts */
+	while (rtc_data.busy) {
+		extern unsigned long lpevent_count;
+		struct ItLpQueue *lpq = get_paca()->lpqueue_ptr;
+		if (lpq && ItLpQueue_isLpIntPending(lpq))
+			lpevent_count += ItLpQueue_process(lpq, NULL);
+	}
+	return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
+}
+
 int mf_set_rtc(struct rtc_time *tm)
 int mf_set_rtc(struct rtc_time *tm)
 {
 {
 	char ce_time[12];
 	char ce_time[12];

+ 21 - 7
arch/ppc64/kernel/pmac_smp.c

@@ -68,6 +68,7 @@ extern struct smp_ops_t *smp_ops;
 
 
 static void (*pmac_tb_freeze)(int freeze);
 static void (*pmac_tb_freeze)(int freeze);
 static struct device_node *pmac_tb_clock_chip_host;
 static struct device_node *pmac_tb_clock_chip_host;
+static u8 pmac_tb_pulsar_addr;
 static DEFINE_SPINLOCK(timebase_lock);
 static DEFINE_SPINLOCK(timebase_lock);
 static unsigned long timebase;
 static unsigned long timebase;
 
 
@@ -106,12 +107,9 @@ static void smp_core99_pulsar_tb_freeze(int freeze)
 	u8 data;
 	u8 data;
 	int rc;
 	int rc;
 
 
-	/* Strangely, the device-tree says address is 0xd2, but darwin
-	 * accesses 0xd0 ...
-	 */
 	pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
 	pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
 	rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
 	rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
-			       0xd4 | pmac_low_i2c_read,
+			       pmac_tb_pulsar_addr | pmac_low_i2c_read,
 			       0x2e, &data, 1);
 			       0x2e, &data, 1);
 	if (rc != 0)
 	if (rc != 0)
 		goto bail;
 		goto bail;
@@ -120,7 +118,7 @@ static void smp_core99_pulsar_tb_freeze(int freeze)
 
 
 	pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
 	pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
 	rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
 	rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
-			       0xd4 | pmac_low_i2c_write,
+			       pmac_tb_pulsar_addr | pmac_low_i2c_write,
 			       0x2e, &data, 1);
 			       0x2e, &data, 1);
  bail:
  bail:
 	if (rc != 0) {
 	if (rc != 0) {
@@ -185,6 +183,12 @@ static int __init smp_core99_probe(void)
 	if (ncpus <= 1)
 	if (ncpus <= 1)
 		return 1;
 		return 1;
 
 
+	/* HW sync only on these platforms */
+	if (!machine_is_compatible("PowerMac7,2") &&
+	    !machine_is_compatible("PowerMac7,3") &&
+	    !machine_is_compatible("RackMac3,1"))
+		goto nohwsync;
+
 	/* Look for the clock chip */
 	/* Look for the clock chip */
 	for (cc = NULL; (cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL;) {
 	for (cc = NULL; (cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL;) {
 		struct device_node *p = of_get_parent(cc);
 		struct device_node *p = of_get_parent(cc);
@@ -198,11 +202,18 @@ static int __init smp_core99_probe(void)
 			goto next;
 			goto next;
 		switch (*reg) {
 		switch (*reg) {
 		case 0xd2:
 		case 0xd2:
-			pmac_tb_freeze = smp_core99_cypress_tb_freeze;
-			printk(KERN_INFO "Timebase clock is Cypress chip\n");
+			if (device_is_compatible(cc, "pulsar-legacy-slewing")) {
+				pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
+				pmac_tb_pulsar_addr = 0xd2;
+				printk(KERN_INFO "Timebase clock is Pulsar chip\n");
+			} else if (device_is_compatible(cc, "cy28508")) {
+				pmac_tb_freeze = smp_core99_cypress_tb_freeze;
+				printk(KERN_INFO "Timebase clock is Cypress chip\n");
+			}
 			break;
 			break;
 		case 0xd4:
 		case 0xd4:
 			pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
 			pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
+			pmac_tb_pulsar_addr = 0xd4;
 			printk(KERN_INFO "Timebase clock is Pulsar chip\n");
 			printk(KERN_INFO "Timebase clock is Pulsar chip\n");
 			break;
 			break;
 		}
 		}
@@ -210,12 +221,15 @@ static int __init smp_core99_probe(void)
 			pmac_tb_clock_chip_host = p;
 			pmac_tb_clock_chip_host = p;
 			smp_ops->give_timebase = smp_core99_give_timebase;
 			smp_ops->give_timebase = smp_core99_give_timebase;
 			smp_ops->take_timebase = smp_core99_take_timebase;
 			smp_ops->take_timebase = smp_core99_take_timebase;
+			of_node_put(cc);
+			of_node_put(p);
 			break;
 			break;
 		}
 		}
 	next:
 	next:
 		of_node_put(p);
 		of_node_put(p);
 	}
 	}
 
 
+ nohwsync:
 	mpic_request_ipis();
 	mpic_request_ipis();
 
 
 	return ncpus;
 	return ncpus;

+ 49 - 1
arch/ppc64/kernel/prom_init.c

@@ -1750,7 +1750,44 @@ static void __init flatten_device_tree(void)
 	prom_printf("Device tree struct  0x%x -> 0x%x\n",
 	prom_printf("Device tree struct  0x%x -> 0x%x\n",
 		    RELOC(dt_struct_start), RELOC(dt_struct_end));
 		    RELOC(dt_struct_start), RELOC(dt_struct_end));
 
 
- }
+}
+
+
+static void __init fixup_device_tree(void)
+{
+	unsigned long offset = reloc_offset();
+	phandle u3, i2c, mpic;
+	u32 u3_rev;
+	u32 interrupts[2];
+	u32 parent;
+
+	/* Some G5s have a missing interrupt definition, fix it up here */
+	u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
+	if ((long)u3 <= 0)
+		return;
+	i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
+	if ((long)i2c <= 0)
+		return;
+	mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
+	if ((long)mpic <= 0)
+		return;
+
+	/* check if proper rev of u3 */
+	if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) <= 0)
+		return;
+	if (u3_rev != 0x35)
+		return;
+	/* does it need fixup ? */
+	if (prom_getproplen(i2c, "interrupts") > 0)
+		return;
+	/* interrupt on this revision of u3 is number 0 and level */
+	interrupts[0] = 0;
+	interrupts[1] = 1;
+	prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts));
+	parent = (u32)mpic;
+	prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent));
+}
+
 
 
 static void __init prom_find_boot_cpu(void)
 static void __init prom_find_boot_cpu(void)
 {
 {
@@ -1843,6 +1880,12 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
 	prom_setprop(_prom->chosen, "linux,platform",
 	prom_setprop(_prom->chosen, "linux,platform",
 		     &getprop_rval, sizeof(getprop_rval));
 		     &getprop_rval, sizeof(getprop_rval));
 
 
+	/*
+	 * On pSeries, inform the firmware about our capabilities
+	 */
+	if (RELOC(of_platform) & PLATFORM_PSERIES)
+		prom_send_capabilities();
+
 	/*
 	/*
 	 * On pSeries, copy the CPU hold code
 	 * On pSeries, copy the CPU hold code
 	 */
 	 */
@@ -1919,6 +1962,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
 			PTRRELOC(&prom_tce_alloc_end), sizeof(RELOC(prom_tce_alloc_end)));
 			PTRRELOC(&prom_tce_alloc_end), sizeof(RELOC(prom_tce_alloc_end)));
 	}
 	}
 
 
+	/*
+	 * Fixup any known bugs in the device-tree
+	 */
+	fixup_device_tree();
+
 	/*
 	/*
 	 * Now finally create the flattened device-tree
 	 * Now finally create the flattened device-tree
 	 */
 	 */

+ 1 - 38
arch/ppc64/kernel/rtc.c

@@ -292,47 +292,10 @@ int iSeries_set_rtc_time(struct rtc_time *tm)
 
 
 void iSeries_get_boot_time(struct rtc_time *tm)
 void iSeries_get_boot_time(struct rtc_time *tm)
 {
 {
-	unsigned long time;
-	static unsigned long lastsec = 1;
-
-	u32 dataWord1 = *((u32 *)(&xSpCommArea.xBcdTimeAtIplStart));
-	u32 dataWord2 = *(((u32 *)&(xSpCommArea.xBcdTimeAtIplStart)) + 1);
-	int year = 1970;
-	int year1 = ( dataWord1 >> 24 ) & 0x000000FF;
-	int year2 = ( dataWord1 >> 16 ) & 0x000000FF;
-	int sec = ( dataWord1 >> 8 ) & 0x000000FF;
-	int min = dataWord1 & 0x000000FF;
-	int hour = ( dataWord2 >> 24 ) & 0x000000FF;
-	int day = ( dataWord2 >> 8 ) & 0x000000FF;
-	int mon = dataWord2 & 0x000000FF;
-
 	if ( piranha_simulator )
 	if ( piranha_simulator )
 		return;
 		return;
 
 
-	BCD_TO_BIN(sec);
-	BCD_TO_BIN(min);
-	BCD_TO_BIN(hour);
-	BCD_TO_BIN(day);
-	BCD_TO_BIN(mon);
-	BCD_TO_BIN(year1);
-	BCD_TO_BIN(year2);
-	year = year1 * 100 + year2;
-
-	time = mktime(year, mon, day, hour, min, sec);
-	time += ( jiffies / HZ );
-
-	/* Now THIS is a nasty hack!
-	* It ensures that the first two calls get different answers.  
-	* That way the loop in init_time (time.c) will not think
-	* the clock is stuck.
-	*/
-	if ( lastsec ) {
-		time -= lastsec;
-		--lastsec;
-	}
-
-	to_tm(time, tm); 
-	tm->tm_year -= 1900;
+	mf_get_boot_rtc(tm);
 	tm->tm_mon  -= 1;
 	tm->tm_mon  -= 1;
 }
 }
 #endif
 #endif

+ 1 - 0
arch/ppc64/kernel/time.c

@@ -515,6 +515,7 @@ void __init time_init(void)
 	do_gtod.varp = &do_gtod.vars[0];
 	do_gtod.varp = &do_gtod.vars[0];
 	do_gtod.var_idx = 0;
 	do_gtod.var_idx = 0;
 	do_gtod.varp->tb_orig_stamp = tb_last_stamp;
 	do_gtod.varp->tb_orig_stamp = tb_last_stamp;
+	get_paca()->next_jiffy_update_tb = tb_last_stamp + tb_ticks_per_jiffy;
 	do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
 	do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
 	do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
 	do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
 	do_gtod.varp->tb_to_xs = tb_to_xs;
 	do_gtod.varp->tb_to_xs = tb_to_xs;

+ 67 - 100
arch/sparc64/kernel/pci_iommu.c

@@ -8,6 +8,7 @@
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/mm.h>
+#include <linux/delay.h>
 
 
 #include <asm/pbm.h>
 #include <asm/pbm.h>
 
 
@@ -379,6 +380,56 @@ dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direct
 	return PCI_DMA_ERROR_CODE;
 	return PCI_DMA_ERROR_CODE;
 }
 }
 
 
+static void pci_strbuf_flush(struct pci_strbuf *strbuf, struct pci_iommu *iommu, u32 vaddr, unsigned long ctx, unsigned long npages)
+{
+	int limit;
+
+	PCI_STC_FLUSHFLAG_INIT(strbuf);
+	if (strbuf->strbuf_ctxflush &&
+	    iommu->iommu_ctxflush) {
+		unsigned long matchreg, flushreg;
+
+		flushreg = strbuf->strbuf_ctxflush;
+		matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
+
+		limit = 100000;
+		pci_iommu_write(flushreg, ctx);
+		for(;;) {
+			if (((long)pci_iommu_read(matchreg)) >= 0L)
+				break;
+			limit--;
+			if (!limit)
+				break;
+			udelay(1);
+		}
+		if (!limit)
+			printk(KERN_WARNING "pci_strbuf_flush: ctx flush "
+			       "timeout vaddr[%08x] ctx[%lx]\n",
+			       vaddr, ctx);
+	} else {
+		unsigned long i;
+
+		for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
+			pci_iommu_write(strbuf->strbuf_pflush, vaddr);
+	}
+
+	pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
+	(void) pci_iommu_read(iommu->write_complete_reg);
+
+	limit = 100000;
+	while (!PCI_STC_FLUSHFLAG_SET(strbuf)) {
+		limit--;
+		if (!limit)
+			break;
+		udelay(1);
+		membar("#LoadLoad");
+	}
+	if (!limit)
+		printk(KERN_WARNING "pci_strbuf_flush: flushflag timeout "
+		       "vaddr[%08x] ctx[%lx] npages[%ld]\n",
+		       vaddr, ctx, npages);
+}
+
 /* Unmap a single streaming mode DMA translation. */
 /* Unmap a single streaming mode DMA translation. */
 void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction)
 void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction)
 {
 {
@@ -386,7 +437,7 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
 	struct pci_iommu *iommu;
 	struct pci_iommu *iommu;
 	struct pci_strbuf *strbuf;
 	struct pci_strbuf *strbuf;
 	iopte_t *base;
 	iopte_t *base;
-	unsigned long flags, npages, i, ctx;
+	unsigned long flags, npages, ctx;
 
 
 	if (direction == PCI_DMA_NONE)
 	if (direction == PCI_DMA_NONE)
 		BUG();
 		BUG();
@@ -414,29 +465,8 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
 		ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL;
 		ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL;
 
 
 	/* Step 1: Kick data out of streaming buffers if necessary. */
 	/* Step 1: Kick data out of streaming buffers if necessary. */
-	if (strbuf->strbuf_enabled) {
-		u32 vaddr = bus_addr;
-
-		PCI_STC_FLUSHFLAG_INIT(strbuf);
-		if (strbuf->strbuf_ctxflush &&
-		    iommu->iommu_ctxflush) {
-			unsigned long matchreg, flushreg;
-
-			flushreg = strbuf->strbuf_ctxflush;
-			matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
-			do {
-				pci_iommu_write(flushreg, ctx);
-			} while(((long)pci_iommu_read(matchreg)) < 0L);
-		} else {
-			for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
-				pci_iommu_write(strbuf->strbuf_pflush, vaddr);
-		}
-
-		pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
-		(void) pci_iommu_read(iommu->write_complete_reg);
-		while (!PCI_STC_FLUSHFLAG_SET(strbuf))
-			membar("#LoadLoad");
-	}
+	if (strbuf->strbuf_enabled)
+		pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages);
 
 
 	/* Step 2: Clear out first TSB entry. */
 	/* Step 2: Clear out first TSB entry. */
 	iopte_make_dummy(iommu, base);
 	iopte_make_dummy(iommu, base);
@@ -647,29 +677,8 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
 		ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL;
 		ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL;
 
 
 	/* Step 1: Kick data out of streaming buffers if necessary. */
 	/* Step 1: Kick data out of streaming buffers if necessary. */
-	if (strbuf->strbuf_enabled) {
-		u32 vaddr = (u32) bus_addr;
-
-		PCI_STC_FLUSHFLAG_INIT(strbuf);
-		if (strbuf->strbuf_ctxflush &&
-		    iommu->iommu_ctxflush) {
-			unsigned long matchreg, flushreg;
-
-			flushreg = strbuf->strbuf_ctxflush;
-			matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
-			do {
-				pci_iommu_write(flushreg, ctx);
-			} while(((long)pci_iommu_read(matchreg)) < 0L);
-		} else {
-			for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
-				pci_iommu_write(strbuf->strbuf_pflush, vaddr);
-		}
-
-		pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
-		(void) pci_iommu_read(iommu->write_complete_reg);
-		while (!PCI_STC_FLUSHFLAG_SET(strbuf))
-			membar("#LoadLoad");
-	}
+	if (strbuf->strbuf_enabled)
+		pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages);
 
 
 	/* Step 2: Clear out first TSB entry. */
 	/* Step 2: Clear out first TSB entry. */
 	iopte_make_dummy(iommu, base);
 	iopte_make_dummy(iommu, base);
@@ -715,28 +724,7 @@ void pci_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size
 	}
 	}
 
 
 	/* Step 2: Kick data out of streaming buffers. */
 	/* Step 2: Kick data out of streaming buffers. */
-	PCI_STC_FLUSHFLAG_INIT(strbuf);
-	if (iommu->iommu_ctxflush &&
-	    strbuf->strbuf_ctxflush) {
-		unsigned long matchreg, flushreg;
-
-		flushreg = strbuf->strbuf_ctxflush;
-		matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
-		do {
-			pci_iommu_write(flushreg, ctx);
-		} while(((long)pci_iommu_read(matchreg)) < 0L);
-	} else {
-		unsigned long i;
-
-		for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE)
-			pci_iommu_write(strbuf->strbuf_pflush, bus_addr);
-	}
-
-	/* Step 3: Perform flush synchronization sequence. */
-	pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
-	(void) pci_iommu_read(iommu->write_complete_reg);
-	while (!PCI_STC_FLUSHFLAG_SET(strbuf))
-		membar("#LoadLoad");
+	pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages);
 
 
 	spin_unlock_irqrestore(&iommu->lock, flags);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 }
@@ -749,7 +737,8 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i
 	struct pcidev_cookie *pcp;
 	struct pcidev_cookie *pcp;
 	struct pci_iommu *iommu;
 	struct pci_iommu *iommu;
 	struct pci_strbuf *strbuf;
 	struct pci_strbuf *strbuf;
-	unsigned long flags, ctx;
+	unsigned long flags, ctx, npages, i;
+	u32 bus_addr;
 
 
 	pcp = pdev->sysdata;
 	pcp = pdev->sysdata;
 	iommu = pcp->pbm->iommu;
 	iommu = pcp->pbm->iommu;
@@ -772,36 +761,14 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i
 	}
 	}
 
 
 	/* Step 2: Kick data out of streaming buffers. */
 	/* Step 2: Kick data out of streaming buffers. */
-	PCI_STC_FLUSHFLAG_INIT(strbuf);
-	if (iommu->iommu_ctxflush &&
-	    strbuf->strbuf_ctxflush) {
-		unsigned long matchreg, flushreg;
-
-		flushreg = strbuf->strbuf_ctxflush;
-		matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
-		do {
-			pci_iommu_write(flushreg, ctx);
-		} while (((long)pci_iommu_read(matchreg)) < 0L);
-	} else {
-		unsigned long i, npages;
-		u32 bus_addr;
-
-		bus_addr = sglist[0].dma_address & IO_PAGE_MASK;
-
-		for(i = 1; i < nelems; i++)
-			if (!sglist[i].dma_length)
-				break;
-		i--;
-		npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - bus_addr) >> IO_PAGE_SHIFT;
-		for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE)
-			pci_iommu_write(strbuf->strbuf_pflush, bus_addr);
-	}
-
-	/* Step 3: Perform flush synchronization sequence. */
-	pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
-	(void) pci_iommu_read(iommu->write_complete_reg);
-	while (!PCI_STC_FLUSHFLAG_SET(strbuf))
-		membar("#LoadLoad");
+	bus_addr = sglist[0].dma_address & IO_PAGE_MASK;
+	for(i = 1; i < nelems; i++)
+		if (!sglist[i].dma_length)
+			break;
+	i--;
+	npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length)
+		  - bus_addr) >> IO_PAGE_SHIFT;
+	pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages);
 
 
 	spin_unlock_irqrestore(&iommu->lock, flags);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 }

+ 23 - 8
arch/sparc64/kernel/sbus.c

@@ -117,19 +117,34 @@ static void iommu_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages
 
 
 #define STRBUF_TAG_VALID	0x02UL
 #define STRBUF_TAG_VALID	0x02UL
 
 
-static void strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages)
+static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages)
 {
 {
+	unsigned long n;
+	int limit;
+
 	iommu->strbuf_flushflag = 0UL;
 	iommu->strbuf_flushflag = 0UL;
-	while (npages--)
-		upa_writeq(base + (npages << IO_PAGE_SHIFT),
+	n = npages;
+	while (n--)
+		upa_writeq(base + (n << IO_PAGE_SHIFT),
 			   iommu->strbuf_regs + STRBUF_PFLUSH);
 			   iommu->strbuf_regs + STRBUF_PFLUSH);
 
 
 	/* Whoopee cushion! */
 	/* Whoopee cushion! */
 	upa_writeq(__pa(&iommu->strbuf_flushflag),
 	upa_writeq(__pa(&iommu->strbuf_flushflag),
 		   iommu->strbuf_regs + STRBUF_FSYNC);
 		   iommu->strbuf_regs + STRBUF_FSYNC);
 	upa_readq(iommu->sbus_control_reg);
 	upa_readq(iommu->sbus_control_reg);
-	while (iommu->strbuf_flushflag == 0UL)
+
+	limit = 100000;
+	while (iommu->strbuf_flushflag == 0UL) {
+		limit--;
+		if (!limit)
+			break;
+		udelay(1);
 		membar("#LoadLoad");
 		membar("#LoadLoad");
+	}
+	if (!limit)
+		printk(KERN_WARNING "sbus_strbuf_flush: flushflag timeout "
+		       "vaddr[%08x] npages[%ld]\n",
+		       base, npages);
 }
 }
 
 
 static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages)
 static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages)
@@ -406,7 +421,7 @@ void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size,
 
 
 	spin_lock_irqsave(&iommu->lock, flags);
 	spin_lock_irqsave(&iommu->lock, flags);
 	free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT);
 	free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT);
-	strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT);
+	sbus_strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 }
 
 
@@ -569,7 +584,7 @@ void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int
 	iommu = sdev->bus->iommu;
 	iommu = sdev->bus->iommu;
 	spin_lock_irqsave(&iommu->lock, flags);
 	spin_lock_irqsave(&iommu->lock, flags);
 	free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT);
 	free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT);
-	strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT);
+	sbus_strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 }
 
 
@@ -581,7 +596,7 @@ void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t base, size_t
 	size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK));
 	size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK));
 
 
 	spin_lock_irqsave(&iommu->lock, flags);
 	spin_lock_irqsave(&iommu->lock, flags);
-	strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT);
+	sbus_strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 }
 
 
@@ -605,7 +620,7 @@ void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int
 	size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base;
 	size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base;
 
 
 	spin_lock_irqsave(&iommu->lock, flags);
 	spin_lock_irqsave(&iommu->lock, flags);
-	strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT);
+	sbus_strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 }
 
 

+ 11 - 0
arch/sparc64/kernel/setup.c

@@ -383,6 +383,17 @@ static void __init process_switch(char c)
 		/* Use PROM debug console. */
 		/* Use PROM debug console. */
 		register_console(&prom_debug_console);
 		register_console(&prom_debug_console);
 		break;
 		break;
+	case 'P':
+		/* Force UltraSPARC-III P-Cache on. */
+		if (tlb_type != cheetah) {
+			printk("BOOT: Ignoring P-Cache force option.\n");
+			break;
+		}
+		cheetah_pcache_forced_on = 1;
+		add_taint(TAINT_MACHINE_CHECK);
+		cheetah_enable_pcache();
+		break;
+
 	default:
 	default:
 		printk("Unknown boot switch (-%c)\n", c);
 		printk("Unknown boot switch (-%c)\n", c);
 		break;
 		break;

+ 3 - 0
arch/sparc64/kernel/smp.c

@@ -123,6 +123,9 @@ void __init smp_callin(void)
 
 
 	smp_setup_percpu_timer();
 	smp_setup_percpu_timer();
 
 
+	if (cheetah_pcache_forced_on)
+		cheetah_enable_pcache();
+
 	local_irq_enable();
 	local_irq_enable();
 
 
 	calibrate_delay();
 	calibrate_delay();

+ 19 - 0
arch/sparc64/kernel/traps.c

@@ -421,6 +421,25 @@ asmlinkage void cee_log(unsigned long ce_status,
 	}
 	}
 }
 }
 
 
+int cheetah_pcache_forced_on;
+
+void cheetah_enable_pcache(void)
+{
+	unsigned long dcr;
+
+	printk("CHEETAH: Enabling P-Cache on cpu %d.\n",
+	       smp_processor_id());
+
+	__asm__ __volatile__("ldxa [%%g0] %1, %0"
+			     : "=r" (dcr)
+			     : "i" (ASI_DCU_CONTROL_REG));
+	dcr |= (DCU_PE | DCU_HPE | DCU_SPE | DCU_SL);
+	__asm__ __volatile__("stxa %0, [%%g0] %1\n\t"
+			     "membar #Sync"
+			     : /* no outputs */
+			     : "r" (dcr), "i" (ASI_DCU_CONTROL_REG));
+}
+
 /* Cheetah error trap handling. */
 /* Cheetah error trap handling. */
 static unsigned long ecache_flush_physbase;
 static unsigned long ecache_flush_physbase;
 static unsigned long ecache_flush_linesize;
 static unsigned long ecache_flush_linesize;

+ 0 - 4
arch/um/Kconfig.debug

@@ -2,10 +2,6 @@ menu "Kernel hacking"
 
 
 source "lib/Kconfig.debug"
 source "lib/Kconfig.debug"
 
 
-config FRAME_POINTER
-	bool
-	default y if DEBUG_INFO
-
 config PT_PROXY
 config PT_PROXY
 	bool "Enable ptrace proxy"
 	bool "Enable ptrace proxy"
 	depends on XTERM_CHAN && DEBUG_INFO && MODE_TT
 	depends on XTERM_CHAN && DEBUG_INFO && MODE_TT

+ 4 - 0
arch/um/Kconfig_x86_64

@@ -6,6 +6,10 @@ config 64BIT
 	bool
 	bool
 	default y
 	default y
 
 
+config TOP_ADDR
+ 	hex
+	default 0x80000000
+
 config 3_LEVEL_PGTABLES
 config 3_LEVEL_PGTABLES
        bool
        bool
        default y
        default y

+ 15 - 7
arch/um/drivers/chan_kern.c

@@ -20,9 +20,17 @@
 #include "os.h"
 #include "os.h"
 
 
 #ifdef CONFIG_NOCONFIG_CHAN
 #ifdef CONFIG_NOCONFIG_CHAN
+
+/* The printk's here are wrong because we are complaining that there is no
+ * output device, but printk is printing to that output device.  The user will
+ * never see the error.  printf would be better, except it can't run on a
+ * kernel stack because it will overflow it.
+ * Use printk for now since that will avoid crashing.
+ */
+
 static void *not_configged_init(char *str, int device, struct chan_opts *opts)
 static void *not_configged_init(char *str, int device, struct chan_opts *opts)
 {
 {
-	printf(KERN_ERR "Using a channel type which is configured out of "
+	printk(KERN_ERR "Using a channel type which is configured out of "
 	       "UML\n");
 	       "UML\n");
 	return(NULL);
 	return(NULL);
 }
 }
@@ -30,27 +38,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
 static int not_configged_open(int input, int output, int primary, void *data,
 static int not_configged_open(int input, int output, int primary, void *data,
 			      char **dev_out)
 			      char **dev_out)
 {
 {
-	printf(KERN_ERR "Using a channel type which is configured out of "
+	printk(KERN_ERR "Using a channel type which is configured out of "
 	       "UML\n");
 	       "UML\n");
 	return(-ENODEV);
 	return(-ENODEV);
 }
 }
 
 
 static void not_configged_close(int fd, void *data)
 static void not_configged_close(int fd, void *data)
 {
 {
-	printf(KERN_ERR "Using a channel type which is configured out of "
+	printk(KERN_ERR "Using a channel type which is configured out of "
 	       "UML\n");
 	       "UML\n");
 }
 }
 
 
 static int not_configged_read(int fd, char *c_out, void *data)
 static int not_configged_read(int fd, char *c_out, void *data)
 {
 {
-	printf(KERN_ERR "Using a channel type which is configured out of "
+	printk(KERN_ERR "Using a channel type which is configured out of "
 	       "UML\n");
 	       "UML\n");
 	return(-EIO);
 	return(-EIO);
 }
 }
 
 
 static int not_configged_write(int fd, const char *buf, int len, void *data)
 static int not_configged_write(int fd, const char *buf, int len, void *data)
 {
 {
-	printf(KERN_ERR "Using a channel type which is configured out of "
+	printk(KERN_ERR "Using a channel type which is configured out of "
 	       "UML\n");
 	       "UML\n");
 	return(-EIO);
 	return(-EIO);
 }
 }
@@ -58,7 +66,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data)
 static int not_configged_console_write(int fd, const char *buf, int len,
 static int not_configged_console_write(int fd, const char *buf, int len,
 				       void *data)
 				       void *data)
 {
 {
-	printf(KERN_ERR "Using a channel type which is configured out of "
+	printk(KERN_ERR "Using a channel type which is configured out of "
 	       "UML\n");
 	       "UML\n");
 	return(-EIO);
 	return(-EIO);
 }
 }
@@ -66,7 +74,7 @@ static int not_configged_console_write(int fd, const char *buf, int len,
 static int not_configged_window_size(int fd, void *data, unsigned short *rows,
 static int not_configged_window_size(int fd, void *data, unsigned short *rows,
 				     unsigned short *cols)
 				     unsigned short *cols)
 {
 {
-	printf(KERN_ERR "Using a channel type which is configured out of "
+	printk(KERN_ERR "Using a channel type which is configured out of "
 	       "UML\n");
 	       "UML\n");
 	return(-ENODEV);
 	return(-ENODEV);
 }
 }

+ 1 - 3
arch/um/drivers/mcast_kern.c

@@ -73,7 +73,6 @@ int mcast_setup(char *str, char **mac_out, void *data)
 	struct mcast_init *init = data;
 	struct mcast_init *init = data;
 	char *port_str = NULL, *ttl_str = NULL, *remain;
 	char *port_str = NULL, *ttl_str = NULL, *remain;
 	char *last;
 	char *last;
-	int n;
 
 
 	*init = ((struct mcast_init)
 	*init = ((struct mcast_init)
 		{ .addr 	= "239.192.168.1",
 		{ .addr 	= "239.192.168.1",
@@ -89,13 +88,12 @@ int mcast_setup(char *str, char **mac_out, void *data)
 	}
 	}
 	
 	
 	if(port_str != NULL){
 	if(port_str != NULL){
-		n = simple_strtoul(port_str, &last, 10);
+		init->port = simple_strtoul(port_str, &last, 10);
 		if((*last != '\0') || (last == port_str)){
 		if((*last != '\0') || (last == port_str)){
 			printk(KERN_ERR "mcast_setup - Bad port : '%s'\n", 
 			printk(KERN_ERR "mcast_setup - Bad port : '%s'\n", 
 			       port_str);
 			       port_str);
 			return(0);
 			return(0);
 		}
 		}
-		init->port = htons(n);
 	}
 	}
 
 
 	if(ttl_str != NULL){
 	if(ttl_str != NULL){

+ 15 - 32
arch/um/drivers/mcast_user.c

@@ -38,7 +38,7 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port)
 	}
 	}
 	sin->sin_family = AF_INET;
 	sin->sin_family = AF_INET;
 	sin->sin_addr.s_addr = in_aton(addr);
 	sin->sin_addr.s_addr = in_aton(addr);
-	sin->sin_port = port;
+	sin->sin_port = htons(port);
 	return(sin);
 	return(sin);
 }
 }
 
 
@@ -55,28 +55,25 @@ static int mcast_open(void *data)
 	struct mcast_data *pri = data;
 	struct mcast_data *pri = data;
 	struct sockaddr_in *sin = pri->mcast_addr;
 	struct sockaddr_in *sin = pri->mcast_addr;
 	struct ip_mreq mreq;
 	struct ip_mreq mreq;
-	int fd, yes = 1;
+	int fd = -EINVAL, yes = 1, err = -EINVAL;;
 
 
 
 
-	if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) {
-		fd = -EINVAL;
+	if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0))
 		goto out;
 		goto out;
-	}
 
 
 	fd = socket(AF_INET, SOCK_DGRAM, 0);
 	fd = socket(AF_INET, SOCK_DGRAM, 0);
+
 	if (fd < 0){
 	if (fd < 0){
 		printk("mcast_open : data socket failed, errno = %d\n", 
 		printk("mcast_open : data socket failed, errno = %d\n", 
 		       errno);
 		       errno);
-		fd = -ENOMEM;
+		fd = -errno;
 		goto out;
 		goto out;
 	}
 	}
 
 
 	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
 	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
 		printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
 		printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
 			errno);
 			errno);
-		os_close_file(fd);
-		fd = -EINVAL;
-		goto out;
+		goto out_close;
 	}
 	}
 
 
 	/* set ttl according to config */
 	/* set ttl according to config */
@@ -84,26 +81,20 @@ static int mcast_open(void *data)
 		       sizeof(pri->ttl)) < 0) {
 		       sizeof(pri->ttl)) < 0) {
 		printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
 		printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
 			errno);
 			errno);
-		os_close_file(fd);
-		fd = -EINVAL;
-		goto out;
+		goto out_close;
 	}
 	}
 
 
 	/* set LOOP, so data does get fed back to local sockets */
 	/* set LOOP, so data does get fed back to local sockets */
 	if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
 	if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
 		printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
 		printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
 			errno);
 			errno);
-		os_close_file(fd);
-		fd = -EINVAL;
-		goto out;
+		goto out_close;
 	}
 	}
 
 
 	/* bind socket to mcast address */
 	/* bind socket to mcast address */
 	if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
 	if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
 		printk("mcast_open : data bind failed, errno = %d\n", errno);
 		printk("mcast_open : data bind failed, errno = %d\n", errno);
-		os_close_file(fd);
-		fd = -EINVAL;
-		goto out;
+		goto out_close;
 	}		
 	}		
 	
 	
 	/* subscribe to the multicast group */
 	/* subscribe to the multicast group */
@@ -117,12 +108,15 @@ static int mcast_open(void *data)
 		       "interface on the host.\n");
 		       "interface on the host.\n");
 		printk("eth0 should be configured in order to use the "
 		printk("eth0 should be configured in order to use the "
 		       "multicast transport.\n");
 		       "multicast transport.\n");
-		os_close_file(fd);
-		fd = -EINVAL;
+                goto out_close;
 	}
 	}
 
 
  out:
  out:
-	return(fd);
+	return fd;
+
+ out_close:
+        os_close_file(fd);
+        return err;
 }
 }
 
 
 static void mcast_close(int fd, void *data)
 static void mcast_close(int fd, void *data)
@@ -164,14 +158,3 @@ struct net_user_info mcast_user_info = {
 	.delete_address = NULL,
 	.delete_address = NULL,
 	.max_packet	= MAX_PACKET - ETH_HEADER_OTHER
 	.max_packet	= MAX_PACKET - ETH_HEADER_OTHER
 };
 };
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */

+ 11 - 5
arch/um/drivers/random.c

@@ -1,5 +1,10 @@
-/* Much of this ripped from hw_random.c */
-
+/* Copyright (C) 2005 Jeff Dike <jdike@addtoit.com> */
+/* Much of this ripped from drivers/char/hw_random.c, see there for other
+ * copyright.
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ */
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
 #include <linux/miscdevice.h>
@@ -12,8 +17,6 @@
  */
  */
 #define RNG_VERSION "1.0.0"
 #define RNG_VERSION "1.0.0"
 #define RNG_MODULE_NAME "random"
 #define RNG_MODULE_NAME "random"
-#define RNG_DRIVER_NAME   RNG_MODULE_NAME " virtual driver " RNG_VERSION
-#define PFX RNG_MODULE_NAME ": "
 
 
 #define RNG_MISCDEV_MINOR		183 /* official */
 #define RNG_MISCDEV_MINOR		183 /* official */
 
 
@@ -98,7 +101,7 @@ static int __init rng_init (void)
 
 
 	err = misc_register (&rng_miscdev);
 	err = misc_register (&rng_miscdev);
 	if (err) {
 	if (err) {
-		printk (KERN_ERR PFX "misc device register failed\n");
+		printk (KERN_ERR RNG_MODULE_NAME ": misc device register failed\n");
 		goto err_out_cleanup_hw;
 		goto err_out_cleanup_hw;
 	}
 	}
 
 
@@ -120,3 +123,6 @@ static void __exit rng_cleanup (void)
 
 
 module_init (rng_init);
 module_init (rng_init);
 module_exit (rng_cleanup);
 module_exit (rng_cleanup);
+
+MODULE_DESCRIPTION("UML Host Random Number Generator (RNG) driver");
+MODULE_LICENSE("GPL");

+ 0 - 1
arch/um/drivers/ssl.c

@@ -22,7 +22,6 @@
 #include "init.h"
 #include "init.h"
 #include "irq_user.h"
 #include "irq_user.h"
 #include "mconsole_kern.h"
 #include "mconsole_kern.h"
-#include "2_5compat.h"
 
 
 static int ssl_version = 1;
 static int ssl_version = 1;
 
 

+ 0 - 1
arch/um/drivers/stdio_console.c

@@ -28,7 +28,6 @@
 #include "irq_user.h"
 #include "irq_user.h"
 #include "mconsole_kern.h"
 #include "mconsole_kern.h"
 #include "init.h"
 #include "init.h"
-#include "2_5compat.h"
 
 
 #define MAX_TTYS (16)
 #define MAX_TTYS (16)
 
 

+ 6 - 297
arch/um/drivers/ubd_kern.c

@@ -49,13 +49,12 @@
 #include "irq_user.h"
 #include "irq_user.h"
 #include "irq_kern.h"
 #include "irq_kern.h"
 #include "ubd_user.h"
 #include "ubd_user.h"
-#include "2_5compat.h"
 #include "os.h"
 #include "os.h"
 #include "mem.h"
 #include "mem.h"
 #include "mem_kern.h"
 #include "mem_kern.h"
 #include "cow.h"
 #include "cow.h"
 
 
-enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
+enum ubd_req { UBD_READ, UBD_WRITE };
 
 
 struct io_thread_req {
 struct io_thread_req {
 	enum ubd_req op;
 	enum ubd_req op;
@@ -68,8 +67,6 @@ struct io_thread_req {
 	unsigned long sector_mask;
 	unsigned long sector_mask;
 	unsigned long long cow_offset;
 	unsigned long long cow_offset;
 	unsigned long bitmap_words[2];
 	unsigned long bitmap_words[2];
-	int map_fd;
-	unsigned long long map_offset;
 	int error;
 	int error;
 };
 };
 
 
@@ -122,10 +119,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
 
 
 #define MAX_DEV (8)
 #define MAX_DEV (8)
 
 
-/* Changed in early boot */
-static int ubd_do_mmap = 0;
-#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE
-
 static struct block_device_operations ubd_blops = {
 static struct block_device_operations ubd_blops = {
         .owner		= THIS_MODULE,
         .owner		= THIS_MODULE,
         .open		= ubd_open,
         .open		= ubd_open,
@@ -175,12 +168,6 @@ struct ubd {
 	int no_cow;
 	int no_cow;
 	struct cow cow;
 	struct cow cow;
 	struct platform_device pdev;
 	struct platform_device pdev;
-
-	int map_writes;
-	int map_reads;
-	int nomap_writes;
-	int nomap_reads;
-	int write_maps;
 };
 };
 
 
 #define DEFAULT_COW { \
 #define DEFAULT_COW { \
@@ -200,11 +187,6 @@ struct ubd {
 	.openflags =		OPEN_FLAGS, \
 	.openflags =		OPEN_FLAGS, \
         .no_cow =               0, \
         .no_cow =               0, \
         .cow =			DEFAULT_COW, \
         .cow =			DEFAULT_COW, \
-	.map_writes		= 0, \
-	.map_reads		= 0, \
-	.nomap_writes		= 0, \
-	.nomap_reads		= 0, \
-	.write_maps		= 0, \
 }
 }
 
 
 struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
 struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
@@ -314,13 +296,6 @@ static int ubd_setup_common(char *str, int *index_out)
 		int major;
 		int major;
 
 
 		str++;
 		str++;
-		if(!strcmp(str, "mmap")){
-			CHOOSE_MODE(printk("mmap not supported by the ubd "
-					   "driver in tt mode\n"),
-				    ubd_do_mmap = 1);
-			return(0);
-		}
-
 		if(!strcmp(str, "sync")){
 		if(!strcmp(str, "sync")){
 			global_openflags = of_sync(global_openflags);
 			global_openflags = of_sync(global_openflags);
 			return(0);
 			return(0);
@@ -464,9 +439,9 @@ static int udb_setup(char *str)
 __setup("udb", udb_setup);
 __setup("udb", udb_setup);
 __uml_help(udb_setup,
 __uml_help(udb_setup,
 "udb\n"
 "udb\n"
-"    This option is here solely to catch ubd -> udb typos, which can be\n\n"
-"    to impossible to catch visually unless you specifically look for\n\n"
-"    them.  The only result of any option starting with 'udb' is an error\n\n"
+"    This option is here solely to catch ubd -> udb typos, which can be\n"
+"    to impossible to catch visually unless you specifically look for\n"
+"    them.  The only result of any option starting with 'udb' is an error\n"
 "    in the boot output.\n\n"
 "    in the boot output.\n\n"
 );
 );
 
 
@@ -524,7 +499,7 @@ static void ubd_handler(void)
 {
 {
 	struct io_thread_req req;
 	struct io_thread_req req;
 	struct request *rq = elv_next_request(ubd_queue);
 	struct request *rq = elv_next_request(ubd_queue);
-	int n, err;
+	int n;
 
 
 	do_ubd = NULL;
 	do_ubd = NULL;
 	intr_count++;
 	intr_count++;
@@ -538,19 +513,6 @@ static void ubd_handler(void)
 		return;
 		return;
 	}
 	}
         
         
-	if((req.op != UBD_MMAP) &&
-	   ((req.offset != ((__u64) (rq->sector)) << 9) ||
-	    (req.length != (rq->current_nr_sectors) << 9)))
-		panic("I/O op mismatch");
-	
-	if(req.map_fd != -1){
-		err = physmem_subst_mapping(req.buffer, req.map_fd,
-					    req.map_offset, 1);
-		if(err)
-			printk("ubd_handler - physmem_subst_mapping failed, "
-			       "err = %d\n", -err);
-	}
-
 	ubd_finish(rq, req.error);
 	ubd_finish(rq, req.error);
 	reactivate_fd(thread_fd, UBD_IRQ);	
 	reactivate_fd(thread_fd, UBD_IRQ);	
 	do_ubd_request(ubd_queue);
 	do_ubd_request(ubd_queue);
@@ -583,14 +545,10 @@ static int ubd_file_size(struct ubd *dev, __u64 *size_out)
 
 
 static void ubd_close(struct ubd *dev)
 static void ubd_close(struct ubd *dev)
 {
 {
-	if(ubd_do_mmap)
-		physmem_forget_descriptor(dev->fd);
 	os_close_file(dev->fd);
 	os_close_file(dev->fd);
 	if(dev->cow.file == NULL)
 	if(dev->cow.file == NULL)
 		return;
 		return;
 
 
-	if(ubd_do_mmap)
-		physmem_forget_descriptor(dev->cow.fd);
 	os_close_file(dev->cow.fd);
 	os_close_file(dev->cow.fd);
 	vfree(dev->cow.bitmap);
 	vfree(dev->cow.bitmap);
 	dev->cow.bitmap = NULL;
 	dev->cow.bitmap = NULL;
@@ -1010,94 +968,13 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
 			   req->bitmap_words, bitmap_len);
 			   req->bitmap_words, bitmap_len);
 }
 }
 
 
-static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
-{
-	__u64 sector;
-	unsigned char *bitmap;
-	int bit, i;
-
-	/* mmap must have been requested on the command line */
-	if(!ubd_do_mmap)
-		return(-1);
-
-	/* The buffer must be page aligned */
-	if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
-		return(-1);
-
-	/* The request must be a page long */
-	if((req->current_nr_sectors << 9) != PAGE_SIZE)
-		return(-1);
-
-	if(dev->cow.file == NULL)
-		return(dev->fd);
-
-	sector = offset >> 9;
-	bitmap = (unsigned char *) dev->cow.bitmap;
-	bit = ubd_test_bit(sector, bitmap);
-
-	for(i = 1; i < req->current_nr_sectors; i++){
-		if(ubd_test_bit(sector + i, bitmap) != bit)
-			return(-1);
-	}
-
-	if(bit || (rq_data_dir(req) == WRITE))
-		offset += dev->cow.data_offset;
-
-	/* The data on disk must be page aligned */
-	if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
-		return(-1);
-
-	return(bit ? dev->fd : dev->cow.fd);
-}
-
-static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset,
-				struct request *req,
-				struct io_thread_req *io_req)
-{
-	int err;
-
-	if(rq_data_dir(req) == WRITE){
-		/* Writes are almost no-ops since the new data is already in the
-		 * host page cache
-		 */
-		dev->map_writes++;
-		if(dev->cow.file != NULL)
-			cowify_bitmap(io_req->offset, io_req->length,
-				      &io_req->sector_mask, &io_req->cow_offset,
-				      dev->cow.bitmap, dev->cow.bitmap_offset,
-				      io_req->bitmap_words,
-				      dev->cow.bitmap_len);
-	}
-	else {
-		int w;
-
-		if((dev->cow.file != NULL) && (fd == dev->cow.fd))
-			w = 0;
-		else w = dev->openflags.w;
-
-		if((dev->cow.file != NULL) && (fd == dev->fd))
-			offset += dev->cow.data_offset;
-
-		err = physmem_subst_mapping(req->buffer, fd, offset, w);
-		if(err){
-			printk("physmem_subst_mapping failed, err = %d\n",
-			       -err);
-			return(1);
-		}
-		dev->map_reads++;
-	}
-	io_req->op = UBD_MMAP;
-	io_req->buffer = req->buffer;
-	return(0);
-}
-
 /* Called with ubd_io_lock held */
 /* Called with ubd_io_lock held */
 static int prepare_request(struct request *req, struct io_thread_req *io_req)
 static int prepare_request(struct request *req, struct io_thread_req *io_req)
 {
 {
 	struct gendisk *disk = req->rq_disk;
 	struct gendisk *disk = req->rq_disk;
 	struct ubd *dev = disk->private_data;
 	struct ubd *dev = disk->private_data;
 	__u64 offset;
 	__u64 offset;
-	int len, fd;
+	int len;
 
 
 	if(req->rq_status == RQ_INACTIVE) return(1);
 	if(req->rq_status == RQ_INACTIVE) return(1);
 
 
@@ -1114,34 +991,12 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
 
 
 	io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
 	io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
 	io_req->fds[1] = dev->fd;
 	io_req->fds[1] = dev->fd;
-	io_req->map_fd = -1;
 	io_req->cow_offset = -1;
 	io_req->cow_offset = -1;
 	io_req->offset = offset;
 	io_req->offset = offset;
 	io_req->length = len;
 	io_req->length = len;
 	io_req->error = 0;
 	io_req->error = 0;
 	io_req->sector_mask = 0;
 	io_req->sector_mask = 0;
 
 
-	fd = mmap_fd(req, dev, io_req->offset);
-	if(fd > 0){
-		/* If mmapping is otherwise OK, but the first access to the
-		 * page is a write, then it's not mapped in yet.  So we have
-		 * to write the data to disk first, then we can map the disk
-		 * page in and continue normally from there.
-		 */
-		if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer)){
-			io_req->map_fd = dev->fd;
-			io_req->map_offset = io_req->offset +
-				dev->cow.data_offset;
-			dev->write_maps++;
-		}
-		else return(prepare_mmap_request(dev, fd, io_req->offset, req,
-						 io_req));
-	}
-
-	if(rq_data_dir(req) == READ)
-		dev->nomap_reads++;
-	else dev->nomap_writes++;
-
 	io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
 	io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
 	io_req->offsets[0] = 0;
 	io_req->offsets[0] = 0;
 	io_req->offsets[1] = dev->cow.data_offset;
 	io_req->offsets[1] = dev->cow.data_offset;
@@ -1229,143 +1084,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
 	return(-EINVAL);
 	return(-EINVAL);
 }
 }
 
 
-static int ubd_check_remapped(int fd, unsigned long address, int is_write,
-			      __u64 offset)
-{
-	__u64 bitmap_offset;
-	unsigned long new_bitmap[2];
-	int i, err, n;
-
-	/* If it's not a write access, we can't do anything about it */
-	if(!is_write)
-		return(0);
-
-	/* We have a write */
-	for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){
-		struct ubd *dev = &ubd_dev[i];
-
-		if((dev->fd != fd) && (dev->cow.fd != fd))
-			continue;
-
-		/* It's a write to a ubd device */
-
-		/* This should be impossible now */
-		if(!dev->openflags.w){
-			/* It's a write access on a read-only device - probably
-			 * shouldn't happen.  If the kernel is trying to change
-			 * something with no intention of writing it back out,
-			 * then this message will clue us in that this needs
-			 * fixing
-			 */
-			printk("Write access to mapped page from readonly ubd "
-			       "device %d\n", i);
-			return(0);
-		}
-
-		/* It's a write to a writeable ubd device - it must be COWed
-		 * because, otherwise, the page would have been mapped in
-		 * writeable
-		 */
-
-		if(!dev->cow.file)
-			panic("Write fault on writeable non-COW ubd device %d",
-			      i);
-
-		/* It should also be an access to the backing file since the
-		 * COW pages should be mapped in read-write
-		 */
-
-		if(fd == dev->fd)
-			panic("Write fault on a backing page of ubd "
-			      "device %d\n", i);
-
-		/* So, we do the write, copying the backing data to the COW
-		 * file...
-		 */
-
-		err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
-		if(err < 0)
-			panic("Couldn't seek to %lld in COW file of ubd "
-			      "device %d, err = %d",
-			      offset + dev->cow.data_offset, i, -err);
-
-		n = os_write_file(dev->fd, (void *) address, PAGE_SIZE);
-		if(n != PAGE_SIZE)
-			panic("Couldn't copy data to COW file of ubd "
-			      "device %d, err = %d", i, -n);
-
-		/* ... updating the COW bitmap... */
-
-		cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset,
-			      dev->cow.bitmap, dev->cow.bitmap_offset,
-			      new_bitmap, dev->cow.bitmap_len);
-
-		err = os_seek_file(dev->fd, bitmap_offset);
-		if(err < 0)
-			panic("Couldn't seek to %lld in COW file of ubd "
-			      "device %d, err = %d", bitmap_offset, i, -err);
-
-		n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap));
-		if(n != sizeof(new_bitmap))
-			panic("Couldn't update bitmap  of ubd device %d, "
-			      "err = %d", i, -n);
-
-		/* Maybe we can map the COW page in, and maybe we can't.  If
-		 * it is a pre-V3 COW file, we can't, since the alignment will
-		 * be wrong.  If it is a V3 or later COW file which has been
-		 * moved to a system with a larger page size, then maybe we
-		 * can't, depending on the exact location of the page.
-		 */
-
-		offset += dev->cow.data_offset;
-
-		/* Remove the remapping, putting the original anonymous page
-		 * back.  If the COW file can be mapped in, that is done.
-		 * Otherwise, the COW page is read in.
-		 */
-
-		if(!physmem_remove_mapping((void *) address))
-			panic("Address 0x%lx not remapped by ubd device %d",
-			      address, i);
-		if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
-			physmem_subst_mapping((void *) address, dev->fd,
-					      offset, 1);
-		else {
-			err = os_seek_file(dev->fd, offset);
-			if(err < 0)
-				panic("Couldn't seek to %lld in COW file of "
-				      "ubd device %d, err = %d", offset, i,
-				      -err);
-
-			n = os_read_file(dev->fd, (void *) address, PAGE_SIZE);
-			if(n != PAGE_SIZE)
-				panic("Failed to read page from offset %llx of "
-				      "COW file of ubd device %d, err = %d",
-				      offset, i, -n);
-		}
-
-		return(1);
-	}
-
-	/* It's not a write on a ubd device */
-	return(0);
-}
-
-static struct remapper ubd_remapper = {
-	.list	= LIST_HEAD_INIT(ubd_remapper.list),
-	.proc	= ubd_check_remapped,
-};
-
-static int ubd_remapper_setup(void)
-{
-	if(ubd_do_mmap)
-		register_remapper(&ubd_remapper);
-
-	return(0);
-}
-
-__initcall(ubd_remapper_setup);
-
 static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
 static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
 {
 {
 	struct uml_stat buf1, buf2;
 	struct uml_stat buf1, buf2;
@@ -1568,15 +1286,6 @@ void do_io(struct io_thread_req *req)
 	int err;
 	int err;
 	__u64 off;
 	__u64 off;
 
 
-	if(req->op == UBD_MMAP){
-		/* Touch the page to force the host to do any necessary IO to
-		 * get it into memory
-		 */
-		n = *((volatile int *) req->buffer);
-		req->error = update_bitmap(req);
-		return;
-	}
-
 	nsectors = req->length / req->sectorsize;
 	nsectors = req->length / req->sectorsize;
 	start = 0;
 	start = 0;
 	do {
 	do {

+ 0 - 24
arch/um/include/2_5compat.h

@@ -1,24 +0,0 @@
-/* 
- * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __2_5_COMPAT_H__
-#define __2_5_COMPAT_H__
-
-#define INIT_HARDSECT(arr, maj, sizes)
-
-#define SET_PRI(task) do ; while(0)
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */

+ 1 - 1
arch/um/include/sysdep-i386/ptrace.h

@@ -31,7 +31,6 @@ extern int sysemu_supported;
 #ifdef UML_CONFIG_MODE_SKAS
 #ifdef UML_CONFIG_MODE_SKAS
 
 
 #include "skas_ptregs.h"
 #include "skas_ptregs.h"
-#include "sysdep/faultinfo.h"
 
 
 #define REGS_IP(r) ((r)[HOST_IP])
 #define REGS_IP(r) ((r)[HOST_IP])
 #define REGS_SP(r) ((r)[HOST_SP])
 #define REGS_SP(r) ((r)[HOST_SP])
@@ -59,6 +58,7 @@ extern int sysemu_supported;
 #define PTRACE_SYSEMU_SINGLESTEP 32
 #define PTRACE_SYSEMU_SINGLESTEP 32
 #endif
 #endif
 
 
+#include "sysdep/faultinfo.h"
 #include "choose-mode.h"
 #include "choose-mode.h"
 
 
 union uml_pt_regs {
 union uml_pt_regs {

+ 10 - 16
arch/um/include/sysdep-x86_64/checksum.h

@@ -9,8 +9,6 @@
 #include "linux/in6.h"
 #include "linux/in6.h"
 #include "asm/uaccess.h"
 #include "asm/uaccess.h"
 
 
-extern unsigned int csum_partial_copy_from(const unsigned char *src, unsigned char *dst, int len,
-					   int sum, int *err_ptr);
 extern unsigned csum_partial(const unsigned char *buff, unsigned len,
 extern unsigned csum_partial(const unsigned char *buff, unsigned len,
                              unsigned sum);
                              unsigned sum);
 
 
@@ -31,10 +29,15 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *
 }
 }
 
 
 static __inline__
 static __inline__
-unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
-					 int len, int sum, int *err_ptr)
+unsigned int csum_partial_copy_from_user(const unsigned char *src,
+                                         unsigned char *dst, int len, int sum,
+                                         int *err_ptr)
 {
 {
-	return csum_partial_copy_from(src, dst, len, sum, err_ptr);
+        if(copy_from_user(dst, src, len)){
+                *err_ptr = -EFAULT;
+                return(-1);
+        }
+        return csum_partial(dst, len, sum);
 }
 }
 
 
 /**
 /**
@@ -137,15 +140,6 @@ static inline unsigned add32_with_carry(unsigned a, unsigned b)
         return a;
         return a;
 }
 }
 
 
-#endif
+extern unsigned short ip_compute_csum(unsigned char * buff, int len);
 
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+#endif

+ 26 - 36
arch/um/include/sysdep-x86_64/ptrace.h

@@ -135,6 +135,7 @@ extern int mode_tt;
 	__CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
 	__CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
 #define UPT_SC(r) ((r)->tt.sc)
 #define UPT_SC(r) ((r)->tt.sc)
 #define UPT_SYSCALL_NR(r) __CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
 #define UPT_SYSCALL_NR(r) __CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
+#define UPT_SYSCALL_RET(r) UPT_RAX(r)
 
 
 extern int user_context(unsigned long sp);
 extern int user_context(unsigned long sp);
 
 
@@ -196,32 +197,32 @@ struct syscall_args {
 
 
 
 
 #define UPT_SET(regs, reg, val) \
 #define UPT_SET(regs, reg, val) \
-        ({      unsigned long val; \
+        ({      unsigned long __upt_val = val; \
                 switch(reg){ \
                 switch(reg){ \
-		case R8: UPT_R8(regs) = val; break; \
-		case R9: UPT_R9(regs) = val; break; \
-		case R10: UPT_R10(regs) = val; break; \
-		case R11: UPT_R11(regs) = val; break; \
-		case R12: UPT_R12(regs) = val; break; \
-		case R13: UPT_R13(regs) = val; break; \
-		case R14: UPT_R14(regs) = val; break; \
-		case R15: UPT_R15(regs) = val; break; \
-                case RIP: UPT_IP(regs) = val; break; \
-                case RSP: UPT_SP(regs) = val; break; \
-                case RAX: UPT_RAX(regs) = val; break; \
-                case RBX: UPT_RBX(regs) = val; break; \
-                case RCX: UPT_RCX(regs) = val; break; \
-                case RDX: UPT_RDX(regs) = val; break; \
-                case RSI: UPT_RSI(regs) = val; break; \
-                case RDI: UPT_RDI(regs) = val; break; \
-                case RBP: UPT_RBP(regs) = val; break; \
-                case ORIG_RAX: UPT_ORIG_RAX(regs) = val; break; \
-                case CS: UPT_CS(regs) = val; break; \
-                case DS: UPT_DS(regs) = val; break; \
-                case ES: UPT_ES(regs) = val; break; \
-                case FS: UPT_FS(regs) = val; break; \
-                case GS: UPT_GS(regs) = val; break; \
-                case EFLAGS: UPT_EFLAGS(regs) = val; break; \
+                case R8: UPT_R8(regs) = __upt_val; break; \
+                case R9: UPT_R9(regs) = __upt_val; break; \
+                case R10: UPT_R10(regs) = __upt_val; break; \
+                case R11: UPT_R11(regs) = __upt_val; break; \
+                case R12: UPT_R12(regs) = __upt_val; break; \
+                case R13: UPT_R13(regs) = __upt_val; break; \
+                case R14: UPT_R14(regs) = __upt_val; break; \
+                case R15: UPT_R15(regs) = __upt_val; break; \
+                case RIP: UPT_IP(regs) = __upt_val; break; \
+                case RSP: UPT_SP(regs) = __upt_val; break; \
+                case RAX: UPT_RAX(regs) = __upt_val; break; \
+                case RBX: UPT_RBX(regs) = __upt_val; break; \
+                case RCX: UPT_RCX(regs) = __upt_val; break; \
+                case RDX: UPT_RDX(regs) = __upt_val; break; \
+                case RSI: UPT_RSI(regs) = __upt_val; break; \
+                case RDI: UPT_RDI(regs) = __upt_val; break; \
+                case RBP: UPT_RBP(regs) = __upt_val; break; \
+                case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \
+                case CS: UPT_CS(regs) = __upt_val; break; \
+                case DS: UPT_DS(regs) = __upt_val; break; \
+                case ES: UPT_ES(regs) = __upt_val; break; \
+                case FS: UPT_FS(regs) = __upt_val; break; \
+                case GS: UPT_GS(regs) = __upt_val; break; \
+                case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \
                 default :  \
                 default :  \
                         panic("Bad register in UPT_SET : %d\n", reg);  \
                         panic("Bad register in UPT_SET : %d\n", reg);  \
 			break; \
 			break; \
@@ -245,14 +246,3 @@ struct syscall_args {
         CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo))
         CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo))
 
 
 #endif
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */

+ 2 - 1
arch/um/include/sysrq.h

@@ -1,6 +1,7 @@
 #ifndef __UM_SYSRQ_H
 #ifndef __UM_SYSRQ_H
 #define __UM_SYSRQ_H
 #define __UM_SYSRQ_H
 
 
-extern void show_trace(unsigned long *stack);
+struct task_struct;
+extern void show_trace(struct task_struct* task, unsigned long *stack);
 
 
 #endif
 #endif

+ 1 - 1
arch/um/kernel/Makefile

@@ -14,7 +14,7 @@ obj-y = config.o exec_kern.o exitcode.o \
 	tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \
 	tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \
 	user_util.o
 	user_util.o
 
 
-obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
+obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
 obj-$(CONFIG_GPROF)	+= gprof_syms.o
 obj-$(CONFIG_GPROF)	+= gprof_syms.o
 obj-$(CONFIG_GCOV)	+= gmon_syms.o
 obj-$(CONFIG_GCOV)	+= gmon_syms.o
 obj-$(CONFIG_TTY_LOG)	+= tty_log.o
 obj-$(CONFIG_TTY_LOG)	+= tty_log.o

+ 0 - 0
arch/um/kernel/checksum.c


+ 0 - 1
arch/um/kernel/exec_kern.c

@@ -16,7 +16,6 @@
 #include "kern.h"
 #include "kern.h"
 #include "irq_user.h"
 #include "irq_user.h"
 #include "tlb.h"
 #include "tlb.h"
-#include "2_5compat.h"
 #include "os.h"
 #include "os.h"
 #include "time_user.h"
 #include "time_user.h"
 #include "choose-mode.h"
 #include "choose-mode.h"

+ 20 - 1
arch/um/kernel/initrd_kern.c → arch/um/kernel/initrd.c

@@ -41,12 +41,31 @@ static int __init uml_initrd_setup(char *line, int *add)
 	return 0;
 	return 0;
 }
 }
 
 
-__uml_setup("initrd=", uml_initrd_setup, 
+__uml_setup("initrd=", uml_initrd_setup,
 "initrd=<initrd image>\n"
 "initrd=<initrd image>\n"
 "    This is used to boot UML from an initrd image.  The argument is the\n"
 "    This is used to boot UML from an initrd image.  The argument is the\n"
 "    name of the file containing the image.\n\n"
 "    name of the file containing the image.\n\n"
 );
 );
 
 
+int load_initrd(char *filename, void *buf, int size)
+{
+	int fd, n;
+
+	fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
+	if(fd < 0){
+		printk("Opening '%s' failed - err = %d\n", filename, -fd);
+		return(-1);
+	}
+	n = os_read_file(fd, buf, size);
+	if(n != size){
+		printk("Read of %d bytes from '%s' failed, err = %d\n", size,
+		       filename, -n);
+		return(-1);
+	}
+
+	os_close_file(fd);
+	return(0);
+}
 /*
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
  * Emacs will notice this stuff at the end of the file and automatically

+ 0 - 46
arch/um/kernel/initrd_user.c

@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-
-#include "user_util.h"
-#include "kern_util.h"
-#include "user.h"
-#include "initrd.h"
-#include "os.h"
-
-int load_initrd(char *filename, void *buf, int size)
-{
-	int fd, n;
-
-	fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
-	if(fd < 0){
-		printk("Opening '%s' failed - err = %d\n", filename, -fd);
-		return(-1);
-	}
-	n = os_read_file(fd, buf, size);
-	if(n != size){
-		printk("Read of %d bytes from '%s' failed, err = %d\n", size,
-		       filename, -n);
-		return(-1);
-	}
-
-	os_close_file(fd);
-	return(0);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */

+ 1 - 0
arch/um/kernel/ksyms.c

@@ -57,6 +57,7 @@ EXPORT_SYMBOL(copy_to_user_tt);
 EXPORT_SYMBOL(strncpy_from_user_skas);
 EXPORT_SYMBOL(strncpy_from_user_skas);
 EXPORT_SYMBOL(copy_to_user_skas);
 EXPORT_SYMBOL(copy_to_user_skas);
 EXPORT_SYMBOL(copy_from_user_skas);
 EXPORT_SYMBOL(copy_from_user_skas);
+EXPORT_SYMBOL(clear_user_skas);
 #endif
 #endif
 EXPORT_SYMBOL(uml_strdup);
 EXPORT_SYMBOL(uml_strdup);
 
 

+ 21 - 19
arch/um/kernel/main.c

@@ -71,7 +71,7 @@ static __init void do_uml_initcalls(void)
 
 
 static void last_ditch_exit(int sig)
 static void last_ditch_exit(int sig)
 {
 {
-	CHOOSE_MODE(kmalloc_ok = 0, (void) 0);
+        kmalloc_ok = 0;
 	signal(SIGINT, SIG_DFL);
 	signal(SIGINT, SIG_DFL);
 	signal(SIGTERM, SIG_DFL);
 	signal(SIGTERM, SIG_DFL);
 	signal(SIGHUP, SIG_DFL);
 	signal(SIGHUP, SIG_DFL);
@@ -87,7 +87,7 @@ int main(int argc, char **argv, char **envp)
 {
 {
 	char **new_argv;
 	char **new_argv;
 	sigset_t mask;
 	sigset_t mask;
-	int ret, i;
+	int ret, i, err;
 
 
 	/* Enable all signals except SIGIO - in some environments, we can
 	/* Enable all signals except SIGIO - in some environments, we can
 	 * enter with some signals blocked
 	 * enter with some signals blocked
@@ -160,27 +160,29 @@ int main(int argc, char **argv, char **envp)
 	 */
 	 */
 	change_sig(SIGPROF, 0);
 	change_sig(SIGPROF, 0);
 
 
-	/* Reboot */
-	if(ret){
-		int err;
-
-		printf("\n");
+        /* This signal stuff used to be in the reboot case.  However,
+         * sometimes a SIGVTALRM can come in when we're halting (reproducably
+         * when writing out gcov information, presumably because that takes
+         * some time) and cause a segfault.
+         */
 
 
-		/* stop timers and set SIG*ALRM to be ignored */
-		disable_timer();
+        /* stop timers and set SIG*ALRM to be ignored */
+        disable_timer();
 
 
-		/* disable SIGIO for the fds and set SIGIO to be ignored */
-		err = deactivate_all_fds();
-		if(err)
-			printf("deactivate_all_fds failed, errno = %d\n",
-			       -err);
+        /* disable SIGIO for the fds and set SIGIO to be ignored */
+        err = deactivate_all_fds();
+        if(err)
+                printf("deactivate_all_fds failed, errno = %d\n", -err);
 
 
-		/* Let any pending signals fire now.  This ensures
-		 * that they won't be delivered after the exec, when
-		 * they are definitely not expected.
-		 */
-		unblock_signals();
+        /* Let any pending signals fire now.  This ensures
+         * that they won't be delivered after the exec, when
+         * they are definitely not expected.
+         */
+        unblock_signals();
 
 
+	/* Reboot */
+	if(ret){
+		printf("\n");
 		execvp(new_argv[0], new_argv);
 		execvp(new_argv[0], new_argv);
 		perror("Failed to exec kernel");
 		perror("Failed to exec kernel");
 		ret = 1;
 		ret = 1;

+ 31 - 9
arch/um/kernel/mem.c

@@ -100,12 +100,37 @@ void mem_init(void)
 #endif
 #endif
 }
 }
 
 
+/*
+ * Create a page table and place a pointer to it in a middle page
+ * directory entry.
+ */
+static void __init one_page_table_init(pmd_t *pmd)
+{
+	if (pmd_none(*pmd)) {
+		pte_t *pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+		set_pmd(pmd, __pmd(_KERNPG_TABLE +
+					   (unsigned long) __pa(pte)));
+		if (pte != pte_offset_kernel(pmd, 0))
+			BUG();
+	}
+}
+
+static void __init one_md_table_init(pud_t *pud)
+{
+#ifdef CONFIG_3_LEVEL_PGTABLES
+	pmd_t *pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+	set_pud(pud, __pud(_KERNPG_TABLE + (unsigned long) __pa(pmd_table)));
+	if (pmd_table != pmd_offset(pud, 0))
+		BUG();
+#endif
+}
+
 static void __init fixrange_init(unsigned long start, unsigned long end, 
 static void __init fixrange_init(unsigned long start, unsigned long end, 
 				 pgd_t *pgd_base)
 				 pgd_t *pgd_base)
 {
 {
 	pgd_t *pgd;
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pmd_t *pmd;
-	pte_t *pte;
 	int i, j;
 	int i, j;
 	unsigned long vaddr;
 	unsigned long vaddr;
 
 
@@ -115,15 +140,12 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
 	pgd = pgd_base + i;
 	pgd = pgd_base + i;
 
 
 	for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
 	for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
-		pmd = (pmd_t *)pgd;
+		pud = pud_offset(pgd, vaddr);
+		if (pud_none(*pud))
+			one_md_table_init(pud);
+		pmd = pmd_offset(pud, vaddr);
 		for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
 		for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
-			if (pmd_none(*pmd)) {
-				pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
-				set_pmd(pmd, __pmd(_KERNPG_TABLE + 
-						   (unsigned long) __pa(pte)));
-				if (pte != pte_offset_kernel(pmd, 0))
-					BUG();
-			}
+			one_page_table_init(pmd);
 			vaddr += PMD_SIZE;
 			vaddr += PMD_SIZE;
 		}
 		}
 		j = 0;
 		j = 0;

+ 0 - 36
arch/um/kernel/process_kern.c

@@ -43,7 +43,6 @@
 #include "tlb.h"
 #include "tlb.h"
 #include "frame_kern.h"
 #include "frame_kern.h"
 #include "sigcontext.h"
 #include "sigcontext.h"
-#include "2_5compat.h"
 #include "os.h"
 #include "os.h"
 #include "mode.h"
 #include "mode.h"
 #include "mode_kern.h"
 #include "mode_kern.h"
@@ -55,18 +54,6 @@
  */
  */
 struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
 struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
 
 
-struct task_struct *get_task(int pid, int require)
-{
-        struct task_struct *ret;
-
-        read_lock(&tasklist_lock);
-	ret = find_task_by_pid(pid);
-        read_unlock(&tasklist_lock);
-
-        if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
-        return(ret);
-}
-
 int external_pid(void *t)
 int external_pid(void *t)
 {
 {
 	struct task_struct *task = t ? t : current;
 	struct task_struct *task = t ? t : current;
@@ -189,7 +176,6 @@ void default_idle(void)
 
 
 	while(1){
 	while(1){
 		/* endless idle loop with no priority at all */
 		/* endless idle loop with no priority at all */
-		SET_PRI(current);
 
 
 		/*
 		/*
 		 * although we are an idle CPU, we do not want to
 		 * although we are an idle CPU, we do not want to
@@ -212,11 +198,6 @@ int page_size(void)
 	return(PAGE_SIZE);
 	return(PAGE_SIZE);
 }
 }
 
 
-unsigned long page_mask(void)
-{
-	return(PAGE_MASK);
-}
-
 void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 
 void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 
 		      pte_t *pte_out)
 		      pte_t *pte_out)
 {
 {
@@ -349,11 +330,6 @@ char *uml_strdup(char *string)
 	return(new);
 	return(new);
 }
 }
 
 
-void *get_init_task(void)
-{
-	return(&init_thread_union.thread_info.task);
-}
-
 int copy_to_user_proc(void __user *to, void *from, int size)
 int copy_to_user_proc(void __user *to, void *from, int size)
 {
 {
 	return(copy_to_user(to, from, size));
 	return(copy_to_user(to, from, size));
@@ -480,15 +456,3 @@ unsigned long arch_align_stack(unsigned long sp)
 	return sp & ~0xf;
 	return sp & ~0xf;
 }
 }
 #endif
 #endif
-
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */

+ 6 - 19
arch/um/kernel/ptrace.c

@@ -28,9 +28,9 @@ static inline void set_singlestepping(struct task_struct *child, int on)
         child->thread.singlestep_syscall = 0;
         child->thread.singlestep_syscall = 0;
 
 
 #ifdef SUBARCH_SET_SINGLESTEPPING
 #ifdef SUBARCH_SET_SINGLESTEPPING
-        SUBARCH_SET_SINGLESTEPPING(child, on)
+        SUBARCH_SET_SINGLESTEPPING(child, on);
 #endif
 #endif
-                }
+}
 
 
 /*
 /*
  * Called by kernel/ptrace.c when detaching..
  * Called by kernel/ptrace.c when detaching..
@@ -83,7 +83,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
 	}
 	}
 
 
 #ifdef SUBACH_PTRACE_SPECIAL
 #ifdef SUBACH_PTRACE_SPECIAL
-        SUBARCH_PTRACE_SPECIAL(child,request,addr,data)
+        SUBARCH_PTRACE_SPECIAL(child,request,addr,data);
 #endif
 #endif
 
 
 	ret = ptrace_check_attach(child, request == PTRACE_KILL);
 	ret = ptrace_check_attach(child, request == PTRACE_KILL);
@@ -322,11 +322,9 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
 					    UPT_SYSCALL_ARG2(regs),
 					    UPT_SYSCALL_ARG2(regs),
 					    UPT_SYSCALL_ARG3(regs),
 					    UPT_SYSCALL_ARG3(regs),
 					    UPT_SYSCALL_ARG4(regs));
 					    UPT_SYSCALL_ARG4(regs));
-		else {
-                        int res = UPT_SYSCALL_RET(regs);
-			audit_syscall_exit(current, AUDITSC_RESULT(res),
-                                           res);
-                }
+		else audit_syscall_exit(current,
+                                        AUDITSC_RESULT(UPT_SYSCALL_RET(regs)),
+                                        UPT_SYSCALL_RET(regs));
 	}
 	}
 
 
 	/* Fake a debug trap */
 	/* Fake a debug trap */
@@ -356,14 +354,3 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
 		current->exit_code = 0;
 		current->exit_code = 0;
 	}
 	}
 }
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */

+ 14 - 7
arch/um/kernel/sysrq.c

@@ -3,6 +3,7 @@
  * Licensed under the GPL
  * Licensed under the GPL
  */
  */
 
 
+#include "linux/config.h"
 #include "linux/sched.h"
 #include "linux/sched.h"
 #include "linux/kernel.h"
 #include "linux/kernel.h"
 #include "linux/module.h"
 #include "linux/module.h"
@@ -12,14 +13,14 @@
 #include "sysrq.h"
 #include "sysrq.h"
 #include "user_util.h"
 #include "user_util.h"
 
 
-void show_trace(unsigned long * stack)
+/* Catch non-i386 SUBARCH's. */
+#if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT)
+void show_trace(struct task_struct *task, unsigned long * stack)
 {
 {
-	/* XXX: Copy the CONFIG_FRAME_POINTER stack-walking backtrace from
-	 * arch/i386/kernel/traps.c, and then move this to sys-i386/sysrq.c.*/
         unsigned long addr;
         unsigned long addr;
 
 
         if (!stack) {
         if (!stack) {
-                stack = (unsigned long*) &stack;
+		stack = (unsigned long*) &stack;
 		WARN_ON(1);
 		WARN_ON(1);
 	}
 	}
 
 
@@ -35,6 +36,7 @@ void show_trace(unsigned long * stack)
         }
         }
         printk("\n");
         printk("\n");
 }
 }
+#endif
 
 
 /*
 /*
  * stack dumps generator - this is used by arch-independent code.
  * stack dumps generator - this is used by arch-independent code.
@@ -44,7 +46,7 @@ void dump_stack(void)
 {
 {
 	unsigned long stack;
 	unsigned long stack;
 
 
-	show_trace(&stack);
+	show_trace(current, &stack);
 }
 }
 EXPORT_SYMBOL(dump_stack);
 EXPORT_SYMBOL(dump_stack);
 
 
@@ -59,7 +61,11 @@ void show_stack(struct task_struct *task, unsigned long *esp)
 	int i;
 	int i;
 
 
 	if (esp == NULL) {
 	if (esp == NULL) {
-		if (task != current) {
+		if (task != current && task != NULL) {
+			/* XXX: Isn't this bogus? I.e. isn't this the
+			 * *userspace* stack of this task? If not so, use this
+			 * even when task == current (as in i386).
+			 */
 			esp = (unsigned long *) KSTK_ESP(task);
 			esp = (unsigned long *) KSTK_ESP(task);
 			/* Which one? No actual difference - just coding style.*/
 			/* Which one? No actual difference - just coding style.*/
 			//esp = (unsigned long *) PT_REGS_IP(&task->thread.regs);
 			//esp = (unsigned long *) PT_REGS_IP(&task->thread.regs);
@@ -77,5 +83,6 @@ void show_stack(struct task_struct *task, unsigned long *esp)
 		printk("%08lx ", *stack++);
 		printk("%08lx ", *stack++);
 	}
 	}
 
 
-	show_trace(esp);
+	printk("Call Trace: \n");
+	show_trace(current, esp);
 }
 }

+ 4 - 33
arch/um/kernel/trap_kern.c

@@ -23,7 +23,6 @@
 #include "kern.h"
 #include "kern.h"
 #include "chan_kern.h"
 #include "chan_kern.h"
 #include "mconsole_kern.h"
 #include "mconsole_kern.h"
-#include "2_5compat.h"
 #include "mem.h"
 #include "mem.h"
 #include "mem_kern.h"
 #include "mem_kern.h"
 
 
@@ -57,10 +56,11 @@ int handle_page_fault(unsigned long address, unsigned long ip,
 	*code_out = SEGV_ACCERR;
 	*code_out = SEGV_ACCERR;
 	if(is_write && !(vma->vm_flags & VM_WRITE)) 
 	if(is_write && !(vma->vm_flags & VM_WRITE)) 
 		goto out;
 		goto out;
+
+        if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
+                goto out;
+
 	page = address & PAGE_MASK;
 	page = address & PAGE_MASK;
-	pgd = pgd_offset(mm, page);
-	pud = pud_offset(pgd, page);
-	pmd = pmd_offset(pud, page);
 	do {
 	do {
  survive:
  survive:
 		switch (handle_mm_fault(mm, vma, address, is_write)){
 		switch (handle_mm_fault(mm, vma, address, is_write)){
@@ -106,33 +106,6 @@ int handle_page_fault(unsigned long address, unsigned long ip,
 	goto out;
 	goto out;
 }
 }
 
 
-LIST_HEAD(physmem_remappers);
-
-void register_remapper(struct remapper *info)
-{
-	list_add(&info->list, &physmem_remappers);
-}
-
-static int check_remapped_addr(unsigned long address, int is_write)
-{
-	struct remapper *remapper;
-	struct list_head *ele;
-	__u64 offset;
-	int fd;
-
-	fd = phys_mapping(__pa(address), &offset);
-	if(fd == -1)
-		return(0);
-
-	list_for_each(ele, &physmem_remappers){
-		remapper = list_entry(ele, struct remapper, list);
-		if((*remapper->proc)(fd, address, is_write, offset))
-			return(1);
-	}
-
-	return(0);
-}
-
 /*
 /*
  * We give a *copy* of the faultinfo in the regs to segv.
  * We give a *copy* of the faultinfo in the regs to segv.
  * This must be done, since nesting SEGVs could overwrite
  * This must be done, since nesting SEGVs could overwrite
@@ -151,8 +124,6 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
                 flush_tlb_kernel_vm();
                 flush_tlb_kernel_vm();
                 return(0);
                 return(0);
         }
         }
-	else if(check_remapped_addr(address & PAGE_MASK, is_write))
-		return(0);
 	else if(current->mm == NULL)
 	else if(current->mm == NULL)
 		panic("Segfault with no mm");
 		panic("Segfault with no mm");
 	err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
 	err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);

+ 1 - 0
arch/um/kernel/tt/ksyms.c

@@ -12,6 +12,7 @@ EXPORT_SYMBOL(__do_copy_to_user);
 EXPORT_SYMBOL(__do_strncpy_from_user);
 EXPORT_SYMBOL(__do_strncpy_from_user);
 EXPORT_SYMBOL(__do_strnlen_user); 
 EXPORT_SYMBOL(__do_strnlen_user); 
 EXPORT_SYMBOL(__do_clear_user);
 EXPORT_SYMBOL(__do_clear_user);
+EXPORT_SYMBOL(clear_user_tt);
 
 
 EXPORT_SYMBOL(tracing_pid);
 EXPORT_SYMBOL(tracing_pid);
 EXPORT_SYMBOL(honeypot);
 EXPORT_SYMBOL(honeypot);

+ 1 - 7
arch/um/kernel/tt/process_kern.c

@@ -32,10 +32,6 @@ void *switch_to_tt(void *prev, void *next, void *last)
 	unsigned long flags;
 	unsigned long flags;
 	int err, vtalrm, alrm, prof, cpu;
 	int err, vtalrm, alrm, prof, cpu;
 	char c;
 	char c;
-	/* jailing and SMP are incompatible, so this doesn't need to be 
-	 * made per-cpu 
-	 */
-	static int reading;
 
 
 	from = prev;
 	from = prev;
 	to = next;
 	to = next;
@@ -59,13 +55,11 @@ void *switch_to_tt(void *prev, void *next, void *last)
 	c = 0;
 	c = 0;
 	set_current(to);
 	set_current(to);
 
 
-	reading = 0;
 	err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
 	err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
 	if(err != sizeof(c))
 	if(err != sizeof(c))
 		panic("write of switch_pipe failed, err = %d", -err);
 		panic("write of switch_pipe failed, err = %d", -err);
 
 
-	reading = 1;
-        if(from->thread.mode.tt.switch_pipe[0] == -1)
+	if(from->thread.mode.tt.switch_pipe[0] == -1)
 		os_kill_process(os_getpid(), 0);
 		os_kill_process(os_getpid(), 0);
 
 
 	err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c));
 	err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c));

+ 0 - 6
arch/um/kernel/um_arch.c

@@ -111,12 +111,6 @@ struct seq_operations cpuinfo_op = {
 	.show	= show_cpuinfo,
 	.show	= show_cpuinfo,
 };
 };
 
 
-pte_t * __bad_pagetable(void)
-{
-	panic("Someone should implement __bad_pagetable");
-	return(NULL);
-}
-
 /* Set in linux_main */
 /* Set in linux_main */
 unsigned long host_task_size;
 unsigned long host_task_size;
 unsigned long task_size;
 unsigned long task_size;

+ 2 - 0
arch/um/kernel/uml.lds.S

@@ -73,6 +73,8 @@ SECTIONS
 
 
   .got           : { *(.got.plt) *(.got) }
   .got           : { *(.got.plt) *(.got) }
   .dynamic       : { *(.dynamic) }
   .dynamic       : { *(.dynamic) }
+  .tdata	  : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+  .tbss		  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
   /* We want the small data sections together, so single-instruction offsets
   /* We want the small data sections together, so single-instruction offsets
      can access them all, and initialized data all before uninitialized, so
      can access them all, and initialized data all before uninitialized, so
      we can shorten the on-disk segment size.  */
      we can shorten the on-disk segment size.  */

+ 2 - 2
arch/um/sys-i386/Makefile

@@ -9,11 +9,11 @@ USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
 
 
 SYMLINKS = bitops.c semaphore.c highmem.c module.c
 SYMLINKS = bitops.c semaphore.c highmem.c module.c
 
 
+include arch/um/scripts/Makefile.rules
+
 bitops.c-dir = lib
 bitops.c-dir = lib
 semaphore.c-dir = kernel
 semaphore.c-dir = kernel
 highmem.c-dir = mm
 highmem.c-dir = mm
 module.c-dir = kernel
 module.c-dir = kernel
 
 
 subdir- := util
 subdir- := util
-
-include arch/um/scripts/Makefile.rules

+ 12 - 4
arch/um/sys-i386/delay.c

@@ -1,5 +1,7 @@
-#include "linux/delay.h"
-#include "asm/param.h"
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <asm/param.h>
 
 
 void __delay(unsigned long time)
 void __delay(unsigned long time)
 {
 {
@@ -20,13 +22,19 @@ void __udelay(unsigned long usecs)
 	int i, n;
 	int i, n;
 
 
 	n = (loops_per_jiffy * HZ * usecs) / MILLION;
 	n = (loops_per_jiffy * HZ * usecs) / MILLION;
-	for(i=0;i<n;i++) ;
+        for(i=0;i<n;i++)
+                cpu_relax();
 }
 }
 
 
+EXPORT_SYMBOL(__udelay);
+
 void __const_udelay(unsigned long usecs)
 void __const_udelay(unsigned long usecs)
 {
 {
 	int i, n;
 	int i, n;
 
 
 	n = (loops_per_jiffy * HZ * usecs) / MILLION;
 	n = (loops_per_jiffy * HZ * usecs) / MILLION;
-	for(i=0;i<n;i++) ;
+        for(i=0;i<n;i++)
+                cpu_relax();
 }
 }
+
+EXPORT_SYMBOL(__const_udelay);

+ 79 - 1
arch/um/sys-i386/sysrq.c

@@ -3,12 +3,15 @@
  * Licensed under the GPL
  * Licensed under the GPL
  */
  */
 
 
+#include "linux/config.h"
 #include "linux/kernel.h"
 #include "linux/kernel.h"
 #include "linux/smp.h"
 #include "linux/smp.h"
 #include "linux/sched.h"
 #include "linux/sched.h"
+#include "linux/kallsyms.h"
 #include "asm/ptrace.h"
 #include "asm/ptrace.h"
 #include "sysrq.h"
 #include "sysrq.h"
 
 
+/* This is declared by <linux/sched.h> */
 void show_regs(struct pt_regs *regs)
 void show_regs(struct pt_regs *regs)
 {
 {
         printk("\n");
         printk("\n");
@@ -31,5 +34,80 @@ void show_regs(struct pt_regs *regs)
 	       0xffff & PT_REGS_DS(regs), 
 	       0xffff & PT_REGS_DS(regs), 
 	       0xffff & PT_REGS_ES(regs));
 	       0xffff & PT_REGS_ES(regs));
 
 
-        show_trace((unsigned long *) &regs);
+        show_trace(NULL, (unsigned long *) &regs);
 }
 }
+
+/* Copied from i386. */
+static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
+{
+	return	p > (void *)tinfo &&
+		p < (void *)tinfo + THREAD_SIZE - 3;
+}
+
+/* Adapted from i386 (we also print the address we read from). */
+static inline unsigned long print_context_stack(struct thread_info *tinfo,
+				unsigned long *stack, unsigned long ebp)
+{
+	unsigned long addr;
+
+#ifdef CONFIG_FRAME_POINTER
+	while (valid_stack_ptr(tinfo, (void *)ebp)) {
+		addr = *(unsigned long *)(ebp + 4);
+		printk("%08lx:  [<%08lx>]", ebp + 4, addr);
+		print_symbol(" %s", addr);
+		printk("\n");
+		ebp = *(unsigned long *)ebp;
+	}
+#else
+	while (valid_stack_ptr(tinfo, stack)) {
+		addr = *stack;
+		if (__kernel_text_address(addr)) {
+			printk("%08lx:  [<%08lx>]", (unsigned long) stack, addr);
+			print_symbol(" %s", addr);
+			printk("\n");
+		}
+		stack++;
+	}
+#endif
+	return ebp;
+}
+
+void show_trace(struct task_struct* task, unsigned long * stack)
+{
+	unsigned long ebp;
+	struct thread_info *context;
+
+	/* Turn this into BUG_ON if possible. */
+	if (!stack) {
+		stack = (unsigned long*) &stack;
+		printk("show_trace: got NULL stack, implicit assumption task == current");
+		WARN_ON(1);
+	}
+
+	if (!task)
+		task = current;
+
+	if (task != current) {
+		//ebp = (unsigned long) KSTK_EBP(task);
+		/* Which one? No actual difference - just coding style.*/
+		ebp = (unsigned long) PT_REGS_EBP(&task->thread.regs);
+	} else {
+		asm ("movl %%ebp, %0" : "=r" (ebp) : );
+	}
+
+	context = (struct thread_info *)
+		((unsigned long)stack & (~(THREAD_SIZE - 1)));
+	print_context_stack(context, stack, ebp);
+
+	/*while (((long) stack & (THREAD_SIZE-1)) != 0) {
+		addr = *stack;
+		if (__kernel_text_address(addr)) {
+			printk("%08lx:	[<%08lx>]", (unsigned long) stack, addr);
+			print_symbol(" %s", addr);
+			printk("\n");
+		}
+		stack++;
+	}*/
+	printk("\n");
+}
+

+ 1 - 13
arch/um/sys-ppc/sysrq.c

@@ -27,17 +27,5 @@ void show_regs(struct pt_regs_subarch *regs)
                 0xffff & regs->xds, 0xffff & regs->xes);
                 0xffff & regs->xds, 0xffff & regs->xes);
 #endif
 #endif
 
 
-        show_trace(&regs->gpr[1]);
+        show_trace(current, &regs->gpr[1]);
 }
 }
-
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */

+ 2 - 4
arch/um/sys-x86_64/Makefile

@@ -14,11 +14,11 @@ obj-$(CONFIG_MODULES) += module.o um_module.o
 
 
 USER_OBJS := ptrace_user.o sigcontext.o
 USER_OBJS := ptrace_user.o sigcontext.o
 
 
-include arch/um/scripts/Makefile.rules
-
 SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \
 SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \
 	semaphore.c thunk.S module.c
 	semaphore.c thunk.S module.c
 
 
+include arch/um/scripts/Makefile.rules
+
 bitops.c-dir = lib
 bitops.c-dir = lib
 csum-copy.S-dir = lib
 csum-copy.S-dir = lib
 csum-partial.c-dir = lib
 csum-partial.c-dir = lib
@@ -28,6 +28,4 @@ semaphore.c-dir = kernel
 thunk.S-dir = lib
 thunk.S-dir = lib
 module.c-dir = kernel
 module.c-dir = kernel
 
 
-CFLAGS_csum-partial.o := -Dcsum_partial=arch_csum_partial
-
 subdir- := util
 subdir- := util

+ 15 - 18
arch/um/sys-x86_64/delay.c

@@ -5,40 +5,37 @@
  * Licensed under the GPL
  * Licensed under the GPL
  */
  */
 
 
-#include "linux/delay.h"
-#include "asm/processor.h"
-#include "asm/param.h"
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <asm/processor.h>
+#include <asm/param.h>
 
 
 void __delay(unsigned long loops)
 void __delay(unsigned long loops)
 {
 {
 	unsigned long i;
 	unsigned long i;
 
 
-	for(i = 0; i < loops; i++) ;
+        for(i = 0; i < loops; i++)
+                cpu_relax();
 }
 }
 
 
 void __udelay(unsigned long usecs)
 void __udelay(unsigned long usecs)
 {
 {
-	int i, n;
+	unsigned long i, n;
 
 
 	n = (loops_per_jiffy * HZ * usecs) / MILLION;
 	n = (loops_per_jiffy * HZ * usecs) / MILLION;
-	for(i=0;i<n;i++) ;
+        for(i=0;i<n;i++)
+                cpu_relax();
 }
 }
 
 
+EXPORT_SYMBOL(__udelay);
+
 void __const_udelay(unsigned long usecs)
 void __const_udelay(unsigned long usecs)
 {
 {
-	int i, n;
+	unsigned long i, n;
 
 
 	n = (loops_per_jiffy * HZ * usecs) / MILLION;
 	n = (loops_per_jiffy * HZ * usecs) / MILLION;
-	for(i=0;i<n;i++) ;
+        for(i=0;i<n;i++)
+                cpu_relax();
 }
 }
 
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+EXPORT_SYMBOL(__const_udelay);

+ 1 - 2
arch/um/sys-x86_64/ksyms.c

@@ -16,5 +16,4 @@ EXPORT_SYMBOL(__up_wakeup);
 EXPORT_SYMBOL(__memcpy);
 EXPORT_SYMBOL(__memcpy);
 
 
 /* Networking helper routines. */
 /* Networking helper routines. */
-/*EXPORT_SYMBOL(csum_partial_copy_from);
-EXPORT_SYMBOL(csum_partial_copy_to);*/
+EXPORT_SYMBOL(ip_compute_csum);

+ 5 - 4
arch/um/sys-x86_64/ptrace.c

@@ -5,10 +5,11 @@
  */
  */
 
 
 #define __FRAME_OFFSETS
 #define __FRAME_OFFSETS
-#include "asm/ptrace.h"
-#include "linux/sched.h"
-#include "linux/errno.h"
-#include "asm/elf.h"
+#include <asm/ptrace.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+#include <asm/elf.h>
 
 
 /* XXX x86_64 */
 /* XXX x86_64 */
 unsigned long not_ss;
 unsigned long not_ss;

+ 11 - 6
arch/um/sys-x86_64/syscalls.c

@@ -15,6 +15,7 @@
 #include "asm/unistd.h"
 #include "asm/unistd.h"
 #include "asm/prctl.h" /* XXX This should get the constants from libc */
 #include "asm/prctl.h" /* XXX This should get the constants from libc */
 #include "choose-mode.h"
 #include "choose-mode.h"
+#include "kern.h"
 
 
 asmlinkage long sys_uname64(struct new_utsname __user * name)
 asmlinkage long sys_uname64(struct new_utsname __user * name)
 {
 {
@@ -132,23 +133,27 @@ static long arch_prctl_tt(int code, unsigned long addr)
 
 
 #ifdef CONFIG_MODE_SKAS
 #ifdef CONFIG_MODE_SKAS
 
 
+/* XXX: Must also call arch_prctl in the host, beside saving the segment bases! */
 static long arch_prctl_skas(int code, unsigned long addr)
 static long arch_prctl_skas(int code, unsigned long addr)
 {
 {
 	long ret = 0;
 	long ret = 0;
 
 
 	switch(code){
 	switch(code){
-	case ARCH_SET_GS:
-		current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr;
-		break;
 	case ARCH_SET_FS:
 	case ARCH_SET_FS:
 		current->thread.regs.regs.skas.regs[FS_BASE / sizeof(unsigned long)] = addr;
 		current->thread.regs.regs.skas.regs[FS_BASE / sizeof(unsigned long)] = addr;
 		break;
 		break;
+	case ARCH_SET_GS:
+		current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr;
+		break;
 	case ARCH_GET_FS:
 	case ARCH_GET_FS:
-		ret = put_user(current->thread.regs.regs.skas.regs[GS / sizeof(unsigned long)], &addr);
+		ret = put_user(current->thread.regs.regs.skas.
+				regs[FS_BASE / sizeof(unsigned long)],
+				(unsigned long __user *)addr);
 	        break;
 	        break;
 	case ARCH_GET_GS:
 	case ARCH_GET_GS:
-		ret = put_user(current->thread.regs.regs.skas.regs[FS / sizeof(unsigned \
-long)], &addr);
+		ret = put_user(current->thread.regs.regs.skas.
+				regs[GS_BASE / sizeof(unsigned long)],
+				(unsigned long __user *)addr);
 	        break;
 	        break;
 	default:
 	default:
 		ret = -EINVAL;
 		ret = -EINVAL;

+ 1 - 10
arch/um/sys-x86_64/sysrq.c

@@ -36,14 +36,5 @@ void __show_regs(struct pt_regs * regs)
 void show_regs(struct pt_regs *regs)
 void show_regs(struct pt_regs *regs)
 {
 {
 	__show_regs(regs);
 	__show_regs(regs);
-	show_trace((unsigned long *) &regs);
+	show_trace(current, (unsigned long *) &regs);
 }
 }
-
-/* Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.