aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/Kconfig28
-rw-r--r--arch/ia64/Makefile5
-rw-r--r--arch/ia64/configs/gensparse_defconfig1
-rw-r--r--arch/ia64/configs/sn2_defconfig1
-rw-r--r--arch/ia64/configs/tiger_defconfig2
-rw-r--r--arch/ia64/defconfig1
-rw-r--r--arch/ia64/dig/setup.c5
-rw-r--r--arch/ia64/hp/sim/simserial.c7
-rw-r--r--arch/ia64/ia32/sys_ia32.c14
-rw-r--r--arch/ia64/kernel/acpi.c49
-rw-r--r--arch/ia64/kernel/entry.S14
-rw-r--r--arch/ia64/kernel/iosapic.c6
-rw-r--r--arch/ia64/kernel/irq.c13
-rw-r--r--arch/ia64/kernel/ivt.S1
-rw-r--r--arch/ia64/kernel/machvec.c19
-rw-r--r--arch/ia64/kernel/mca.c194
-rw-r--r--arch/ia64/kernel/mca_drv.c22
-rw-r--r--arch/ia64/kernel/mca_drv.h7
-rw-r--r--arch/ia64/kernel/mca_drv_asm.S13
-rw-r--r--arch/ia64/kernel/numa.c2
-rw-r--r--arch/ia64/kernel/patch.c8
-rw-r--r--arch/ia64/kernel/perfmon.c5
-rw-r--r--arch/ia64/kernel/setup.c61
-rw-r--r--arch/ia64/kernel/signal.c101
-rw-r--r--arch/ia64/kernel/smpboot.c221
-rw-r--r--arch/ia64/kernel/time.c9
-rw-r--r--arch/ia64/kernel/topology.c2
-rw-r--r--arch/ia64/kernel/vmlinux.lds.S60
-rw-r--r--arch/ia64/mm/contig.c12
-rw-r--r--arch/ia64/mm/discontig.c11
-rw-r--r--arch/ia64/mm/hugetlbpage.c12
-rw-r--r--arch/ia64/mm/init.c22
-rw-r--r--arch/ia64/sn/kernel/Makefile3
-rw-r--r--arch/ia64/sn/kernel/bte.c2
-rw-r--r--arch/ia64/sn/kernel/io_init.c29
-rw-r--r--arch/ia64/sn/kernel/irq.c21
-rw-r--r--arch/ia64/sn/kernel/pio_phys.S71
-rw-r--r--arch/ia64/sn/kernel/setup.c6
-rw-r--r--arch/ia64/sn/kernel/sn2/sn2_smp.c21
-rw-r--r--arch/ia64/sn/kernel/tiocx.c10
-rw-r--r--arch/ia64/sn/kernel/xpc_channel.c102
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c1
-rw-r--r--arch/ia64/sn/kernel/xpc_partition.c28
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_provider.c17
-rw-r--r--arch/ia64/sn/pci/tioca_provider.c2
-rw-r--r--arch/ia64/sn/pci/tioce_provider.c326
46 files changed, 1038 insertions, 529 deletions
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index a85ea9d37f05..10b6b9e7716b 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -252,6 +252,15 @@ config NR_CPUS
252 than 64 will cause the use of a CPU mask array, causing a small 252 than 64 will cause the use of a CPU mask array, causing a small
253 performance hit. 253 performance hit.
254 254
255config IA64_NR_NODES
256 int "Maximum number of NODEs (256-1024)" if (IA64_SGI_SN2 || IA64_GENERIC)
257 range 256 1024
258 depends on IA64_SGI_SN2 || IA64_GENERIC
259 default "256"
260 help
261 This option specifies the maximum number of nodes in your SSI system.
262 If in doubt, use the default.
263
255config HOTPLUG_CPU 264config HOTPLUG_CPU
256 bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" 265 bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
257 depends on SMP && EXPERIMENTAL 266 depends on SMP && EXPERIMENTAL
@@ -271,6 +280,25 @@ config SCHED_SMT
271 Intel IA64 chips with MultiThreading at a cost of slightly increased 280 Intel IA64 chips with MultiThreading at a cost of slightly increased
272 overhead in some places. If unsure say N here. 281 overhead in some places. If unsure say N here.
273 282
283config PERMIT_BSP_REMOVE
284 bool "Support removal of Bootstrap Processor"
285 depends on HOTPLUG_CPU
286 default n
287 ---help---
288 Say Y here if your platform SAL will support removal of BSP with HOTPLUG_CPU
289 support.
290
291config FORCE_CPEI_RETARGET
292 bool "Force assumption that CPEI can be re-targetted"
293 depends on PERMIT_BSP_REMOVE
294 default n
295 ---help---
296 Say Y if you need to force the assumption that CPEI can be re-targetted to
297 any cpu in the system. This hint is available via ACPI 3.0 specifications.
298 Tiger4 systems are capable of re-directing CPEI to any CPU other than BSP.
299 This option it useful to enable this feature on older BIOS's as well.
300 You can also enable this by using boot command line option force_cpei=1.
301
274config PREEMPT 302config PREEMPT
275 bool "Preemptible Kernel" 303 bool "Preemptible Kernel"
276 help 304 help
diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
index f722e1a25948..80ea7506fa1a 100644
--- a/arch/ia64/Makefile
+++ b/arch/ia64/Makefile
@@ -1,6 +1,9 @@
1# 1#
2# ia64/Makefile 2# ia64/Makefile
3# 3#
4# This file is included by the global makefile so that you can add your own
5# architecture-specific flags and dependencies.
6#
4# This file is subject to the terms and conditions of the GNU General Public 7# This file is subject to the terms and conditions of the GNU General Public
5# License. See the file "COPYING" in the main directory of this archive 8# License. See the file "COPYING" in the main directory of this archive
6# for more details. 9# for more details.
@@ -62,7 +65,7 @@ drivers-$(CONFIG_OPROFILE) += arch/ia64/oprofile/
62 65
63boot := arch/ia64/hp/sim/boot 66boot := arch/ia64/hp/sim/boot
64 67
65.PHONY: boot compressed check 68PHONY += boot compressed check
66 69
67all: compressed unwcheck 70all: compressed unwcheck
68 71
diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig
index 744fd2f79f61..0d29aa2066b3 100644
--- a/arch/ia64/configs/gensparse_defconfig
+++ b/arch/ia64/configs/gensparse_defconfig
@@ -116,6 +116,7 @@ CONFIG_IOSAPIC=y
116CONFIG_FORCE_MAX_ZONEORDER=17 116CONFIG_FORCE_MAX_ZONEORDER=17
117CONFIG_SMP=y 117CONFIG_SMP=y
118CONFIG_NR_CPUS=512 118CONFIG_NR_CPUS=512
119CONFIG_IA64_NR_NODES=256
119CONFIG_HOTPLUG_CPU=y 120CONFIG_HOTPLUG_CPU=y
120# CONFIG_SCHED_SMT is not set 121# CONFIG_SCHED_SMT is not set
121# CONFIG_PREEMPT is not set 122# CONFIG_PREEMPT is not set
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig
index 8206752161bb..a718034d68d0 100644
--- a/arch/ia64/configs/sn2_defconfig
+++ b/arch/ia64/configs/sn2_defconfig
@@ -116,6 +116,7 @@ CONFIG_IA64_SGI_SN_XP=m
116CONFIG_FORCE_MAX_ZONEORDER=17 116CONFIG_FORCE_MAX_ZONEORDER=17
117CONFIG_SMP=y 117CONFIG_SMP=y
118CONFIG_NR_CPUS=1024 118CONFIG_NR_CPUS=1024
119CONFIG_IA64_NR_NODES=256
119# CONFIG_HOTPLUG_CPU is not set 120# CONFIG_HOTPLUG_CPU is not set
120CONFIG_SCHED_SMT=y 121CONFIG_SCHED_SMT=y
121CONFIG_PREEMPT=y 122CONFIG_PREEMPT=y
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
index 125568118b84..766bf4955432 100644
--- a/arch/ia64/configs/tiger_defconfig
+++ b/arch/ia64/configs/tiger_defconfig
@@ -116,6 +116,8 @@ CONFIG_FORCE_MAX_ZONEORDER=17
116CONFIG_SMP=y 116CONFIG_SMP=y
117CONFIG_NR_CPUS=4 117CONFIG_NR_CPUS=4
118CONFIG_HOTPLUG_CPU=y 118CONFIG_HOTPLUG_CPU=y
119CONFIG_PERMIT_BSP_REMOVE=y
120CONFIG_FORCE_CPEI_RETARGET=y
119# CONFIG_SCHED_SMT is not set 121# CONFIG_SCHED_SMT is not set
120# CONFIG_PREEMPT is not set 122# CONFIG_PREEMPT is not set
121CONFIG_SELECT_MEMORY_MODEL=y 123CONFIG_SELECT_MEMORY_MODEL=y
diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig
index 3e767288a745..6cba55da572a 100644
--- a/arch/ia64/defconfig
+++ b/arch/ia64/defconfig
@@ -116,6 +116,7 @@ CONFIG_IOSAPIC=y
116CONFIG_FORCE_MAX_ZONEORDER=17 116CONFIG_FORCE_MAX_ZONEORDER=17
117CONFIG_SMP=y 117CONFIG_SMP=y
118CONFIG_NR_CPUS=512 118CONFIG_NR_CPUS=512
119CONFIG_IA64_NR_NODES=256
119CONFIG_HOTPLUG_CPU=y 120CONFIG_HOTPLUG_CPU=y
120# CONFIG_SCHED_SMT is not set 121# CONFIG_SCHED_SMT is not set
121# CONFIG_PREEMPT is not set 122# CONFIG_PREEMPT is not set
diff --git a/arch/ia64/dig/setup.c b/arch/ia64/dig/setup.c
index c9104bfff667..38aa9c108857 100644
--- a/arch/ia64/dig/setup.c
+++ b/arch/ia64/dig/setup.c
@@ -69,8 +69,3 @@ dig_setup (char **cmdline_p)
69 screen_info.orig_video_isVGA = 1; /* XXX fake */ 69 screen_info.orig_video_isVGA = 1; /* XXX fake */
70 screen_info.orig_video_ega_bx = 3; /* XXX fake */ 70 screen_info.orig_video_ega_bx = 3; /* XXX fake */
71} 71}
72
73void __init
74dig_irq_init (void)
75{
76}
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index 626cdc83668b..0e5c6ae50228 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -46,11 +46,6 @@
46#define KEYBOARD_INTR 3 /* must match with simulator! */ 46#define KEYBOARD_INTR 3 /* must match with simulator! */
47 47
48#define NR_PORTS 1 /* only one port for now */ 48#define NR_PORTS 1 /* only one port for now */
49#define SERIAL_INLINE 1
50
51#ifdef SERIAL_INLINE
52#define _INLINE_ inline
53#endif
54 49
55#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT) 50#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
56 51
@@ -237,7 +232,7 @@ static void rs_put_char(struct tty_struct *tty, unsigned char ch)
237 local_irq_restore(flags); 232 local_irq_restore(flags);
238} 233}
239 234
240static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) 235static void transmit_chars(struct async_struct *info, int *intr_done)
241{ 236{
242 int count; 237 int count;
243 unsigned long flags; 238 unsigned long flags;
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index 70dba1f0e2ee..13e739e4c84d 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -1166,19 +1166,7 @@ put_tv32 (struct compat_timeval __user *o, struct timeval *i)
1166asmlinkage unsigned long 1166asmlinkage unsigned long
1167sys32_alarm (unsigned int seconds) 1167sys32_alarm (unsigned int seconds)
1168{ 1168{
1169 struct itimerval it_new, it_old; 1169 return alarm_setitimer(seconds);
1170 unsigned int oldalarm;
1171
1172 it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
1173 it_new.it_value.tv_sec = seconds;
1174 it_new.it_value.tv_usec = 0;
1175 do_setitimer(ITIMER_REAL, &it_new, &it_old);
1176 oldalarm = it_old.it_value.tv_sec;
1177 /* ehhh.. We can't return 0 if we have an alarm pending.. */
1178 /* And we'd better return too much than too little anyway */
1179 if (it_old.it_value.tv_usec)
1180 oldalarm++;
1181 return oldalarm;
1182} 1170}
1183 1171
1184/* Translations due to time_t size differences. Which affects all 1172/* Translations due to time_t size differences. Which affects all
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index ecd44bdc8394..a4e218ce2edb 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -284,19 +284,24 @@ acpi_parse_plat_int_src(acpi_table_entry_header * header,
284 return 0; 284 return 0;
285} 285}
286 286
287#ifdef CONFIG_HOTPLUG_CPU
287unsigned int can_cpei_retarget(void) 288unsigned int can_cpei_retarget(void)
288{ 289{
289 extern int cpe_vector; 290 extern int cpe_vector;
291 extern unsigned int force_cpei_retarget;
290 292
291 /* 293 /*
292 * Only if CPEI is supported and the override flag 294 * Only if CPEI is supported and the override flag
293 * is present, otherwise return that its re-targettable 295 * is present, otherwise return that its re-targettable
294 * if we are in polling mode. 296 * if we are in polling mode.
295 */ 297 */
296 if (cpe_vector > 0 && !acpi_cpei_override) 298 if (cpe_vector > 0) {
297 return 0; 299 if (acpi_cpei_override || force_cpei_retarget)
298 else 300 return 1;
299 return 1; 301 else
302 return 0;
303 }
304 return 1;
300} 305}
301 306
302unsigned int is_cpu_cpei_target(unsigned int cpu) 307unsigned int is_cpu_cpei_target(unsigned int cpu)
@@ -315,6 +320,7 @@ void set_cpei_target_cpu(unsigned int cpu)
315{ 320{
316 acpi_cpei_phys_cpuid = cpu_physical_id(cpu); 321 acpi_cpei_phys_cpuid = cpu_physical_id(cpu);
317} 322}
323#endif
318 324
319unsigned int get_cpei_target_cpu(void) 325unsigned int get_cpei_target_cpu(void)
320{ 326{
@@ -414,6 +420,26 @@ int __devinitdata pxm_to_nid_map[MAX_PXM_DOMAINS];
414int __initdata nid_to_pxm_map[MAX_NUMNODES]; 420int __initdata nid_to_pxm_map[MAX_NUMNODES];
415static struct acpi_table_slit __initdata *slit_table; 421static struct acpi_table_slit __initdata *slit_table;
416 422
423static int get_processor_proximity_domain(struct acpi_table_processor_affinity *pa)
424{
425 int pxm;
426
427 pxm = pa->proximity_domain;
428 if (ia64_platform_is("sn2"))
429 pxm += pa->reserved[0] << 8;
430 return pxm;
431}
432
433static int get_memory_proximity_domain(struct acpi_table_memory_affinity *ma)
434{
435 int pxm;
436
437 pxm = ma->proximity_domain;
438 if (ia64_platform_is("sn2"))
439 pxm += ma->reserved1[0] << 8;
440 return pxm;
441}
442
417/* 443/*
418 * ACPI 2.0 SLIT (System Locality Information Table) 444 * ACPI 2.0 SLIT (System Locality Information Table)
419 * http://devresource.hp.com/devresource/Docs/TechPapers/IA64/slit.pdf 445 * http://devresource.hp.com/devresource/Docs/TechPapers/IA64/slit.pdf
@@ -437,13 +463,20 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
437void __init 463void __init
438acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) 464acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa)
439{ 465{
466 int pxm;
467
468 if (!pa->flags.enabled)
469 return;
470
471 pxm = get_processor_proximity_domain(pa);
472
440 /* record this node in proximity bitmap */ 473 /* record this node in proximity bitmap */
441 pxm_bit_set(pa->proximity_domain); 474 pxm_bit_set(pxm);
442 475
443 node_cpuid[srat_num_cpus].phys_id = 476 node_cpuid[srat_num_cpus].phys_id =
444 (pa->apic_id << 8) | (pa->lsapic_eid); 477 (pa->apic_id << 8) | (pa->lsapic_eid);
445 /* nid should be overridden as logical node id later */ 478 /* nid should be overridden as logical node id later */
446 node_cpuid[srat_num_cpus].nid = pa->proximity_domain; 479 node_cpuid[srat_num_cpus].nid = pxm;
447 srat_num_cpus++; 480 srat_num_cpus++;
448} 481}
449 482
@@ -451,10 +484,10 @@ void __init
451acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) 484acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
452{ 485{
453 unsigned long paddr, size; 486 unsigned long paddr, size;
454 u8 pxm; 487 int pxm;
455 struct node_memblk_s *p, *q, *pend; 488 struct node_memblk_s *p, *q, *pend;
456 489
457 pxm = ma->proximity_domain; 490 pxm = get_memory_proximity_domain(ma);
458 491
459 /* fill node memory chunk structure */ 492 /* fill node memory chunk structure */
460 paddr = ma->base_addr_hi; 493 paddr = ma->base_addr_hi;
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 930fdfca6ddb..0e3eda99e549 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1102,9 +1102,6 @@ skip_rbs_switch:
1102 st8 [r2]=r8 1102 st8 [r2]=r8
1103 st8 [r3]=r10 1103 st8 [r3]=r10
1104.work_pending: 1104.work_pending:
1105 tbit.nz p6,p0=r31,TIF_SIGDELAYED // signal delayed from MCA/INIT/NMI/PMI context?
1106(p6) br.cond.sptk.few .sigdelayed
1107 ;;
1108 tbit.z p6,p0=r31,TIF_NEED_RESCHED // current_thread_info()->need_resched==0? 1105 tbit.z p6,p0=r31,TIF_NEED_RESCHED // current_thread_info()->need_resched==0?
1109(p6) br.cond.sptk.few .notify 1106(p6) br.cond.sptk.few .notify
1110#ifdef CONFIG_PREEMPT 1107#ifdef CONFIG_PREEMPT
@@ -1131,17 +1128,6 @@ skip_rbs_switch:
1131(pLvSys)br.cond.sptk.few .work_pending_syscall_end 1128(pLvSys)br.cond.sptk.few .work_pending_syscall_end
1132 br.cond.sptk.many .work_processed_kernel // don't re-check 1129 br.cond.sptk.many .work_processed_kernel // don't re-check
1133 1130
1134// There is a delayed signal that was detected in MCA/INIT/NMI/PMI context where
1135// it could not be delivered. Deliver it now. The signal might be for us and
1136// may set TIF_SIGPENDING, so redrive ia64_leave_* after processing the delayed
1137// signal.
1138
1139.sigdelayed:
1140 br.call.sptk.many rp=do_sigdelayed
1141 cmp.eq p6,p0=r0,r0 // p6 <- 1, always re-check
1142(pLvSys)br.cond.sptk.few .work_pending_syscall_end
1143 br.cond.sptk.many .work_processed_kernel // re-check
1144
1145.work_pending_syscall_end: 1131.work_pending_syscall_end:
1146 adds r2=PT(R8)+16,r12 1132 adds r2=PT(R8)+16,r12
1147 adds r3=PT(R10)+16,r12 1133 adds r3=PT(R10)+16,r12
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 574084f343fa..8832c553230a 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -631,6 +631,7 @@ get_target_cpu (unsigned int gsi, int vector)
631{ 631{
632#ifdef CONFIG_SMP 632#ifdef CONFIG_SMP
633 static int cpu = -1; 633 static int cpu = -1;
634 extern int cpe_vector;
634 635
635 /* 636 /*
636 * In case of vector shared by multiple RTEs, all RTEs that 637 * In case of vector shared by multiple RTEs, all RTEs that
@@ -653,6 +654,11 @@ get_target_cpu (unsigned int gsi, int vector)
653 if (!cpu_online(smp_processor_id())) 654 if (!cpu_online(smp_processor_id()))
654 return cpu_physical_id(smp_processor_id()); 655 return cpu_physical_id(smp_processor_id());
655 656
657#ifdef CONFIG_ACPI
658 if (cpe_vector > 0 && vector == IA64_CPEP_VECTOR)
659 return get_cpei_target_cpu();
660#endif
661
656#ifdef CONFIG_NUMA 662#ifdef CONFIG_NUMA
657 { 663 {
658 int num_cpus, cpu_index, iosapic_index, numa_cpu, i = 0; 664 int num_cpus, cpu_index, iosapic_index, numa_cpu, i = 0;
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
index d33244c32759..5ce908ef9c95 100644
--- a/arch/ia64/kernel/irq.c
+++ b/arch/ia64/kernel/irq.c
@@ -163,8 +163,19 @@ void fixup_irqs(void)
163{ 163{
164 unsigned int irq; 164 unsigned int irq;
165 extern void ia64_process_pending_intr(void); 165 extern void ia64_process_pending_intr(void);
166 extern void ia64_disable_timer(void);
167 extern volatile int time_keeper_id;
168
169 ia64_disable_timer();
170
171 /*
172 * Find a new timesync master
173 */
174 if (smp_processor_id() == time_keeper_id) {
175 time_keeper_id = first_cpu(cpu_online_map);
176 printk ("CPU %d is now promoted to time-keeper master\n", time_keeper_id);
177 }
166 178
167 ia64_set_itv(1<<16);
168 /* 179 /*
169 * Phase 1: Locate irq's bound to this cpu and 180 * Phase 1: Locate irq's bound to this cpu and
170 * relocate them for cpu removal. 181 * relocate them for cpu removal.
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
index dcd906fe5749..829a43cab797 100644
--- a/arch/ia64/kernel/ivt.S
+++ b/arch/ia64/kernel/ivt.S
@@ -865,6 +865,7 @@ ENTRY(interrupt)
865 ;; 865 ;;
866 SAVE_REST 866 SAVE_REST
867 ;; 867 ;;
868 MCA_RECOVER_RANGE(interrupt)
868 alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group 869 alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
869 mov out0=cr.ivr // pass cr.ivr as first arg 870 mov out0=cr.ivr // pass cr.ivr as first arg
870 add out1=16,sp // pass pointer to pt_regs as second arg 871 add out1=16,sp // pass pointer to pt_regs as second arg
diff --git a/arch/ia64/kernel/machvec.c b/arch/ia64/kernel/machvec.c
index c3a04ee7f4f6..4b0b71d5aef4 100644
--- a/arch/ia64/kernel/machvec.c
+++ b/arch/ia64/kernel/machvec.c
@@ -14,7 +14,15 @@
14struct ia64_machine_vector ia64_mv; 14struct ia64_machine_vector ia64_mv;
15EXPORT_SYMBOL(ia64_mv); 15EXPORT_SYMBOL(ia64_mv);
16 16
17static struct ia64_machine_vector * 17static __initdata const char *mvec_name;
18static __init int setup_mvec(char *s)
19{
20 mvec_name = s;
21 return 0;
22}
23early_param("machvec", setup_mvec);
24
25static struct ia64_machine_vector * __init
18lookup_machvec (const char *name) 26lookup_machvec (const char *name)
19{ 27{
20 extern struct ia64_machine_vector machvec_start[]; 28 extern struct ia64_machine_vector machvec_start[];
@@ -33,10 +41,13 @@ machvec_init (const char *name)
33{ 41{
34 struct ia64_machine_vector *mv; 42 struct ia64_machine_vector *mv;
35 43
44 if (!name)
45 name = mvec_name ? mvec_name : acpi_get_sysname();
36 mv = lookup_machvec(name); 46 mv = lookup_machvec(name);
37 if (!mv) { 47 if (!mv)
38 panic("generic kernel failed to find machine vector for platform %s!", name); 48 panic("generic kernel failed to find machine vector for"
39 } 49 " platform %s!", name);
50
40 ia64_mv = *mv; 51 ia64_mv = *mv;
41 printk(KERN_INFO "booting generic kernel on platform %s\n", name); 52 printk(KERN_INFO "booting generic kernel on platform %s\n", name);
42} 53}
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index ee7eec9ee576..87ff7fe33cfb 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -83,6 +83,7 @@
83#include <asm/irq.h> 83#include <asm/irq.h>
84#include <asm/hw_irq.h> 84#include <asm/hw_irq.h>
85 85
86#include "mca_drv.h"
86#include "entry.h" 87#include "entry.h"
87 88
88#if defined(IA64_MCA_DEBUG_INFO) 89#if defined(IA64_MCA_DEBUG_INFO)
@@ -133,7 +134,7 @@ static int cpe_poll_enabled = 1;
133 134
134extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe); 135extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe);
135 136
136static int mca_init; 137static int mca_init __initdata;
137 138
138 139
139static void inline 140static void inline
@@ -184,7 +185,7 @@ static ia64_state_log_t ia64_state_log[IA64_MAX_LOG_TYPES];
184 * Inputs : info_type (SAL_INFO_TYPE_{MCA,INIT,CMC,CPE}) 185 * Inputs : info_type (SAL_INFO_TYPE_{MCA,INIT,CMC,CPE})
185 * Outputs : None 186 * Outputs : None
186 */ 187 */
187static void 188static void __init
188ia64_log_init(int sal_info_type) 189ia64_log_init(int sal_info_type)
189{ 190{
190 u64 max_size = 0; 191 u64 max_size = 0;
@@ -282,13 +283,53 @@ ia64_mca_log_sal_error_record(int sal_info_type)
282} 283}
283 284
284/* 285/*
285 * platform dependent error handling 286 * search_mca_table
287 * See if the MCA surfaced in an instruction range
288 * that has been tagged as recoverable.
289 *
290 * Inputs
291 * first First address range to check
292 * last Last address range to check
293 * ip Instruction pointer, address we are looking for
294 *
295 * Return value:
296 * 1 on Success (in the table)/ 0 on Failure (not in the table)
286 */ 297 */
287#ifndef PLATFORM_MCA_HANDLERS 298int
299search_mca_table (const struct mca_table_entry *first,
300 const struct mca_table_entry *last,
301 unsigned long ip)
302{
303 const struct mca_table_entry *curr;
304 u64 curr_start, curr_end;
305
306 curr = first;
307 while (curr <= last) {
308 curr_start = (u64) &curr->start_addr + curr->start_addr;
309 curr_end = (u64) &curr->end_addr + curr->end_addr;
310
311 if ((ip >= curr_start) && (ip <= curr_end)) {
312 return 1;
313 }
314 curr++;
315 }
316 return 0;
317}
318
319/* Given an address, look for it in the mca tables. */
320int mca_recover_range(unsigned long addr)
321{
322 extern struct mca_table_entry __start___mca_table[];
323 extern struct mca_table_entry __stop___mca_table[];
324
325 return search_mca_table(__start___mca_table, __stop___mca_table-1, addr);
326}
327EXPORT_SYMBOL_GPL(mca_recover_range);
288 328
289#ifdef CONFIG_ACPI 329#ifdef CONFIG_ACPI
290 330
291int cpe_vector = -1; 331int cpe_vector = -1;
332int ia64_cpe_irq = -1;
292 333
293static irqreturn_t 334static irqreturn_t
294ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs) 335ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
@@ -359,7 +400,7 @@ ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
359 * Outputs 400 * Outputs
360 * None 401 * None
361 */ 402 */
362static void 403static void __init
363ia64_mca_register_cpev (int cpev) 404ia64_mca_register_cpev (int cpev)
364{ 405{
365 /* Register the CPE interrupt vector with SAL */ 406 /* Register the CPE interrupt vector with SAL */
@@ -377,8 +418,6 @@ ia64_mca_register_cpev (int cpev)
377} 418}
378#endif /* CONFIG_ACPI */ 419#endif /* CONFIG_ACPI */
379 420
380#endif /* PLATFORM_MCA_HANDLERS */
381
382/* 421/*
383 * ia64_mca_cmc_vector_setup 422 * ia64_mca_cmc_vector_setup
384 * 423 *
@@ -392,7 +431,7 @@ ia64_mca_register_cpev (int cpev)
392 * Outputs 431 * Outputs
393 * None 432 * None
394 */ 433 */
395void 434void __cpuinit
396ia64_mca_cmc_vector_setup (void) 435ia64_mca_cmc_vector_setup (void)
397{ 436{
398 cmcv_reg_t cmcv; 437 cmcv_reg_t cmcv;
@@ -630,6 +669,32 @@ copy_reg(const u64 *fr, u64 fnat, u64 *tr, u64 *tnat)
630 *tnat |= (nat << tslot); 669 *tnat |= (nat << tslot);
631} 670}
632 671
672/* Change the comm field on the MCA/INT task to include the pid that
673 * was interrupted, it makes for easier debugging. If that pid was 0
674 * (swapper or nested MCA/INIT) then use the start of the previous comm
675 * field suffixed with its cpu.
676 */
677
678static void
679ia64_mca_modify_comm(const task_t *previous_current)
680{
681 char *p, comm[sizeof(current->comm)];
682 if (previous_current->pid)
683 snprintf(comm, sizeof(comm), "%s %d",
684 current->comm, previous_current->pid);
685 else {
686 int l;
687 if ((p = strchr(previous_current->comm, ' ')))
688 l = p - previous_current->comm;
689 else
690 l = strlen(previous_current->comm);
691 snprintf(comm, sizeof(comm), "%s %*s %d",
692 current->comm, l, previous_current->comm,
693 task_thread_info(previous_current)->cpu);
694 }
695 memcpy(current->comm, comm, sizeof(current->comm));
696}
697
633/* On entry to this routine, we are running on the per cpu stack, see 698/* On entry to this routine, we are running on the per cpu stack, see
634 * mca_asm.h. The original stack has not been touched by this event. Some of 699 * mca_asm.h. The original stack has not been touched by this event. Some of
635 * the original stack's registers will be in the RBS on this stack. This stack 700 * the original stack's registers will be in the RBS on this stack. This stack
@@ -648,7 +713,7 @@ ia64_mca_modify_original_stack(struct pt_regs *regs,
648 struct ia64_sal_os_state *sos, 713 struct ia64_sal_os_state *sos,
649 const char *type) 714 const char *type)
650{ 715{
651 char *p, comm[sizeof(current->comm)]; 716 char *p;
652 ia64_va va; 717 ia64_va va;
653 extern char ia64_leave_kernel[]; /* Need asm address, not function descriptor */ 718 extern char ia64_leave_kernel[]; /* Need asm address, not function descriptor */
654 const pal_min_state_area_t *ms = sos->pal_min_state; 719 const pal_min_state_area_t *ms = sos->pal_min_state;
@@ -721,54 +786,43 @@ ia64_mca_modify_original_stack(struct pt_regs *regs,
721 /* Verify the previous stack state before we change it */ 786 /* Verify the previous stack state before we change it */
722 if (user_mode(regs)) { 787 if (user_mode(regs)) {
723 msg = "occurred in user space"; 788 msg = "occurred in user space";
724 goto no_mod; 789 /* previous_current is guaranteed to be valid when the task was
725 } 790 * in user space, so ...
726 if (r13 != sos->prev_IA64_KR_CURRENT) { 791 */
727 msg = "inconsistent previous current and r13"; 792 ia64_mca_modify_comm(previous_current);
728 goto no_mod;
729 }
730 if ((r12 - r13) >= KERNEL_STACK_SIZE) {
731 msg = "inconsistent r12 and r13";
732 goto no_mod;
733 }
734 if ((ar_bspstore - r13) >= KERNEL_STACK_SIZE) {
735 msg = "inconsistent ar.bspstore and r13";
736 goto no_mod;
737 }
738 va.p = old_bspstore;
739 if (va.f.reg < 5) {
740 msg = "old_bspstore is in the wrong region";
741 goto no_mod;
742 }
743 if ((ar_bsp - r13) >= KERNEL_STACK_SIZE) {
744 msg = "inconsistent ar.bsp and r13";
745 goto no_mod;
746 }
747 size += (ia64_rse_skip_regs(old_bspstore, slots) - old_bspstore) * 8;
748 if (ar_bspstore + size > r12) {
749 msg = "no room for blocked state";
750 goto no_mod; 793 goto no_mod;
751 } 794 }
752 795
753 /* Change the comm field on the MCA/INT task to include the pid that 796 if (!mca_recover_range(ms->pmsa_iip)) {
754 * was interrupted, it makes for easier debugging. If that pid was 0 797 if (r13 != sos->prev_IA64_KR_CURRENT) {
755 * (swapper or nested MCA/INIT) then use the start of the previous comm 798 msg = "inconsistent previous current and r13";
756 * field suffixed with its cpu. 799 goto no_mod;
757 */ 800 }
758 if (previous_current->pid) 801 if ((r12 - r13) >= KERNEL_STACK_SIZE) {
759 snprintf(comm, sizeof(comm), "%s %d", 802 msg = "inconsistent r12 and r13";
760 current->comm, previous_current->pid); 803 goto no_mod;
761 else { 804 }
762 int l; 805 if ((ar_bspstore - r13) >= KERNEL_STACK_SIZE) {
763 if ((p = strchr(previous_current->comm, ' '))) 806 msg = "inconsistent ar.bspstore and r13";
764 l = p - previous_current->comm; 807 goto no_mod;
765 else 808 }
766 l = strlen(previous_current->comm); 809 va.p = old_bspstore;
767 snprintf(comm, sizeof(comm), "%s %*s %d", 810 if (va.f.reg < 5) {
768 current->comm, l, previous_current->comm, 811 msg = "old_bspstore is in the wrong region";
769 task_thread_info(previous_current)->cpu); 812 goto no_mod;
813 }
814 if ((ar_bsp - r13) >= KERNEL_STACK_SIZE) {
815 msg = "inconsistent ar.bsp and r13";
816 goto no_mod;
817 }
818 size += (ia64_rse_skip_regs(old_bspstore, slots) - old_bspstore) * 8;
819 if (ar_bspstore + size > r12) {
820 msg = "no room for blocked state";
821 goto no_mod;
822 }
770 } 823 }
771 memcpy(current->comm, comm, sizeof(current->comm)); 824
825 ia64_mca_modify_comm(previous_current);
772 826
773 /* Make the original task look blocked. First stack a struct pt_regs, 827 /* Make the original task look blocked. First stack a struct pt_regs,
774 * describing the state at the time of interrupt. mca_asm.S built a 828 * describing the state at the time of interrupt. mca_asm.S built a
@@ -908,7 +962,7 @@ no_mod:
908static void 962static void
909ia64_wait_for_slaves(int monarch) 963ia64_wait_for_slaves(int monarch)
910{ 964{
911 int c, wait = 0; 965 int c, wait = 0, missing = 0;
912 for_each_online_cpu(c) { 966 for_each_online_cpu(c) {
913 if (c == monarch) 967 if (c == monarch)
914 continue; 968 continue;
@@ -919,15 +973,32 @@ ia64_wait_for_slaves(int monarch)
919 } 973 }
920 } 974 }
921 if (!wait) 975 if (!wait)
922 return; 976 goto all_in;
923 for_each_online_cpu(c) { 977 for_each_online_cpu(c) {
924 if (c == monarch) 978 if (c == monarch)
925 continue; 979 continue;
926 if (ia64_mc_info.imi_rendez_checkin[c] == IA64_MCA_RENDEZ_CHECKIN_NOTDONE) { 980 if (ia64_mc_info.imi_rendez_checkin[c] == IA64_MCA_RENDEZ_CHECKIN_NOTDONE) {
927 udelay(5*1000000); /* wait 5 seconds for slaves (arbitrary) */ 981 udelay(5*1000000); /* wait 5 seconds for slaves (arbitrary) */
982 if (ia64_mc_info.imi_rendez_checkin[c] == IA64_MCA_RENDEZ_CHECKIN_NOTDONE)
983 missing = 1;
928 break; 984 break;
929 } 985 }
930 } 986 }
987 if (!missing)
988 goto all_in;
989 printk(KERN_INFO "OS MCA slave did not rendezvous on cpu");
990 for_each_online_cpu(c) {
991 if (c == monarch)
992 continue;
993 if (ia64_mc_info.imi_rendez_checkin[c] == IA64_MCA_RENDEZ_CHECKIN_NOTDONE)
994 printk(" %d", c);
995 }
996 printk("\n");
997 return;
998
999all_in:
1000 printk(KERN_INFO "All OS MCA slaves have reached rendezvous\n");
1001 return;
931} 1002}
932 1003
933/* 1004/*
@@ -953,6 +1024,10 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
953 task_t *previous_current; 1024 task_t *previous_current;
954 1025
955 oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ 1026 oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */
1027 console_loglevel = 15; /* make sure printks make it to console */
1028 printk(KERN_INFO "Entered OS MCA handler. PSP=%lx cpu=%d monarch=%ld\n",
1029 sos->proc_state_param, cpu, sos->monarch);
1030
956 previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA"); 1031 previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA");
957 monarch_cpu = cpu; 1032 monarch_cpu = cpu;
958 if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, 0, 0, 0) 1033 if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, 0, 0, 0)
@@ -1416,7 +1491,7 @@ static struct irqaction mca_cpep_irqaction = {
1416 * format most of the fields. 1491 * format most of the fields.
1417 */ 1492 */
1418 1493
1419static void 1494static void __cpuinit
1420format_mca_init_stack(void *mca_data, unsigned long offset, 1495format_mca_init_stack(void *mca_data, unsigned long offset,
1421 const char *type, int cpu) 1496 const char *type, int cpu)
1422{ 1497{
@@ -1440,15 +1515,17 @@ format_mca_init_stack(void *mca_data, unsigned long offset,
1440 1515
1441/* Do per-CPU MCA-related initialization. */ 1516/* Do per-CPU MCA-related initialization. */
1442 1517
1443void __devinit 1518void __cpuinit
1444ia64_mca_cpu_init(void *cpu_data) 1519ia64_mca_cpu_init(void *cpu_data)
1445{ 1520{
1446 void *pal_vaddr; 1521 void *pal_vaddr;
1522 static int first_time = 1;
1447 1523
1448 if (smp_processor_id() == 0) { 1524 if (first_time) {
1449 void *mca_data; 1525 void *mca_data;
1450 int cpu; 1526 int cpu;
1451 1527
1528 first_time = 0;
1452 mca_data = alloc_bootmem(sizeof(struct ia64_mca_cpu) 1529 mca_data = alloc_bootmem(sizeof(struct ia64_mca_cpu)
1453 * NR_CPUS + KERNEL_STACK_SIZE); 1530 * NR_CPUS + KERNEL_STACK_SIZE);
1454 mca_data = (void *)(((unsigned long)mca_data + 1531 mca_data = (void *)(((unsigned long)mca_data +
@@ -1704,6 +1781,7 @@ ia64_mca_late_init(void)
1704 desc = irq_descp(irq); 1781 desc = irq_descp(irq);
1705 desc->status |= IRQ_PER_CPU; 1782 desc->status |= IRQ_PER_CPU;
1706 setup_irq(irq, &mca_cpe_irqaction); 1783 setup_irq(irq, &mca_cpe_irqaction);
1784 ia64_cpe_irq = irq;
1707 } 1785 }
1708 ia64_mca_register_cpev(cpe_vector); 1786 ia64_mca_register_cpev(cpe_vector);
1709 IA64_MCA_DEBUG("%s: CPEI/P setup and enabled.\n", __FUNCTION__); 1787 IA64_MCA_DEBUG("%s: CPEI/P setup and enabled.\n", __FUNCTION__);
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
index e883d85906db..37c88eb55873 100644
--- a/arch/ia64/kernel/mca_drv.c
+++ b/arch/ia64/kernel/mca_drv.c
@@ -6,6 +6,7 @@
6 * Copyright (C) Hidetoshi Seto (seto.hidetoshi@jp.fujitsu.com) 6 * Copyright (C) Hidetoshi Seto (seto.hidetoshi@jp.fujitsu.com)
7 * Copyright (C) 2005 Silicon Graphics, Inc 7 * Copyright (C) 2005 Silicon Graphics, Inc
8 * Copyright (C) 2005 Keith Owens <kaos@sgi.com> 8 * Copyright (C) 2005 Keith Owens <kaos@sgi.com>
9 * Copyright (C) 2006 Russ Anderson <rja@sgi.com>
9 */ 10 */
10#include <linux/config.h> 11#include <linux/config.h>
11#include <linux/types.h> 12#include <linux/types.h>
@@ -121,11 +122,12 @@ mca_page_isolate(unsigned long paddr)
121 */ 122 */
122 123
123void 124void
124mca_handler_bh(unsigned long paddr) 125mca_handler_bh(unsigned long paddr, void *iip, unsigned long ipsr)
125{ 126{
126 printk(KERN_ERR 127 printk(KERN_ERR "OS_MCA: process [cpu %d, pid: %d, uid: %d, "
127 "OS_MCA: process [pid: %d](%s) encounters MCA (paddr=%lx)\n", 128 "iip: %p, psr: 0x%lx,paddr: 0x%lx](%s) encounters MCA.\n",
128 current->pid, current->comm, paddr); 129 raw_smp_processor_id(), current->pid, current->uid,
130 iip, ipsr, paddr, current->comm);
129 131
130 spin_lock(&mca_bh_lock); 132 spin_lock(&mca_bh_lock);
131 switch (mca_page_isolate(paddr)) { 133 switch (mca_page_isolate(paddr)) {
@@ -442,21 +444,26 @@ recover_from_read_error(slidx_table_t *slidx,
442 if (!peidx_bottom(peidx) || !(peidx_bottom(peidx)->valid.minstate)) 444 if (!peidx_bottom(peidx) || !(peidx_bottom(peidx)->valid.minstate))
443 return 0; 445 return 0;
444 psr1 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_ipsr); 446 psr1 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_ipsr);
447 psr2 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_xpsr);
445 448
446 /* 449 /*
447 * Check the privilege level of interrupted context. 450 * Check the privilege level of interrupted context.
448 * If it is user-mode, then terminate affected process. 451 * If it is user-mode, then terminate affected process.
449 */ 452 */
450 if (psr1->cpl != 0) { 453
454 pmsa = sos->pal_min_state;
455 if (psr1->cpl != 0 ||
456 ((psr2->cpl != 0) && mca_recover_range(pmsa->pmsa_iip))) {
451 smei = peidx_bus_check(peidx, 0); 457 smei = peidx_bus_check(peidx, 0);
452 if (smei->valid.target_identifier) { 458 if (smei->valid.target_identifier) {
453 /* 459 /*
454 * setup for resume to bottom half of MCA, 460 * setup for resume to bottom half of MCA,
455 * "mca_handler_bhhook" 461 * "mca_handler_bhhook"
456 */ 462 */
457 pmsa = sos->pal_min_state; 463 /* pass to bhhook as argument (gr8, ...) */
458 /* pass to bhhook as 1st argument (gr8) */
459 pmsa->pmsa_gr[8-1] = smei->target_identifier; 464 pmsa->pmsa_gr[8-1] = smei->target_identifier;
465 pmsa->pmsa_gr[9-1] = pmsa->pmsa_iip;
466 pmsa->pmsa_gr[10-1] = pmsa->pmsa_ipsr;
460 /* set interrupted return address (but no use) */ 467 /* set interrupted return address (but no use) */
461 pmsa->pmsa_br0 = pmsa->pmsa_iip; 468 pmsa->pmsa_br0 = pmsa->pmsa_iip;
462 /* change resume address to bottom half */ 469 /* change resume address to bottom half */
@@ -466,6 +473,7 @@ recover_from_read_error(slidx_table_t *slidx,
466 psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr; 473 psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr;
467 psr2->cpl = 0; 474 psr2->cpl = 0;
468 psr2->ri = 0; 475 psr2->ri = 0;
476 psr2->bn = 1;
469 psr2->i = 0; 477 psr2->i = 0;
470 478
471 return 1; 479 return 1;
diff --git a/arch/ia64/kernel/mca_drv.h b/arch/ia64/kernel/mca_drv.h
index e2f6fa1e0ef6..31a2e52bb16f 100644
--- a/arch/ia64/kernel/mca_drv.h
+++ b/arch/ia64/kernel/mca_drv.h
@@ -111,3 +111,10 @@ typedef struct slidx_table {
111 slidx_foreach_entry(__pos, &((slidx)->sec)) { __count++; }\ 111 slidx_foreach_entry(__pos, &((slidx)->sec)) { __count++; }\
112 __count; }) 112 __count; })
113 113
114struct mca_table_entry {
115 int start_addr; /* location-relative starting address of MCA recoverable range */
116 int end_addr; /* location-relative ending address of MCA recoverable range */
117};
118
119extern const struct mca_table_entry *search_mca_tables (unsigned long addr);
120extern int mca_recover_range(unsigned long);
diff --git a/arch/ia64/kernel/mca_drv_asm.S b/arch/ia64/kernel/mca_drv_asm.S
index 3f298ee4d00c..e6a580d354b9 100644
--- a/arch/ia64/kernel/mca_drv_asm.S
+++ b/arch/ia64/kernel/mca_drv_asm.S
@@ -14,15 +14,12 @@
14 14
15GLOBAL_ENTRY(mca_handler_bhhook) 15GLOBAL_ENTRY(mca_handler_bhhook)
16 invala // clear RSE ? 16 invala // clear RSE ?
17 ;;
18 cover 17 cover
19 ;; 18 ;;
20 clrrrb 19 clrrrb
21 ;; 20 ;;
22 alloc r16=ar.pfs,0,2,1,0 // make a new frame 21 alloc r16=ar.pfs,0,2,3,0 // make a new frame
23 ;;
24 mov ar.rsc=0 22 mov ar.rsc=0
25 ;;
26 mov r13=IA64_KR(CURRENT) // current task pointer 23 mov r13=IA64_KR(CURRENT) // current task pointer
27 ;; 24 ;;
28 mov r2=r13 25 mov r2=r13
@@ -30,7 +27,6 @@ GLOBAL_ENTRY(mca_handler_bhhook)
30 addl r22=IA64_RBS_OFFSET,r2 27 addl r22=IA64_RBS_OFFSET,r2
31 ;; 28 ;;
32 mov ar.bspstore=r22 29 mov ar.bspstore=r22
33 ;;
34 addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 30 addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2
35 ;; 31 ;;
36 adds r2=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 32 adds r2=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
@@ -40,12 +36,12 @@ GLOBAL_ENTRY(mca_handler_bhhook)
40 movl loc1=mca_handler_bh // recovery C function 36 movl loc1=mca_handler_bh // recovery C function
41 ;; 37 ;;
42 mov out0=r8 // poisoned address 38 mov out0=r8 // poisoned address
39 mov out1=r9 // iip
40 mov out2=r10 // psr
43 mov b6=loc1 41 mov b6=loc1
44 ;; 42 ;;
45 mov loc1=rp 43 mov loc1=rp
46 ;; 44 ssm psr.i | psr.ic
47 ssm psr.i
48 ;;
49 br.call.sptk.many rp=b6 // does not return ... 45 br.call.sptk.many rp=b6 // does not return ...
50 ;; 46 ;;
51 mov ar.pfs=loc0 47 mov ar.pfs=loc0
@@ -53,5 +49,4 @@ GLOBAL_ENTRY(mca_handler_bhhook)
53 ;; 49 ;;
54 mov r8=r0 50 mov r8=r0
55 br.ret.sptk.many rp 51 br.ret.sptk.many rp
56 ;;
57END(mca_handler_bhhook) 52END(mca_handler_bhhook)
diff --git a/arch/ia64/kernel/numa.c b/arch/ia64/kernel/numa.c
index a68ce6678092..0766493d4d00 100644
--- a/arch/ia64/kernel/numa.c
+++ b/arch/ia64/kernel/numa.c
@@ -25,7 +25,7 @@
25#include <asm/processor.h> 25#include <asm/processor.h>
26#include <asm/smp.h> 26#include <asm/smp.h>
27 27
28u8 cpu_to_node_map[NR_CPUS] __cacheline_aligned; 28u16 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
29EXPORT_SYMBOL(cpu_to_node_map); 29EXPORT_SYMBOL(cpu_to_node_map);
30 30
31cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned; 31cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
diff --git a/arch/ia64/kernel/patch.c b/arch/ia64/kernel/patch.c
index 6a4ac7d70b35..bc11bb096f58 100644
--- a/arch/ia64/kernel/patch.c
+++ b/arch/ia64/kernel/patch.c
@@ -115,7 +115,7 @@ ia64_patch_vtop (unsigned long start, unsigned long end)
115 ia64_srlz_i(); 115 ia64_srlz_i();
116} 116}
117 117
118void 118void __init
119ia64_patch_mckinley_e9 (unsigned long start, unsigned long end) 119ia64_patch_mckinley_e9 (unsigned long start, unsigned long end)
120{ 120{
121 static int first_time = 1; 121 static int first_time = 1;
@@ -149,7 +149,7 @@ ia64_patch_mckinley_e9 (unsigned long start, unsigned long end)
149 ia64_srlz_i(); 149 ia64_srlz_i();
150} 150}
151 151
152static void 152static void __init
153patch_fsyscall_table (unsigned long start, unsigned long end) 153patch_fsyscall_table (unsigned long start, unsigned long end)
154{ 154{
155 extern unsigned long fsyscall_table[NR_syscalls]; 155 extern unsigned long fsyscall_table[NR_syscalls];
@@ -166,7 +166,7 @@ patch_fsyscall_table (unsigned long start, unsigned long end)
166 ia64_srlz_i(); 166 ia64_srlz_i();
167} 167}
168 168
169static void 169static void __init
170patch_brl_fsys_bubble_down (unsigned long start, unsigned long end) 170patch_brl_fsys_bubble_down (unsigned long start, unsigned long end)
171{ 171{
172 extern char fsys_bubble_down[]; 172 extern char fsys_bubble_down[];
@@ -184,7 +184,7 @@ patch_brl_fsys_bubble_down (unsigned long start, unsigned long end)
184 ia64_srlz_i(); 184 ia64_srlz_i();
185} 185}
186 186
187void 187void __init
188ia64_patch_gate (void) 188ia64_patch_gate (void)
189{ 189{
190# define START(name) ((unsigned long) __start_gate_##name##_patchlist) 190# define START(name) ((unsigned long) __start_gate_##name##_patchlist)
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 9c5194b385da..077f21216b65 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -6722,6 +6722,7 @@ __initcall(pfm_init);
6722void 6722void
6723pfm_init_percpu (void) 6723pfm_init_percpu (void)
6724{ 6724{
6725 static int first_time=1;
6725 /* 6726 /*
6726 * make sure no measurement is active 6727 * make sure no measurement is active
6727 * (may inherit programmed PMCs from EFI). 6728 * (may inherit programmed PMCs from EFI).
@@ -6734,8 +6735,10 @@ pfm_init_percpu (void)
6734 */ 6735 */
6735 pfm_unfreeze_pmu(); 6736 pfm_unfreeze_pmu();
6736 6737
6737 if (smp_processor_id() == 0) 6738 if (first_time) {
6738 register_percpu_irq(IA64_PERFMON_VECTOR, &perfmon_irqaction); 6739 register_percpu_irq(IA64_PERFMON_VECTOR, &perfmon_irqaction);
6740 first_time=0;
6741 }
6739 6742
6740 ia64_setreg(_IA64_REG_CR_PMV, IA64_PERFMON_VECTOR); 6743 ia64_setreg(_IA64_REG_CR_PMV, IA64_PERFMON_VECTOR);
6741 ia64_srlz_d(); 6744 ia64_srlz_d();
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 3258e09278d0..eb388e271b2b 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -41,7 +41,6 @@
41#include <linux/serial_core.h> 41#include <linux/serial_core.h>
42#include <linux/efi.h> 42#include <linux/efi.h>
43#include <linux/initrd.h> 43#include <linux/initrd.h>
44#include <linux/platform.h>
45#include <linux/pm.h> 44#include <linux/pm.h>
46#include <linux/cpufreq.h> 45#include <linux/cpufreq.h>
47 46
@@ -131,8 +130,8 @@ EXPORT_SYMBOL(ia64_max_iommu_merge_mask);
131/* 130/*
132 * We use a special marker for the end of memory and it uses the extra (+1) slot 131 * We use a special marker for the end of memory and it uses the extra (+1) slot
133 */ 132 */
134struct rsvd_region rsvd_region[IA64_MAX_RSVD_REGIONS + 1]; 133struct rsvd_region rsvd_region[IA64_MAX_RSVD_REGIONS + 1] __initdata;
135int num_rsvd_regions; 134int num_rsvd_regions __initdata;
136 135
137 136
138/* 137/*
@@ -141,7 +140,7 @@ int num_rsvd_regions;
141 * caller-specified function is called with the memory ranges that remain after filtering. 140 * caller-specified function is called with the memory ranges that remain after filtering.
142 * This routine does not assume the incoming segments are sorted. 141 * This routine does not assume the incoming segments are sorted.
143 */ 142 */
144int 143int __init
145filter_rsvd_memory (unsigned long start, unsigned long end, void *arg) 144filter_rsvd_memory (unsigned long start, unsigned long end, void *arg)
146{ 145{
147 unsigned long range_start, range_end, prev_start; 146 unsigned long range_start, range_end, prev_start;
@@ -177,7 +176,7 @@ filter_rsvd_memory (unsigned long start, unsigned long end, void *arg)
177 return 0; 176 return 0;
178} 177}
179 178
180static void 179static void __init
181sort_regions (struct rsvd_region *rsvd_region, int max) 180sort_regions (struct rsvd_region *rsvd_region, int max)
182{ 181{
183 int j; 182 int j;
@@ -218,7 +217,7 @@ __initcall(register_memory);
218 * initrd, etc. There are currently %IA64_MAX_RSVD_REGIONS defined, 217 * initrd, etc. There are currently %IA64_MAX_RSVD_REGIONS defined,
219 * see include/asm-ia64/meminit.h if you need to define more. 218 * see include/asm-ia64/meminit.h if you need to define more.
220 */ 219 */
221void 220void __init
222reserve_memory (void) 221reserve_memory (void)
223{ 222{
224 int n = 0; 223 int n = 0;
@@ -270,7 +269,7 @@ reserve_memory (void)
270 * Grab the initrd start and end from the boot parameter struct given us by 269 * Grab the initrd start and end from the boot parameter struct given us by
271 * the boot loader. 270 * the boot loader.
272 */ 271 */
273void 272void __init
274find_initrd (void) 273find_initrd (void)
275{ 274{
276#ifdef CONFIG_BLK_DEV_INITRD 275#ifdef CONFIG_BLK_DEV_INITRD
@@ -362,7 +361,7 @@ mark_bsp_online (void)
362} 361}
363 362
364#ifdef CONFIG_SMP 363#ifdef CONFIG_SMP
365static void 364static void __init
366check_for_logical_procs (void) 365check_for_logical_procs (void)
367{ 366{
368 pal_logical_to_physical_t info; 367 pal_logical_to_physical_t info;
@@ -389,6 +388,14 @@ check_for_logical_procs (void)
389} 388}
390#endif 389#endif
391 390
391static __initdata int nomca;
392static __init int setup_nomca(char *s)
393{
394 nomca = 1;
395 return 0;
396}
397early_param("nomca", setup_nomca);
398
392void __init 399void __init
393setup_arch (char **cmdline_p) 400setup_arch (char **cmdline_p)
394{ 401{
@@ -402,35 +409,15 @@ setup_arch (char **cmdline_p)
402 efi_init(); 409 efi_init();
403 io_port_init(); 410 io_port_init();
404 411
412 parse_early_param();
413
405#ifdef CONFIG_IA64_GENERIC 414#ifdef CONFIG_IA64_GENERIC
406 { 415 machvec_init(NULL);
407 const char *mvec_name = strstr (*cmdline_p, "machvec=");
408 char str[64];
409
410 if (mvec_name) {
411 const char *end;
412 size_t len;
413
414 mvec_name += 8;
415 end = strchr (mvec_name, ' ');
416 if (end)
417 len = end - mvec_name;
418 else
419 len = strlen (mvec_name);
420 len = min(len, sizeof (str) - 1);
421 strncpy (str, mvec_name, len);
422 str[len] = '\0';
423 mvec_name = str;
424 } else
425 mvec_name = acpi_get_sysname();
426 machvec_init(mvec_name);
427 }
428#endif 416#endif
429 417
430 if (early_console_setup(*cmdline_p) == 0) 418 if (early_console_setup(*cmdline_p) == 0)
431 mark_bsp_online(); 419 mark_bsp_online();
432 420
433 parse_early_param();
434#ifdef CONFIG_ACPI 421#ifdef CONFIG_ACPI
435 /* Initialize the ACPI boot-time table parser */ 422 /* Initialize the ACPI boot-time table parser */
436 acpi_table_init(); 423 acpi_table_init();
@@ -493,7 +480,7 @@ setup_arch (char **cmdline_p)
493#endif 480#endif
494 481
495 /* enable IA-64 Machine Check Abort Handling unless disabled */ 482 /* enable IA-64 Machine Check Abort Handling unless disabled */
496 if (!strstr(saved_command_line, "nomca")) 483 if (!nomca)
497 ia64_mca_init(); 484 ia64_mca_init();
498 485
499 platform_setup(cmdline_p); 486 platform_setup(cmdline_p);
@@ -623,7 +610,7 @@ struct seq_operations cpuinfo_op = {
623 .show = show_cpuinfo 610 .show = show_cpuinfo
624}; 611};
625 612
626void 613static void __cpuinit
627identify_cpu (struct cpuinfo_ia64 *c) 614identify_cpu (struct cpuinfo_ia64 *c)
628{ 615{
629 union { 616 union {
@@ -700,7 +687,7 @@ setup_per_cpu_areas (void)
700 * In addition, the minimum of the i-cache stride sizes is calculated for 687 * In addition, the minimum of the i-cache stride sizes is calculated for
701 * "flush_icache_range()". 688 * "flush_icache_range()".
702 */ 689 */
703static void 690static void __cpuinit
704get_max_cacheline_size (void) 691get_max_cacheline_size (void)
705{ 692{
706 unsigned long line_size, max = 1; 693 unsigned long line_size, max = 1;
@@ -763,10 +750,10 @@ get_max_cacheline_size (void)
763 * cpu_init() initializes state that is per-CPU. This function acts 750 * cpu_init() initializes state that is per-CPU. This function acts
764 * as a 'CPU state barrier', nothing should get across. 751 * as a 'CPU state barrier', nothing should get across.
765 */ 752 */
766void 753void __cpuinit
767cpu_init (void) 754cpu_init (void)
768{ 755{
769 extern void __devinit ia64_mmu_init (void *); 756 extern void __cpuinit ia64_mmu_init (void *);
770 unsigned long num_phys_stacked; 757 unsigned long num_phys_stacked;
771 pal_vm_info_2_u_t vmi; 758 pal_vm_info_2_u_t vmi;
772 unsigned int max_ctx; 759 unsigned int max_ctx;
@@ -894,7 +881,7 @@ void sched_cacheflush(void)
894 ia64_sal_cache_flush(3); 881 ia64_sal_cache_flush(3);
895} 882}
896 883
897void 884void __init
898check_bugs (void) 885check_bugs (void)
899{ 886{
900 ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles, 887 ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles,
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 463f6bb44d07..1d7903ee2126 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -588,104 +588,3 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
588 } 588 }
589 return 0; 589 return 0;
590} 590}
591
592/* Set a delayed signal that was detected in MCA/INIT/NMI/PMI context where it
593 * could not be delivered. It is important that the target process is not
594 * allowed to do any more work in user space. Possible cases for the target
595 * process:
596 *
597 * - It is sleeping and will wake up soon. Store the data in the current task,
598 * the signal will be sent when the current task returns from the next
599 * interrupt.
600 *
601 * - It is running in user context. Store the data in the current task, the
602 * signal will be sent when the current task returns from the next interrupt.
603 *
604 * - It is running in kernel context on this or another cpu and will return to
605 * user context. Store the data in the target task, the signal will be sent
606 * to itself when the target task returns to user space.
607 *
608 * - It is running in kernel context on this cpu and will sleep before
609 * returning to user context. Because this is also the current task, the
610 * signal will not get delivered and the task could sleep indefinitely.
611 * Store the data in the idle task for this cpu, the signal will be sent
612 * after the idle task processes its next interrupt.
613 *
614 * To cover all cases, store the data in the target task, the current task and
615 * the idle task on this cpu. Whatever happens, the signal will be delivered
616 * to the target task before it can do any useful user space work. Multiple
617 * deliveries have no unwanted side effects.
618 *
619 * Note: This code is executed in MCA/INIT/NMI/PMI context, with interrupts
620 * disabled. It must not take any locks nor use kernel structures or services
621 * that require locks.
622 */
623
624/* To ensure that we get the right pid, check its start time. To avoid extra
625 * include files in thread_info.h, convert the task start_time to unsigned long,
626 * giving us a cycle time of > 580 years.
627 */
628static inline unsigned long
629start_time_ul(const struct task_struct *t)
630{
631 return t->start_time.tv_sec * NSEC_PER_SEC + t->start_time.tv_nsec;
632}
633
634void
635set_sigdelayed(pid_t pid, int signo, int code, void __user *addr)
636{
637 struct task_struct *t;
638 unsigned long start_time = 0;
639 int i;
640
641 for (i = 1; i <= 3; ++i) {
642 switch (i) {
643 case 1:
644 t = find_task_by_pid(pid);
645 if (t)
646 start_time = start_time_ul(t);
647 break;
648 case 2:
649 t = current;
650 break;
651 default:
652 t = idle_task(smp_processor_id());
653 break;
654 }
655
656 if (!t)
657 return;
658 task_thread_info(t)->sigdelayed.signo = signo;
659 task_thread_info(t)->sigdelayed.code = code;
660 task_thread_info(t)->sigdelayed.addr = addr;
661 task_thread_info(t)->sigdelayed.start_time = start_time;
662 task_thread_info(t)->sigdelayed.pid = pid;
663 wmb();
664 set_tsk_thread_flag(t, TIF_SIGDELAYED);
665 }
666}
667
668/* Called from entry.S when it detects TIF_SIGDELAYED, a delayed signal that
669 * was detected in MCA/INIT/NMI/PMI context where it could not be delivered.
670 */
671
672void
673do_sigdelayed(void)
674{
675 struct siginfo siginfo;
676 pid_t pid;
677 struct task_struct *t;
678
679 clear_thread_flag(TIF_SIGDELAYED);
680 memset(&siginfo, 0, sizeof(siginfo));
681 siginfo.si_signo = current_thread_info()->sigdelayed.signo;
682 siginfo.si_code = current_thread_info()->sigdelayed.code;
683 siginfo.si_addr = current_thread_info()->sigdelayed.addr;
684 pid = current_thread_info()->sigdelayed.pid;
685 t = find_task_by_pid(pid);
686 if (!t)
687 return;
688 if (current_thread_info()->sigdelayed.start_time != start_time_ul(t))
689 return;
690 force_sig_info(siginfo.si_signo, &siginfo, t);
691}
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index b681ef34a86e..44e9547878ac 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -70,6 +70,12 @@
70#endif 70#endif
71 71
72#ifdef CONFIG_HOTPLUG_CPU 72#ifdef CONFIG_HOTPLUG_CPU
73#ifdef CONFIG_PERMIT_BSP_REMOVE
74#define bsp_remove_ok 1
75#else
76#define bsp_remove_ok 0
77#endif
78
73/* 79/*
74 * Store all idle threads, this can be reused instead of creating 80 * Store all idle threads, this can be reused instead of creating
75 * a new thread. Also avoids complicated thread destroy functionality 81 * a new thread. Also avoids complicated thread destroy functionality
@@ -104,7 +110,7 @@ struct sal_to_os_boot *sal_state_for_booting_cpu = &sal_boot_rendez_state[0];
104/* 110/*
105 * ITC synchronization related stuff: 111 * ITC synchronization related stuff:
106 */ 112 */
107#define MASTER 0 113#define MASTER (0)
108#define SLAVE (SMP_CACHE_BYTES/8) 114#define SLAVE (SMP_CACHE_BYTES/8)
109 115
110#define NUM_ROUNDS 64 /* magic value */ 116#define NUM_ROUNDS 64 /* magic value */
@@ -151,6 +157,27 @@ char __initdata no_int_routing;
151 157
152unsigned char smp_int_redirect; /* are INT and IPI redirectable by the chipset? */ 158unsigned char smp_int_redirect; /* are INT and IPI redirectable by the chipset? */
153 159
160#ifdef CONFIG_FORCE_CPEI_RETARGET
161#define CPEI_OVERRIDE_DEFAULT (1)
162#else
163#define CPEI_OVERRIDE_DEFAULT (0)
164#endif
165
166unsigned int force_cpei_retarget = CPEI_OVERRIDE_DEFAULT;
167
168static int __init
169cmdl_force_cpei(char *str)
170{
171 int value=0;
172
173 get_option (&str, &value);
174 force_cpei_retarget = value;
175
176 return 1;
177}
178
179__setup("force_cpei=", cmdl_force_cpei);
180
154static int __init 181static int __init
155nointroute (char *str) 182nointroute (char *str)
156{ 183{
@@ -161,6 +188,27 @@ nointroute (char *str)
161 188
162__setup("nointroute", nointroute); 189__setup("nointroute", nointroute);
163 190
191static void fix_b0_for_bsp(void)
192{
193#ifdef CONFIG_HOTPLUG_CPU
194 int cpuid;
195 static int fix_bsp_b0 = 1;
196
197 cpuid = smp_processor_id();
198
199 /*
200 * Cache the b0 value on the first AP that comes up
201 */
202 if (!(fix_bsp_b0 && cpuid))
203 return;
204
205 sal_boot_rendez_state[0].br[0] = sal_boot_rendez_state[cpuid].br[0];
206 printk ("Fixed BSP b0 value from CPU %d\n", cpuid);
207
208 fix_bsp_b0 = 0;
209#endif
210}
211
164void 212void
165sync_master (void *arg) 213sync_master (void *arg)
166{ 214{
@@ -327,8 +375,9 @@ smp_setup_percpu_timer (void)
327static void __devinit 375static void __devinit
328smp_callin (void) 376smp_callin (void)
329{ 377{
330 int cpuid, phys_id; 378 int cpuid, phys_id, itc_master;
331 extern void ia64_init_itm(void); 379 extern void ia64_init_itm(void);
380 extern volatile int time_keeper_id;
332 381
333#ifdef CONFIG_PERFMON 382#ifdef CONFIG_PERFMON
334 extern void pfm_init_percpu(void); 383 extern void pfm_init_percpu(void);
@@ -336,6 +385,7 @@ smp_callin (void)
336 385
337 cpuid = smp_processor_id(); 386 cpuid = smp_processor_id();
338 phys_id = hard_smp_processor_id(); 387 phys_id = hard_smp_processor_id();
388 itc_master = time_keeper_id;
339 389
340 if (cpu_online(cpuid)) { 390 if (cpu_online(cpuid)) {
341 printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n", 391 printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n",
@@ -343,6 +393,8 @@ smp_callin (void)
343 BUG(); 393 BUG();
344 } 394 }
345 395
396 fix_b0_for_bsp();
397
346 lock_ipi_calllock(); 398 lock_ipi_calllock();
347 cpu_set(cpuid, cpu_online_map); 399 cpu_set(cpuid, cpu_online_map);
348 unlock_ipi_calllock(); 400 unlock_ipi_calllock();
@@ -365,8 +417,8 @@ smp_callin (void)
365 * calls spin_unlock_bh(), which calls spin_unlock_bh(), which calls 417 * calls spin_unlock_bh(), which calls spin_unlock_bh(), which calls
366 * local_bh_enable(), which bugs out if irqs are not enabled... 418 * local_bh_enable(), which bugs out if irqs are not enabled...
367 */ 419 */
368 Dprintk("Going to syncup ITC with BP.\n"); 420 Dprintk("Going to syncup ITC with ITC Master.\n");
369 ia64_sync_itc(0); 421 ia64_sync_itc(itc_master);
370 } 422 }
371 423
372 /* 424 /*
@@ -572,32 +624,8 @@ void __devinit smp_prepare_boot_cpu(void)
572 per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; 624 per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
573} 625}
574 626
575/*
576 * mt_info[] is a temporary store for all info returned by
577 * PAL_LOGICAL_TO_PHYSICAL, to be copied into cpuinfo_ia64 when the
578 * specific cpu comes.
579 */
580static struct {
581 __u32 socket_id;
582 __u16 core_id;
583 __u16 thread_id;
584 __u16 proc_fixed_addr;
585 __u8 valid;
586} mt_info[NR_CPUS] __devinitdata;
587
588#ifdef CONFIG_HOTPLUG_CPU 627#ifdef CONFIG_HOTPLUG_CPU
589static inline void 628static inline void
590remove_from_mtinfo(int cpu)
591{
592 int i;
593
594 for_each_cpu(i)
595 if (mt_info[i].valid && mt_info[i].socket_id ==
596 cpu_data(cpu)->socket_id)
597 mt_info[i].valid = 0;
598}
599
600static inline void
601clear_cpu_sibling_map(int cpu) 629clear_cpu_sibling_map(int cpu)
602{ 630{
603 int i; 631 int i;
@@ -626,15 +654,50 @@ remove_siblinginfo(int cpu)
626 654
627 /* remove it from all sibling map's */ 655 /* remove it from all sibling map's */
628 clear_cpu_sibling_map(cpu); 656 clear_cpu_sibling_map(cpu);
657}
658
659extern void fixup_irqs(void);
629 660
630 /* if this cpu is the last in the core group, remove all its info 661int migrate_platform_irqs(unsigned int cpu)
631 * from mt_info structure 662{
663 int new_cpei_cpu;
664 irq_desc_t *desc = NULL;
665 cpumask_t mask;
666 int retval = 0;
667
668 /*
669 * dont permit CPEI target to removed.
632 */ 670 */
633 if (last) 671 if (cpe_vector > 0 && is_cpu_cpei_target(cpu)) {
634 remove_from_mtinfo(cpu); 672 printk ("CPU (%d) is CPEI Target\n", cpu);
673 if (can_cpei_retarget()) {
674 /*
675 * Now re-target the CPEI to a different processor
676 */
677 new_cpei_cpu = any_online_cpu(cpu_online_map);
678 mask = cpumask_of_cpu(new_cpei_cpu);
679 set_cpei_target_cpu(new_cpei_cpu);
680 desc = irq_descp(ia64_cpe_irq);
681 /*
682 * Switch for now, immediatly, we need to do fake intr
683 * as other interrupts, but need to study CPEI behaviour with
684 * polling before making changes.
685 */
686 if (desc) {
687 desc->handler->disable(ia64_cpe_irq);
688 desc->handler->set_affinity(ia64_cpe_irq, mask);
689 desc->handler->enable(ia64_cpe_irq);
690 printk ("Re-targetting CPEI to cpu %d\n", new_cpei_cpu);
691 }
692 }
693 if (!desc) {
694 printk ("Unable to retarget CPEI, offline cpu [%d] failed\n", cpu);
695 retval = -EBUSY;
696 }
697 }
698 return retval;
635} 699}
636 700
637extern void fixup_irqs(void);
638/* must be called with cpucontrol mutex held */ 701/* must be called with cpucontrol mutex held */
639int __cpu_disable(void) 702int __cpu_disable(void)
640{ 703{
@@ -643,8 +706,17 @@ int __cpu_disable(void)
643 /* 706 /*
644 * dont permit boot processor for now 707 * dont permit boot processor for now
645 */ 708 */
646 if (cpu == 0) 709 if (cpu == 0 && !bsp_remove_ok) {
647 return -EBUSY; 710 printk ("Your platform does not support removal of BSP\n");
711 return (-EBUSY);
712 }
713
714 cpu_clear(cpu, cpu_online_map);
715
716 if (migrate_platform_irqs(cpu)) {
717 cpu_set(cpu, cpu_online_map);
718 return (-EBUSY);
719 }
648 720
649 remove_siblinginfo(cpu); 721 remove_siblinginfo(cpu);
650 cpu_clear(cpu, cpu_online_map); 722 cpu_clear(cpu, cpu_online_map);
@@ -776,40 +848,6 @@ init_smp_config(void)
776 ia64_sal_strerror(sal_ret)); 848 ia64_sal_strerror(sal_ret));
777} 849}
778 850
779static inline int __devinit
780check_for_mtinfo_index(void)
781{
782 int i;
783
784 for_each_cpu(i)
785 if (!mt_info[i].valid)
786 return i;
787
788 return -1;
789}
790
791/*
792 * Search the mt_info to find out if this socket's cid/tid information is
793 * cached or not. If the socket exists, fill in the core_id and thread_id
794 * in cpuinfo
795 */
796static int __devinit
797check_for_new_socket(__u16 logical_address, struct cpuinfo_ia64 *c)
798{
799 int i;
800 __u32 sid = c->socket_id;
801
802 for_each_cpu(i) {
803 if (mt_info[i].valid && mt_info[i].proc_fixed_addr == logical_address
804 && mt_info[i].socket_id == sid) {
805 c->core_id = mt_info[i].core_id;
806 c->thread_id = mt_info[i].thread_id;
807 return 1; /* not a new socket */
808 }
809 }
810 return 0;
811}
812
813/* 851/*
814 * identify_siblings(cpu) gets called from identify_cpu. This populates the 852 * identify_siblings(cpu) gets called from identify_cpu. This populates the
815 * information related to logical execution units in per_cpu_data structure. 853 * information related to logical execution units in per_cpu_data structure.
@@ -819,14 +857,12 @@ identify_siblings(struct cpuinfo_ia64 *c)
819{ 857{
820 s64 status; 858 s64 status;
821 u16 pltid; 859 u16 pltid;
822 u64 proc_fixed_addr;
823 int count, i;
824 pal_logical_to_physical_t info; 860 pal_logical_to_physical_t info;
825 861
826 if (smp_num_cpucores == 1 && smp_num_siblings == 1) 862 if (smp_num_cpucores == 1 && smp_num_siblings == 1)
827 return; 863 return;
828 864
829 if ((status = ia64_pal_logical_to_phys(0, &info)) != PAL_STATUS_SUCCESS) { 865 if ((status = ia64_pal_logical_to_phys(-1, &info)) != PAL_STATUS_SUCCESS) {
830 printk(KERN_ERR "ia64_pal_logical_to_phys failed with %ld\n", 866 printk(KERN_ERR "ia64_pal_logical_to_phys failed with %ld\n",
831 status); 867 status);
832 return; 868 return;
@@ -835,47 +871,12 @@ identify_siblings(struct cpuinfo_ia64 *c)
835 printk(KERN_ERR "ia64_sal_pltid failed with %ld\n", status); 871 printk(KERN_ERR "ia64_sal_pltid failed with %ld\n", status);
836 return; 872 return;
837 } 873 }
838 if ((status = ia64_pal_fixed_addr(&proc_fixed_addr)) != PAL_STATUS_SUCCESS) {
839 printk(KERN_ERR "ia64_pal_fixed_addr failed with %ld\n", status);
840 return;
841 }
842 874
843 c->socket_id = (pltid << 8) | info.overview_ppid; 875 c->socket_id = (pltid << 8) | info.overview_ppid;
844 c->cores_per_socket = info.overview_cpp; 876 c->cores_per_socket = info.overview_cpp;
845 c->threads_per_core = info.overview_tpc; 877 c->threads_per_core = info.overview_tpc;
846 count = c->num_log = info.overview_num_log; 878 c->num_log = info.overview_num_log;
847
848 /* If the thread and core id information is already cached, then
849 * we will simply update cpu_info and return. Otherwise, we will
850 * do the PAL calls and cache core and thread id's of all the siblings.
851 */
852 if (check_for_new_socket(proc_fixed_addr, c))
853 return;
854
855 for (i = 0; i < count; i++) {
856 int index;
857
858 if (i && (status = ia64_pal_logical_to_phys(i, &info))
859 != PAL_STATUS_SUCCESS) {
860 printk(KERN_ERR "ia64_pal_logical_to_phys failed"
861 " with %ld\n", status);
862 return;
863 }
864 if (info.log2_la == proc_fixed_addr) {
865 c->core_id = info.log1_cid;
866 c->thread_id = info.log1_tid;
867 }
868 879
869 index = check_for_mtinfo_index(); 880 c->core_id = info.log1_cid;
870 /* We will not do the mt_info caching optimization in this case. 881 c->thread_id = info.log1_tid;
871 */
872 if (index < 0)
873 continue;
874
875 mt_info[index].valid = 1;
876 mt_info[index].socket_id = c->socket_id;
877 mt_info[index].core_id = info.log1_cid;
878 mt_info[index].thread_id = info.log1_tid;
879 mt_info[index].proc_fixed_addr = info.log2_la;
880 }
881} 882}
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 307d01e15b2e..ac167436e936 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -32,7 +32,7 @@
32 32
33extern unsigned long wall_jiffies; 33extern unsigned long wall_jiffies;
34 34
35#define TIME_KEEPER_ID 0 /* smp_processor_id() of time-keeper */ 35volatile int time_keeper_id = 0; /* smp_processor_id() of time-keeper */
36 36
37#ifdef CONFIG_IA64_DEBUG_IRQ 37#ifdef CONFIG_IA64_DEBUG_IRQ
38 38
@@ -71,7 +71,7 @@ timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
71 71
72 new_itm += local_cpu_data->itm_delta; 72 new_itm += local_cpu_data->itm_delta;
73 73
74 if (smp_processor_id() == TIME_KEEPER_ID) { 74 if (smp_processor_id() == time_keeper_id) {
75 /* 75 /*
76 * Here we are in the timer irq handler. We have irqs locally 76 * Here we are in the timer irq handler. We have irqs locally
77 * disabled, but we don't know if the timer_bh is running on 77 * disabled, but we don't know if the timer_bh is running on
@@ -236,6 +236,11 @@ static struct irqaction timer_irqaction = {
236 .name = "timer" 236 .name = "timer"
237}; 237};
238 238
239void __devinit ia64_disable_timer(void)
240{
241 ia64_set_itv(1 << 16);
242}
243
239void __init 244void __init
240time_init (void) 245time_init (void)
241{ 246{
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
index 6e5eea19fa67..3b6fd798c4d6 100644
--- a/arch/ia64/kernel/topology.c
+++ b/arch/ia64/kernel/topology.c
@@ -36,7 +36,7 @@ int arch_register_cpu(int num)
36 parent = &sysfs_nodes[cpu_to_node(num)]; 36 parent = &sysfs_nodes[cpu_to_node(num)];
37#endif /* CONFIG_NUMA */ 37#endif /* CONFIG_NUMA */
38 38
39#ifdef CONFIG_ACPI 39#if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU)
40 /* 40 /*
41 * If CPEI cannot be re-targetted, and this is 41 * If CPEI cannot be re-targetted, and this is
42 * CPEI target, then dont create the control file 42 * CPEI target, then dont create the control file
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 73af6267d2ef..0b9e56dd7f05 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -70,34 +70,9 @@ SECTIONS
70 __stop___ex_table = .; 70 __stop___ex_table = .;
71 } 71 }
72 72
73 .data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET)
74 {
75 __start___vtop_patchlist = .;
76 *(.data.patch.vtop)
77 __end___vtop_patchlist = .;
78 }
79
80 .data.patch.mckinley_e9 : AT(ADDR(.data.patch.mckinley_e9) - LOAD_OFFSET)
81 {
82 __start___mckinley_e9_bundles = .;
83 *(.data.patch.mckinley_e9)
84 __end___mckinley_e9_bundles = .;
85 }
86
87 /* Global data */ 73 /* Global data */
88 _data = .; 74 _data = .;
89 75
90#if defined(CONFIG_IA64_GENERIC)
91 /* Machine Vector */
92 . = ALIGN(16);
93 .machvec : AT(ADDR(.machvec) - LOAD_OFFSET)
94 {
95 machvec_start = .;
96 *(.machvec)
97 machvec_end = .;
98 }
99#endif
100
101 /* Unwind info & table: */ 76 /* Unwind info & table: */
102 . = ALIGN(8); 77 . = ALIGN(8);
103 .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - LOAD_OFFSET) 78 .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - LOAD_OFFSET)
@@ -154,6 +129,41 @@ SECTIONS
154 *(.initcall7.init) 129 *(.initcall7.init)
155 __initcall_end = .; 130 __initcall_end = .;
156 } 131 }
132
133 /* MCA table */
134 . = ALIGN(16);
135 __mca_table : AT(ADDR(__mca_table) - LOAD_OFFSET)
136 {
137 __start___mca_table = .;
138 *(__mca_table)
139 __stop___mca_table = .;
140 }
141
142 .data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET)
143 {
144 __start___vtop_patchlist = .;
145 *(.data.patch.vtop)
146 __end___vtop_patchlist = .;
147 }
148
149 .data.patch.mckinley_e9 : AT(ADDR(.data.patch.mckinley_e9) - LOAD_OFFSET)
150 {
151 __start___mckinley_e9_bundles = .;
152 *(.data.patch.mckinley_e9)
153 __end___mckinley_e9_bundles = .;
154 }
155
156#if defined(CONFIG_IA64_GENERIC)
157 /* Machine Vector */
158 . = ALIGN(16);
159 .machvec : AT(ADDR(.machvec) - LOAD_OFFSET)
160 {
161 machvec_start = .;
162 *(.machvec)
163 machvec_end = .;
164 }
165#endif
166
157 __con_initcall_start = .; 167 __con_initcall_start = .;
158 .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) 168 .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET)
159 { *(.con_initcall.init) } 169 { *(.con_initcall.init) }
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
index acaaec4e4681..84fd1c14c8a9 100644
--- a/arch/ia64/mm/contig.c
+++ b/arch/ia64/mm/contig.c
@@ -97,7 +97,7 @@ find_max_pfn (unsigned long start, unsigned long end, void *arg)
97 * Find a place to put the bootmap and return its starting address in 97 * Find a place to put the bootmap and return its starting address in
98 * bootmap_start. This address must be page-aligned. 98 * bootmap_start. This address must be page-aligned.
99 */ 99 */
100int 100static int __init
101find_bootmap_location (unsigned long start, unsigned long end, void *arg) 101find_bootmap_location (unsigned long start, unsigned long end, void *arg)
102{ 102{
103 unsigned long needed = *(unsigned long *)arg; 103 unsigned long needed = *(unsigned long *)arg;
@@ -141,7 +141,7 @@ find_bootmap_location (unsigned long start, unsigned long end, void *arg)
141 * Walk the EFI memory map and find usable memory for the system, taking 141 * Walk the EFI memory map and find usable memory for the system, taking
142 * into account reserved areas. 142 * into account reserved areas.
143 */ 143 */
144void 144void __init
145find_memory (void) 145find_memory (void)
146{ 146{
147 unsigned long bootmap_size; 147 unsigned long bootmap_size;
@@ -176,18 +176,20 @@ find_memory (void)
176 * 176 *
177 * Allocate and setup per-cpu data areas. 177 * Allocate and setup per-cpu data areas.
178 */ 178 */
179void * 179void * __cpuinit
180per_cpu_init (void) 180per_cpu_init (void)
181{ 181{
182 void *cpu_data; 182 void *cpu_data;
183 int cpu; 183 int cpu;
184 static int first_time=1;
184 185
185 /* 186 /*
186 * get_free_pages() cannot be used before cpu_init() done. BSP 187 * get_free_pages() cannot be used before cpu_init() done. BSP
187 * allocates "NR_CPUS" pages for all CPUs to avoid that AP calls 188 * allocates "NR_CPUS" pages for all CPUs to avoid that AP calls
188 * get_zeroed_page(). 189 * get_zeroed_page().
189 */ 190 */
190 if (smp_processor_id() == 0) { 191 if (first_time) {
192 first_time=0;
191 cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS, 193 cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS,
192 PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS)); 194 PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
193 for (cpu = 0; cpu < NR_CPUS; cpu++) { 195 for (cpu = 0; cpu < NR_CPUS; cpu++) {
@@ -226,7 +228,7 @@ count_dma_pages (u64 start, u64 end, void *arg)
226 * Set up the page tables. 228 * Set up the page tables.
227 */ 229 */
228 230
229void 231void __init
230paging_init (void) 232paging_init (void)
231{ 233{
232 unsigned long max_dma; 234 unsigned long max_dma;
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index c87d6d1d5813..2f5e44862e91 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -525,15 +525,20 @@ void __init find_memory(void)
525 * find_pernode_space() does most of this already, we just need to set 525 * find_pernode_space() does most of this already, we just need to set
526 * local_per_cpu_offset 526 * local_per_cpu_offset
527 */ 527 */
528void *per_cpu_init(void) 528void __cpuinit *per_cpu_init(void)
529{ 529{
530 int cpu; 530 int cpu;
531 static int first_time = 1;
532
531 533
532 if (smp_processor_id() != 0) 534 if (smp_processor_id() != 0)
533 return __per_cpu_start + __per_cpu_offset[smp_processor_id()]; 535 return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
534 536
535 for (cpu = 0; cpu < NR_CPUS; cpu++) 537 if (first_time) {
536 per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu]; 538 first_time = 0;
539 for (cpu = 0; cpu < NR_CPUS; cpu++)
540 per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
541 }
537 542
538 return __per_cpu_start + __per_cpu_offset[smp_processor_id()]; 543 return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
539} 544}
diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
index 2d13889d0a99..8d506710fdbd 100644
--- a/arch/ia64/mm/hugetlbpage.c
+++ b/arch/ia64/mm/hugetlbpage.c
@@ -68,9 +68,10 @@ huge_pte_offset (struct mm_struct *mm, unsigned long addr)
68#define mk_pte_huge(entry) { pte_val(entry) |= _PAGE_P; } 68#define mk_pte_huge(entry) { pte_val(entry) |= _PAGE_P; }
69 69
70/* 70/*
71 * This function checks for proper alignment of input addr and len parameters. 71 * Don't actually need to do any preparation, but need to make sure
72 * the address is in the right region.
72 */ 73 */
73int is_aligned_hugepage_range(unsigned long addr, unsigned long len) 74int prepare_hugepage_range(unsigned long addr, unsigned long len)
74{ 75{
75 if (len & ~HPAGE_MASK) 76 if (len & ~HPAGE_MASK)
76 return -EINVAL; 77 return -EINVAL;
@@ -112,8 +113,7 @@ void hugetlb_free_pgd_range(struct mmu_gather **tlb,
112 unsigned long floor, unsigned long ceiling) 113 unsigned long floor, unsigned long ceiling)
113{ 114{
114 /* 115 /*
115 * This is called only when is_hugepage_only_range(addr,), 116 * This is called to free hugetlb page tables.
116 * and it follows that is_hugepage_only_range(end,) also.
117 * 117 *
118 * The offset of these addresses from the base of the hugetlb 118 * The offset of these addresses from the base of the hugetlb
119 * region must be scaled down by HPAGE_SIZE/PAGE_SIZE so that 119 * region must be scaled down by HPAGE_SIZE/PAGE_SIZE so that
@@ -125,9 +125,9 @@ void hugetlb_free_pgd_range(struct mmu_gather **tlb,
125 125
126 addr = htlbpage_to_page(addr); 126 addr = htlbpage_to_page(addr);
127 end = htlbpage_to_page(end); 127 end = htlbpage_to_page(end);
128 if (is_hugepage_only_range(tlb->mm, floor, HPAGE_SIZE)) 128 if (REGION_NUMBER(floor) == RGN_HPAGE)
129 floor = htlbpage_to_page(floor); 129 floor = htlbpage_to_page(floor);
130 if (is_hugepage_only_range(tlb->mm, ceiling, HPAGE_SIZE)) 130 if (REGION_NUMBER(ceiling) == RGN_HPAGE)
131 ceiling = htlbpage_to_page(ceiling); 131 ceiling = htlbpage_to_page(ceiling);
132 132
133 free_pgd_range(tlb, addr, end, floor, ceiling); 133 free_pgd_range(tlb, addr, end, floor, ceiling);
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index b38b6d213c15..ff4f31fcd330 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -197,7 +197,7 @@ free_initmem (void)
197 eaddr = (unsigned long) ia64_imva(__init_end); 197 eaddr = (unsigned long) ia64_imva(__init_end);
198 while (addr < eaddr) { 198 while (addr < eaddr) {
199 ClearPageReserved(virt_to_page(addr)); 199 ClearPageReserved(virt_to_page(addr));
200 set_page_count(virt_to_page(addr), 1); 200 init_page_count(virt_to_page(addr));
201 free_page(addr); 201 free_page(addr);
202 ++totalram_pages; 202 ++totalram_pages;
203 addr += PAGE_SIZE; 203 addr += PAGE_SIZE;
@@ -206,7 +206,7 @@ free_initmem (void)
206 (__init_end - __init_begin) >> 10); 206 (__init_end - __init_begin) >> 10);
207} 207}
208 208
209void 209void __init
210free_initrd_mem (unsigned long start, unsigned long end) 210free_initrd_mem (unsigned long start, unsigned long end)
211{ 211{
212 struct page *page; 212 struct page *page;
@@ -252,7 +252,7 @@ free_initrd_mem (unsigned long start, unsigned long end)
252 continue; 252 continue;
253 page = virt_to_page(start); 253 page = virt_to_page(start);
254 ClearPageReserved(page); 254 ClearPageReserved(page);
255 set_page_count(page, 1); 255 init_page_count(page);
256 free_page(start); 256 free_page(start);
257 ++totalram_pages; 257 ++totalram_pages;
258 } 258 }
@@ -261,7 +261,7 @@ free_initrd_mem (unsigned long start, unsigned long end)
261/* 261/*
262 * This installs a clean page in the kernel's page table. 262 * This installs a clean page in the kernel's page table.
263 */ 263 */
264struct page * 264static struct page * __init
265put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot) 265put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot)
266{ 266{
267 pgd_t *pgd; 267 pgd_t *pgd;
@@ -294,7 +294,7 @@ put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot)
294 return page; 294 return page;
295} 295}
296 296
297static void 297static void __init
298setup_gate (void) 298setup_gate (void)
299{ 299{
300 struct page *page; 300 struct page *page;
@@ -411,7 +411,7 @@ ia64_mmu_init (void *my_cpu_data)
411 411
412#ifdef CONFIG_VIRTUAL_MEM_MAP 412#ifdef CONFIG_VIRTUAL_MEM_MAP
413 413
414int 414int __init
415create_mem_map_page_table (u64 start, u64 end, void *arg) 415create_mem_map_page_table (u64 start, u64 end, void *arg)
416{ 416{
417 unsigned long address, start_page, end_page; 417 unsigned long address, start_page, end_page;
@@ -519,7 +519,7 @@ ia64_pfn_valid (unsigned long pfn)
519} 519}
520EXPORT_SYMBOL(ia64_pfn_valid); 520EXPORT_SYMBOL(ia64_pfn_valid);
521 521
522int 522int __init
523find_largest_hole (u64 start, u64 end, void *arg) 523find_largest_hole (u64 start, u64 end, void *arg)
524{ 524{
525 u64 *max_gap = arg; 525 u64 *max_gap = arg;
@@ -535,7 +535,7 @@ find_largest_hole (u64 start, u64 end, void *arg)
535} 535}
536#endif /* CONFIG_VIRTUAL_MEM_MAP */ 536#endif /* CONFIG_VIRTUAL_MEM_MAP */
537 537
538static int 538static int __init
539count_reserved_pages (u64 start, u64 end, void *arg) 539count_reserved_pages (u64 start, u64 end, void *arg)
540{ 540{
541 unsigned long num_reserved = 0; 541 unsigned long num_reserved = 0;
@@ -556,7 +556,7 @@ count_reserved_pages (u64 start, u64 end, void *arg)
556 * purposes. 556 * purposes.
557 */ 557 */
558 558
559static int nolwsys; 559static int nolwsys __initdata;
560 560
561static int __init 561static int __init
562nolwsys_setup (char *s) 562nolwsys_setup (char *s)
@@ -567,7 +567,7 @@ nolwsys_setup (char *s)
567 567
568__setup("nolwsys", nolwsys_setup); 568__setup("nolwsys", nolwsys_setup);
569 569
570void 570void __init
571mem_init (void) 571mem_init (void)
572{ 572{
573 long reserved_pages, codesize, datasize, initsize; 573 long reserved_pages, codesize, datasize, initsize;
@@ -640,7 +640,7 @@ mem_init (void)
640void online_page(struct page *page) 640void online_page(struct page *page)
641{ 641{
642 ClearPageReserved(page); 642 ClearPageReserved(page);
643 set_page_count(page, 1); 643 init_page_count(page);
644 __free_page(page); 644 __free_page(page);
645 totalram_pages++; 645 totalram_pages++;
646 num_physpages++; 646 num_physpages++;
diff --git a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile
index 3e9b4eea7418..ab9c48c88012 100644
--- a/arch/ia64/sn/kernel/Makefile
+++ b/arch/ia64/sn/kernel/Makefile
@@ -10,7 +10,8 @@
10CPPFLAGS += -I$(srctree)/arch/ia64/sn/include 10CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
11 11
12obj-y += setup.o bte.o bte_error.o irq.o mca.o idle.o \ 12obj-y += setup.o bte.o bte_error.o irq.o mca.o idle.o \
13 huberror.o io_init.o iomv.o klconflib.o sn2/ 13 huberror.o io_init.o iomv.o klconflib.o pio_phys.o \
14 sn2/
14obj-$(CONFIG_IA64_GENERIC) += machvec.o 15obj-$(CONFIG_IA64_GENERIC) += machvec.o
15obj-$(CONFIG_SGI_TIOCX) += tiocx.o 16obj-$(CONFIG_SGI_TIOCX) += tiocx.o
16obj-$(CONFIG_IA64_SGI_SN_XP) += xp.o 17obj-$(CONFIG_IA64_SGI_SN_XP) += xp.o
diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c
index 1f11db470d90..e952ef4f6d91 100644
--- a/arch/ia64/sn/kernel/bte.c
+++ b/arch/ia64/sn/kernel/bte.c
@@ -36,7 +36,7 @@ static struct bteinfo_s *bte_if_on_node(nasid_t nasid, int interface)
36 nodepda_t *tmp_nodepda; 36 nodepda_t *tmp_nodepda;
37 37
38 if (nasid_to_cnodeid(nasid) == -1) 38 if (nasid_to_cnodeid(nasid) == -1)
39 return (struct bteinfo_s *)NULL;; 39 return (struct bteinfo_s *)NULL;
40 40
41 tmp_nodepda = NODEPDA(nasid_to_cnodeid(nasid)); 41 tmp_nodepda = NODEPDA(nasid_to_cnodeid(nasid));
42 return &tmp_nodepda->bte_if[interface]; 42 return &tmp_nodepda->bte_if[interface];
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index dfb3f2902379..5101ac462643 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -13,6 +13,8 @@
13#include <asm/sn/sn_feature_sets.h> 13#include <asm/sn/sn_feature_sets.h>
14#include <asm/sn/geo.h> 14#include <asm/sn/geo.h>
15#include <asm/sn/io.h> 15#include <asm/sn/io.h>
16#include <asm/sn/l1.h>
17#include <asm/sn/module.h>
16#include <asm/sn/pcibr_provider.h> 18#include <asm/sn/pcibr_provider.h>
17#include <asm/sn/pcibus_provider_defs.h> 19#include <asm/sn/pcibus_provider_defs.h>
18#include <asm/sn/pcidev.h> 20#include <asm/sn/pcidev.h>
@@ -710,9 +712,36 @@ cnodeid_get_geoid(cnodeid_t cnode)
710 return hubdev->hdi_geoid; 712 return hubdev->hdi_geoid;
711} 713}
712 714
715void sn_generate_path(struct pci_bus *pci_bus, char *address)
716{
717 nasid_t nasid;
718 cnodeid_t cnode;
719 geoid_t geoid;
720 moduleid_t moduleid;
721 u16 bricktype;
722
723 nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base);
724 cnode = nasid_to_cnodeid(nasid);
725 geoid = cnodeid_get_geoid(cnode);
726 moduleid = geo_module(geoid);
727
728 sprintf(address, "module_%c%c%c%c%.2d",
729 '0'+RACK_GET_CLASS(MODULE_GET_RACK(moduleid)),
730 '0'+RACK_GET_GROUP(MODULE_GET_RACK(moduleid)),
731 '0'+RACK_GET_NUM(MODULE_GET_RACK(moduleid)),
732 MODULE_GET_BTCHAR(moduleid), MODULE_GET_BPOS(moduleid));
733
734 /* Tollhouse requires slot id to be displayed */
735 bricktype = MODULE_GET_BTYPE(moduleid);
736 if ((bricktype == L1_BRICKTYPE_191010) ||
737 (bricktype == L1_BRICKTYPE_1932))
738 sprintf(address, "%s^%d", address, geo_slot(geoid));
739}
740
713subsys_initcall(sn_pci_init); 741subsys_initcall(sn_pci_init);
714EXPORT_SYMBOL(sn_pci_fixup_slot); 742EXPORT_SYMBOL(sn_pci_fixup_slot);
715EXPORT_SYMBOL(sn_pci_unfixup_slot); 743EXPORT_SYMBOL(sn_pci_unfixup_slot);
716EXPORT_SYMBOL(sn_pci_controller_fixup); 744EXPORT_SYMBOL(sn_pci_controller_fixup);
717EXPORT_SYMBOL(sn_bus_store_sysdata); 745EXPORT_SYMBOL(sn_bus_store_sysdata);
718EXPORT_SYMBOL(sn_bus_free_sysdata); 746EXPORT_SYMBOL(sn_bus_free_sysdata);
747EXPORT_SYMBOL(sn_generate_path);
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index c373113d073a..c265e02f5036 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -350,9 +350,6 @@ static void force_interrupt(int irq)
350static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) 350static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info)
351{ 351{
352 u64 regval; 352 u64 regval;
353 int irr_reg_num;
354 int irr_bit;
355 u64 irr_reg;
356 struct pcidev_info *pcidev_info; 353 struct pcidev_info *pcidev_info;
357 struct pcibus_info *pcibus_info; 354 struct pcibus_info *pcibus_info;
358 355
@@ -373,23 +370,7 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info)
373 pdi_pcibus_info; 370 pdi_pcibus_info;
374 regval = pcireg_intr_status_get(pcibus_info); 371 regval = pcireg_intr_status_get(pcibus_info);
375 372
376 irr_reg_num = irq_to_vector(irq) / 64; 373 if (!ia64_get_irr(irq_to_vector(irq))) {
377 irr_bit = irq_to_vector(irq) % 64;
378 switch (irr_reg_num) {
379 case 0:
380 irr_reg = ia64_getreg(_IA64_REG_CR_IRR0);
381 break;
382 case 1:
383 irr_reg = ia64_getreg(_IA64_REG_CR_IRR1);
384 break;
385 case 2:
386 irr_reg = ia64_getreg(_IA64_REG_CR_IRR2);
387 break;
388 case 3:
389 irr_reg = ia64_getreg(_IA64_REG_CR_IRR3);
390 break;
391 }
392 if (!test_bit(irr_bit, &irr_reg)) {
393 if (!test_bit(irq, pda->sn_in_service_ivecs)) { 374 if (!test_bit(irq, pda->sn_in_service_ivecs)) {
394 regval &= 0xff; 375 regval &= 0xff;
395 if (sn_irq_info->irq_int_bit & regval & 376 if (sn_irq_info->irq_int_bit & regval &
diff --git a/arch/ia64/sn/kernel/pio_phys.S b/arch/ia64/sn/kernel/pio_phys.S
new file mode 100644
index 000000000000..3c7d48d6ecb8
--- /dev/null
+++ b/arch/ia64/sn/kernel/pio_phys.S
@@ -0,0 +1,71 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
7 *
8 * This file contains macros used to access MMR registers via
9 * uncached physical addresses.
10 * pio_phys_read_mmr - read an MMR
11 * pio_phys_write_mmr - write an MMR
12 * pio_atomic_phys_write_mmrs - atomically write 1 or 2 MMRs with psr.ic=0
13 * Second MMR will be skipped if address is NULL
14 *
15 * Addresses passed to these routines should be uncached physical addresses
16 * ie., 0x80000....
17 */
18
19
20
21#include <asm/asmmacro.h>
22#include <asm/page.h>
23
24GLOBAL_ENTRY(pio_phys_read_mmr)
25 .prologue
26 .regstk 1,0,0,0
27 .body
28 mov r2=psr
29 rsm psr.i | psr.dt
30 ;;
31 srlz.d
32 ld8.acq r8=[r32]
33 ;;
34 mov psr.l=r2;;
35 srlz.d
36 br.ret.sptk.many rp
37END(pio_phys_read_mmr)
38
39GLOBAL_ENTRY(pio_phys_write_mmr)
40 .prologue
41 .regstk 2,0,0,0
42 .body
43 mov r2=psr
44 rsm psr.i | psr.dt
45 ;;
46 srlz.d
47 st8.rel [r32]=r33
48 ;;
49 mov psr.l=r2;;
50 srlz.d
51 br.ret.sptk.many rp
52END(pio_phys_write_mmr)
53
54GLOBAL_ENTRY(pio_atomic_phys_write_mmrs)
55 .prologue
56 .regstk 4,0,0,0
57 .body
58 mov r2=psr
59 cmp.ne p9,p0=r34,r0;
60 rsm psr.i | psr.dt | psr.ic
61 ;;
62 srlz.d
63 st8.rel [r32]=r33
64(p9) st8.rel [r34]=r35
65 ;;
66 mov psr.l=r2;;
67 srlz.d
68 br.ret.sptk.many rp
69END(pio_atomic_phys_write_mmrs)
70
71
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index 5b84836c2171..8b6d5c844708 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 1999,2001-2005 Silicon Graphics, Inc. All rights reserved. 6 * Copyright (C) 1999,2001-2006 Silicon Graphics, Inc. All rights reserved.
7 */ 7 */
8 8
9#include <linux/config.h> 9#include <linux/config.h>
@@ -498,6 +498,7 @@ void __init sn_setup(char **cmdline_p)
498 * for sn. 498 * for sn.
499 */ 499 */
500 pm_power_off = ia64_sn_power_down; 500 pm_power_off = ia64_sn_power_down;
501 current->thread.flags |= IA64_THREAD_MIGRATION;
501} 502}
502 503
503/** 504/**
@@ -660,7 +661,8 @@ void __init sn_cpu_init(void)
660 SH2_PIO_WRITE_STATUS_1, SH2_PIO_WRITE_STATUS_3}; 661 SH2_PIO_WRITE_STATUS_1, SH2_PIO_WRITE_STATUS_3};
661 u64 *pio; 662 u64 *pio;
662 pio = is_shub1() ? pio1 : pio2; 663 pio = is_shub1() ? pio1 : pio2;
663 pda->pio_write_status_addr = (volatile unsigned long *) LOCAL_MMR_ADDR(pio[slice]); 664 pda->pio_write_status_addr =
665 (volatile unsigned long *)GLOBAL_MMR_ADDR(nasid, pio[slice]);
664 pda->pio_write_status_val = is_shub1() ? SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK : 0; 666 pda->pio_write_status_val = is_shub1() ? SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK : 0;
665 } 667 }
666 668
diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c
index b2e1e746b47f..d9d306c79f2d 100644
--- a/arch/ia64/sn/kernel/sn2/sn2_smp.c
+++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c
@@ -93,6 +93,27 @@ static inline unsigned long wait_piowc(void)
93 return (ws & SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK) != 0; 93 return (ws & SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK) != 0;
94} 94}
95 95
96/**
97 * sn_migrate - SN-specific task migration actions
98 * @task: Task being migrated to new CPU
99 *
100 * SN2 PIO writes from separate CPUs are not guaranteed to arrive in order.
101 * Context switching user threads which have memory-mapped MMIO may cause
102 * PIOs to issue from seperate CPUs, thus the PIO writes must be drained
103 * from the previous CPU's Shub before execution resumes on the new CPU.
104 */
105void sn_migrate(struct task_struct *task)
106{
107 pda_t *last_pda = pdacpu(task_thread_info(task)->last_cpu);
108 volatile unsigned long *adr = last_pda->pio_write_status_addr;
109 unsigned long val = last_pda->pio_write_status_val;
110
111 /* Drain PIO writes from old CPU's Shub */
112 while (unlikely((*adr & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK)
113 != val))
114 cpu_relax();
115}
116
96void sn_tlb_migrate_finish(struct mm_struct *mm) 117void sn_tlb_migrate_finish(struct mm_struct *mm)
97{ 118{
98 /* flush_tlb_mm is inefficient if more than 1 users of mm */ 119 /* flush_tlb_mm is inefficient if more than 1 users of mm */
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c
index 99cb28e74295..feaf1a6e8101 100644
--- a/arch/ia64/sn/kernel/tiocx.c
+++ b/arch/ia64/sn/kernel/tiocx.c
@@ -369,9 +369,15 @@ static void tio_corelet_reset(nasid_t nasid, int corelet)
369 369
370static int is_fpga_tio(int nasid, int *bt) 370static int is_fpga_tio(int nasid, int *bt)
371{ 371{
372 int ioboard_type; 372 u16 ioboard_type;
373 s64 rc;
373 374
374 ioboard_type = ia64_sn_sysctl_ioboard_get(nasid); 375 rc = ia64_sn_sysctl_ioboard_get(nasid, &ioboard_type);
376 if (rc) {
377 printk(KERN_WARNING "ia64_sn_sysctl_ioboard_get failed: %ld\n",
378 rc);
379 return 0;
380 }
375 381
376 switch (ioboard_type) { 382 switch (ioboard_type) {
377 case L1_BRICKTYPE_SA: 383 case L1_BRICKTYPE_SA:
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
index cdf6856ce089..d0abddd9ffe6 100644
--- a/arch/ia64/sn/kernel/xpc_channel.c
+++ b/arch/ia64/sn/kernel/xpc_channel.c
@@ -21,7 +21,6 @@
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <linux/cache.h> 22#include <linux/cache.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/slab.h>
25#include <linux/mutex.h> 24#include <linux/mutex.h>
26#include <linux/completion.h> 25#include <linux/completion.h>
27#include <asm/sn/bte.h> 26#include <asm/sn/bte.h>
@@ -30,6 +29,31 @@
30 29
31 30
32/* 31/*
32 * Guarantee that the kzalloc'd memory is cacheline aligned.
33 */
34static void *
35xpc_kzalloc_cacheline_aligned(size_t size, gfp_t flags, void **base)
36{
37 /* see if kzalloc will give us cachline aligned memory by default */
38 *base = kzalloc(size, flags);
39 if (*base == NULL) {
40 return NULL;
41 }
42 if ((u64) *base == L1_CACHE_ALIGN((u64) *base)) {
43 return *base;
44 }
45 kfree(*base);
46
47 /* nope, we'll have to do it ourselves */
48 *base = kzalloc(size + L1_CACHE_BYTES, flags);
49 if (*base == NULL) {
50 return NULL;
51 }
52 return (void *) L1_CACHE_ALIGN((u64) *base);
53}
54
55
56/*
33 * Set up the initial values for the XPartition Communication channels. 57 * Set up the initial values for the XPartition Communication channels.
34 */ 58 */
35static void 59static void
@@ -93,20 +117,19 @@ xpc_setup_infrastructure(struct xpc_partition *part)
93 * Allocate all of the channel structures as a contiguous chunk of 117 * Allocate all of the channel structures as a contiguous chunk of
94 * memory. 118 * memory.
95 */ 119 */
96 part->channels = kmalloc(sizeof(struct xpc_channel) * XPC_NCHANNELS, 120 part->channels = kzalloc(sizeof(struct xpc_channel) * XPC_NCHANNELS,
97 GFP_KERNEL); 121 GFP_KERNEL);
98 if (part->channels == NULL) { 122 if (part->channels == NULL) {
99 dev_err(xpc_chan, "can't get memory for channels\n"); 123 dev_err(xpc_chan, "can't get memory for channels\n");
100 return xpcNoMemory; 124 return xpcNoMemory;
101 } 125 }
102 memset(part->channels, 0, sizeof(struct xpc_channel) * XPC_NCHANNELS);
103 126
104 part->nchannels = XPC_NCHANNELS; 127 part->nchannels = XPC_NCHANNELS;
105 128
106 129
107 /* allocate all the required GET/PUT values */ 130 /* allocate all the required GET/PUT values */
108 131
109 part->local_GPs = xpc_kmalloc_cacheline_aligned(XPC_GP_SIZE, 132 part->local_GPs = xpc_kzalloc_cacheline_aligned(XPC_GP_SIZE,
110 GFP_KERNEL, &part->local_GPs_base); 133 GFP_KERNEL, &part->local_GPs_base);
111 if (part->local_GPs == NULL) { 134 if (part->local_GPs == NULL) {
112 kfree(part->channels); 135 kfree(part->channels);
@@ -115,55 +138,51 @@ xpc_setup_infrastructure(struct xpc_partition *part)
115 "values\n"); 138 "values\n");
116 return xpcNoMemory; 139 return xpcNoMemory;
117 } 140 }
118 memset(part->local_GPs, 0, XPC_GP_SIZE);
119 141
120 part->remote_GPs = xpc_kmalloc_cacheline_aligned(XPC_GP_SIZE, 142 part->remote_GPs = xpc_kzalloc_cacheline_aligned(XPC_GP_SIZE,
121 GFP_KERNEL, &part->remote_GPs_base); 143 GFP_KERNEL, &part->remote_GPs_base);
122 if (part->remote_GPs == NULL) { 144 if (part->remote_GPs == NULL) {
123 kfree(part->channels);
124 part->channels = NULL;
125 kfree(part->local_GPs_base);
126 part->local_GPs = NULL;
127 dev_err(xpc_chan, "can't get memory for remote get/put " 145 dev_err(xpc_chan, "can't get memory for remote get/put "
128 "values\n"); 146 "values\n");
147 kfree(part->local_GPs_base);
148 part->local_GPs = NULL;
149 kfree(part->channels);
150 part->channels = NULL;
129 return xpcNoMemory; 151 return xpcNoMemory;
130 } 152 }
131 memset(part->remote_GPs, 0, XPC_GP_SIZE);
132 153
133 154
134 /* allocate all the required open and close args */ 155 /* allocate all the required open and close args */
135 156
136 part->local_openclose_args = xpc_kmalloc_cacheline_aligned( 157 part->local_openclose_args = xpc_kzalloc_cacheline_aligned(
137 XPC_OPENCLOSE_ARGS_SIZE, GFP_KERNEL, 158 XPC_OPENCLOSE_ARGS_SIZE, GFP_KERNEL,
138 &part->local_openclose_args_base); 159 &part->local_openclose_args_base);
139 if (part->local_openclose_args == NULL) { 160 if (part->local_openclose_args == NULL) {
140 kfree(part->channels); 161 dev_err(xpc_chan, "can't get memory for local connect args\n");
141 part->channels = NULL;
142 kfree(part->local_GPs_base);
143 part->local_GPs = NULL;
144 kfree(part->remote_GPs_base); 162 kfree(part->remote_GPs_base);
145 part->remote_GPs = NULL; 163 part->remote_GPs = NULL;
146 dev_err(xpc_chan, "can't get memory for local connect args\n"); 164 kfree(part->local_GPs_base);
165 part->local_GPs = NULL;
166 kfree(part->channels);
167 part->channels = NULL;
147 return xpcNoMemory; 168 return xpcNoMemory;
148 } 169 }
149 memset(part->local_openclose_args, 0, XPC_OPENCLOSE_ARGS_SIZE);
150 170
151 part->remote_openclose_args = xpc_kmalloc_cacheline_aligned( 171 part->remote_openclose_args = xpc_kzalloc_cacheline_aligned(
152 XPC_OPENCLOSE_ARGS_SIZE, GFP_KERNEL, 172 XPC_OPENCLOSE_ARGS_SIZE, GFP_KERNEL,
153 &part->remote_openclose_args_base); 173 &part->remote_openclose_args_base);
154 if (part->remote_openclose_args == NULL) { 174 if (part->remote_openclose_args == NULL) {
155 kfree(part->channels); 175 dev_err(xpc_chan, "can't get memory for remote connect args\n");
156 part->channels = NULL;
157 kfree(part->local_GPs_base);
158 part->local_GPs = NULL;
159 kfree(part->remote_GPs_base);
160 part->remote_GPs = NULL;
161 kfree(part->local_openclose_args_base); 176 kfree(part->local_openclose_args_base);
162 part->local_openclose_args = NULL; 177 part->local_openclose_args = NULL;
163 dev_err(xpc_chan, "can't get memory for remote connect args\n"); 178 kfree(part->remote_GPs_base);
179 part->remote_GPs = NULL;
180 kfree(part->local_GPs_base);
181 part->local_GPs = NULL;
182 kfree(part->channels);
183 part->channels = NULL;
164 return xpcNoMemory; 184 return xpcNoMemory;
165 } 185 }
166 memset(part->remote_openclose_args, 0, XPC_OPENCLOSE_ARGS_SIZE);
167 186
168 187
169 xpc_initialize_channels(part, partid); 188 xpc_initialize_channels(part, partid);
@@ -186,18 +205,18 @@ xpc_setup_infrastructure(struct xpc_partition *part)
186 ret = request_irq(SGI_XPC_NOTIFY, xpc_notify_IRQ_handler, SA_SHIRQ, 205 ret = request_irq(SGI_XPC_NOTIFY, xpc_notify_IRQ_handler, SA_SHIRQ,
187 part->IPI_owner, (void *) (u64) partid); 206 part->IPI_owner, (void *) (u64) partid);
188 if (ret != 0) { 207 if (ret != 0) {
189 kfree(part->channels);
190 part->channels = NULL;
191 kfree(part->local_GPs_base);
192 part->local_GPs = NULL;
193 kfree(part->remote_GPs_base);
194 part->remote_GPs = NULL;
195 kfree(part->local_openclose_args_base);
196 part->local_openclose_args = NULL;
197 kfree(part->remote_openclose_args_base);
198 part->remote_openclose_args = NULL;
199 dev_err(xpc_chan, "can't register NOTIFY IRQ handler, " 208 dev_err(xpc_chan, "can't register NOTIFY IRQ handler, "
200 "errno=%d\n", -ret); 209 "errno=%d\n", -ret);
210 kfree(part->remote_openclose_args_base);
211 part->remote_openclose_args = NULL;
212 kfree(part->local_openclose_args_base);
213 part->local_openclose_args = NULL;
214 kfree(part->remote_GPs_base);
215 part->remote_GPs = NULL;
216 kfree(part->local_GPs_base);
217 part->local_GPs = NULL;
218 kfree(part->channels);
219 part->channels = NULL;
201 return xpcLackOfResources; 220 return xpcLackOfResources;
202 } 221 }
203 222
@@ -446,22 +465,20 @@ xpc_allocate_local_msgqueue(struct xpc_channel *ch)
446 for (nentries = ch->local_nentries; nentries > 0; nentries--) { 465 for (nentries = ch->local_nentries; nentries > 0; nentries--) {
447 466
448 nbytes = nentries * ch->msg_size; 467 nbytes = nentries * ch->msg_size;
449 ch->local_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes, 468 ch->local_msgqueue = xpc_kzalloc_cacheline_aligned(nbytes,
450 GFP_KERNEL, 469 GFP_KERNEL,
451 &ch->local_msgqueue_base); 470 &ch->local_msgqueue_base);
452 if (ch->local_msgqueue == NULL) { 471 if (ch->local_msgqueue == NULL) {
453 continue; 472 continue;
454 } 473 }
455 memset(ch->local_msgqueue, 0, nbytes);
456 474
457 nbytes = nentries * sizeof(struct xpc_notify); 475 nbytes = nentries * sizeof(struct xpc_notify);
458 ch->notify_queue = kmalloc(nbytes, GFP_KERNEL); 476 ch->notify_queue = kzalloc(nbytes, GFP_KERNEL);
459 if (ch->notify_queue == NULL) { 477 if (ch->notify_queue == NULL) {
460 kfree(ch->local_msgqueue_base); 478 kfree(ch->local_msgqueue_base);
461 ch->local_msgqueue = NULL; 479 ch->local_msgqueue = NULL;
462 continue; 480 continue;
463 } 481 }
464 memset(ch->notify_queue, 0, nbytes);
465 482
466 spin_lock_irqsave(&ch->lock, irq_flags); 483 spin_lock_irqsave(&ch->lock, irq_flags);
467 if (nentries < ch->local_nentries) { 484 if (nentries < ch->local_nentries) {
@@ -501,13 +518,12 @@ xpc_allocate_remote_msgqueue(struct xpc_channel *ch)
501 for (nentries = ch->remote_nentries; nentries > 0; nentries--) { 518 for (nentries = ch->remote_nentries; nentries > 0; nentries--) {
502 519
503 nbytes = nentries * ch->msg_size; 520 nbytes = nentries * ch->msg_size;
504 ch->remote_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes, 521 ch->remote_msgqueue = xpc_kzalloc_cacheline_aligned(nbytes,
505 GFP_KERNEL, 522 GFP_KERNEL,
506 &ch->remote_msgqueue_base); 523 &ch->remote_msgqueue_base);
507 if (ch->remote_msgqueue == NULL) { 524 if (ch->remote_msgqueue == NULL) {
508 continue; 525 continue;
509 } 526 }
510 memset(ch->remote_msgqueue, 0, nbytes);
511 527
512 spin_lock_irqsave(&ch->lock, irq_flags); 528 spin_lock_irqsave(&ch->lock, irq_flags);
513 if (nentries < ch->remote_nentries) { 529 if (nentries < ch->remote_nentries) {
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index 8cbf16432570..99b123a6421a 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -52,7 +52,6 @@
52#include <linux/syscalls.h> 52#include <linux/syscalls.h>
53#include <linux/cache.h> 53#include <linux/cache.h>
54#include <linux/interrupt.h> 54#include <linux/interrupt.h>
55#include <linux/slab.h>
56#include <linux/delay.h> 55#include <linux/delay.h>
57#include <linux/reboot.h> 56#include <linux/reboot.h>
58#include <linux/completion.h> 57#include <linux/completion.h>
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c
index 88a730e6cfdb..94211429fd0c 100644
--- a/arch/ia64/sn/kernel/xpc_partition.c
+++ b/arch/ia64/sn/kernel/xpc_partition.c
@@ -81,6 +81,31 @@ char ____cacheline_aligned xpc_remote_copy_buffer[XPC_RP_HEADER_SIZE +
81 81
82 82
83/* 83/*
84 * Guarantee that the kmalloc'd memory is cacheline aligned.
85 */
86static void *
87xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base)
88{
89 /* see if kmalloc will give us cachline aligned memory by default */
90 *base = kmalloc(size, flags);
91 if (*base == NULL) {
92 return NULL;
93 }
94 if ((u64) *base == L1_CACHE_ALIGN((u64) *base)) {
95 return *base;
96 }
97 kfree(*base);
98
99 /* nope, we'll have to do it ourselves */
100 *base = kmalloc(size + L1_CACHE_BYTES, flags);
101 if (*base == NULL) {
102 return NULL;
103 }
104 return (void *) L1_CACHE_ALIGN((u64) *base);
105}
106
107
108/*
84 * Given a nasid, get the physical address of the partition's reserved page 109 * Given a nasid, get the physical address of the partition's reserved page
85 * for that nasid. This function returns 0 on any error. 110 * for that nasid. This function returns 0 on any error.
86 */ 111 */
@@ -1038,13 +1063,12 @@ xpc_discovery(void)
1038 remote_vars = (struct xpc_vars *) remote_rp; 1063 remote_vars = (struct xpc_vars *) remote_rp;
1039 1064
1040 1065
1041 discovered_nasids = kmalloc(sizeof(u64) * xp_nasid_mask_words, 1066 discovered_nasids = kzalloc(sizeof(u64) * xp_nasid_mask_words,
1042 GFP_KERNEL); 1067 GFP_KERNEL);
1043 if (discovered_nasids == NULL) { 1068 if (discovered_nasids == NULL) {
1044 kfree(remote_rp_base); 1069 kfree(remote_rp_base);
1045 return; 1070 return;
1046 } 1071 }
1047 memset(discovered_nasids, 0, sizeof(u64) * xp_nasid_mask_words);
1048 1072
1049 rp = (struct xpc_rsvd_page *) xpc_rsvd_page; 1073 rp = (struct xpc_rsvd_page *) xpc_rsvd_page;
1050 1074
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
index 98f716bd92f0..ab1211ef0176 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
@@ -74,6 +74,22 @@ static int sal_pcibr_error_interrupt(struct pcibus_info *soft)
74 return (int)ret_stuff.v0; 74 return (int)ret_stuff.v0;
75} 75}
76 76
77u16 sn_ioboard_to_pci_bus(struct pci_bus *pci_bus)
78{
79 s64 rc;
80 u16 ioboard;
81 nasid_t nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base);
82
83 rc = ia64_sn_sysctl_ioboard_get(nasid, &ioboard);
84 if (rc) {
85 printk(KERN_WARNING "ia64_sn_sysctl_ioboard_get failed: %ld\n",
86 rc);
87 return 0;
88 }
89
90 return ioboard;
91}
92
77/* 93/*
78 * PCI Bridge Error interrupt handler. Gets invoked whenever a PCI 94 * PCI Bridge Error interrupt handler. Gets invoked whenever a PCI
79 * bridge sends an error interrupt. 95 * bridge sends an error interrupt.
@@ -255,3 +271,4 @@ pcibr_init_provider(void)
255 271
256EXPORT_SYMBOL_GPL(sal_pcibr_slot_enable); 272EXPORT_SYMBOL_GPL(sal_pcibr_slot_enable);
257EXPORT_SYMBOL_GPL(sal_pcibr_slot_disable); 273EXPORT_SYMBOL_GPL(sal_pcibr_slot_disable);
274EXPORT_SYMBOL_GPL(sn_ioboard_to_pci_bus);
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
index 7571a4025529..be0176912968 100644
--- a/arch/ia64/sn/pci/tioca_provider.c
+++ b/arch/ia64/sn/pci/tioca_provider.c
@@ -377,7 +377,7 @@ tioca_dma_mapped(struct pci_dev *pdev, u64 paddr, size_t req_size)
377 struct tioca_dmamap *ca_dmamap; 377 struct tioca_dmamap *ca_dmamap;
378 void *map; 378 void *map;
379 unsigned long flags; 379 unsigned long flags;
380 struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev);; 380 struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev);
381 381
382 tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info; 382 tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info;
383 tioca_kern = (struct tioca_kernel *)tioca_common->ca_kernel_private; 383 tioca_kern = (struct tioca_kernel *)tioca_common->ca_kernel_private;
diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c
index e52831ed93eb..fa073cc4b565 100644
--- a/arch/ia64/sn/pci/tioce_provider.c
+++ b/arch/ia64/sn/pci/tioce_provider.c
@@ -15,6 +15,124 @@
15#include <asm/sn/pcidev.h> 15#include <asm/sn/pcidev.h>
16#include <asm/sn/pcibus_provider_defs.h> 16#include <asm/sn/pcibus_provider_defs.h>
17#include <asm/sn/tioce_provider.h> 17#include <asm/sn/tioce_provider.h>
18#include <asm/sn/sn2/sn_hwperf.h>
19
20/*
21 * 1/26/2006
22 *
23 * WAR for SGI PV 944642. For revA TIOCE, need to use the following recipe
24 * (taken from the above PV) before and after accessing tioce internal MMR's
25 * to avoid tioce lockups.
26 *
27 * The recipe as taken from the PV:
28 *
29 * if(mmr address < 0x45000) {
30 * if(mmr address == 0 or 0x80)
31 * mmr wrt or read address 0xc0
32 * else if(mmr address == 0x148 or 0x200)
33 * mmr wrt or read address 0x28
34 * else
35 * mmr wrt or read address 0x158
36 *
37 * do desired mmr access (rd or wrt)
38 *
39 * if(mmr address == 0x100)
40 * mmr wrt or read address 0x38
41 * mmr wrt or read address 0xb050
42 * } else
43 * do desired mmr access
44 *
45 * According to hw, we can use reads instead of writes to the above addres
46 *
47 * Note this WAR can only to be used for accessing internal MMR's in the
48 * TIOCE Coretalk Address Range 0x0 - 0x07ff_ffff. This includes the
49 * "Local CE Registers and Memories" and "PCI Compatible Config Space" address
50 * spaces from table 2-1 of the "CE Programmer's Reference Overview" document.
51 *
52 * All registers defined in struct tioce will meet that criteria.
53 */
54
55static void inline
56tioce_mmr_war_pre(struct tioce_kernel *kern, void *mmr_addr)
57{
58 u64 mmr_base;
59 u64 mmr_offset;
60
61 if (kern->ce_common->ce_rev != TIOCE_REV_A)
62 return;
63
64 mmr_base = kern->ce_common->ce_pcibus.bs_base;
65 mmr_offset = (u64)mmr_addr - mmr_base;
66
67 if (mmr_offset < 0x45000) {
68 u64 mmr_war_offset;
69
70 if (mmr_offset == 0 || mmr_offset == 0x80)
71 mmr_war_offset = 0xc0;
72 else if (mmr_offset == 0x148 || mmr_offset == 0x200)
73 mmr_war_offset = 0x28;
74 else
75 mmr_war_offset = 0x158;
76
77 readq_relaxed((void *)(mmr_base + mmr_war_offset));
78 }
79}
80
81static void inline
82tioce_mmr_war_post(struct tioce_kernel *kern, void *mmr_addr)
83{
84 u64 mmr_base;
85 u64 mmr_offset;
86
87 if (kern->ce_common->ce_rev != TIOCE_REV_A)
88 return;
89
90 mmr_base = kern->ce_common->ce_pcibus.bs_base;
91 mmr_offset = (u64)mmr_addr - mmr_base;
92
93 if (mmr_offset < 0x45000) {
94 if (mmr_offset == 0x100)
95 readq_relaxed((void *)(mmr_base + 0x38));
96 readq_relaxed((void *)(mmr_base + 0xb050));
97 }
98}
99
100/* load mmr contents into a variable */
101#define tioce_mmr_load(kern, mmrp, varp) do {\
102 tioce_mmr_war_pre(kern, mmrp); \
103 *(varp) = readq_relaxed(mmrp); \
104 tioce_mmr_war_post(kern, mmrp); \
105} while (0)
106
107/* store variable contents into mmr */
108#define tioce_mmr_store(kern, mmrp, varp) do {\
109 tioce_mmr_war_pre(kern, mmrp); \
110 writeq(*varp, mmrp); \
111 tioce_mmr_war_post(kern, mmrp); \
112} while (0)
113
114/* store immediate value into mmr */
115#define tioce_mmr_storei(kern, mmrp, val) do {\
116 tioce_mmr_war_pre(kern, mmrp); \
117 writeq(val, mmrp); \
118 tioce_mmr_war_post(kern, mmrp); \
119} while (0)
120
121/* set bits (immediate value) into mmr */
122#define tioce_mmr_seti(kern, mmrp, bits) do {\
123 u64 tmp; \
124 tioce_mmr_load(kern, mmrp, &tmp); \
125 tmp |= (bits); \
126 tioce_mmr_store(kern, mmrp, &tmp); \
127} while (0)
128
129/* clear bits (immediate value) into mmr */
130#define tioce_mmr_clri(kern, mmrp, bits) do { \
131 u64 tmp; \
132 tioce_mmr_load(kern, mmrp, &tmp); \
133 tmp &= ~(bits); \
134 tioce_mmr_store(kern, mmrp, &tmp); \
135} while (0)
18 136
19/** 137/**
20 * Bus address ranges for the 5 flavors of TIOCE DMA 138 * Bus address ranges for the 5 flavors of TIOCE DMA
@@ -62,9 +180,9 @@
62#define TIOCE_ATE_M40 2 180#define TIOCE_ATE_M40 2
63#define TIOCE_ATE_M40S 3 181#define TIOCE_ATE_M40S 3
64 182
65#define KB(x) ((x) << 10) 183#define KB(x) ((u64)(x) << 10)
66#define MB(x) ((x) << 20) 184#define MB(x) ((u64)(x) << 20)
67#define GB(x) ((x) << 30) 185#define GB(x) ((u64)(x) << 30)
68 186
69/** 187/**
70 * tioce_dma_d64 - create a DMA mapping using 64-bit direct mode 188 * tioce_dma_d64 - create a DMA mapping using 64-bit direct mode
@@ -151,7 +269,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
151 int last; 269 int last;
152 int entries; 270 int entries;
153 int nates; 271 int nates;
154 int pagesize; 272 u64 pagesize;
155 u64 *ate_shadow; 273 u64 *ate_shadow;
156 u64 *ate_reg; 274 u64 *ate_reg;
157 u64 addr; 275 u64 addr;
@@ -228,7 +346,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
228 346
229 ate = ATE_MAKE(addr, pagesize); 347 ate = ATE_MAKE(addr, pagesize);
230 ate_shadow[i + j] = ate; 348 ate_shadow[i + j] = ate;
231 writeq(ate, &ate_reg[i + j]); 349 tioce_mmr_storei(ce_kern, &ate_reg[i + j], ate);
232 addr += pagesize; 350 addr += pagesize;
233 } 351 }
234 352
@@ -272,7 +390,8 @@ tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr)
272 u64 tmp; 390 u64 tmp;
273 391
274 ce_kern->ce_port[port].dirmap_shadow = ct_upper; 392 ce_kern->ce_port[port].dirmap_shadow = ct_upper;
275 writeq(ct_upper, &ce_mmr->ce_ure_dir_map[port]); 393 tioce_mmr_storei(ce_kern, &ce_mmr->ce_ure_dir_map[port],
394 ct_upper);
276 tmp = ce_mmr->ce_ure_dir_map[port]; 395 tmp = ce_mmr->ce_ure_dir_map[port];
277 dma_ok = 1; 396 dma_ok = 1;
278 } else 397 } else
@@ -344,7 +463,8 @@ tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
344 if (TIOCE_D32_ADDR(bus_addr)) { 463 if (TIOCE_D32_ADDR(bus_addr)) {
345 if (--ce_kern->ce_port[port].dirmap_refcnt == 0) { 464 if (--ce_kern->ce_port[port].dirmap_refcnt == 0) {
346 ce_kern->ce_port[port].dirmap_shadow = 0; 465 ce_kern->ce_port[port].dirmap_shadow = 0;
347 writeq(0, &ce_mmr->ce_ure_dir_map[port]); 466 tioce_mmr_storei(ce_kern, &ce_mmr->ce_ure_dir_map[port],
467 0);
348 } 468 }
349 } else { 469 } else {
350 struct tioce_dmamap *map; 470 struct tioce_dmamap *map;
@@ -365,7 +485,7 @@ tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
365 } else if (--map->refcnt == 0) { 485 } else if (--map->refcnt == 0) {
366 for (i = 0; i < map->ate_count; i++) { 486 for (i = 0; i < map->ate_count; i++) {
367 map->ate_shadow[i] = 0; 487 map->ate_shadow[i] = 0;
368 map->ate_hw[i] = 0; 488 tioce_mmr_storei(ce_kern, &map->ate_hw[i], 0);
369 } 489 }
370 490
371 list_del(&map->ce_dmamap_list); 491 list_del(&map->ce_dmamap_list);
@@ -486,7 +606,7 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count,
486 spin_unlock_irqrestore(&ce_kern->ce_lock, flags); 606 spin_unlock_irqrestore(&ce_kern->ce_lock, flags);
487 607
488dma_map_done: 608dma_map_done:
489 if (mapaddr & barrier) 609 if (mapaddr && barrier)
490 mapaddr = tioce_dma_barrier(mapaddr, 1); 610 mapaddr = tioce_dma_barrier(mapaddr, 1);
491 611
492 return mapaddr; 612 return mapaddr;
@@ -541,17 +661,61 @@ tioce_error_intr_handler(int irq, void *arg, struct pt_regs *pt)
541 soft->ce_pcibus.bs_persist_segment, 661 soft->ce_pcibus.bs_persist_segment,
542 soft->ce_pcibus.bs_persist_busnum, 0, 0, 0, 0, 0); 662 soft->ce_pcibus.bs_persist_busnum, 0, 0, 0, 0, 0);
543 663
664 if (ret_stuff.v0)
665 panic("tioce_error_intr_handler: Fatal TIOCE error");
666
544 return IRQ_HANDLED; 667 return IRQ_HANDLED;
545} 668}
546 669
547/** 670/**
671 * tioce_reserve_m32 - reserve M32 ate's for the indicated address range
672 * @tioce_kernel: TIOCE context to reserve ate's for
673 * @base: starting bus address to reserve
674 * @limit: last bus address to reserve
675 *
676 * If base/limit falls within the range of bus space mapped through the
677 * M32 space, reserve the resources corresponding to the range.
678 */
679static void
680tioce_reserve_m32(struct tioce_kernel *ce_kern, u64 base, u64 limit)
681{
682 int ate_index, last_ate, ps;
683 struct tioce *ce_mmr;
684
685 if (!TIOCE_M32_ADDR(base))
686 return;
687
688 ce_mmr = (struct tioce *)ce_kern->ce_common->ce_pcibus.bs_base;
689 ps = ce_kern->ce_ate3240_pagesize;
690 ate_index = ATE_PAGE(base, ps);
691 last_ate = ate_index + ATE_NPAGES(base, limit-base+1, ps) - 1;
692
693 if (ate_index < 64)
694 ate_index = 64;
695
696 while (ate_index <= last_ate) {
697 u64 ate;
698
699 ate = ATE_MAKE(0xdeadbeef, ps);
700 ce_kern->ce_ate3240_shadow[ate_index] = ate;
701 tioce_mmr_storei(ce_kern, &ce_mmr->ce_ure_ate3240[ate_index],
702 ate);
703 ate_index++;
704 }
705}
706
707/**
548 * tioce_kern_init - init kernel structures related to a given TIOCE 708 * tioce_kern_init - init kernel structures related to a given TIOCE
549 * @tioce_common: ptr to a cached tioce_common struct that originated in prom 709 * @tioce_common: ptr to a cached tioce_common struct that originated in prom
550 */ static struct tioce_kernel * 710 */
711static struct tioce_kernel *
551tioce_kern_init(struct tioce_common *tioce_common) 712tioce_kern_init(struct tioce_common *tioce_common)
552{ 713{
553 int i; 714 int i;
715 int ps;
716 int dev;
554 u32 tmp; 717 u32 tmp;
718 unsigned int seg, bus;
555 struct tioce *tioce_mmr; 719 struct tioce *tioce_mmr;
556 struct tioce_kernel *tioce_kern; 720 struct tioce_kernel *tioce_kern;
557 721
@@ -572,9 +736,10 @@ tioce_kern_init(struct tioce_common *tioce_common)
572 * here to use pci_read_config_xxx() so use the raw_pci_ops vector. 736 * here to use pci_read_config_xxx() so use the raw_pci_ops vector.
573 */ 737 */
574 738
575 raw_pci_ops->read(tioce_common->ce_pcibus.bs_persist_segment, 739 seg = tioce_common->ce_pcibus.bs_persist_segment;
576 tioce_common->ce_pcibus.bs_persist_busnum, 740 bus = tioce_common->ce_pcibus.bs_persist_busnum;
577 PCI_DEVFN(2, 0), PCI_SECONDARY_BUS, 1, &tmp); 741
742 raw_pci_ops->read(seg, bus, PCI_DEVFN(2, 0), PCI_SECONDARY_BUS, 1,&tmp);
578 tioce_kern->ce_port1_secondary = (u8) tmp; 743 tioce_kern->ce_port1_secondary = (u8) tmp;
579 744
580 /* 745 /*
@@ -583,18 +748,76 @@ tioce_kern_init(struct tioce_common *tioce_common)
583 */ 748 */
584 749
585 tioce_mmr = (struct tioce *)tioce_common->ce_pcibus.bs_base; 750 tioce_mmr = (struct tioce *)tioce_common->ce_pcibus.bs_base;
586 __sn_clrq_relaxed(&tioce_mmr->ce_ure_page_map, CE_URE_PAGESIZE_MASK); 751 tioce_mmr_clri(tioce_kern, &tioce_mmr->ce_ure_page_map,
587 __sn_setq_relaxed(&tioce_mmr->ce_ure_page_map, CE_URE_256K_PAGESIZE); 752 CE_URE_PAGESIZE_MASK);
588 tioce_kern->ce_ate3240_pagesize = KB(256); 753 tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_ure_page_map,
754 CE_URE_256K_PAGESIZE);
755 ps = tioce_kern->ce_ate3240_pagesize = KB(256);
589 756
590 for (i = 0; i < TIOCE_NUM_M40_ATES; i++) { 757 for (i = 0; i < TIOCE_NUM_M40_ATES; i++) {
591 tioce_kern->ce_ate40_shadow[i] = 0; 758 tioce_kern->ce_ate40_shadow[i] = 0;
592 writeq(0, &tioce_mmr->ce_ure_ate40[i]); 759 tioce_mmr_storei(tioce_kern, &tioce_mmr->ce_ure_ate40[i], 0);
593 } 760 }
594 761
595 for (i = 0; i < TIOCE_NUM_M3240_ATES; i++) { 762 for (i = 0; i < TIOCE_NUM_M3240_ATES; i++) {
596 tioce_kern->ce_ate3240_shadow[i] = 0; 763 tioce_kern->ce_ate3240_shadow[i] = 0;
597 writeq(0, &tioce_mmr->ce_ure_ate3240[i]); 764 tioce_mmr_storei(tioce_kern, &tioce_mmr->ce_ure_ate3240[i], 0);
765 }
766
767 /*
768 * Reserve ATE's corresponding to reserved address ranges. These
769 * include:
770 *
771 * Memory space covered by each PPB mem base/limit register
772 * Memory space covered by each PPB prefetch base/limit register
773 *
774 * These bus ranges are for pio (downstream) traffic only, and so
775 * cannot be used for DMA.
776 */
777
778 for (dev = 1; dev <= 2; dev++) {
779 u64 base, limit;
780
781 /* mem base/limit */
782
783 raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0),
784 PCI_MEMORY_BASE, 2, &tmp);
785 base = (u64)tmp << 16;
786
787 raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0),
788 PCI_MEMORY_LIMIT, 2, &tmp);
789 limit = (u64)tmp << 16;
790 limit |= 0xfffffUL;
791
792 if (base < limit)
793 tioce_reserve_m32(tioce_kern, base, limit);
794
795 /*
796 * prefetch mem base/limit. The tioce ppb's have 64-bit
797 * decoders, so read the upper portions w/o checking the
798 * attributes.
799 */
800
801 raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0),
802 PCI_PREF_MEMORY_BASE, 2, &tmp);
803 base = ((u64)tmp & PCI_PREF_RANGE_MASK) << 16;
804
805 raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0),
806 PCI_PREF_BASE_UPPER32, 4, &tmp);
807 base |= (u64)tmp << 32;
808
809 raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0),
810 PCI_PREF_MEMORY_LIMIT, 2, &tmp);
811
812 limit = ((u64)tmp & PCI_PREF_RANGE_MASK) << 16;
813 limit |= 0xfffffUL;
814
815 raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0),
816 PCI_PREF_LIMIT_UPPER32, 4, &tmp);
817 limit |= (u64)tmp << 32;
818
819 if ((base < limit) && TIOCE_M32_ADDR(base))
820 tioce_reserve_m32(tioce_kern, base, limit);
598 } 821 }
599 822
600 return tioce_kern; 823 return tioce_kern;
@@ -614,6 +837,7 @@ tioce_force_interrupt(struct sn_irq_info *sn_irq_info)
614{ 837{
615 struct pcidev_info *pcidev_info; 838 struct pcidev_info *pcidev_info;
616 struct tioce_common *ce_common; 839 struct tioce_common *ce_common;
840 struct tioce_kernel *ce_kern;
617 struct tioce *ce_mmr; 841 struct tioce *ce_mmr;
618 u64 force_int_val; 842 u64 force_int_val;
619 843
@@ -629,6 +853,29 @@ tioce_force_interrupt(struct sn_irq_info *sn_irq_info)
629 853
630 ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info; 854 ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info;
631 ce_mmr = (struct tioce *)ce_common->ce_pcibus.bs_base; 855 ce_mmr = (struct tioce *)ce_common->ce_pcibus.bs_base;
856 ce_kern = (struct tioce_kernel *)ce_common->ce_kernel_private;
857
858 /*
859 * TIOCE Rev A workaround (PV 945826), force an interrupt by writing
860 * the TIO_INTx register directly (1/26/2006)
861 */
862 if (ce_common->ce_rev == TIOCE_REV_A) {
863 u64 int_bit_mask = (1ULL << sn_irq_info->irq_int_bit);
864 u64 status;
865
866 tioce_mmr_load(ce_kern, &ce_mmr->ce_adm_int_status, &status);
867 if (status & int_bit_mask) {
868 u64 force_irq = (1 << 8) | sn_irq_info->irq_irq;
869 u64 ctalk = sn_irq_info->irq_xtalkaddr;
870 u64 nasid, offset;
871
872 nasid = (ctalk & CTALK_NASID_MASK) >> CTALK_NASID_SHFT;
873 offset = (ctalk & CTALK_NODE_OFFSET);
874 HUB_S(TIO_IOSPACE_ADDR(nasid, offset), force_irq);
875 }
876
877 return;
878 }
632 879
633 /* 880 /*
634 * irq_int_bit is originally set up by prom, and holds the interrupt 881 * irq_int_bit is originally set up by prom, and holds the interrupt
@@ -666,7 +913,7 @@ tioce_force_interrupt(struct sn_irq_info *sn_irq_info)
666 default: 913 default:
667 return; 914 return;
668 } 915 }
669 writeq(force_int_val, &ce_mmr->ce_adm_force_int); 916 tioce_mmr_storei(ce_kern, &ce_mmr->ce_adm_force_int, force_int_val);
670} 917}
671 918
672/** 919/**
@@ -685,6 +932,7 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info)
685{ 932{
686 struct pcidev_info *pcidev_info; 933 struct pcidev_info *pcidev_info;
687 struct tioce_common *ce_common; 934 struct tioce_common *ce_common;
935 struct tioce_kernel *ce_kern;
688 struct tioce *ce_mmr; 936 struct tioce *ce_mmr;
689 int bit; 937 int bit;
690 u64 vector; 938 u64 vector;
@@ -695,14 +943,15 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info)
695 943
696 ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info; 944 ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info;
697 ce_mmr = (struct tioce *)ce_common->ce_pcibus.bs_base; 945 ce_mmr = (struct tioce *)ce_common->ce_pcibus.bs_base;
946 ce_kern = (struct tioce_kernel *)ce_common->ce_kernel_private;
698 947
699 bit = sn_irq_info->irq_int_bit; 948 bit = sn_irq_info->irq_int_bit;
700 949
701 __sn_setq_relaxed(&ce_mmr->ce_adm_int_mask, (1UL << bit)); 950 tioce_mmr_seti(ce_kern, &ce_mmr->ce_adm_int_mask, (1UL << bit));
702 vector = (u64)sn_irq_info->irq_irq << INTR_VECTOR_SHFT; 951 vector = (u64)sn_irq_info->irq_irq << INTR_VECTOR_SHFT;
703 vector |= sn_irq_info->irq_xtalkaddr; 952 vector |= sn_irq_info->irq_xtalkaddr;
704 writeq(vector, &ce_mmr->ce_adm_int_dest[bit]); 953 tioce_mmr_storei(ce_kern, &ce_mmr->ce_adm_int_dest[bit], vector);
705 __sn_clrq_relaxed(&ce_mmr->ce_adm_int_mask, (1UL << bit)); 954 tioce_mmr_clri(ce_kern, &ce_mmr->ce_adm_int_mask, (1UL << bit));
706 955
707 tioce_force_interrupt(sn_irq_info); 956 tioce_force_interrupt(sn_irq_info);
708} 957}
@@ -721,7 +970,11 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info)
721static void * 970static void *
722tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller) 971tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller)
723{ 972{
973 int my_nasid;
974 cnodeid_t my_cnode, mem_cnode;
724 struct tioce_common *tioce_common; 975 struct tioce_common *tioce_common;
976 struct tioce_kernel *tioce_kern;
977 struct tioce *tioce_mmr;
725 978
726 /* 979 /*
727 * Allocate kernel bus soft and copy from prom. 980 * Allocate kernel bus soft and copy from prom.
@@ -734,11 +987,23 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
734 memcpy(tioce_common, prom_bussoft, sizeof(struct tioce_common)); 987 memcpy(tioce_common, prom_bussoft, sizeof(struct tioce_common));
735 tioce_common->ce_pcibus.bs_base |= __IA64_UNCACHED_OFFSET; 988 tioce_common->ce_pcibus.bs_base |= __IA64_UNCACHED_OFFSET;
736 989
737 if (tioce_kern_init(tioce_common) == NULL) { 990 tioce_kern = tioce_kern_init(tioce_common);
991 if (tioce_kern == NULL) {
738 kfree(tioce_common); 992 kfree(tioce_common);
739 return NULL; 993 return NULL;
740 } 994 }
741 995
996 /*
997 * Clear out any transient errors before registering the error
998 * interrupt handler.
999 */
1000
1001 tioce_mmr = (struct tioce *)tioce_common->ce_pcibus.bs_base;
1002 tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_adm_int_status_alias, ~0ULL);
1003 tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_adm_error_summary_alias,
1004 ~0ULL);
1005 tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_dre_comp_err_addr, ~0ULL);
1006
742 if (request_irq(SGI_PCIASIC_ERROR, 1007 if (request_irq(SGI_PCIASIC_ERROR,
743 tioce_error_intr_handler, 1008 tioce_error_intr_handler,
744 SA_SHIRQ, "TIOCE error", (void *)tioce_common)) 1009 SA_SHIRQ, "TIOCE error", (void *)tioce_common))
@@ -750,6 +1015,21 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
750 tioce_common->ce_pcibus.bs_persist_segment, 1015 tioce_common->ce_pcibus.bs_persist_segment,
751 tioce_common->ce_pcibus.bs_persist_busnum); 1016 tioce_common->ce_pcibus.bs_persist_busnum);
752 1017
1018 /*
1019 * identify closest nasid for memory allocations
1020 */
1021
1022 my_nasid = NASID_GET(tioce_common->ce_pcibus.bs_base);
1023 my_cnode = nasid_to_cnodeid(my_nasid);
1024
1025 if (sn_hwperf_get_nearest_node(my_cnode, &mem_cnode, NULL) < 0) {
1026 printk(KERN_WARNING "tioce_bus_fixup: failed to find "
1027 "closest node with MEM to TIO node %d\n", my_cnode);
1028 mem_cnode = (cnodeid_t)-1; /* use any node */
1029 }
1030
1031 controller->node = mem_cnode;
1032
753 return tioce_common; 1033 return tioce_common;
754} 1034}
755 1035