diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig --- a/arch/ia64/Kconfig Fri May 21 14:48:24 2004 +++ b/arch/ia64/Kconfig Fri May 21 14:48:24 2004 @@ -436,6 +436,33 @@ keys are documented in . Don't say Y unless you really know what this hack does. +config IA64_EARLY_PRINTK + bool "Early printk support" + depends on DEBUG_KERNEL && !IA64_GENERIC + help + Selecting this option uses the VGA screen or serial console for + printk() output before the consoles are initialised. It is useful + for debugging problems early in the boot process, but only if you + have a suitable VGA/serial console attached. If you're unsure, + select N. + +config IA64_EARLY_PRINTK_UART + bool "Early printk on MMIO serial port" + depends on IA64_EARLY_PRINTK + +config IA64_EARLY_PRINTK_UART_BASE + hex "UART MMIO base address" + depends on IA64_EARLY_PRINTK_UART + default "ff5e0000" + +config IA64_EARLY_PRINTK_VGA + bool "Early printk on VGA" + depends on IA64_EARLY_PRINTK + +config IA64_EARLY_PRINTK_SGI_SN + bool "Early printk on SGI SN serial console" + depends on IA64_EARLY_PRINTK && (IA64_GENERIC || IA64_SGI_SN2) + config DEBUG_SLAB bool "Debug memory allocations" depends on DEBUG_KERNEL diff -Nru a/arch/ia64/defconfig b/arch/ia64/defconfig --- a/arch/ia64/defconfig Fri May 21 14:48:23 2004 +++ b/arch/ia64/defconfig Fri May 21 14:48:23 2004 @@ -16,8 +16,10 @@ # CONFIG_SWAP=y CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set CONFIG_LOG_BUF_SHIFT=16 CONFIG_HOTPLUG=y CONFIG_IKCONFIG=y @@ -29,6 +31,7 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # @@ -69,7 +72,6 @@ # CONFIG_IA64_CYCLONE is not set CONFIG_IOSAPIC=y CONFIG_FORCE_MAX_ZONEORDER=18 -# CONFIG_IA64_PAL_IDLE is not set CONFIG_SMP=y CONFIG_NR_CPUS=16 # CONFIG_PREEMPT is not set @@ -78,6 +80,10 @@ CONFIG_COMPAT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y + +# +# Firmware Drivers +# CONFIG_EFI_VARS=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=y @@ -87,13 +93,12 @@ # CONFIG_PM=y CONFIG_ACPI=y -CONFIG_ACPI_INTERPRETER=y -CONFIG_ACPI_KERNEL_CONFIG=y # # ACPI (Advanced Configuration and Power Interface) Support # CONFIG_ACPI_BOOT=y +CONFIG_ACPI_INTERPRETER=y CONFIG_ACPI_BUTTON=y CONFIG_ACPI_FAN=y CONFIG_ACPI_PROCESSOR=y @@ -109,6 +114,7 @@ # CONFIG_PCI=y CONFIG_PCI_DOMAINS=y +# CONFIG_PCI_USE_VECTOR is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -149,7 +155,6 @@ # # Block devices # -# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -345,7 +350,6 @@ # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set # CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set @@ -356,8 +360,6 @@ # # CONFIG_IP_VS is not set # CONFIG_IPV6 is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -376,10 +378,11 @@ # # SCTP Configuration (EXPERIMENTAL) # -CONFIG_IPV6_SCTP__=y # CONFIG_IP_SCTP is not set # CONFIG_ATM is not set +# CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set # CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set @@ -400,16 +403,21 @@ # Network testing # # CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +CONFIG_BONDING=y +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # # ARCnet devices # # CONFIG_ARCNET is not set -CONFIG_DUMMY=y -CONFIG_BONDING=y -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set # # Ethernet (10 or 100Mbit) @@ -456,7 +464,6 @@ # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set -# CONFIG_SIS190 is not set # CONFIG_SK98LIN is not set CONFIG_TIGON3=y @@ -464,45 +471,29 @@ # Ethernet (10000 Mbit) # # CONFIG_IXGB is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set +# CONFIG_S2IO is not set # # Token Ring devices # # CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set # -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support +# Wireless LAN (non-hamradio) # -# CONFIG_IRDA is not set +# CONFIG_NET_RADIO is not set # -# Bluetooth support +# Wan interfaces # -# CONFIG_BT is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set # # ISDN subsystem @@ -577,11 +568,6 @@ CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 - -# -# Mice -# -# CONFIG_BUSMOUSE is not set # CONFIG_QIC02_TAPE is not set # @@ -594,7 +580,6 @@ # # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set -# CONFIG_GEN_RTC is not set CONFIG_EFI_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set @@ -631,6 +616,7 @@ # I2C Hardware Bus support # # CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set # CONFIG_I2C_ALI15X3 is not set # CONFIG_I2C_AMD756 is not set # CONFIG_I2C_AMD8111 is not set @@ -674,6 +660,8 @@ # Other I2C Chip support # # CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -704,7 +692,7 @@ CONFIG_FB_RIVA=m # CONFIG_FB_MATROX is not set # CONFIG_FB_RADEON_OLD is not set -CONFIG_FB_RADEON=y +CONFIG_FB_RADEON=m CONFIG_FB_RADEON_I2C=y # CONFIG_FB_RADEON_DEBUG is not set # CONFIG_FB_ATY128 is not set @@ -837,6 +825,8 @@ # USB Host Controller Drivers # CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_SPLIT_ISO is not set +CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_UHCI_HCD=y @@ -861,7 +851,9 @@ # CONFIG_USB_WACOM is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set # CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set # # USB Imaging devices @@ -908,6 +900,7 @@ # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set # CONFIG_USB_TEST is not set # @@ -959,6 +952,7 @@ # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y # CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y @@ -1075,6 +1069,7 @@ # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set # # Profiling support @@ -1090,6 +1085,7 @@ CONFIG_IA64_PRINT_HAZARDS=y CONFIG_DISABLE_VHPT=y CONFIG_MAGIC_SYSRQ=y +# CONFIG_IA64_EARLY_PRINTK_VGA is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set @@ -1123,4 +1119,6 @@ # CONFIG_CRYPTO_CAST6 is not set # CONFIG_CRYPTO_ARC4 is not set # CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_TEST is not set diff -Nru a/arch/ia64/hp/sim/boot/boot_head.S b/arch/ia64/hp/sim/boot/boot_head.S --- a/arch/ia64/hp/sim/boot/boot_head.S Fri May 21 14:48:24 2004 +++ b/arch/ia64/hp/sim/boot/boot_head.S Fri May 21 14:48:24 2004 @@ -105,37 +105,37 @@ 1: cmp.eq p6,p7=15,r28 /* PAL_PERF_MON_INFO */ (p7) br.cond.sptk.few 1f mov r8=0 /* status = 0 */ - movl r9 =0x12082004 /* generic=4 width=32 retired=8 cycles=18 */ + movl r9 =0x08122f04 /* generic=4 width=47 retired=8 cycles=18 */ mov r10=0 /* reserved */ mov r11=0 /* reserved */ mov r16=0xffff /* implemented PMC */ - mov r17=0xffff /* implemented PMD */ + mov r17=0x3ffff /* implemented PMD */ add r18=8,r29 /* second index */ ;; st8 [r29]=r16,16 /* store implemented PMC */ st8 [r18]=r0,16 /* clear remaining bits */ ;; - st8 [r29]=r0,16 /* store implemented PMC */ + st8 [r29]=r0,16 /* clear remaining bits */ st8 [r18]=r0,16 /* clear remaining bits */ ;; st8 [r29]=r17,16 /* store implemented PMD */ st8 [r18]=r0,16 /* clear remaining bits */ mov r16=0xf0 /* cycles count capable PMC */ ;; - st8 [r29]=r0,16 /* store implemented PMC */ + st8 [r29]=r0,16 /* clear remaining bits */ st8 [r18]=r0,16 /* clear remaining bits */ - mov r17=0x10 /* retired bundles capable PMC */ + mov r17=0xf0 /* retired bundles capable PMC */ ;; st8 [r29]=r16,16 /* store cycles capable */ st8 [r18]=r0,16 /* clear remaining bits */ ;; - st8 [r29]=r0,16 /* store implemented PMC */ + st8 [r29]=r0,16 /* clear remaining bits */ st8 [r18]=r0,16 /* clear remaining bits */ ;; st8 [r29]=r17,16 /* store retired bundle capable */ st8 [r18]=r0,16 /* clear remaining bits */ ;; - st8 [r29]=r0,16 /* store implemented PMC */ + st8 [r29]=r0,16 /* clear remaining bits */ st8 [r18]=r0,16 /* clear remaining bits */ ;; 1: br.cond.sptk.few rp diff -Nru a/arch/ia64/ia32/Makefile b/arch/ia64/ia32/Makefile --- a/arch/ia64/ia32/Makefile Fri May 21 14:48:24 2004 +++ b/arch/ia64/ia32/Makefile Fri May 21 14:48:24 2004 @@ -6,3 +6,7 @@ ia32_support.o ia32_traps.o binfmt_elf32.o ia32_ldt.o CFLAGS_ia32_ioctl.o += -Ifs/ + +# Don't let GCC uses f16-f31 so that save_ia32_fpstate_live() and +# restore_ia32_fpstate_live() can be sure the live register contain user-level state. +CFLAGS_ia32_signal.o += -mfixed-range=f16-f31 diff -Nru a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c --- a/arch/ia64/ia32/ia32_signal.c Fri May 21 14:48:23 2004 +++ b/arch/ia64/ia32/ia32_signal.c Fri May 21 14:48:23 2004 @@ -43,22 +43,6 @@ #define __IA32_NR_sigreturn 119 #define __IA32_NR_rt_sigreturn 173 -#ifdef ASM_SUPPORTED -/* - * Don't let GCC uses f16-f31 so that save_ia32_fpstate_live() and - * restore_ia32_fpstate_live() can be sure the live register contain user-level state. - */ -register double f16 asm ("f16"); register double f17 asm ("f17"); -register double f18 asm ("f18"); register double f19 asm ("f19"); -register double f20 asm ("f20"); register double f21 asm ("f21"); -register double f22 asm ("f22"); register double f23 asm ("f23"); - -register double f24 asm ("f24"); register double f25 asm ("f25"); -register double f26 asm ("f26"); register double f27 asm ("f27"); -register double f28 asm ("f28"); register double f29 asm ("f29"); -register double f30 asm ("f30"); register double f31 asm ("f31"); -#endif - struct sigframe_ia32 { int pretcode; @@ -173,7 +157,8 @@ case __SI_MESGQ >> 16: err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_pid, &to->si_pid); - err |= __put_user(from->si_ptr, &to->si_ptr); + addr = (unsigned long) from->si_ptr; + err |= __put_user(addr, &to->si_ptr); break; } } diff -Nru a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile --- a/arch/ia64/kernel/Makefile Fri May 21 14:48:24 2004 +++ b/arch/ia64/kernel/Makefile Fri May 21 14:48:24 2004 @@ -23,6 +23,9 @@ extra-y += gate.so gate-syms.o gate.lds.s gate.o +# fp_emulate() expects f2-f5,f16-f31 to contain the user-level state. +CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31 + AFLAGS_gate.lds.o += -P -C -U$(ARCH) quiet_cmd_gate = GATE $@ diff -Nru a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c --- a/arch/ia64/kernel/efi.c Fri May 21 14:48:23 2004 +++ b/arch/ia64/kernel/efi.c Fri May 21 14:48:23 2004 @@ -39,7 +39,7 @@ struct efi efi; EXPORT_SYMBOL(efi); static efi_runtime_services_t *runtime; -static unsigned long mem_limit = ~0UL; +static unsigned long mem_limit = ~0UL, max_addr = ~0UL; #define efi_call_virt(f, args...) (*(f))(args) @@ -290,6 +290,7 @@ void *efi_map_start, *efi_map_end, *p, *q; efi_memory_desc_t *md, *check_md; u64 efi_desc_size, start, end, granule_addr, last_granule_addr, first_non_wb_addr = 0; + unsigned long total_mem = 0; efi_map_start = __va(ia64_boot_param->efi_memmap); efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; @@ -331,12 +332,18 @@ trim_top(md, last_granule_addr); if (is_available_memory(md)) { - if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) { - if (md->phys_addr > mem_limit) + if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > max_addr) { + if (md->phys_addr > max_addr) continue; - md->num_pages = (mem_limit - md->phys_addr) >> EFI_PAGE_SHIFT; + md->num_pages = (max_addr - md->phys_addr) >> EFI_PAGE_SHIFT; } + if (total_mem >= mem_limit) + continue; + total_mem += (md->num_pages << EFI_PAGE_SHIFT); + if (total_mem > mem_limit) + md->num_pages -= ((total_mem - mem_limit) >> EFI_PAGE_SHIFT); + if (md->num_pages == 0) continue; @@ -470,7 +477,13 @@ for (cp = saved_command_line; *cp; ) { if (memcmp(cp, "mem=", 4) == 0) { cp += 4; - mem_limit = memparse(cp, &end) - 1; + mem_limit = memparse(cp, &end) - 2; + if (end != cp) + break; + cp = end; + } else if (memcmp(cp, "max_addr=", 9) == 0) { + cp += 9; + max_addr = memparse(cp, &end) - 1; if (end != cp) break; cp = end; @@ -481,8 +494,8 @@ ++cp; } } - if (mem_limit != ~0UL) - printk(KERN_INFO "Ignoring memory above %luMB\n", mem_limit >> 20); + if (max_addr != ~0UL) + printk(KERN_INFO "Ignoring memory above %luMB\n", max_addr >> 20); efi.systab = __va(ia64_boot_param->efi_systab); diff -Nru a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S --- a/arch/ia64/kernel/fsys.S Fri May 21 14:48:24 2004 +++ b/arch/ia64/kernel/fsys.S Fri May 21 14:48:24 2004 @@ -345,40 +345,33 @@ .altrp b6 .body - mf // ensure reading of current->blocked is ordered add r2=IA64_TASK_BLOCKED_OFFSET,r16 add r9=TI_FLAGS+IA64_TASK_SIZE,r16 + cmp4.ltu p6,p0=SIG_SETMASK,r32 + + cmp.ne p15,p0=r0,r34 // oset != NULL? + tnat.nz p8,p0=r34 + add r31=IA64_TASK_SIGHAND_OFFSET,r16 ;; - /* - * Since we're only reading a single word, we can do it - * atomically without acquiring current->sighand->siglock. To - * be on the safe side, we need a fully-ordered load, though: - */ - ld8.acq r3=[r2] // read/prefetch current->blocked + ld8 r3=[r2] // read/prefetch current->blocked ld4 r9=[r9] - add r31=IA64_TASK_SIGHAND_OFFSET,r16 + tnat.nz.or p6,p0=r35 + + cmp.ne.or p6,p0=_NSIG_WORDS*8,r35 + tnat.nz.or p6,p0=r32 +(p6) br.spnt.few .fail_einval // fail with EINVAL ;; #ifdef CONFIG_SMP ld8 r31=[r31] // r31 <- current->sighand #endif and r9=TIF_ALLWORK_MASK,r9 - tnat.nz p6,p0=r32 - ;; - cmp.ne p7,p0=0,r9 - tnat.nz.or p6,p0=r35 - tnat.nz p8,p0=r34 - ;; - cmp.ne p15,p0=r0,r34 // oset != NULL? - cmp.ne.or p6,p0=_NSIG_WORDS*8,r35 tnat.nz.or p8,p0=r33 - -(p6) br.spnt.few .fail_einval // fail with EINVAL -(p7) br.spnt.many fsys_fallback_syscall // got pending kernel work... -(p8) br.spnt.few .fail_efault // fail with EFAULT ;; - - cmp.eq p6,p7=r0,r33 // set == NULL? + cmp.ne p7,p0=0,r9 + cmp.eq p6,p0=r0,r33 // set == NULL? add r31=IA64_SIGHAND_SIGLOCK_OFFSET,r31 // r31 <- current->sighand->siglock +(p8) br.spnt.few .fail_efault // fail with EFAULT +(p7) br.spnt.many fsys_fallback_syscall // got pending kernel work... (p6) br.dpnt.many .store_mask // -> short-circuit to just reading the signal mask /* Argh, we actually have to do some work and _update_ the signal mask: */ @@ -462,12 +455,10 @@ st4.rel [r31]=r0 // release the lock #endif ssm psr.i - cmp.ne p9,p0=r8,r0 // check for bad HOW value ;; srlz.d // ensure psr.i is set again mov r18=0 // i must not leak kernel bits... -(p9) br.spnt.few .fail_einval // bail out for bad HOW value .store_mask: EX(.fail_efault, (p15) probe.w.fault r34, 3) // verify user has write-access to *oset @@ -574,6 +565,10 @@ or r29=r8,r29 // construct cr.ipsr value to save addl r22=IA64_RBS_OFFSET,r2 // compute base of RBS ;; + // GAS reports a spurious RAW hazard on the read of ar.rnat because it thinks + // we may be reading ar.itc after writing to psr.l. Avoid that message with + // this directive: + dv_serialize_data mov.m r24=ar.rnat // read ar.rnat (5 cyc lat) lfetch.fault.excl.nt1 [r22] adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r2 diff -Nru a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S --- a/arch/ia64/kernel/head.S Fri May 21 14:48:24 2004 +++ b/arch/ia64/kernel/head.S Fri May 21 14:48:24 2004 @@ -56,8 +56,7 @@ GLOBAL_ENTRY(_start) start_ap: .prologue - .save rp, r4 // terminate unwind chain with a NULL rp - mov r4=r0 + .save rp, r0 // terminate unwind chain with a NULL rp .body rsm psr.i | psr.ic diff -Nru a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S --- a/arch/ia64/kernel/ivt.S Fri May 21 14:48:23 2004 +++ b/arch/ia64/kernel/ivt.S Fri May 21 14:48:23 2004 @@ -182,6 +182,12 @@ ;; #ifdef CONFIG_SMP /* + * Tell the assemblers dependency-violation checker that the above "itc" instructions + * cannot possibly affect the following loads: + */ + dv_serialize_data + + /* * Re-check L2 and L3 pagetable. If they changed, we may have received a ptc.g * between reading the pagetable and the "itc". If so, flush the entry we * inserted and retry. @@ -229,6 +235,12 @@ itc.i r18 ;; #ifdef CONFIG_SMP + /* + * Tell the assemblers dependency-violation checker that the above "itc" instructions + * cannot possibly affect the following loads: + */ + dv_serialize_data + ld8 r19=[r17] // read L3 PTE again and see if same mov r20=PAGE_SHIFT<<2 // setup page size for purge ;; @@ -267,6 +279,12 @@ itc.d r18 ;; #ifdef CONFIG_SMP + /* + * Tell the assemblers dependency-violation checker that the above "itc" instructions + * cannot possibly affect the following loads: + */ + dv_serialize_data + ld8 r19=[r17] // read L3 PTE again and see if same mov r20=PAGE_SHIFT<<2 // setup page size for purge ;; @@ -504,6 +522,12 @@ ;; (p6) itc.d r25 // install updated PTE ;; + /* + * Tell the assemblers dependency-violation checker that the above "itc" instructions + * cannot possibly affect the following loads: + */ + dv_serialize_data + ld8 r18=[r17] // read PTE again ;; cmp.eq p6,p7=r18,r25 // is it same as the newly installed @@ -563,6 +587,12 @@ ;; (p6) itc.i r25 // install updated PTE ;; + /* + * Tell the assemblers dependency-violation checker that the above "itc" instructions + * cannot possibly affect the following loads: + */ + dv_serialize_data + ld8 r18=[r17] // read PTE again ;; cmp.eq p6,p7=r18,r25 // is it same as the newly installed @@ -610,6 +640,11 @@ cmp.eq p6,p7=r26,r18 ;; (p6) itc.d r25 // install updated PTE + /* + * Tell the assemblers dependency-violation checker that the above "itc" instructions + * cannot possibly affect the following loads: + */ + dv_serialize_data ;; ld8 r18=[r17] // read PTE again ;; diff -Nru a/arch/ia64/kernel/machvec.c b/arch/ia64/kernel/machvec.c --- a/arch/ia64/kernel/machvec.c Fri May 21 14:48:24 2004 +++ b/arch/ia64/kernel/machvec.c Fri May 21 14:48:24 2004 @@ -1,6 +1,7 @@ #include #include +#include #include #ifdef CONFIG_IA64_GENERIC @@ -8,7 +9,6 @@ #include #include -#include #include struct ia64_machine_vector ia64_mv; diff -Nru a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c --- a/arch/ia64/kernel/perfmon.c Fri May 21 14:48:24 2004 +++ b/arch/ia64/kernel/perfmon.c Fri May 21 14:48:24 2004 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -86,27 +87,25 @@ #define PFM_REG_CONFIG (0x8<<4|PFM_REG_IMPL) /* configuration register */ #define PFM_REG_BUFFER (0xc<<4|PFM_REG_IMPL) /* PMD used as buffer */ -#define PMC_IS_LAST(i) (pmu_conf.pmc_desc[i].type & PFM_REG_END) -#define PMD_IS_LAST(i) (pmu_conf.pmd_desc[i].type & PFM_REG_END) - -#define PFM_IS_DISABLED() (pmu_conf.enabled == 0) +#define PMC_IS_LAST(i) (pmu_conf->pmc_desc[i].type & PFM_REG_END) +#define PMD_IS_LAST(i) (pmu_conf->pmd_desc[i].type & PFM_REG_END) #define PMC_OVFL_NOTIFY(ctx, i) ((ctx)->ctx_pmds[i].flags & PFM_REGFL_OVFL_NOTIFY) /* i assumed unsigned */ -#define PMC_IS_IMPL(i) (i< PMU_MAX_PMCS && (pmu_conf.pmc_desc[i].type & PFM_REG_IMPL)) -#define PMD_IS_IMPL(i) (i< PMU_MAX_PMDS && (pmu_conf.pmd_desc[i].type & PFM_REG_IMPL)) +#define PMC_IS_IMPL(i) (i< PMU_MAX_PMCS && (pmu_conf->pmc_desc[i].type & PFM_REG_IMPL)) +#define PMD_IS_IMPL(i) (i< PMU_MAX_PMDS && (pmu_conf->pmd_desc[i].type & PFM_REG_IMPL)) /* XXX: these assume that register i is implemented */ -#define PMD_IS_COUNTING(i) ((pmu_conf.pmd_desc[i].type & PFM_REG_COUNTING) == PFM_REG_COUNTING) -#define PMC_IS_COUNTING(i) ((pmu_conf.pmc_desc[i].type & PFM_REG_COUNTING) == PFM_REG_COUNTING) -#define PMC_IS_MONITOR(i) ((pmu_conf.pmc_desc[i].type & PFM_REG_MONITOR) == PFM_REG_MONITOR) -#define PMC_IS_CONTROL(i) ((pmu_conf.pmc_desc[i].type & PFM_REG_CONTROL) == PFM_REG_CONTROL) - -#define PMC_DFL_VAL(i) pmu_conf.pmc_desc[i].default_value -#define PMC_RSVD_MASK(i) pmu_conf.pmc_desc[i].reserved_mask -#define PMD_PMD_DEP(i) pmu_conf.pmd_desc[i].dep_pmd[0] -#define PMC_PMD_DEP(i) pmu_conf.pmc_desc[i].dep_pmd[0] +#define PMD_IS_COUNTING(i) ((pmu_conf->pmd_desc[i].type & PFM_REG_COUNTING) == PFM_REG_COUNTING) +#define PMC_IS_COUNTING(i) ((pmu_conf->pmc_desc[i].type & PFM_REG_COUNTING) == PFM_REG_COUNTING) +#define PMC_IS_MONITOR(i) ((pmu_conf->pmc_desc[i].type & PFM_REG_MONITOR) == PFM_REG_MONITOR) +#define PMC_IS_CONTROL(i) ((pmu_conf->pmc_desc[i].type & PFM_REG_CONTROL) == PFM_REG_CONTROL) + +#define PMC_DFL_VAL(i) pmu_conf->pmc_desc[i].default_value +#define PMC_RSVD_MASK(i) pmu_conf->pmc_desc[i].reserved_mask +#define PMD_PMD_DEP(i) pmu_conf->pmd_desc[i].dep_pmd[0] +#define PMC_PMD_DEP(i) pmu_conf->pmc_desc[i].dep_pmd[0] #define PFM_NUM_IBRS IA64_NUM_DBG_REGS #define PFM_NUM_DBRS IA64_NUM_DBG_REGS @@ -133,6 +132,8 @@ #define PFM_CPUINFO_SET(v) pfm_get_cpu_var(pfm_syst_info) |= (v) #define PFM_CPUINFO_GET() pfm_get_cpu_var(pfm_syst_info) +#define RDEP(x) (1UL<<(x)) + /* * context protection macros * in SMP: @@ -374,26 +375,32 @@ * dep_pmd[]: a bitmask of dependent PMD registers * dep_pmc[]: a bitmask of dependent PMC registers */ +typedef int (*pfm_reg_check_t)(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs); typedef struct { unsigned int type; int pm_pos; unsigned long default_value; /* power-on default value */ unsigned long reserved_mask; /* bitmask of reserved bits */ - int (*read_check)(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs); - int (*write_check)(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs); + pfm_reg_check_t read_check; + pfm_reg_check_t write_check; unsigned long dep_pmd[4]; unsigned long dep_pmc[4]; } pfm_reg_desc_t; /* assume cnum is a valid monitor */ -#define PMC_PM(cnum, val) (((val) >> (pmu_conf.pmc_desc[cnum].pm_pos)) & 0x1) -#define PMC_WR_FUNC(cnum) (pmu_conf.pmc_desc[cnum].write_check) -#define PMD_WR_FUNC(cnum) (pmu_conf.pmd_desc[cnum].write_check) -#define PMD_RD_FUNC(cnum) (pmu_conf.pmd_desc[cnum].read_check) +#define PMC_PM(cnum, val) (((val) >> (pmu_conf->pmc_desc[cnum].pm_pos)) & 0x1) /* * This structure is initialized at boot time and contains * a description of the PMU main characteristics. + * + * If the probe function is defined, detection is based + * on its return value: + * - 0 means recognized PMU + * - anything else means not supported + * When the probe function is not defined, then the pmu_family field + * is used and it must match the host CPU family such that: + * - cpu->family & config->pmu_family != 0 */ typedef struct { unsigned long ovfl_val; /* overflow value for counters */ @@ -407,15 +414,18 @@ unsigned long impl_pmds[4]; /* bitmask of implemented PMDS */ char *pmu_name; /* PMU family name */ - unsigned int enabled; /* indicates if perfmon initialized properly */ unsigned int pmu_family; /* cpuid family pattern used to identify pmu */ - + unsigned int flags; /* pmu specific flags */ unsigned int num_ibrs; /* number of IBRS: computed at init time */ unsigned int num_dbrs; /* number of DBRS: computed at init time */ unsigned int num_counters; /* PMC/PMD counting pairs : computed at init time */ - + int (*probe)(void); /* customized probe routine */ unsigned int use_rr_dbregs:1; /* set if debug registers used for range restriction */ } pmu_config_t; +/* + * PMU specific flags + */ +#define PFM_PMU_IRQ_RESEND 1 /* PMU needs explicit IRQ resend */ /* * debug register related type definitions @@ -500,6 +510,8 @@ static spinlock_t pfm_buffer_fmt_lock; static LIST_HEAD(pfm_buffer_fmt_list); +static pmu_config_t *pmu_conf; + /* sysctl() controls */ static pfm_sysctl_t pfm_sysctl; int pfm_debug_var; @@ -620,20 +632,19 @@ #endif void dump_pmu_state(const char *); +static int pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs); -/* - * the HP simulator must be first because - * CONFIG_IA64_HP_SIM is independent of CONFIG_MCKINLEY or CONFIG_ITANIUM - */ -#if defined(CONFIG_IA64_HP_SIM) -#include "perfmon_hpsim.h" -#elif defined(CONFIG_ITANIUM) #include "perfmon_itanium.h" -#elif defined(CONFIG_MCKINLEY) #include "perfmon_mckinley.h" -#else #include "perfmon_generic.h" -#endif + +static pmu_config_t *pmu_confs[]={ + &pmu_conf_mck, + &pmu_conf_ita, + &pmu_conf_gen, /* must be last */ + NULL +}; + static int pfm_end_notify_user(pfm_context_t *ctx); @@ -702,6 +713,7 @@ for (i=0; i < nibrs; i++) { ia64_set_ibr(i, ibrs[i]); + ia64_dv_serialize_instruction(); } ia64_srlz_i(); } @@ -713,6 +725,7 @@ for (i=0; i < ndbrs; i++) { ia64_set_dbr(i, dbrs[i]); + ia64_dv_serialize_data(); } ia64_srlz_d(); } @@ -723,7 +736,7 @@ static inline unsigned long pfm_read_soft_counter(pfm_context_t *ctx, int i) { - return ctx->ctx_pmds[i].val + (ia64_get_pmd(i) & pmu_conf.ovfl_val); + return ctx->ctx_pmds[i].val + (ia64_get_pmd(i) & pmu_conf->ovfl_val); } /* @@ -732,7 +745,7 @@ static inline void pfm_write_soft_counter(pfm_context_t *ctx, int i, unsigned long val) { - unsigned long ovfl_val = pmu_conf.ovfl_val; + unsigned long ovfl_val = pmu_conf->ovfl_val; ctx->ctx_pmds[i].val = val & ~ovfl_val; /* @@ -878,7 +891,7 @@ DPRINT_ovfl(("masking monitoring for [%d]\n", task->pid)); - ovfl_mask = pmu_conf.ovfl_val; + ovfl_mask = pmu_conf->ovfl_val; /* * monitoring can only be masked as a result of a valid * counter overflow. In UP, it means that the PMU still @@ -953,7 +966,7 @@ int i, is_system; is_system = ctx->ctx_fl_system; - ovfl_mask = pmu_conf.ovfl_val; + ovfl_mask = pmu_conf->ovfl_val; if (task != current) { printk(KERN_ERR "perfmon.%d: invalid task[%d] current[%d]\n", __LINE__, task->pid, current->pid); @@ -1024,8 +1037,8 @@ * XXX: need to optimize */ if (ctx->ctx_fl_using_dbreg) { - pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf.num_ibrs); - pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf.num_dbrs); + pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf->num_ibrs); + pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf->num_dbrs); } /* @@ -1058,7 +1071,7 @@ pfm_restore_pmds(unsigned long *pmds, unsigned long mask) { int i; - unsigned long val, ovfl_val = pmu_conf.ovfl_val; + unsigned long val, ovfl_val = pmu_conf->ovfl_val; for (i=0; mask; i++, mask>>=1) { if ((mask & 0x1) == 0) continue; @@ -1075,7 +1088,7 @@ pfm_copy_pmds(struct task_struct *task, pfm_context_t *ctx) { struct thread_struct *thread = &task->thread; - unsigned long ovfl_val = pmu_conf.ovfl_val; + unsigned long ovfl_val = pmu_conf->ovfl_val; unsigned long mask = ctx->ctx_all_pmds[0]; unsigned long val; int i; @@ -2513,12 +2526,12 @@ * * PMC0 is treated differently. */ - ctx->ctx_all_pmcs[0] = pmu_conf.impl_pmcs[0] & ~0x1; + ctx->ctx_all_pmcs[0] = pmu_conf->impl_pmcs[0] & ~0x1; /* * bitmask of all PMDs that are accesible to this context */ - ctx->ctx_all_pmds[0] = pmu_conf.impl_pmds[0]; + ctx->ctx_all_pmds[0] = pmu_conf->impl_pmds[0]; DPRINT(("<%d> all_pmcs=0x%lx all_pmds=0x%lx\n", ctx->ctx_fd, ctx->ctx_all_pmcs[0],ctx->ctx_all_pmds[0])); @@ -2858,16 +2871,17 @@ unsigned long value, pmc_pm; unsigned long smpl_pmds, reset_pmds, impl_pmds; unsigned int cnum, reg_flags, flags, pmc_type; - int i, can_access_pmu = 0, is_loaded, is_system; + int i, can_access_pmu = 0, is_loaded, is_system, expert_mode; int is_monitor, is_counting, state; int ret = -EINVAL; + pfm_reg_check_t wr_func; #define PFM_CHECK_PMC_PM(x, y, z) ((x)->ctx_fl_system ^ PMC_PM(y, z)) state = ctx->ctx_state; is_loaded = state == PFM_CTX_LOADED ? 1 : 0; is_system = ctx->ctx_fl_system; task = ctx->ctx_task; - impl_pmds = pmu_conf.impl_pmds[0]; + impl_pmds = pmu_conf->impl_pmds[0]; if (state == PFM_CTX_ZOMBIE) return -EINVAL; @@ -2884,6 +2898,7 @@ } can_access_pmu = GET_PMU_OWNER() == task || is_system ? 1 : 0; } + expert_mode = pfm_sysctl.expert_mode; for (i = 0; i < count; i++, req++) { @@ -2900,8 +2915,8 @@ goto error; } - pmc_type = pmu_conf.pmc_desc[cnum].type; - pmc_pm = (value >> pmu_conf.pmc_desc[cnum].pm_pos) & 0x1; + pmc_type = pmu_conf->pmc_desc[cnum].type; + pmc_pm = (value >> pmu_conf->pmc_desc[cnum].pm_pos) & 0x1; is_counting = (pmc_type & PFM_REG_COUNTING) == PFM_REG_COUNTING ? 1 : 0; is_monitor = (pmc_type & PFM_REG_MONITOR) == PFM_REG_MONITOR ? 1 : 0; @@ -2914,6 +2929,7 @@ DPRINT(("pmc%u is unimplemented or no-access pmc_type=%x\n", cnum, pmc_type)); goto error; } + wr_func = pmu_conf->pmc_desc[cnum].write_check; /* * If the PMC is a monitor, then if the value is not the default: * - system-wide session: PMCx.pm=1 (privileged monitor) @@ -2962,8 +2978,8 @@ /* * execute write checker, if any */ - if (pfm_sysctl.expert_mode == 0 && PMC_WR_FUNC(cnum)) { - ret = PMC_WR_FUNC(cnum)(task, ctx, cnum, &value, regs); + if (likely(expert_mode == 0 && wr_func)) { + ret = (*wr_func)(task, ctx, cnum, &value, regs); if (ret) goto error; ret = -EINVAL; } @@ -3014,7 +3030,7 @@ * PMD. Clearing is done indirectly via pfm_reset_pmu_state() so there is no * possible leak here. */ - CTX_USED_PMD(ctx, pmu_conf.pmc_desc[cnum].dep_pmd[0]); + CTX_USED_PMD(ctx, pmu_conf->pmc_desc[cnum].dep_pmd[0]); /* * keep track of the monitor PMC that we are using. @@ -3096,14 +3112,15 @@ unsigned long value, hw_value, ovfl_mask; unsigned int cnum; int i, can_access_pmu = 0, state; - int is_counting, is_loaded, is_system; + int is_counting, is_loaded, is_system, expert_mode; int ret = -EINVAL; + pfm_reg_check_t wr_func; state = ctx->ctx_state; is_loaded = state == PFM_CTX_LOADED ? 1 : 0; is_system = ctx->ctx_fl_system; - ovfl_mask = pmu_conf.ovfl_val; + ovfl_mask = pmu_conf->ovfl_val; task = ctx->ctx_task; if (unlikely(state == PFM_CTX_ZOMBIE)) return -EINVAL; @@ -3125,6 +3142,7 @@ } can_access_pmu = GET_PMU_OWNER() == task || is_system ? 1 : 0; } + expert_mode = pfm_sysctl.expert_mode; for (i = 0; i < count; i++, req++) { @@ -3136,14 +3154,15 @@ goto abort_mission; } is_counting = PMD_IS_COUNTING(cnum); + wr_func = pmu_conf->pmd_desc[cnum].write_check; /* * execute write checker, if any */ - if (pfm_sysctl.expert_mode == 0 && PMD_WR_FUNC(cnum)) { + if (unlikely(expert_mode == 0 && wr_func)) { unsigned long v = value; - ret = PMD_WR_FUNC(cnum)(task, ctx, cnum, &v, regs); + ret = (*wr_func)(task, ctx, cnum, &v, regs); if (ret) goto abort_mission; value = v; @@ -3289,8 +3308,9 @@ pfarg_reg_t *req = (pfarg_reg_t *)arg; unsigned int cnum, reg_flags = 0; int i, can_access_pmu = 0, state; - int is_loaded, is_system, is_counting; + int is_loaded, is_system, is_counting, expert_mode; int ret = -EINVAL; + pfm_reg_check_t rd_func; /* * access is possible when loaded only for @@ -3300,7 +3320,7 @@ state = ctx->ctx_state; is_loaded = state == PFM_CTX_LOADED ? 1 : 0; is_system = ctx->ctx_fl_system; - ovfl_mask = pmu_conf.ovfl_val; + ovfl_mask = pmu_conf->ovfl_val; task = ctx->ctx_task; if (state == PFM_CTX_ZOMBIE) return -EINVAL; @@ -3323,6 +3343,7 @@ if (can_access_pmu) ia64_srlz_d(); } + expert_mode = pfm_sysctl.expert_mode; DPRINT(("loaded=%d access_pmu=%d ctx_state=%d\n", is_loaded, @@ -3369,6 +3390,7 @@ */ val = is_loaded ? thread->pmds[cnum] : 0UL; } + rd_func = pmu_conf->pmd_desc[cnum].read_check; if (is_counting) { /* @@ -3381,9 +3403,9 @@ /* * execute read checker, if any */ - if (unlikely(pfm_sysctl.expert_mode == 0 && PMD_RD_FUNC(cnum))) { + if (unlikely(expert_mode == 0 && rd_func)) { unsigned long v = val; - ret = PMD_RD_FUNC(cnum)(ctx->ctx_task, ctx, cnum, &v, regs); + ret = (*rd_func)(ctx->ctx_task, ctx, cnum, &v, regs); if (ret) goto error; val = v; ret = -EINVAL; @@ -3463,7 +3485,7 @@ unsigned long flags; int ret = 0; - if (pmu_conf.use_rr_dbregs == 0) return 0; + if (pmu_conf->use_rr_dbregs == 0) return 0; DPRINT(("called for [%d]\n", task->pid)); @@ -3517,7 +3539,7 @@ unsigned long flags; int ret; - if (pmu_conf.use_rr_dbregs == 0) return 0; + if (pmu_conf->use_rr_dbregs == 0) return 0; LOCK_PFS(flags); if (pfm_sessions.pfs_ptrace_use_dbregs == 0) { @@ -3720,7 +3742,7 @@ int i, can_access_pmu = 0; int is_system, is_loaded; - if (pmu_conf.use_rr_dbregs == 0) return -EINVAL; + if (pmu_conf->use_rr_dbregs == 0) return -EINVAL; state = ctx->ctx_state; is_loaded = state == PFM_CTX_LOADED ? 1 : 0; @@ -3802,14 +3824,14 @@ */ if (first_time && can_access_pmu) { DPRINT(("[%d] clearing ibrs, dbrs\n", task->pid)); - for (i=0; i < pmu_conf.num_ibrs; i++) { + for (i=0; i < pmu_conf->num_ibrs; i++) { ia64_set_ibr(i, 0UL); - ia64_srlz_i(); + ia64_dv_serialize_instruction(); } ia64_srlz_i(); - for (i=0; i < pmu_conf.num_dbrs; i++) { + for (i=0; i < pmu_conf->num_dbrs; i++) { ia64_set_dbr(i, 0UL); - ia64_srlz_d(); + ia64_dv_serialize_data(); } ia64_srlz_d(); } @@ -3856,7 +3878,10 @@ if (mode == PFM_CODE_RR) { CTX_USED_IBR(ctx, rnum); - if (can_access_pmu) ia64_set_ibr(rnum, dbreg.val); + if (can_access_pmu) { + ia64_set_ibr(rnum, dbreg.val); + ia64_dv_serialize_instruction(); + } ctx->ctx_ibrs[rnum] = dbreg.val; @@ -3865,8 +3890,10 @@ } else { CTX_USED_DBR(ctx, rnum); - if (can_access_pmu) ia64_set_dbr(rnum, dbreg.val); - + if (can_access_pmu) { + ia64_set_dbr(rnum, dbreg.val); + ia64_dv_serialize_data(); + } ctx->ctx_dbrs[rnum] = dbreg.val; DPRINT(("write dbr%u=0x%lx used_dbrs=0x%x is_loaded=%d access_pmu=%d\n", @@ -4367,8 +4394,8 @@ * guaranteed safe by earlier check against DBG_VALID */ if (ctx->ctx_fl_using_dbreg) { - pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf.num_ibrs); - pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf.num_dbrs); + pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf->num_ibrs); + pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf->num_dbrs); } /* * set new ownership @@ -4777,7 +4804,7 @@ /* * reject any call if perfmon was disabled at initialization */ - if (unlikely(PFM_IS_DISABLED())) return -ENOSYS; + if (unlikely(pmu_conf == NULL)) return -ENOSYS; if (unlikely(cmd < 0 || cmd >= PFM_CMD_COUNT)) { DPRINT(("invalid cmd=%d\n", cmd)); @@ -5178,7 +5205,7 @@ tstamp = ia64_get_itc(); mask = pmc0 >> PMU_FIRST_COUNTER; - ovfl_val = pmu_conf.ovfl_val; + ovfl_val = pmu_conf->ovfl_val; has_smpl = CTX_HAS_SMPL(ctx); DPRINT_ovfl(("pmc0=0x%lx pid=%d iip=0x%lx, %s " @@ -5536,111 +5563,185 @@ return IRQ_HANDLED; } +/* + * /proc/perfmon interface, for debug only + */ -/* for debug only */ -static int -pfm_proc_info(char *page) -{ - char *p = page; - struct list_head * pos; - pfm_buffer_fmt_t * entry; - unsigned long psr, flags; - int online_cpus = 0; - int i; +#define PFM_PROC_SHOW_HEADER ((void *)NR_CPUS+1) - p += sprintf(p, "perfmon version : %u.%u\n", PFM_VERSION_MAJ, PFM_VERSION_MIN); - p += sprintf(p, "model : %s\n", pmu_conf.pmu_name); - p += sprintf(p, "fastctxsw : %s\n", pfm_sysctl.fastctxsw > 0 ? "Yes": "No"); - p += sprintf(p, "expert mode : %s\n", pfm_sysctl.expert_mode > 0 ? "Yes": "No"); - p += sprintf(p, "ovfl_mask : 0x%lx\n", pmu_conf.ovfl_val); - - for(i=0; i < NR_CPUS; i++) { - if (cpu_online(i) == 0) continue; - p += sprintf(p, "CPU%-2d overflow intrs : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_count); - p += sprintf(p, "CPU%-2d overflow cycles : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_cycles); - p += sprintf(p, "CPU%-2d overflow min : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_cycles_min); - p += sprintf(p, "CPU%-2d overflow max : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_cycles_max); - p += sprintf(p, "CPU%-2d smpl handler calls : %lu\n", i, pfm_stats[i].pfm_smpl_handler_calls); - p += sprintf(p, "CPU%-2d smpl handler cycles : %lu\n", i, pfm_stats[i].pfm_smpl_handler_cycles); - p += sprintf(p, "CPU%-2d spurious intrs : %lu\n", i, pfm_stats[i].pfm_spurious_ovfl_intr_count); - p += sprintf(p, "CPU%-2d replay intrs : %lu\n", i, pfm_stats[i].pfm_replay_ovfl_intr_count); - p += sprintf(p, "CPU%-2d syst_wide : %d\n" , i, pfm_get_cpu_data(pfm_syst_info, i) & PFM_CPUINFO_SYST_WIDE ? 1 : 0); - p += sprintf(p, "CPU%-2d dcr_pp : %d\n" , i, pfm_get_cpu_data(pfm_syst_info, i) & PFM_CPUINFO_DCR_PP ? 1 : 0); - p += sprintf(p, "CPU%-2d exclude idle : %d\n" , i, pfm_get_cpu_data(pfm_syst_info, i) & PFM_CPUINFO_EXCL_IDLE ? 1 : 0); - p += sprintf(p, "CPU%-2d owner : %d\n" , i, pfm_get_cpu_data(pmu_owner, i) ? pfm_get_cpu_data(pmu_owner, i)->pid: -1); - p += sprintf(p, "CPU%-2d context : %p\n" , i, pfm_get_cpu_data(pmu_ctx, i)); - p += sprintf(p, "CPU%-2d activations : %lu\n", i, pfm_get_cpu_data(pmu_activation_number,i)); - online_cpus++; +static void * +pfm_proc_start(struct seq_file *m, loff_t *pos) +{ + if (*pos == 0) { + return PFM_PROC_SHOW_HEADER; } - if (online_cpus == 1) - { - psr = pfm_get_psr(); - ia64_srlz_d(); - p += sprintf(p, "CPU%-2d psr : 0x%lx\n", smp_processor_id(), psr); - p += sprintf(p, "CPU%-2d pmc0 : 0x%lx\n", smp_processor_id(), ia64_get_pmc(0)); - for(i=4; i < 8; i++) { - p += sprintf(p, "CPU%-2d pmc%u : 0x%lx\n", smp_processor_id(), i, ia64_get_pmc(i)); - p += sprintf(p, "CPU%-2d pmd%u : 0x%lx\n", smp_processor_id(), i, ia64_get_pmd(i)); - } + while (*pos <= NR_CPUS) { + if (cpu_online(*pos - 1)) { + return (void *)*pos; + } + ++*pos; } + return NULL; +} - LOCK_PFS(flags); - p += sprintf(p, "proc_sessions : %u\n" - "sys_sessions : %u\n" - "sys_use_dbregs : %u\n" - "ptrace_use_dbregs : %u\n", - pfm_sessions.pfs_task_sessions, - pfm_sessions.pfs_sys_sessions, - pfm_sessions.pfs_sys_use_dbregs, - pfm_sessions.pfs_ptrace_use_dbregs); - UNLOCK_PFS(flags); +static void * +pfm_proc_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return pfm_proc_start(m, pos); +} + +static void +pfm_proc_stop(struct seq_file *m, void *v) +{ +} + +static void +pfm_proc_show_header(struct seq_file *m) +{ + struct list_head * pos; + pfm_buffer_fmt_t * entry; + unsigned long flags; + + seq_printf(m, + "perfmon version : %u.%u\n" + "model : %s\n" + "fastctxsw : %s\n" + "expert mode : %s\n" + "ovfl_mask : 0x%lx\n" + "PMU flags : 0x%x\n", + PFM_VERSION_MAJ, PFM_VERSION_MIN, + pmu_conf->pmu_name, + pfm_sysctl.fastctxsw > 0 ? "Yes": "No", + pfm_sysctl.expert_mode > 0 ? "Yes": "No", + pmu_conf->ovfl_val, + pmu_conf->flags); + + LOCK_PFS(flags); + + seq_printf(m, + "proc_sessions : %u\n" + "sys_sessions : %u\n" + "sys_use_dbregs : %u\n" + "ptrace_use_dbregs : %u\n", + pfm_sessions.pfs_task_sessions, + pfm_sessions.pfs_sys_sessions, + pfm_sessions.pfs_sys_use_dbregs, + pfm_sessions.pfs_ptrace_use_dbregs); + + UNLOCK_PFS(flags); spin_lock(&pfm_buffer_fmt_lock); list_for_each(pos, &pfm_buffer_fmt_list) { entry = list_entry(pos, pfm_buffer_fmt_t, fmt_list); - p += sprintf(p, "format : %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x %s\n", - entry->fmt_uuid[0], - entry->fmt_uuid[1], - entry->fmt_uuid[2], - entry->fmt_uuid[3], - entry->fmt_uuid[4], - entry->fmt_uuid[5], - entry->fmt_uuid[6], - entry->fmt_uuid[7], - entry->fmt_uuid[8], - entry->fmt_uuid[9], - entry->fmt_uuid[10], - entry->fmt_uuid[11], - entry->fmt_uuid[12], - entry->fmt_uuid[13], - entry->fmt_uuid[14], - entry->fmt_uuid[15], - entry->fmt_name); + seq_printf(m, "format : %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x %s\n", + entry->fmt_uuid[0], + entry->fmt_uuid[1], + entry->fmt_uuid[2], + entry->fmt_uuid[3], + entry->fmt_uuid[4], + entry->fmt_uuid[5], + entry->fmt_uuid[6], + entry->fmt_uuid[7], + entry->fmt_uuid[8], + entry->fmt_uuid[9], + entry->fmt_uuid[10], + entry->fmt_uuid[11], + entry->fmt_uuid[12], + entry->fmt_uuid[13], + entry->fmt_uuid[14], + entry->fmt_uuid[15], + entry->fmt_name); } spin_unlock(&pfm_buffer_fmt_lock); - return p - page; } -/* /proc interface, for debug only */ static int -perfmon_read_entry(char *page, char **start, off_t off, int count, int *eof, void *data) +pfm_proc_show(struct seq_file *m, void *v) { - int len = pfm_proc_info(page); + unsigned long psr; + unsigned int i; + int cpu; - if (len <= off+count) *eof = 1; + if (v == PFM_PROC_SHOW_HEADER) { + pfm_proc_show_header(m); + return 0; + } + + /* show info for CPU (v - 1) */ + + cpu = (long)v - 1; + seq_printf(m, + "CPU%-2d overflow intrs : %lu\n" + "CPU%-2d overflow cycles : %lu\n" + "CPU%-2d overflow min : %lu\n" + "CPU%-2d overflow max : %lu\n" + "CPU%-2d smpl handler calls : %lu\n" + "CPU%-2d smpl handler cycles : %lu\n" + "CPU%-2d spurious intrs : %lu\n" + "CPU%-2d replay intrs : %lu\n" + "CPU%-2d syst_wide : %d\n" + "CPU%-2d dcr_pp : %d\n" + "CPU%-2d exclude idle : %d\n" + "CPU%-2d owner : %d\n" + "CPU%-2d context : %p\n" + "CPU%-2d activations : %lu\n", + cpu, pfm_stats[cpu].pfm_ovfl_intr_count, + cpu, pfm_stats[cpu].pfm_ovfl_intr_cycles, + cpu, pfm_stats[cpu].pfm_ovfl_intr_cycles_min, + cpu, pfm_stats[cpu].pfm_ovfl_intr_cycles_max, + cpu, pfm_stats[cpu].pfm_smpl_handler_calls, + cpu, pfm_stats[cpu].pfm_smpl_handler_cycles, + cpu, pfm_stats[cpu].pfm_spurious_ovfl_intr_count, + cpu, pfm_stats[cpu].pfm_replay_ovfl_intr_count, + cpu, pfm_get_cpu_data(pfm_syst_info, cpu) & PFM_CPUINFO_SYST_WIDE ? 1 : 0, + cpu, pfm_get_cpu_data(pfm_syst_info, cpu) & PFM_CPUINFO_DCR_PP ? 1 : 0, + cpu, pfm_get_cpu_data(pfm_syst_info, cpu) & PFM_CPUINFO_EXCL_IDLE ? 1 : 0, + cpu, pfm_get_cpu_data(pmu_owner, cpu) ? pfm_get_cpu_data(pmu_owner, cpu)->pid: -1, + cpu, pfm_get_cpu_data(pmu_ctx, cpu), + cpu, pfm_get_cpu_data(pmu_activation_number, cpu)); - *start = page + off; - len -= off; + if (num_online_cpus() == 1 && pfm_sysctl.debug > 0) { - if (len>count) len = count; - if (len<0) len = 0; + psr = pfm_get_psr(); + + ia64_srlz_d(); - return len; + seq_printf(m, + "CPU%-2d psr : 0x%lx\n" + "CPU%-2d pmc0 : 0x%lx\n", + cpu, psr, + cpu, ia64_get_pmc(0)); + + for (i=0; PMC_IS_LAST(i) == 0; i++) { + if (PMC_IS_COUNTING(i) == 0) continue; + seq_printf(m, + "CPU%-2d pmc%u : 0x%lx\n" + "CPU%-2d pmd%u : 0x%lx\n", + cpu, i, ia64_get_pmc(i), + cpu, i, ia64_get_pmd(i)); + } + } + return 0; } +struct seq_operations pfm_seq_ops = { + .start = pfm_proc_start, + .next = pfm_proc_next, + .stop = pfm_proc_stop, + .show = pfm_proc_show +}; + +static int +pfm_proc_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &pfm_seq_ops); +} + + /* * we come here as soon as local_cpu_data->pfm_syst_wide is set. this happens * during pfm_enable() hence before pfm_start(). We cannot assume monitoring @@ -5899,6 +6000,7 @@ unsigned long pmc_mask = 0UL, pmd_mask = 0UL; unsigned long flags; u64 psr, psr_up; + int need_irq_resend; ctx = PFM_GET_CTX(task); if (unlikely(ctx == NULL)) return; @@ -5919,6 +6021,8 @@ flags = pfm_protect_ctx_ctxsw(ctx); psr = pfm_get_psr(); + need_irq_resend = pmu_conf->flags & PFM_PMU_IRQ_RESEND; + BUG_ON(psr & (IA64_PSR_UP|IA64_PSR_PP)); BUG_ON(psr & IA64_PSR_I); @@ -5944,8 +6048,8 @@ * stale state. */ if (ctx->ctx_fl_using_dbreg) { - pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf.num_ibrs); - pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf.num_dbrs); + pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf->num_ibrs); + pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf->num_dbrs); } /* * retrieve saved psr.up @@ -6004,12 +6108,12 @@ ia64_set_pmc(0, t->pmcs[0]); ia64_srlz_d(); t->pmcs[0] = 0UL; -#ifndef CONFIG_MCKINLEY + /* * will replay the PMU interrupt */ - hw_resend_irq(NULL, IA64_PERFMON_VECTOR); -#endif + if (need_irq_resend) hw_resend_irq(NULL, IA64_PERFMON_VECTOR); + pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++; } @@ -6061,6 +6165,7 @@ struct task_struct *owner; unsigned long pmd_mask, pmc_mask; u64 psr, psr_up; + int need_irq_resend; owner = GET_PMU_OWNER(); ctx = PFM_GET_CTX(task); @@ -6079,14 +6184,15 @@ * (not perfmon) by the previous task. */ if (ctx->ctx_fl_using_dbreg) { - pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf.num_ibrs); - pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf.num_dbrs); + pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf->num_ibrs); + pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf->num_dbrs); } /* * retrieved saved psr.up */ psr_up = ctx->ctx_saved_psr_up; + need_irq_resend = pmu_conf->flags & PFM_PMU_IRQ_RESEND; /* * short path, our state is still there, just @@ -6143,12 +6249,11 @@ t->pmcs[0] = 0UL; -#ifndef CONFIG_MCKINLEY /* * will replay the PMU interrupt */ - hw_resend_irq(NULL, IA64_PERFMON_VECTOR); -#endif + if (need_irq_resend) hw_resend_irq(NULL, IA64_PERFMON_VECTOR); + pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++; } @@ -6222,7 +6327,7 @@ */ task->thread.pmcs[0] = 0; } - ovfl_val = pmu_conf.ovfl_val; + ovfl_val = pmu_conf->ovfl_val; /* * we save all the used pmds * we take care of overflows for counting PMDs @@ -6287,6 +6392,36 @@ */ static int init_pfm_fs(void); +static int __init +pfm_probe_pmu(void) +{ + pmu_config_t **p; + int family; + + family = local_cpu_data->family; + p = pmu_confs; + + while(*p) { + if ((*p)->probe) { + if ((*p)->probe() == 0) goto found; + } else if ((*p)->pmu_family == family || (*p)->pmu_family == 0xff) { + goto found; + } + p++; + } + return -1; +found: + pmu_conf = *p; + return 0; +} + +static struct file_operations pfm_proc_fops = { + .open = pfm_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + int __init pfm_init(void) { @@ -6297,12 +6432,9 @@ PFM_VERSION_MIN, IA64_PERFMON_VECTOR); - /* - * PMU type sanity check - * XXX: maybe better to implement autodetection (but then we have a larger kernel) - */ - if (local_cpu_data->family != pmu_conf.pmu_family) { - printk(KERN_INFO "perfmon: disabled, kernel only supports %s PMU family\n", pmu_conf.pmu_name); + if (pfm_probe_pmu()) { + printk(KERN_INFO "perfmon: disabled, there is no support for processor family %d\n", + local_cpu_data->family); return -ENODEV; } @@ -6313,56 +6445,64 @@ n = 0; for (i=0; PMC_IS_LAST(i) == 0; i++) { if (PMC_IS_IMPL(i) == 0) continue; - pmu_conf.impl_pmcs[i>>6] |= 1UL << (i&63); + pmu_conf->impl_pmcs[i>>6] |= 1UL << (i&63); n++; } - pmu_conf.num_pmcs = n; + pmu_conf->num_pmcs = n; n = 0; n_counters = 0; for (i=0; PMD_IS_LAST(i) == 0; i++) { if (PMD_IS_IMPL(i) == 0) continue; - pmu_conf.impl_pmds[i>>6] |= 1UL << (i&63); + pmu_conf->impl_pmds[i>>6] |= 1UL << (i&63); n++; if (PMD_IS_COUNTING(i)) n_counters++; } - pmu_conf.num_pmds = n; - pmu_conf.num_counters = n_counters; + pmu_conf->num_pmds = n; + pmu_conf->num_counters = n_counters; /* * sanity checks on the number of debug registers */ - if (pmu_conf.use_rr_dbregs) { - if (pmu_conf.num_ibrs > IA64_NUM_DBG_REGS) { - printk(KERN_INFO "perfmon: unsupported number of code debug registers (%u)\n", pmu_conf.num_ibrs); + if (pmu_conf->use_rr_dbregs) { + if (pmu_conf->num_ibrs > IA64_NUM_DBG_REGS) { + printk(KERN_INFO "perfmon: unsupported number of code debug registers (%u)\n", pmu_conf->num_ibrs); + pmu_conf = NULL; return -1; } - if (pmu_conf.num_dbrs > IA64_NUM_DBG_REGS) { - printk(KERN_INFO "perfmon: unsupported number of data debug registers (%u)\n", pmu_conf.num_ibrs); + if (pmu_conf->num_dbrs > IA64_NUM_DBG_REGS) { + printk(KERN_INFO "perfmon: unsupported number of data debug registers (%u)\n", pmu_conf->num_ibrs); + pmu_conf = NULL; return -1; } } printk("perfmon: %s PMU detected, %u PMCs, %u PMDs, %u counters (%lu bits)\n", - pmu_conf.pmu_name, - pmu_conf.num_pmcs, - pmu_conf.num_pmds, - pmu_conf.num_counters, - ffz(pmu_conf.ovfl_val)); + pmu_conf->pmu_name, + pmu_conf->num_pmcs, + pmu_conf->num_pmds, + pmu_conf->num_counters, + ffz(pmu_conf->ovfl_val)); /* sanity check */ - if (pmu_conf.num_pmds >= IA64_NUM_PMD_REGS || pmu_conf.num_pmcs >= IA64_NUM_PMC_REGS) { + if (pmu_conf->num_pmds >= IA64_NUM_PMD_REGS || pmu_conf->num_pmcs >= IA64_NUM_PMC_REGS) { printk(KERN_ERR "perfmon: not enough pmc/pmd, perfmon disabled\n"); + pmu_conf = NULL; return -1; } /* * create /proc/perfmon (mostly for debugging purposes) */ - perfmon_dir = create_proc_read_entry ("perfmon", 0, 0, perfmon_read_entry, NULL); + perfmon_dir = create_proc_entry("perfmon", S_IRUGO, NULL); if (perfmon_dir == NULL) { printk(KERN_ERR "perfmon: cannot create /proc entry, perfmon disabled\n"); + pmu_conf = NULL; return -1; } + /* + * install customized file operations for /proc/perfmon entry + */ + perfmon_dir->proc_fops = &pfm_proc_fops; /* * create /proc/sys/kernel/perfmon (for debugging purposes) @@ -6379,9 +6519,6 @@ for(i=0; i < NR_CPUS; i++) pfm_stats[i].pfm_ovfl_intr_cycles_min = ~0UL; - /* we are all set */ - pmu_conf.enabled = 1; - return 0; } @@ -6393,8 +6530,6 @@ void pfm_init_percpu (void) { - int i; - /* * make sure no measurement is active * (may inherit programmed PMCs from EFI). @@ -6412,28 +6547,6 @@ ia64_setreg(_IA64_REG_CR_PMV, IA64_PERFMON_VECTOR); ia64_srlz_d(); - - /* - * we first initialize the PMU to a stable state. - * the values may have been changed from their power-up - * values by software executed before the kernel took over. - * - * At this point, pmu_conf has not yet been initialized - * - * On McKinley, this code is ineffective until PMC4 is initialized - * but that's all right because we take care of pmc0 later. - * - * XXX: potential problems with pmc1. - */ - for (i=1; PMC_IS_LAST(i) == 0; i++) { - if (PMC_IS_IMPL(i) == 0) continue; - ia64_set_pmc(i, PMC_DFL_VAL(i)); - } - - for (i=0; PMD_IS_LAST(i) == 0; i++) { - if (PMD_IS_IMPL(i) == 0) continue; - ia64_set_pmd(i, 0UL); - } } /* diff -Nru a/arch/ia64/kernel/perfmon_generic.h b/arch/ia64/kernel/perfmon_generic.h --- a/arch/ia64/kernel/perfmon_generic.h Fri May 21 14:48:23 2004 +++ b/arch/ia64/kernel/perfmon_generic.h Fri May 21 14:48:23 2004 @@ -6,13 +6,6 @@ * Stephane Eranian */ - -#define RDEP(x) (1UL<<(x)) - -#if defined(CONFIG_ITANIUM) || defined (CONFIG_MCKINLEY) -#error "This file should not be used when CONFIG_ITANIUM or CONFIG_MCKINLEY is defined" -#endif - static pfm_reg_desc_t pfm_gen_pmc_desc[PMU_MAX_PMCS]={ /* pmc0 */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, /* pmc1 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, @@ -40,10 +33,9 @@ /* * impl_pmcs, impl_pmds are computed at runtime to minimize errors! */ -static pmu_config_t pmu_conf={ +static pmu_config_t pmu_conf_gen={ .pmu_name = "Generic", .pmu_family = 0xff, /* any */ - .enabled = 0, .ovfl_val = (1UL << 32) - 1, .num_ibrs = 0, /* does not use */ .num_dbrs = 0, /* does not use */ diff -Nru a/arch/ia64/kernel/perfmon_hpsim.h b/arch/ia64/kernel/perfmon_hpsim.h --- a/arch/ia64/kernel/perfmon_hpsim.h Fri May 21 14:48:24 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,75 +0,0 @@ -/* - * This file contains the HP SKI Simulator PMU register description tables - * and pmc checkers used by perfmon.c. - * - * Copyright (C) 2002-2003 Hewlett Packard Co - * Stephane Eranian - * - * File mostly contributed by Ian Wienand - * - * This file is included as a dummy template so the kernel does not - * try to initalize registers the simulator can't handle. - * - * Note the simulator does not (currently) implement these registers, i.e., - * they do not count anything. But you can read/write them. - */ - -#define RDEP(x) (1UL<<(x)) - -#ifndef CONFIG_IA64_HP_SIM -#error "This file should only be included for the HP Simulator" -#endif - -static pfm_reg_desc_t pfm_hpsim_pmc_desc[PMU_MAX_PMCS]={ -/* pmc0 */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL, 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc1 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL, 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc2 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL, 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc3 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL, 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc4 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(4), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc5 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(5), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc6 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(6), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc7 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(7), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc8 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc9 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(9), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc10 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(10), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc11 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(11), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc12 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(12), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc13 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(13), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc14 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(14), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc15 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(15), 0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, - { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */ -}; - -static pfm_reg_desc_t pfm_hpsim_pmd_desc[PMU_MAX_PMDS]={ -/* pmd0 */ { PFM_REG_BUFFER, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmd1 */ { PFM_REG_BUFFER, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmd2 */ { PFM_REG_BUFFER, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmd3 */ { PFM_REG_BUFFER, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmd4 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}}, -/* pmd5 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}}, -/* pmd6 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}}, -/* pmd7 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}}, -/* pmd8 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(8),0UL, 0UL, 0UL}}, -/* pmd9 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(9),0UL, 0UL, 0UL}}, -/* pmd10 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}}, -/* pmd11 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}}, -/* pmd12 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}}, -/* pmd13 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(13),0UL, 0UL, 0UL}}, -/* pmd14 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(14),0UL, 0UL, 0UL}}, -/* pmd15 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(15),0UL, 0UL, 0UL}}, - { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */ -}; - -/* - * impl_pmcs, impl_pmds are computed at runtime to minimize errors! - */ -static pmu_config_t pmu_conf={ - .pmu_name = "hpsim", - .pmu_family = 0x7, /* ski emulator reports as Itanium */ - .enabled = 0, - .ovfl_val = (1UL << 32) - 1, - .num_ibrs = 0, /* does not use */ - .num_dbrs = 0, /* does not use */ - .pmd_desc = pfm_hpsim_pmd_desc, - .pmc_desc = pfm_hpsim_pmc_desc -}; diff -Nru a/arch/ia64/kernel/perfmon_itanium.h b/arch/ia64/kernel/perfmon_itanium.h --- a/arch/ia64/kernel/perfmon_itanium.h Fri May 21 14:48:24 2004 +++ b/arch/ia64/kernel/perfmon_itanium.h Fri May 21 14:48:24 2004 @@ -5,15 +5,7 @@ * Copyright (C) 2002-2003 Hewlett Packard Co * Stephane Eranian */ - -#define RDEP(x) (1UL<<(x)) - -#ifndef CONFIG_ITANIUM -#error "This file is only valid when CONFIG_ITANIUM is defined" -#endif - static int pfm_ita_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs); -static int pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs); static pfm_reg_desc_t pfm_ita_pmc_desc[PMU_MAX_PMCS]={ /* pmc0 */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, @@ -55,31 +47,22 @@ { PFM_REG_END , 0, 0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */ }; -/* - * impl_pmcs, impl_pmds are computed at runtime to minimize errors! - */ -static pmu_config_t pmu_conf={ - .pmu_name = "Itanium", - .pmu_family = 0x7, - .enabled = 0, - .ovfl_val = (1UL << 32) - 1, - .pmd_desc = pfm_ita_pmd_desc, - .pmc_desc = pfm_ita_pmc_desc, - .num_ibrs = 8, - .num_dbrs = 8, - .use_rr_dbregs = 1 /* debug register are use for range retrictions */ -}; - static int pfm_ita_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs) { int ret; + int is_loaded; + + /* sanitfy check */ + if (ctx == NULL) return -EINVAL; + + is_loaded = ctx->ctx_state == PFM_CTX_LOADED || ctx->ctx_state == PFM_CTX_MASKED; /* * we must clear the (instruction) debug registers if pmc13.ta bit is cleared * before they are written (fl_using_dbreg==0) to avoid picking up stale information. */ - if (cnum == 13 && ((*val & 0x1) == 0UL) && ctx->ctx_fl_using_dbreg == 0) { + if (cnum == 13 && is_loaded && ((*val & 0x1) == 0UL) && ctx->ctx_fl_using_dbreg == 0) { DPRINT(("pmc[%d]=0x%lx has active pmc13.ta cleared, clearing ibr\n", cnum, *val)); @@ -98,7 +81,7 @@ * we must clear the (data) debug registers if pmc11.pt bit is cleared * before they are written (fl_using_dbreg==0) to avoid picking up stale information. */ - if (cnum == 11 && ((*val >> 28)& 0x1) == 0 && ctx->ctx_fl_using_dbreg == 0) { + if (cnum == 11 && is_loaded && ((*val >> 28)& 0x1) == 0 && ctx->ctx_fl_using_dbreg == 0) { DPRINT(("pmc[%d]=0x%lx has active pmc11.pt cleared, clearing dbr\n", cnum, *val)); @@ -114,4 +97,19 @@ } return 0; } + +/* + * impl_pmcs, impl_pmds are computed at runtime to minimize errors! + */ +static pmu_config_t pmu_conf_ita={ + .pmu_name = "Itanium", + .pmu_family = 0x7, + .ovfl_val = (1UL << 32) - 1, + .pmd_desc = pfm_ita_pmd_desc, + .pmc_desc = pfm_ita_pmc_desc, + .num_ibrs = 8, + .num_dbrs = 8, + .use_rr_dbregs = 1, /* debug register are use for range retrictions */ +}; + diff -Nru a/arch/ia64/kernel/perfmon_mckinley.h b/arch/ia64/kernel/perfmon_mckinley.h --- a/arch/ia64/kernel/perfmon_mckinley.h Fri May 21 14:48:24 2004 +++ b/arch/ia64/kernel/perfmon_mckinley.h Fri May 21 14:48:24 2004 @@ -5,15 +5,7 @@ * Copyright (C) 2002-2003 Hewlett Packard Co * Stephane Eranian */ - -#define RDEP(x) (1UL<<(x)) - -#ifndef CONFIG_MCKINLEY -#error "This file is only valid when CONFIG_MCKINLEY is defined" -#endif - static int pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs); -static int pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs); static pfm_reg_desc_t pfm_mck_pmc_desc[PMU_MAX_PMCS]={ /* pmc0 */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, @@ -58,21 +50,6 @@ }; /* - * impl_pmcs, impl_pmds are computed at runtime to minimize errors! - */ -static pmu_config_t pmu_conf={ - .pmu_name = "Itanium 2", - .pmu_family = 0x1f, - .enabled = 0, - .ovfl_val = (1UL << 47) - 1, - .pmd_desc = pfm_mck_pmd_desc, - .pmc_desc = pfm_mck_pmc_desc, - .num_ibrs = 8, - .num_dbrs = 8, - .use_rr_dbregs = 1 /* debug register are use for range retrictions */ -}; - -/* * PMC reserved fields must have their power-up values preserved */ static int @@ -120,12 +97,11 @@ * one of the pmc13.cfg_dbrpXX field is different from 0x3 * AND * at the corresponding pmc13.ena_dbrpXX is set. - * - * For now, we just check on cfg_dbrXX != 0x3. */ DPRINT(("cnum=%u val=0x%lx, using_dbreg=%d loaded=%d\n", cnum, *val, ctx->ctx_fl_using_dbreg, is_loaded)); - if (cnum == 13 && is_loaded && ((*val & 0x18181818UL) != 0x18181818UL) && ctx->ctx_fl_using_dbreg == 0) { + if (cnum == 13 && is_loaded + && (*val & 0x1e00000000000UL) && (*val & 0x18181818UL) != 0x18181818UL && ctx->ctx_fl_using_dbreg == 0) { DPRINT(("pmc[%d]=0x%lx has active pmc13 settings, clearing dbr\n", cnum, *val)); @@ -192,3 +168,20 @@ return ret ? -EINVAL : 0; } + +/* + * impl_pmcs, impl_pmds are computed at runtime to minimize errors! + */ +static pmu_config_t pmu_conf_mck={ + .pmu_name = "Itanium 2", + .pmu_family = 0x1f, + .flags = PFM_PMU_IRQ_RESEND, + .ovfl_val = (1UL << 47) - 1, + .pmd_desc = pfm_mck_pmd_desc, + .pmc_desc = pfm_mck_pmc_desc, + .num_ibrs = 8, + .num_dbrs = 8, + .use_rr_dbregs = 1 /* debug register are use for range retrictions */ +}; + + diff -Nru a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c --- a/arch/ia64/kernel/process.c Fri May 21 14:48:24 2004 +++ b/arch/ia64/kernel/process.c Fri May 21 14:48:24 2004 @@ -90,6 +90,7 @@ { unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri; + print_modules(); printk("\nPid: %d, CPU %d, comm: %20s\n", current->pid, smp_processor_id(), current->comm); printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s\n", regs->cr_ipsr, regs->cr_ifs, ip, print_tainted()); diff -Nru a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c --- a/arch/ia64/kernel/signal.c Fri May 21 14:48:24 2004 +++ b/arch/ia64/kernel/signal.c Fri May 21 14:48:24 2004 @@ -42,23 +42,6 @@ # define GET_SIGSET(k,u) __get_user((k)->sig[0], &(u)->sig[0]) #endif -#ifdef ASM_SUPPORTED -/* - * Don't let GCC uses f16-f31 so that when we setup/restore the registers in the signal - * context in __kernel_sigtramp(), we can be sure that registers f16-f31 contain user-level - * values. - */ -register double f16 asm ("f16"); register double f17 asm ("f17"); -register double f18 asm ("f18"); register double f19 asm ("f19"); -register double f20 asm ("f20"); register double f21 asm ("f21"); -register double f22 asm ("f22"); register double f23 asm ("f23"); - -register double f24 asm ("f24"); register double f25 asm ("f25"); -register double f26 asm ("f26"); register double f27 asm ("f27"); -register double f28 asm ("f28"); register double f29 asm ("f29"); -register double f30 asm ("f30"); register double f31 asm ("f31"); -#endif - long ia64_rt_sigsuspend (sigset_t *uset, size_t sigsetsize, struct sigscratch *scr) { diff -Nru a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c --- a/arch/ia64/kernel/smp.c Fri May 21 14:48:24 2004 +++ b/arch/ia64/kernel/smp.c Fri May 21 14:48:24 2004 @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff -Nru a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c --- a/arch/ia64/kernel/smpboot.c Fri May 21 14:48:23 2004 +++ b/arch/ia64/kernel/smpboot.c Fri May 21 14:48:23 2004 @@ -202,6 +202,14 @@ } t[NUM_ROUNDS]; #endif + /* + * Make sure local timer ticks are disabled while we sync. If + * they were enabled, we'd have to worry about nasty issues + * like setting the ITC ahead of (or a long time before) the + * next scheduled tick. + */ + BUG_ON((ia64_get_itv() & (1 << 16)) == 0); + go[MASTER] = 1; if (smp_call_function_single(master, sync_master, NULL, 1, 0) < 0) { @@ -247,16 +255,6 @@ printk(KERN_INFO "CPU %d: synchronized ITC with CPU %u (last diff %ld cycles, " "maxerr %lu cycles)\n", smp_processor_id(), master, delta, rt); - - /* - * Check whether we sync'd the itc ahead of the next timer interrupt. If so, just - * reset it. - */ - if (time_after(ia64_get_itc(), local_cpu_data->itm_next)) { - Dprintk("CPU %d: oops, jumped a timer tick; resetting timer.\n", - smp_processor_id()); - ia64_cpu_local_tick(); - } } /* @@ -288,16 +286,6 @@ smp_setup_percpu_timer(); - /* - * Get our bogomips. - */ - ia64_init_itm(); - - /* - * Set I/O port base per CPU - */ - ia64_set_kr(IA64_KR_IO_BASE, __pa(ia64_iobase)); - ia64_mca_cmc_vector_setup(); /* Setup vector on AP & enable */ #ifdef CONFIG_PERFMON @@ -305,11 +293,6 @@ #endif local_irq_enable(); - calibrate_delay(); - local_cpu_data->loops_per_jiffy = loops_per_jiffy; -#ifdef CONFIG_IA32_SUPPORT - ia32_gdt_init(); -#endif if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) { /* @@ -323,6 +306,17 @@ } /* + * Get our bogomips. + */ + ia64_init_itm(); + calibrate_delay(); + local_cpu_data->loops_per_jiffy = loops_per_jiffy; + +#ifdef CONFIG_IA32_SUPPORT + ia32_gdt_init(); +#endif + + /* * Allow the master to continue. */ cpu_set(cpuid, cpu_callin_map); @@ -337,6 +331,9 @@ start_secondary (void *unused) { extern int cpu_idle (void); + + /* Early console may use I/O ports */ + ia64_set_kr(IA64_KR_IO_BASE, __pa(ia64_iobase)); Dprintk("start_secondary: starting CPU 0x%x\n", hard_smp_processor_id()); efi_map_pal_code(); diff -Nru a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c --- a/arch/ia64/kernel/traps.c Fri May 21 14:48:24 2004 +++ b/arch/ia64/kernel/traps.c Fri May 21 14:48:24 2004 @@ -22,29 +22,6 @@ #include #include -/* - * fp_emulate() needs to be able to access and update all floating point registers. Those - * saved in pt_regs can be accessed through that structure, but those not saved, will be - * accessed directly. To make this work, we need to ensure that the compiler does not end - * up using a preserved floating point register on its own. The following achieves this - * by declaring preserved registers that are not marked as "fixed" as global register - * variables. - */ -#ifdef ASM_SUPPORTED -register double f2 asm ("f2"); register double f3 asm ("f3"); -register double f4 asm ("f4"); register double f5 asm ("f5"); - -register long f16 asm ("f16"); register long f17 asm ("f17"); -register long f18 asm ("f18"); register long f19 asm ("f19"); -register long f20 asm ("f20"); register long f21 asm ("f21"); -register long f22 asm ("f22"); register long f23 asm ("f23"); - -register double f24 asm ("f24"); register double f25 asm ("f25"); -register double f26 asm ("f26"); register double f27 asm ("f27"); -register double f28 asm ("f28"); register double f29 asm ("f29"); -register double f30 asm ("f30"); register double f31 asm ("f31"); -#endif - extern spinlock_t timerlist_lock; fpswa_interface_t *fpswa_interface; diff -Nru a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c --- a/arch/ia64/kernel/unwind.c Fri May 21 14:48:24 2004 +++ b/arch/ia64/kernel/unwind.c Fri May 21 14:48:24 2004 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1999-2003 Hewlett-Packard Co + * Copyright (C) 1999-2004 Hewlett-Packard Co * David Mosberger-Tang * Copyright (C) 2003 Fenghua Yu * - Change pt_regs_off() to make it less dependant on pt_regs structure. @@ -89,6 +89,8 @@ /* list of unwind tables (one per load-module) */ struct unw_table *tables; + unsigned long r0; /* constant 0 for r0 */ + /* table of registers that prologues can save (and order in which they're saved): */ const unsigned char save_order[8]; @@ -239,7 +241,11 @@ #endif }; -/* Unwind accessors. */ +static inline int +read_only (void *addr) +{ + return (unsigned long) ((char *) addr - (char *) &unw.r0) < sizeof(unw.r0); +} /* * Returns offset of rREG in struct pt_regs. @@ -274,6 +280,8 @@ return (struct pt_regs *) info->pt; } +/* Unwind accessors. */ + int unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char *nat, int write) { @@ -377,11 +385,15 @@ } if (write) { - *addr = *val; - if (*nat) - *nat_addr |= nat_mask; - else - *nat_addr &= ~nat_mask; + if (read_only(addr)) + UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n"); + else { + *addr = *val; + if (*nat) + *nat_addr |= nat_mask; + else + *nat_addr &= ~nat_mask; + } } else { if ((*nat_addr & nat_mask) == 0) { *val = *addr; @@ -420,7 +432,10 @@ return -1; } if (write) - *addr = *val; + if (read_only(addr)) + UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n"); + else + *addr = *val; else *val = *addr; return 0; @@ -465,7 +480,10 @@ } if (write) - *addr = *val; + if (read_only(addr)) + UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n"); + else + *addr = *val; else *val = *addr; return 0; @@ -557,9 +575,12 @@ return -1; } - if (write) - *addr = *val; - else + if (write) { + if (read_only(addr)) + UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n"); + else + *addr = *val; + } else *val = *addr; return 0; } @@ -574,9 +595,12 @@ if (!addr) addr = &info->sw->pr; - if (write) - *addr = *val; - else + if (write) { + if (read_only(addr)) + UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n"); + else + *addr = *val; + } else *val = *addr; return 0; } @@ -1407,6 +1431,9 @@ need_nat_info = 0; } val = unw.preg_index[UNW_REG_R4 + (rval - 4)]; + } else if (rval == 0) { + opc = UNW_INSN_MOVE_CONST; + val = 0; } else { /* register got spilled to a scratch register */ opc = UNW_INSN_MOVE_SCRATCH; @@ -1728,6 +1755,17 @@ __FUNCTION__, dst, val); } break; + + case UNW_INSN_MOVE_CONST: + if (val == 0) + s[dst] = (unsigned long) &unw.r0; + else { + s[dst] = 0; + UNW_DPRINT(0, "unwind.%s: UNW_INSN_MOVE_CONST bad val=%ld\n", + __FUNCTION__, val); + } + break; + case UNW_INSN_MOVE_STACKED: s[dst] = (unsigned long) ia64_rse_skip_regs((unsigned long *)state->bsp, diff -Nru a/arch/ia64/kernel/unwind_i.h b/arch/ia64/kernel/unwind_i.h --- a/arch/ia64/kernel/unwind_i.h Fri May 21 14:48:23 2004 +++ b/arch/ia64/kernel/unwind_i.h Fri May 21 14:48:23 2004 @@ -133,6 +133,7 @@ UNW_INSN_SETNAT_TYPE, /* s[dst+1].nat.type = val */ UNW_INSN_LOAD, /* s[dst] = *s[val] */ UNW_INSN_MOVE_SCRATCH, /* s[dst] = scratch reg "val" */ + UNW_INSN_MOVE_CONST, /* s[dst] = constant reg "val" */ }; struct unw_insn { diff -Nru a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c --- a/arch/ia64/mm/init.c Fri May 21 14:48:23 2004 +++ b/arch/ia64/mm/init.c Fri May 21 14:48:23 2004 @@ -343,6 +343,7 @@ #ifdef CONFIG_HUGETLB_PAGE ia64_set_rr(HPAGE_REGION_BASE, HPAGE_SHIFT << 2); + ia64_srlz_d(); #endif cpu = smp_processor_id(); diff -Nru a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c --- a/arch/ia64/pci/pci.c Fri May 21 14:48:23 2004 +++ b/arch/ia64/pci/pci.c Fri May 21 14:48:23 2004 @@ -356,8 +356,7 @@ for (ln = b->devices.next; ln != &b->devices; ln = ln->next) pcibios_fixup_device_resources(pci_dev_b(ln), b); - - return; + pci_read_bridge_bases(b); } void __devinit diff -Nru a/arch/ia64/scripts/check-serialize.S b/arch/ia64/scripts/check-serialize.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ia64/scripts/check-serialize.S Fri May 21 14:48:24 2004 @@ -0,0 +1,2 @@ + .serialize.data + .serialize.instruction diff -Nru a/arch/ia64/scripts/toolchain-flags b/arch/ia64/scripts/toolchain-flags --- a/arch/ia64/scripts/toolchain-flags Fri May 21 14:48:24 2004 +++ b/arch/ia64/scripts/toolchain-flags Fri May 21 14:48:24 2004 @@ -40,4 +40,14 @@ CPPFLAGS="$CPPFLAGS -DHAVE_MODEL_SMALL_ATTRIBUTE" fi rm -f $out + +# Check whether assembler supports .serialize.{data,instruction} directive. + +$CC -c $dir/check-serialize.S -o $out 2>/dev/null +res=$? +rm -f $out +if [ $res -eq 0 ]; then + CPPFLAGS="$CPPFLAGS -DHAVE_SERIALIZE_DIRECTIVE" +fi + echo $CPPFLAGS diff -Nru a/arch/ia64/sn/io/io.c b/arch/ia64/sn/io/io.c --- a/arch/ia64/sn/io/io.c Fri May 21 14:48:23 2004 +++ b/arch/ia64/sn/io/io.c Fri May 21 14:48:23 2004 @@ -651,7 +651,7 @@ hubii_wcr_t ii_wcr; int prbnum; - ASSERT(NASID_TO_COMPACT_NODEID(nasid) != INVALID_CNODEID); + ASSERT(nasid_to_cnodeid(nasid) != INVALID_CNODEID); ii_iowa = REMOTE_HUB_L(nasid, IIO_OUTWIDGET_ACCESS); REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, 0); diff -Nru a/arch/ia64/sn/io/machvec/pci_bus_cvlink.c b/arch/ia64/sn/io/machvec/pci_bus_cvlink.c --- a/arch/ia64/sn/io/machvec/pci_bus_cvlink.c Fri May 21 14:48:24 2004 +++ b/arch/ia64/sn/io/machvec/pci_bus_cvlink.c Fri May 21 14:48:24 2004 @@ -328,6 +328,34 @@ cmd |= PCI_COMMAND_MEMORY; } + /* + * Assign addresses to the ROMs, but don't enable them yet + * Also note that we only map display card ROMs due to PIO mapping + * space scarcity. + */ + if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { + unsigned long addr; + size = dev->resource[PCI_ROM_RESOURCE].end - + dev->resource[PCI_ROM_RESOURCE].start; + + if (size) { + addr = (unsigned long) pciio_pio_addr(vhdl, 0, + PCIIO_SPACE_ROM, + 0, size, 0, PIOMAP_FIXED); + if (!addr) { + dev->resource[PCI_ROM_RESOURCE].start = 0; + dev->resource[PCI_ROM_RESOURCE].end = 0; + printk("sn_pci_fixup(): ROM pio map failure " + "for %s\n", dev->slot_name); + } + addr |= __IA64_UNCACHED_OFFSET; + dev->resource[PCI_ROM_RESOURCE].start = addr; + dev->resource[PCI_ROM_RESOURCE].end = addr + size; + if (dev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + } + /* * Update the Command Word on the Card. */ @@ -712,7 +740,7 @@ /* Is this PCI bus associated with this moduleid? */ moduleid = NODE_MODULEID( - NASID_TO_COMPACT_NODEID(pcibr_soft->bs_nasid)); + nasid_to_cnodeid(pcibr_soft->bs_nasid)); if (modules[i]->id == moduleid) { struct pcibr_list_s *new_element; @@ -791,8 +819,7 @@ struct list_head *ln; struct pci_bus *pci_bus = NULL; struct pci_dev *pci_dev = NULL; - extern int numnodes; - int cnode, ret; + int ret; #ifdef CONFIG_PROC_FS extern void register_sn_procfs(void); #endif diff -Nru a/arch/ia64/sn/io/platform_init/sgi_io_init.c b/arch/ia64/sn/io/platform_init/sgi_io_init.c --- a/arch/ia64/sn/io/platform_init/sgi_io_init.c Fri May 21 14:48:23 2004 +++ b/arch/ia64/sn/io/platform_init/sgi_io_init.c Fri May 21 14:48:23 2004 @@ -26,7 +26,6 @@ extern void io_module_init(void); extern int pci_bus_to_hcl_cvlink(void); -cpuid_t master_procid; nasid_t console_nasid = (nasid_t) - 1; char master_baseio_wid; @@ -47,10 +46,10 @@ ii_ibcr_u_t ii_ibcr; ii_ilcsr_u_t ii_ilcsr; - nasid = COMPACT_TO_NASID_NODEID(cnode); + nasid = cnodeid_to_nasid(cnode); ASSERT(nasid != INVALID_NASID); - ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode); + ASSERT(nasid_to_cnodeid(nasid) == cnode); npdap = NODEPDA(cnode); @@ -150,7 +149,7 @@ check_nasid_equiv(nasid_t nasida, nasid_t nasidb) { if ((nasida == nasidb) - || (nasida == NODEPDA(NASID_TO_COMPACT_NODEID(nasidb))->xbow_peer)) + || (nasida == NODEPDA(nasid_to_cnodeid(nasidb))->xbow_peer)) return 1; else return 0; diff -Nru a/arch/ia64/sn/io/sn2/klgraph.c b/arch/ia64/sn/io/sn2/klgraph.c --- a/arch/ia64/sn/io/sn2/klgraph.c Fri May 21 14:48:24 2004 +++ b/arch/ia64/sn/io/sn2/klgraph.c Fri May 21 14:48:24 2004 @@ -65,7 +65,7 @@ cpuid_t cpu_id; nasid_t nasid; - nasid = COMPACT_TO_NASID_NODEID(cnode); + nasid = cnodeid_to_nasid(cnode); cpu_id = nasid_slice_to_cpuid(nasid, cpu->cpu_info.physid); if(cpu_id != -1){ snprintf(name, 120, "%s/%s/%c", EDGE_LBL_DISABLED, EDGE_LBL_CPU, 'a' + cpu->cpu_info.physid); @@ -88,7 +88,7 @@ cpuid_t cpu_id; nasid_t nasid; - nasid = COMPACT_TO_NASID_NODEID(cnode); + nasid = cnodeid_to_nasid(cnode); cpu_id = nasid_slice_to_cpuid(nasid, cpu->cpu_info.physid); snprintf(name, 120, "%s/%d/%c", @@ -145,7 +145,7 @@ continue; } - hub_cnode = NASID_TO_COMPACT_NODEID(hub_nasid); + hub_cnode = nasid_to_cnodeid(hub_nasid); if (hub_cnode == INVALID_CNODEID) { continue; @@ -178,7 +178,7 @@ */ if (hub_nasid != nasid) { NODEPDA(hub_cnode)->xbow_peer = nasid; - NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->xbow_peer = + NODEPDA(nasid_to_cnodeid(nasid))->xbow_peer = hub_nasid; } } @@ -200,7 +200,7 @@ klcpu_t *cpu; vertex_hdl_t cpu_dir; - nasid = COMPACT_TO_NASID_NODEID(cnode); + nasid = cnodeid_to_nasid(cnode); brd = find_lboard_any((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA); ASSERT(brd); @@ -280,7 +280,7 @@ int rv; for (cnode = 0; cnode < numnodes; cnode++) { - nasid = COMPACT_TO_NASID_NODEID(cnode); + nasid = cnodeid_to_nasid(cnode); brd = find_lboard_class_any((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_ROUTER); @@ -363,7 +363,7 @@ port)); continue; } - if (NASID_TO_COMPACT_NODEID(router->rou_port[port].port_nasid) + if (nasid_to_cnodeid(router->rou_port[port].port_nasid) == INVALID_CNODEID) { continue; } @@ -414,7 +414,7 @@ lboard_t *brd; for (cnode = 0; cnode < numnodes; cnode++) { - nasid = COMPACT_TO_NASID_NODEID(cnode); + nasid = cnodeid_to_nasid(cnode); brd = find_lboard_class_any((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_ROUTER); @@ -423,7 +423,7 @@ do { - nasid = COMPACT_TO_NASID_NODEID(cnode); + nasid = cnodeid_to_nasid(cnode); klhwg_connect_one_router(hwgraph_root, brd, cnode, nasid); @@ -451,7 +451,7 @@ int port; for (cnode = 0; cnode < numionodes; cnode++) { - nasid = COMPACT_TO_NASID_NODEID(cnode); + nasid = cnodeid_to_nasid(cnode); brd = find_lboard_any((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA); @@ -463,7 +463,7 @@ continue; /* Port not active */ } - if (NASID_TO_COMPACT_NODEID(hub->hub_port[port].port_nasid) == INVALID_CNODEID) + if (nasid_to_cnodeid(hub->hub_port[port].port_nasid) == INVALID_CNODEID) continue; /* Generate a hardware graph path for this board. */ diff -Nru a/arch/ia64/sn/io/sn2/ml_SN_init.c b/arch/ia64/sn/io/sn2/ml_SN_init.c --- a/arch/ia64/sn/io/sn2/ml_SN_init.c Fri May 21 14:48:23 2004 +++ b/arch/ia64/sn/io/sn2/ml_SN_init.c Fri May 21 14:48:23 2004 @@ -31,13 +31,9 @@ hubinfo_t hubinfo; nasid_t nasid; - extern void router_map_init(nodepda_t *); - extern void router_queue_init(nodepda_t *,cnodeid_t); - extern void intr_init_vecblk(nodepda_t *, cnodeid_t, int); - /* Allocate per-node platform-dependent data */ - nasid = COMPACT_TO_NASID_NODEID(node); + nasid = cnodeid_to_nasid(node); if (node >= numnodes) /* Headless/memless IO nodes */ hubinfo = (hubinfo_t)alloc_bootmem_node(NODE_DATA(0), sizeof(struct hubinfo_s)); else @@ -81,7 +77,7 @@ for (cnode = 0; cnode < numionodes; cnode++) { npda = nodepdaindr[cnode]; hubinfo = (hubinfo_t)npda->pdinfo; - hubinfo->h_nasid = COMPACT_TO_NASID_NODEID(cnode); + hubinfo->h_nasid = cnodeid_to_nasid(cnode); hubinfo->h_widgetid = hub_widget_id(hubinfo->h_nasid); } } diff -Nru a/arch/ia64/sn/io/sn2/ml_SN_intr.c b/arch/ia64/sn/io/sn2/ml_SN_intr.c --- a/arch/ia64/sn/io/sn2/ml_SN_intr.c Fri May 21 14:48:24 2004 +++ b/arch/ia64/sn/io/sn2/ml_SN_intr.c Fri May 21 14:48:24 2004 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -43,7 +44,6 @@ sh_ii_int0_config_u_t ii_int_config; cpuid_t cpu; cpuid_t cpu0, cpu1; - nodepda_t *lnodepda; sh_ii_int0_enable_u_t ii_int_enable; sh_int_node_id_config_u_t node_id_config; sh_local_int5_config_u_t local5_config; @@ -60,15 +60,13 @@ HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_INT_NODE_ID_CONFIG), node_id_config.sh_int_node_id_config_regval); cnode = nasid_to_cnodeid(master_nasid); - lnodepda = NODEPDA(cnode); - cpu = lnodepda->node_first_cpu; + cpu = first_cpu(node_to_cpumask(cnode)); cpu = cpu_physical_id(cpu); SAL_CALL(ret_stuff, SN_SAL_REGISTER_CE, nasid, cpu, master_nasid,0,0,0,0); if (ret_stuff.status < 0) printk("%s: SN_SAL_REGISTER_CE SAL_CALL failed\n",__FUNCTION__); } else { - lnodepda = NODEPDA(node); - cpu = lnodepda->node_first_cpu; + cpu = first_cpu(node_to_cpumask(node)); cpu = cpu_physical_id(cpu); } diff -Nru a/arch/ia64/sn/io/sn2/ml_iograph.c b/arch/ia64/sn/io/sn2/ml_iograph.c --- a/arch/ia64/sn/io/sn2/ml_iograph.c Fri May 21 14:48:23 2004 +++ b/arch/ia64/sn/io/sn2/ml_iograph.c Fri May 21 14:48:23 2004 @@ -313,7 +313,7 @@ hubinfo_get(hubv, &hubinfo); nasid = hubinfo->h_nasid; - cnode = NASID_TO_COMPACT_NODEID(nasid); + cnode = nasid_to_cnodeid(nasid); hub_widgetid = hubinfo->h_widgetid; /* @@ -567,7 +567,7 @@ * and hence widget id is Not 0. */ widget_partnum = (((*(volatile int32_t *)(NODE_SWIN_BASE - (COMPACT_TO_NASID_NODEID(cnodeid), 0) + + (cnodeid_to_nasid(cnodeid), 0) + WIDGET_ID))) & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT; @@ -584,7 +584,7 @@ } else { void *bridge; - bridge = (void *)NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0); + bridge = (void *)NODE_SWIN_BASE(cnodeid_to_nasid(cnodeid), 0); npdap->basew_id = pcireg_bridge_control_get(bridge) & WIDGET_WIDGET_ID; printk(" ****io_init_node: Unknown Widget Part Number 0x%x Widget ID 0x%x attached to Hubv 0x%p ****\n", widget_partnum, npdap->basew_id, (void *)hubv); @@ -637,7 +637,7 @@ /* If there's someone else on this crossbow, recognize him */ if (npdap->xbow_peer != INVALID_NASID) { - nodepda_t *peer_npdap = NODEPDA(NASID_TO_COMPACT_NODEID(npdap->xbow_peer)); + nodepda_t *peer_npdap = NODEPDA(nasid_to_cnodeid(npdap->xbow_peer)); peer_sema = &peer_npdap->xbow_sema; volunteer_for_widgets(switchv, peer_npdap->node_vertex); } diff -Nru a/arch/ia64/sn/io/sn2/module.c b/arch/ia64/sn/io/sn2/module.c --- a/arch/ia64/sn/io/sn2/module.c Fri May 21 14:48:23 2004 +++ b/arch/ia64/sn/io/sn2/module.c Fri May 21 14:48:23 2004 @@ -196,7 +196,7 @@ * We do not support memoryless compute nodes. */ for (node = 0; node < numnodes; node++) { - nasid = COMPACT_TO_NASID_NODEID(node); + nasid = cnodeid_to_nasid(node); board = find_lboard_nasid((lboard_t *) KL_CONFIG_INFO(nasid), nasid, KLTYPE_SNIA); ASSERT(board); @@ -214,7 +214,7 @@ nasid_t nasid; char serial_number[16]; - nasid = COMPACT_TO_NASID_NODEID(node); + nasid = cnodeid_to_nasid(node); board = find_lboard_nasid((lboard_t *) KL_CONFIG_INFO(nasid), nasid, KLTYPE_SNIA); ASSERT(board); diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c --- a/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c Fri May 21 14:48:24 2004 +++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c Fri May 21 14:48:24 2004 @@ -758,7 +758,7 @@ cnodeid_t cnodeid = 0; /* We need api for diroff api */ nasid_t nasid; - nasid = COMPACT_TO_NASID_NODEID(cnodeid); + nasid = cnodeid_to_nasid(cnodeid); paddr = NODE_OFFSET(nasid) + 0; /* Assume that if we ask for a DMA mapping to zero the XIO host will @@ -2092,7 +2092,7 @@ pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - return NASID_TO_COMPACT_NODEID(NASID_GET(pcibr_soft->bs_dir_xbase)); + return nasid_to_cnodeid(NASID_GET(pcibr_soft->bs_dir_xbase)); } /*ARGSUSED */ @@ -2645,7 +2645,7 @@ brd = KLCF_NEXT(brd); } /* if it's dual ported, check the peer also */ - nasid = NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->xbow_peer; + nasid = NODEPDA(nasid_to_cnodeid(nasid))->xbow_peer; if (nasid < 0) return 0; brd = (lboard_t *)KL_CONFIG_INFO(nasid); while (brd) { diff -Nru a/arch/ia64/sn/io/sn2/pic.c b/arch/ia64/sn/io/sn2/pic.c --- a/arch/ia64/sn/io/sn2/pic.c Fri May 21 14:48:24 2004 +++ b/arch/ia64/sn/io/sn2/pic.c Fri May 21 14:48:24 2004 @@ -124,7 +124,7 @@ static vertex_hdl_t pic_bus1_redist(nasid_t nasid, vertex_hdl_t conn_v) { - cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid); + cnodeid_t cnode = nasid_to_cnodeid(nasid); cnodeid_t xbow_peer = -1; char pathname[256], peer_path[256], tmpbuf[256]; char *p; @@ -137,7 +137,7 @@ /* create a path for this widget on the peer Cbrick */ /* pcibr widget hw/module/001c11/slab/0/Pbrick/xtalk/12 */ /* sprintf(pathname, "%v", conn_v); */ - xbow_peer = NASID_TO_COMPACT_NODEID(NODEPDA(cnode)->xbow_peer); + xbow_peer = nasid_to_cnodeid(NODEPDA(cnode)->xbow_peer); pos = hwgfs_generate_path(conn_v, tmpbuf, 256); strcpy(pathname, &tmpbuf[pos]); p = pathname + strlen("hw/module/001c01/slab/0/"); diff -Nru a/arch/ia64/sn/io/sn2/shuberror.c b/arch/ia64/sn/io/sn2/shuberror.c --- a/arch/ia64/sn/io/sn2/shuberror.c Fri May 21 14:48:24 2004 +++ b/arch/ia64/sn/io/sn2/shuberror.c Fri May 21 14:48:24 2004 @@ -157,7 +157,7 @@ hubio_eint.ii_iidsr_regval = 0; hubio_eint.ii_iidsr_fld_s.i_enable = 1; hubio_eint.ii_iidsr_fld_s.i_level = bit;/* Take the least significant bits*/ - hubio_eint.ii_iidsr_fld_s.i_node = COMPACT_TO_NASID_NODEID(cnode); + hubio_eint.ii_iidsr_fld_s.i_node = cnodeid_to_nasid(cnode); hubio_eint.ii_iidsr_fld_s.i_pi_id = cpuid_to_subnode(intr_cpu); REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, hubio_eint.ii_iidsr_regval); @@ -450,7 +450,7 @@ int rc; nasid = hinfo->h_nasid; - cnode = NASID_TO_COMPACT_NODEID(nasid); + cnode = nasid_to_cnodeid(nasid); /* * XXX - Add locking for any recovery actions diff -Nru a/arch/ia64/sn/io/sn2/shubio.c b/arch/ia64/sn/io/sn2/shubio.c --- a/arch/ia64/sn/io/sn2/shubio.c Fri May 21 14:48:24 2004 +++ b/arch/ia64/sn/io/sn2/shubio.c Fri May 21 14:48:24 2004 @@ -76,7 +76,7 @@ /* Get the error state of the hub */ e_state = error_state_get(hub_v); - cnode = NASID_TO_COMPACT_NODEID(nasid); + cnode = nasid_to_cnodeid(nasid); xswitch = NODEPDA(cnode)->basew_xc; @@ -119,7 +119,7 @@ return(0); /* Get the nasid for the cnode */ - src_nasid = COMPACT_TO_NASID_NODEID(src_node); + src_nasid = cnodeid_to_nasid(src_node); if (src_nasid == INVALID_NASID) return(0); diff -Nru a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c --- a/arch/ia64/sn/kernel/setup.c Fri May 21 14:48:23 2004 +++ b/arch/ia64/sn/kernel/setup.c Fri May 21 14:48:23 2004 @@ -451,10 +451,6 @@ } pda->shub_1_1_found = shub_1_1_found; - if (local_node_data->active_cpu_count == 1) - nodepda->node_first_cpu = cpuid; - - /* * We must use different memory allocators for first cpu (bootmem @@ -474,7 +470,7 @@ pda->mem_write_status_addr = (volatile u64 *) LOCAL_MMR_ADDR((slice < 2 ? SH_MEMORY_WRITE_STATUS_0 : SH_MEMORY_WRITE_STATUS_1 ) ); - if (nodepda->node_first_cpu == cpuid) { + if (local_node_data->active_cpu_count++ == 0) { int buddy_nasid; buddy_nasid = cnodeid_to_nasid(numa_node_id() == numnodes-1 ? 0 : numa_node_id()+ 1); pda->pio_shub_war_cam_addr = (volatile unsigned long*)GLOBAL_MMR_ADDR(nasid, SH_PI_CAM_CONTROL); diff -Nru a/arch/ia64/sn/kernel/sn2/prominfo_proc.c b/arch/ia64/sn/kernel/sn2/prominfo_proc.c --- a/arch/ia64/sn/kernel/sn2/prominfo_proc.c Fri May 21 14:48:23 2004 +++ b/arch/ia64/sn/kernel/sn2/prominfo_proc.c Fri May 21 14:48:23 2004 @@ -228,11 +228,9 @@ { int len = 0; - MOD_INC_USE_COUNT; /* data holds the pointer to this node's FIT */ len = dump_version(page, (unsigned long *)data); len = proc_calc_metrics(page, start, off, count, eof, len); - MOD_DEC_USE_COUNT; return len; } @@ -242,11 +240,9 @@ { int len = 0; - MOD_INC_USE_COUNT; /* data holds the pointer to this node's FIT */ len = dump_fit(page, (unsigned long *)data); len = proc_calc_metrics(page, start, off, count, eof, len); - MOD_DEC_USE_COUNT; return len; } @@ -310,6 +306,7 @@ prominfo_init(void) { struct proc_dir_entry **entp; + struct proc_dir_entry *p; cnodeid_t cnodeid; nasid_t nasid; char name[NODE_NAME_LEN]; @@ -333,12 +330,16 @@ sprintf(name, "node%d", cnodeid); *entp = proc_mkdir(name, sgi_prominfo_entry); nasid = cnodeid_to_nasid(cnodeid); - create_proc_read_entry( + p = create_proc_read_entry( "fit", 0, *entp, read_fit_entry, lookup_fit(nasid)); - create_proc_read_entry( + if (p) + p->owner = THIS_MODULE; + p = create_proc_read_entry( "version", 0, *entp, read_version_entry, lookup_fit(nasid)); + if (p) + p->owner = THIS_MODULE; } return 0; diff -Nru a/drivers/char/sn_serial.c b/drivers/char/sn_serial.c --- a/drivers/char/sn_serial.c Fri May 21 14:48:24 2004 +++ b/drivers/char/sn_serial.c Fri May 21 14:48:24 2004 @@ -502,7 +502,7 @@ int result; console_nasid = ia64_sn_get_console_nasid(); - intr_cpuid = NODEPDA(NASID_TO_COMPACT_NODEID(console_nasid))->node_first_cpu; + intr_cpuid = first_cpu(node_to_cpumask(nasid_to_cnodeid(console_nasid))); intr_cpuloc = cpu_physical_id(intr_cpuid); console_irq = CPU_VECTOR_TO_IRQ(intr_cpuloc, SGI_UART_VECTOR); diff -Nru a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile --- a/drivers/media/radio/Makefile Fri May 21 14:48:24 2004 +++ b/drivers/media/radio/Makefile Fri May 21 14:48:24 2004 @@ -2,6 +2,8 @@ # Makefile for the kernel character device drivers. # +obj-y := dummy.o + miropcm20-objs := miropcm20-rds-core.o miropcm20-radio.o obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o diff -Nru a/drivers/media/radio/dummy.c b/drivers/media/radio/dummy.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/media/radio/dummy.c Fri May 21 14:48:24 2004 @@ -0,0 +1 @@ +/* just so the linker knows what kind of object files it's deadling with... */ diff -Nru a/drivers/media/video/Makefile b/drivers/media/video/Makefile --- a/drivers/media/video/Makefile Fri May 21 14:48:23 2004 +++ b/drivers/media/video/Makefile Fri May 21 14:48:23 2004 @@ -7,6 +7,7 @@ zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o zr36067-objs := zoran_procfs.o zoran_device.o \ zoran_driver.o zoran_card.o +obj-y := dummy.o obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o diff -Nru a/drivers/media/video/dummy.c b/drivers/media/video/dummy.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/media/video/dummy.c Fri May 21 14:48:24 2004 @@ -0,0 +1 @@ +/* just so the linker knows what kind of object files it's deadling with... */ diff -Nru a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c --- a/drivers/usb/serial/ipaq.c Fri May 21 14:48:24 2004 +++ b/drivers/usb/serial/ipaq.c Fri May 21 14:48:24 2004 @@ -222,7 +222,7 @@ * discipline instead of queueing. */ - port->tty->low_latency = 1; + port->tty->low_latency = 0; port->tty->raw = 1; port->tty->real_raw = 1; diff -Nru a/include/asm-ia64/asmmacro.h b/include/asm-ia64/asmmacro.h --- a/include/asm-ia64/asmmacro.h Fri May 21 14:48:23 2004 +++ b/include/asm-ia64/asmmacro.h Fri May 21 14:48:23 2004 @@ -100,4 +100,12 @@ # define TEXT_ALIGN(n) #endif +#ifdef HAVE_SERIALIZE_DIRECTIVE +# define dv_serialize_data .serialize.data +# define dv_serialize_instruction .serialize.instruction +#else +# define dv_serialize_data +# define dv_serialize_instruction +#endif + #endif /* _ASM_IA64_ASMMACRO_H */ diff -Nru a/include/asm-ia64/atomic.h b/include/asm-ia64/atomic.h --- a/include/asm-ia64/atomic.h Fri May 21 14:48:23 2004 +++ b/include/asm-ia64/atomic.h Fri May 21 14:48:23 2004 @@ -159,10 +159,10 @@ #define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0) #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) -#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) != 0) +#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0) #define atomic64_sub_and_test(i,v) (atomic64_sub_return((i), (v)) == 0) #define atomic64_dec_and_test(v) (atomic64_sub_return(1, (v)) == 0) -#define atomic64_inc_and_test(v) (atomic64_add_return(1, (v)) != 0) +#define atomic64_inc_and_test(v) (atomic64_add_return(1, (v)) == 0) #define atomic_add(i,v) atomic_add_return((i), (v)) #define atomic_sub(i,v) atomic_sub_return((i), (v)) diff -Nru a/include/asm-ia64/delay.h b/include/asm-ia64/delay.h --- a/include/asm-ia64/delay.h Fri May 21 14:48:23 2004 +++ b/include/asm-ia64/delay.h Fri May 21 14:48:23 2004 @@ -44,6 +44,12 @@ ia64_srlz_d(); } +static __inline__ unsigned long +ia64_get_itv (void) +{ + return ia64_getreg(_IA64_REG_CR_ITV); +} + static __inline__ void ia64_set_itc (unsigned long val) { diff -Nru a/include/asm-ia64/gcc_intrin.h b/include/asm-ia64/gcc_intrin.h --- a/include/asm-ia64/gcc_intrin.h Fri May 21 14:48:24 2004 +++ b/include/asm-ia64/gcc_intrin.h Fri May 21 14:48:24 2004 @@ -4,9 +4,10 @@ * * Copyright (C) 2002,2003 Jun Nakajima * Copyright (C) 2002,2003 Suresh Siddha - * */ +#include + /* define this macro to get some asm stmts included in 'c' files */ #define ASM_SUPPORTED @@ -23,7 +24,7 @@ extern void ia64_bad_param_for_setreg (void); extern void ia64_bad_param_for_getreg (void); -register unsigned long ia64_r13 asm ("r13"); +register unsigned long ia64_r13 asm ("r13") __attribute_used__; #define ia64_setreg(regnum, val) \ ({ \ @@ -377,8 +378,15 @@ }) #define ia64_srlz_i() asm volatile (";; srlz.i ;;" ::: "memory") - #define ia64_srlz_d() asm volatile (";; srlz.d" ::: "memory"); + +#ifdef HAVE_SERIALIZE_DIRECTIVE +# define ia64_dv_serialize_data() asm volatile (".serialize.data"); +# define ia64_dv_serialize_instruction() asm volatile (".serialize.instruction"); +#else +# define ia64_dv_serialize_data() +# define ia64_dv_serialize_instruction() +#endif #define ia64_nop(x) asm volatile ("nop %0"::"i"(x)); diff -Nru a/include/asm-ia64/intel_intrin.h b/include/asm-ia64/intel_intrin.h --- a/include/asm-ia64/intel_intrin.h Fri May 21 14:48:24 2004 +++ b/include/asm-ia64/intel_intrin.h Fri May 21 14:48:24 2004 @@ -204,6 +204,9 @@ #define ia64_srlz_d __dsrlz #define ia64_srlz_i __isrlz +#define ia64_dv_serialize_data() +#define ia64_dv_serialize_instruction() + #define ia64_st1_rel __st1_rel #define ia64_st2_rel __st2_rel #define ia64_st4_rel __st4_rel diff -Nru a/include/asm-ia64/sn/arch.h b/include/asm-ia64/sn/arch.h --- a/include/asm-ia64/sn/arch.h Fri May 21 14:48:23 2004 +++ b/include/asm-ia64/sn/arch.h Fri May 21 14:48:23 2004 @@ -20,12 +20,6 @@ typedef u64 mmr_t; typedef u64 nic_t; -#define CNODE_TO_CPU_BASE(_cnode) (NODEPDA(_cnode)->node_first_cpu) - -#define NASID_TO_COMPACT_NODEID(nasid) (nasid_to_cnodeid(nasid)) -#define COMPACT_TO_NASID_NODEID(cnode) (cnodeid_to_nasid(cnode)) - - #define INVALID_NASID ((nasid_t)-1) #define INVALID_CNODEID ((cnodeid_t)-1) #define INVALID_PNODEID ((pnodeid_t)-1) @@ -34,9 +28,7 @@ #define INVALID_PARTID ((partid_t)-1) extern cpuid_t cnodetocpu(cnodeid_t); -void sn_flush_all_caches(long addr, long bytes); - -extern int is_fine_dirmode(void); - +extern void sn_flush_all_caches(long addr, long bytes); +extern int is_fine_dirmode(void); #endif /* _ASM_IA64_SN_ARCH_H */ diff -Nru a/include/asm-ia64/sn/intr.h b/include/asm-ia64/sn/intr.h --- a/include/asm-ia64/sn/intr.h Fri May 21 14:48:23 2004 +++ b/include/asm-ia64/sn/intr.h Fri May 21 14:48:23 2004 @@ -8,9 +8,11 @@ #ifndef _ASM_IA64_SN_INTR_H #define _ASM_IA64_SN_INTR_H +#include #include extern void sn_send_IPI_phys(long, int, int); +extern void intr_init_vecblk(cnodeid_t node); #define CPU_VECTOR_TO_IRQ(cpuid,vector) (vector) #define SN_CPU_FROM_IRQ(irq) (0) diff -Nru a/include/asm-ia64/sn/module.h b/include/asm-ia64/sn/module.h --- a/include/asm-ia64/sn/module.h Fri May 21 14:48:23 2004 +++ b/include/asm-ia64/sn/module.h Fri May 21 14:48:23 2004 @@ -184,10 +184,6 @@ extern int nummodules; extern module_t *module_lookup(moduleid_t id); - -extern int get_kmod_sys_snum(cmoduleid_t cmod, - char *snum); - extern void format_module_id(char *buffer, moduleid_t m, int fmt); extern int parse_module_id(char *buffer); diff -Nru a/include/asm-ia64/sn/nodepda.h b/include/asm-ia64/sn/nodepda.h --- a/include/asm-ia64/sn/nodepda.h Fri May 21 14:48:23 2004 +++ b/include/asm-ia64/sn/nodepda.h Fri May 21 14:48:23 2004 @@ -36,13 +36,6 @@ struct nodepda_s { - - - cpuid_t node_first_cpu; /* Starting cpu number for node */ - /* WARNING: no guarantee that */ - /* the second cpu on a node is */ - /* node_first_cpu+1. */ - vertex_hdl_t xbow_vhdl; nasid_t xbow_peer; /* NASID of our peer hub on xbow */ struct semaphore xbow_sema; /* Sema for xbow synchronization */ diff -Nru a/include/asm-ia64/sn/sn2/sn_private.h b/include/asm-ia64/sn/sn2/sn_private.h --- a/include/asm-ia64/sn/sn2/sn_private.h Fri May 21 14:48:23 2004 +++ b/include/asm-ia64/sn/sn2/sn_private.h Fri May 21 14:48:23 2004 @@ -233,7 +233,7 @@ * address. */ #define paddr_dimm(_pa) ((_pa & MD_BANK_MASK) >> MD_BANK_SHFT) -#define paddr_cnode(_pa) (NASID_TO_COMPACT_NODEID(NASID_GET(_pa))) +#define paddr_cnode(_pa) (nasid_to_cnodeid(NASID_GET(_pa))) extern void membank_pathname_get(paddr_t, char *); extern void crbx(nasid_t nasid, void (*pf) (char *, ...)); diff -Nru a/include/asm-ia64/sn/types.h b/include/asm-ia64/sn/types.h --- a/include/asm-ia64/sn/types.h Fri May 21 14:48:24 2004 +++ b/include/asm-ia64/sn/types.h Fri May 21 14:48:24 2004 @@ -15,11 +15,9 @@ typedef unsigned int moduleid_t; /* user-visible module number type */ typedef unsigned int cmoduleid_t; /* kernel compact module id type */ typedef signed char slabid_t; -typedef unsigned char clusterid_t; /* Clusterid of the cell */ typedef unsigned long iopaddr_t; typedef unsigned long paddr_t; -typedef unsigned long pfn_t; typedef short cnodeid_t; #endif /* _ASM_IA64_SN_TYPES_H */ diff -Nru a/include/asm-ia64/system.h b/include/asm-ia64/system.h --- a/include/asm-ia64/system.h Fri May 21 14:48:23 2004 +++ b/include/asm-ia64/system.h Fri May 21 14:48:23 2004 @@ -114,10 +114,16 @@ */ /* For spinlocks etc */ -/* clearing psr.i is implicitly serialized (visible by next insn) */ -/* setting psr.i requires data serialization */ +/* + * - clearing psr.i is implicitly serialized (visible by next insn) + * - setting psr.i requires data serialization + * - we need a stop-bit before reading PSR because we sometimes + * write a floating-point register right before reading the PSR + * and that writes to PSR.mfl + */ #define __local_irq_save(x) \ do { \ + ia64_stop(); \ (x) = ia64_getreg(_IA64_REG_PSR); \ ia64_stop(); \ ia64_rsm(IA64_PSR_I); \ @@ -166,7 +172,7 @@ #endif /* !CONFIG_IA64_DEBUG_IRQ */ #define local_irq_enable() ({ ia64_ssm(IA64_PSR_I); ia64_srlz_d(); }) -#define local_save_flags(flags) ((flags) = ia64_getreg(_IA64_REG_PSR)) +#define local_save_flags(flags) ({ ia64_stop(); (flags) = ia64_getreg(_IA64_REG_PSR); }) #define irqs_disabled() \ ({ \ diff -Nru a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h --- a/include/asm-ia64/unistd.h Fri May 21 14:48:23 2004 +++ b/include/asm-ia64/unistd.h Fri May 21 14:48:23 2004 @@ -4,7 +4,7 @@ /* * IA-64 Linux syscall numbers and inline-functions. * - * Copyright (C) 1998-2003 Hewlett-Packard Co + * Copyright (C) 1998-2004 Hewlett-Packard Co * David Mosberger-Tang */ @@ -257,6 +257,7 @@ #define __NR_mq_timedreceive 1265 #define __NR_mq_notify 1266 #define __NR_mq_getsetattr 1267 +#define __NR_kexec_load 1268 #ifdef __KERNEL__ @@ -303,10 +304,10 @@ return sys_lseek(fd, off, whence); } -static inline long +static inline void _exit (int value) { - return sys_exit(value); + sys_exit(value); } #define exit(x) _exit(x) @@ -372,7 +373,7 @@ * proper prototype, but we can't use __typeof__ either, because not all cond_syscall() * declarations have prototypes at the moment. */ -#define cond_syscall(x) asmlinkage long x() __attribute__((weak,alias("sys_ni_syscall"))); +#define cond_syscall(x) asmlinkage long x (void) __attribute__((weak,alias("sys_ni_syscall"))); #endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */ diff -Nru a/include/linux/sched.h b/include/linux/sched.h --- a/include/linux/sched.h Fri May 21 14:48:23 2004 +++ b/include/linux/sched.h Fri May 21 14:48:23 2004 @@ -349,7 +349,7 @@ void exit_io_context(void); #define NGROUPS_SMALL 32 -#define NGROUPS_PER_BLOCK ((int)(EXEC_PAGESIZE / sizeof(gid_t))) +#define NGROUPS_PER_BLOCK ((int)(PAGE_SIZE / sizeof(gid_t))) struct group_info { int ngroups; atomic_t usage; diff -Nru a/kernel/printk.c b/kernel/printk.c --- a/kernel/printk.c Fri May 21 14:48:24 2004 +++ b/kernel/printk.c Fri May 21 14:48:24 2004 @@ -406,6 +406,12 @@ __call_console_drivers(start, end); } } +#ifdef CONFIG_IA64_EARLY_PRINTK + if (!console_drivers) { + void early_printk (const char *str, size_t len); + early_printk(&LOG_BUF(start), end - start); + } +#endif } /* @@ -735,7 +741,11 @@ * for us. */ spin_lock_irqsave(&logbuf_lock, flags); +#ifdef CONFIG_IA64_EARLY_PRINTK + con_start = log_end; +#else con_start = log_start; +#endif spin_unlock_irqrestore(&logbuf_lock, flags); } release_console_sem(); @@ -837,3 +847,117 @@ printk_ratelimit_burst); } EXPORT_SYMBOL(printk_ratelimit); + +#ifdef CONFIG_IA64_EARLY_PRINTK + +#include + +# ifdef CONFIG_IA64_EARLY_PRINTK_VGA + + +#define VGABASE ((char *)0xc0000000000b8000) +#define VGALINES 24 +#define VGACOLS 80 + +static int current_ypos = VGALINES, current_xpos = 0; + +static void +early_printk_vga (const char *str, size_t len) +{ + char c; + int i, k, j; + + while (len-- > 0) { + c = *str++; + if (current_ypos >= VGALINES) { + /* scroll 1 line up */ + for (k = 1, j = 0; k < VGALINES; k++, j++) { + for (i = 0; i < VGACOLS; i++) { + writew(readw(VGABASE + 2*(VGACOLS*k + i)), + VGABASE + 2*(VGACOLS*j + i)); + } + } + for (i = 0; i < VGACOLS; i++) { + writew(0x720, VGABASE + 2*(VGACOLS*j + i)); + } + current_ypos = VGALINES-1; + } + if (c == '\n') { + current_xpos = 0; + current_ypos++; + } else if (c != '\r') { + writew(((0x7 << 8) | (unsigned short) c), + VGABASE + 2*(VGACOLS*current_ypos + current_xpos++)); + if (current_xpos >= VGACOLS) { + current_xpos = 0; + current_ypos++; + } + } + } +} + +# endif /* CONFIG_IA64_EARLY_PRINTK_VGA */ + +# ifdef CONFIG_IA64_EARLY_PRINTK_UART + +#include +#include + +static void early_printk_uart(const char *str, size_t len) +{ + static char *uart = NULL; + unsigned long uart_base; + char c; + + if (!uart) { + uart_base = 0; +# ifdef CONFIG_SERIAL_8250_HCDP + { + extern unsigned long hcdp_early_uart(void); + uart_base = hcdp_early_uart(); + } +# endif +# if CONFIG_IA64_EARLY_PRINTK_UART_BASE + if (!uart_base) + uart_base = CONFIG_IA64_EARLY_PRINTK_UART_BASE; +# endif + if (!uart_base) + return; + + uart = ioremap(uart_base, 64); + if (!uart) + return; + } + + while (len-- > 0) { + c = *str++; + while ((readb(uart + UART_LSR) & UART_LSR_TEMT) == 0) + cpu_relax(); /* spin */ + + writeb(c, uart + UART_TX); + + if (c == '\n') + writeb('\r', uart + UART_TX); + } +} + +# endif /* CONFIG_IA64_EARLY_PRINTK_UART */ + +#ifdef CONFIG_IA64_EARLY_PRINTK_SGI_SN +extern int early_printk_sn_sal(const char *str, int len); +#endif + +void early_printk(const char *str, size_t len) +{ +#ifdef CONFIG_IA64_EARLY_PRINTK_UART + early_printk_uart(str, len); +#endif +#ifdef CONFIG_IA64_EARLY_PRINTK_VGA + early_printk_vga(str, len); +#endif +#ifdef CONFIG_IA64_EARLY_PRINTK_SGI_SN + early_printk_sn_sal(str, len); +#endif +} + +#endif /* CONFIG_IA64_EARLY_PRINTK */