Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc

Pull more powerpc updates from Ben Herrenschmidt:
"Here are the remaining bits I was mentioning earlier. Mostly bug
fixes and new selftests from Michael (yay !). He also removed the WSP
platform and A2 core support which were dead before release, so less
clutter.

One little "feature" I snuck in is the doorbell IPI support for
non-virtualized P8 which speeds up IPIs significantly between threads
of a core"

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (34 commits)
powerpc/book3s: Fix some ABIv2 issues in machine check code
powerpc/book3s: Fix guest MC delivery mechanism to avoid soft lockups in guest.
powerpc/book3s: Increment the mce counter during machine_check_early call.
powerpc/book3s: Add stack overflow check in machine check handler.
powerpc/book3s: Fix machine check handling for unhandled errors
powerpc/eeh: Dump PE location code
powerpc/powernv: Enable POWER8 doorbell IPIs
powerpc/cpuidle: Only clear LPCR decrementer wakeup bit on fast sleep entry
powerpc/powernv: Fix killed EEH event
powerpc: fix typo 'CONFIG_PMAC'
powerpc: fix typo 'CONFIG_PPC_CPU'
powerpc/powernv: Don't escalate non-existing frozen PE
powerpc/eeh: Report frozen parent PE prior to child PE
powerpc/eeh: Clear frozen state for child PE
powerpc/powernv: Reduce panic timeout from 180s to 10s
powerpc/xmon: avoid format string leaking to printk
selftests/powerpc: Add tests of PMU EBBs
selftests/powerpc: Add support for skipping tests
selftests/powerpc: Put the test in a separate process group
selftests/powerpc: Fix instruction loop for ABIv2 (LE)
...

+4514 -4505
-5
arch/powerpc/Kconfig.debug
··· 235 235 Select this to enable early debugging for Nintendo GameCube/Wii 236 236 consoles via an external USB Gecko adapter. 237 237 238 - config PPC_EARLY_DEBUG_WSP 239 - bool "Early debugging via WSP's internal UART" 240 - depends on PPC_WSP 241 - select PPC_UDBG_16550 242 - 243 238 config PPC_EARLY_DEBUG_PS3GELIC 244 239 bool "Early debugging through the PS3 Ethernet port" 245 240 depends on PPC_PS3
-307
arch/powerpc/configs/chroma_defconfig
··· 1 - CONFIG_PPC64=y 2 - CONFIG_PPC_BOOK3E_64=y 3 - # CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set 4 - CONFIG_SMP=y 5 - CONFIG_NR_CPUS=256 6 - CONFIG_EXPERIMENTAL=y 7 - CONFIG_SYSVIPC=y 8 - CONFIG_POSIX_MQUEUE=y 9 - CONFIG_BSD_PROCESS_ACCT=y 10 - CONFIG_TASKSTATS=y 11 - CONFIG_TASK_DELAY_ACCT=y 12 - CONFIG_TASK_XACCT=y 13 - CONFIG_TASK_IO_ACCOUNTING=y 14 - CONFIG_AUDIT=y 15 - CONFIG_AUDITSYSCALL=y 16 - CONFIG_IKCONFIG=y 17 - CONFIG_IKCONFIG_PROC=y 18 - CONFIG_LOG_BUF_SHIFT=19 19 - CONFIG_CGROUPS=y 20 - CONFIG_CGROUP_DEVICE=y 21 - CONFIG_CPUSETS=y 22 - CONFIG_CGROUP_CPUACCT=y 23 - CONFIG_RESOURCE_COUNTERS=y 24 - CONFIG_CGROUP_MEMCG=y 25 - CONFIG_CGROUP_MEMCG_SWAP=y 26 - CONFIG_NAMESPACES=y 27 - CONFIG_RELAY=y 28 - CONFIG_BLK_DEV_INITRD=y 29 - CONFIG_INITRAMFS_SOURCE="" 30 - CONFIG_RD_BZIP2=y 31 - CONFIG_RD_LZMA=y 32 - CONFIG_INITRAMFS_COMPRESSION_GZIP=y 33 - CONFIG_KALLSYMS_ALL=y 34 - CONFIG_EMBEDDED=y 35 - CONFIG_PERF_EVENTS=y 36 - CONFIG_PROFILING=y 37 - CONFIG_OPROFILE=y 38 - CONFIG_KPROBES=y 39 - CONFIG_MODULES=y 40 - CONFIG_MODULE_FORCE_LOAD=y 41 - CONFIG_MODULE_UNLOAD=y 42 - CONFIG_MODULE_FORCE_UNLOAD=y 43 - CONFIG_MODVERSIONS=y 44 - CONFIG_MODULE_SRCVERSION_ALL=y 45 - CONFIG_SCOM_DEBUGFS=y 46 - CONFIG_PPC_A2_DD2=y 47 - CONFIG_KVM_GUEST=y 48 - CONFIG_NO_HZ=y 49 - CONFIG_HIGH_RES_TIMERS=y 50 - CONFIG_HZ_100=y 51 - # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set 52 - CONFIG_BINFMT_MISC=y 53 - CONFIG_NUMA=y 54 - # CONFIG_MIGRATION is not set 55 - CONFIG_PPC_64K_PAGES=y 56 - CONFIG_SCHED_SMT=y 57 - CONFIG_CMDLINE_BOOL=y 58 - CONFIG_CMDLINE="" 59 - # CONFIG_SECCOMP is not set 60 - CONFIG_PCIEPORTBUS=y 61 - # CONFIG_PCIEASPM is not set 62 - CONFIG_PCI_MSI=y 63 - CONFIG_PACKET=y 64 - CONFIG_UNIX=y 65 - CONFIG_XFRM_USER=m 66 - CONFIG_XFRM_SUB_POLICY=y 67 - CONFIG_XFRM_STATISTICS=y 68 - CONFIG_NET_KEY=m 69 - CONFIG_NET_KEY_MIGRATE=y 70 - CONFIG_INET=y 71 - CONFIG_IP_MULTICAST=y 72 - CONFIG_IP_ADVANCED_ROUTER=y 73 - CONFIG_IP_ROUTE_MULTIPATH=y 74 - CONFIG_IP_ROUTE_VERBOSE=y 75 - CONFIG_IP_PNP=y 76 - CONFIG_IP_PNP_DHCP=y 77 - CONFIG_IP_PNP_BOOTP=y 78 - CONFIG_NET_IPIP=y 79 - CONFIG_IP_MROUTE=y 80 - CONFIG_IP_PIMSM_V1=y 81 - CONFIG_IP_PIMSM_V2=y 82 - CONFIG_SYN_COOKIES=y 83 - CONFIG_INET_AH=m 84 - CONFIG_INET_ESP=m 85 - CONFIG_INET_IPCOMP=m 86 - CONFIG_IPV6=y 87 - CONFIG_IPV6_PRIVACY=y 88 - CONFIG_IPV6_ROUTER_PREF=y 89 - CONFIG_IPV6_ROUTE_INFO=y 90 - CONFIG_IPV6_OPTIMISTIC_DAD=y 91 - CONFIG_INET6_AH=y 92 - CONFIG_INET6_ESP=y 93 - CONFIG_INET6_IPCOMP=y 94 - CONFIG_IPV6_MIP6=y 95 - CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=y 96 - CONFIG_IPV6_TUNNEL=y 97 - CONFIG_IPV6_MULTIPLE_TABLES=y 98 - CONFIG_IPV6_SUBTREES=y 99 - CONFIG_IPV6_MROUTE=y 100 - CONFIG_IPV6_PIMSM_V2=y 101 - CONFIG_NETFILTER=y 102 - CONFIG_NF_CONNTRACK=m 103 - CONFIG_NF_CONNTRACK_EVENTS=y 104 - CONFIG_NF_CT_PROTO_UDPLITE=m 105 - CONFIG_NF_CONNTRACK_FTP=m 106 - CONFIG_NF_CONNTRACK_IRC=m 107 - CONFIG_NF_CONNTRACK_TFTP=m 108 - CONFIG_NF_CT_NETLINK=m 109 - CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m 110 - CONFIG_NETFILTER_XT_TARGET_CONNMARK=m 111 - CONFIG_NETFILTER_XT_TARGET_MARK=m 112 - CONFIG_NETFILTER_XT_TARGET_NFLOG=m 113 - CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m 114 - CONFIG_NETFILTER_XT_TARGET_TCPMSS=m 115 - CONFIG_NETFILTER_XT_MATCH_COMMENT=m 116 - CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m 117 - CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m 118 - CONFIG_NETFILTER_XT_MATCH_CONNMARK=m 119 - CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m 120 - CONFIG_NETFILTER_XT_MATCH_DCCP=m 121 - CONFIG_NETFILTER_XT_MATCH_DSCP=m 122 - CONFIG_NETFILTER_XT_MATCH_ESP=m 123 - CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m 124 - CONFIG_NETFILTER_XT_MATCH_HELPER=m 125 - CONFIG_NETFILTER_XT_MATCH_IPRANGE=m 126 - CONFIG_NETFILTER_XT_MATCH_LENGTH=m 127 - CONFIG_NETFILTER_XT_MATCH_LIMIT=m 128 - CONFIG_NETFILTER_XT_MATCH_MAC=m 129 - CONFIG_NETFILTER_XT_MATCH_MARK=m 130 - CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m 131 - CONFIG_NETFILTER_XT_MATCH_OWNER=m 132 - CONFIG_NETFILTER_XT_MATCH_POLICY=m 133 - CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m 134 - CONFIG_NETFILTER_XT_MATCH_QUOTA=m 135 - CONFIG_NETFILTER_XT_MATCH_RATEEST=m 136 - CONFIG_NETFILTER_XT_MATCH_REALM=m 137 - CONFIG_NETFILTER_XT_MATCH_RECENT=m 138 - CONFIG_NETFILTER_XT_MATCH_SCTP=m 139 - CONFIG_NETFILTER_XT_MATCH_STATE=m 140 - CONFIG_NETFILTER_XT_MATCH_STATISTIC=m 141 - CONFIG_NETFILTER_XT_MATCH_STRING=m 142 - CONFIG_NETFILTER_XT_MATCH_TCPMSS=m 143 - CONFIG_NETFILTER_XT_MATCH_TIME=m 144 - CONFIG_NETFILTER_XT_MATCH_U32=m 145 - CONFIG_NF_CONNTRACK_IPV4=m 146 - CONFIG_IP_NF_QUEUE=m 147 - CONFIG_IP_NF_IPTABLES=m 148 - CONFIG_IP_NF_MATCH_AH=m 149 - CONFIG_IP_NF_MATCH_ECN=m 150 - CONFIG_IP_NF_MATCH_TTL=m 151 - CONFIG_IP_NF_FILTER=m 152 - CONFIG_IP_NF_TARGET_REJECT=m 153 - CONFIG_IP_NF_TARGET_LOG=m 154 - CONFIG_IP_NF_TARGET_ULOG=m 155 - CONFIG_NF_NAT=m 156 - CONFIG_IP_NF_TARGET_MASQUERADE=m 157 - CONFIG_IP_NF_TARGET_NETMAP=m 158 - CONFIG_IP_NF_TARGET_REDIRECT=m 159 - CONFIG_NET_TCPPROBE=y 160 - # CONFIG_WIRELESS is not set 161 - CONFIG_NET_9P=y 162 - CONFIG_NET_9P_DEBUG=y 163 - CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 164 - CONFIG_DEVTMPFS=y 165 - CONFIG_MTD=y 166 - CONFIG_MTD_CHAR=y 167 - CONFIG_MTD_BLOCK=y 168 - CONFIG_MTD_CFI=y 169 - CONFIG_MTD_CFI_ADV_OPTIONS=y 170 - CONFIG_MTD_CFI_LE_BYTE_SWAP=y 171 - CONFIG_MTD_CFI_INTELEXT=y 172 - CONFIG_MTD_CFI_AMDSTD=y 173 - CONFIG_MTD_CFI_STAA=y 174 - CONFIG_MTD_PHYSMAP_OF=y 175 - CONFIG_PROC_DEVICETREE=y 176 - CONFIG_BLK_DEV_LOOP=y 177 - CONFIG_BLK_DEV_CRYPTOLOOP=y 178 - CONFIG_BLK_DEV_NBD=m 179 - CONFIG_BLK_DEV_RAM=y 180 - CONFIG_BLK_DEV_RAM_SIZE=65536 181 - CONFIG_CDROM_PKTCDVD=y 182 - CONFIG_MISC_DEVICES=y 183 - CONFIG_BLK_DEV_SD=y 184 - CONFIG_BLK_DEV_SR=y 185 - CONFIG_BLK_DEV_SR_VENDOR=y 186 - CONFIG_CHR_DEV_SG=y 187 - CONFIG_SCSI_MULTI_LUN=y 188 - CONFIG_SCSI_CONSTANTS=y 189 - CONFIG_SCSI_SPI_ATTRS=y 190 - CONFIG_SCSI_FC_ATTRS=y 191 - CONFIG_SCSI_ISCSI_ATTRS=m 192 - CONFIG_SCSI_SAS_ATTRS=m 193 - CONFIG_SCSI_SRP_ATTRS=y 194 - CONFIG_ATA=y 195 - CONFIG_SATA_AHCI=y 196 - CONFIG_SATA_SIL24=y 197 - CONFIG_SATA_MV=y 198 - CONFIG_SATA_SIL=y 199 - CONFIG_PATA_CMD64X=y 200 - CONFIG_PATA_MARVELL=y 201 - CONFIG_PATA_SIL680=y 202 - CONFIG_MD=y 203 - CONFIG_BLK_DEV_MD=y 204 - CONFIG_MD_LINEAR=y 205 - CONFIG_BLK_DEV_DM=y 206 - CONFIG_DM_CRYPT=y 207 - CONFIG_DM_SNAPSHOT=y 208 - CONFIG_DM_MIRROR=y 209 - CONFIG_DM_ZERO=y 210 - CONFIG_DM_UEVENT=y 211 - CONFIG_NETDEVICES=y 212 - CONFIG_TUN=y 213 - CONFIG_E1000E=y 214 - CONFIG_TIGON3=y 215 - # CONFIG_WLAN is not set 216 - # CONFIG_INPUT is not set 217 - # CONFIG_SERIO is not set 218 - # CONFIG_VT is not set 219 - CONFIG_DEVPTS_MULTIPLE_INSTANCES=y 220 - CONFIG_SERIAL_8250=y 221 - CONFIG_SERIAL_8250_CONSOLE=y 222 - CONFIG_HW_RANDOM=y 223 - CONFIG_RAW_DRIVER=y 224 - CONFIG_MAX_RAW_DEVS=1024 225 - # CONFIG_HWMON is not set 226 - # CONFIG_VGA_ARB is not set 227 - # CONFIG_USB_SUPPORT is not set 228 - CONFIG_EDAC=y 229 - CONFIG_EDAC_MM_EDAC=y 230 - CONFIG_RTC_CLASS=y 231 - CONFIG_RTC_DRV_DS1511=y 232 - CONFIG_RTC_DRV_DS1553=y 233 - CONFIG_EXT2_FS=y 234 - CONFIG_EXT2_FS_XATTR=y 235 - CONFIG_EXT2_FS_POSIX_ACL=y 236 - CONFIG_EXT2_FS_SECURITY=y 237 - CONFIG_EXT2_FS_XIP=y 238 - CONFIG_EXT3_FS=y 239 - # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set 240 - CONFIG_EXT3_FS_POSIX_ACL=y 241 - CONFIG_EXT3_FS_SECURITY=y 242 - CONFIG_EXT4_FS=y 243 - # CONFIG_DNOTIFY is not set 244 - CONFIG_FUSE_FS=y 245 - CONFIG_ISO9660_FS=y 246 - CONFIG_JOLIET=y 247 - CONFIG_ZISOFS=y 248 - CONFIG_UDF_FS=m 249 - CONFIG_MSDOS_FS=y 250 - CONFIG_VFAT_FS=y 251 - CONFIG_PROC_KCORE=y 252 - CONFIG_TMPFS=y 253 - CONFIG_TMPFS_POSIX_ACL=y 254 - CONFIG_CONFIGFS_FS=m 255 - CONFIG_CRAMFS=y 256 - CONFIG_NFS_FS=y 257 - CONFIG_NFS_V3=y 258 - CONFIG_NFS_V3_ACL=y 259 - CONFIG_NFS_V4=y 260 - CONFIG_NFS_V4_1=y 261 - CONFIG_ROOT_NFS=y 262 - CONFIG_CIFS=y 263 - CONFIG_CIFS_WEAK_PW_HASH=y 264 - CONFIG_CIFS_XATTR=y 265 - CONFIG_CIFS_POSIX=y 266 - CONFIG_NLS_CODEPAGE_437=y 267 - CONFIG_NLS_ASCII=y 268 - CONFIG_NLS_ISO8859_1=y 269 - CONFIG_CRC_CCITT=m 270 - CONFIG_CRC_T10DIF=y 271 - CONFIG_LIBCRC32C=m 272 - CONFIG_PRINTK_TIME=y 273 - CONFIG_MAGIC_SYSRQ=y 274 - CONFIG_STRIP_ASM_SYMS=y 275 - CONFIG_DETECT_HUNG_TASK=y 276 - # CONFIG_SCHED_DEBUG is not set 277 - CONFIG_DEBUG_INFO=y 278 - CONFIG_FTRACE_SYSCALLS=y 279 - CONFIG_PPC_EMULATED_STATS=y 280 - CONFIG_XMON=y 281 - CONFIG_XMON_DEFAULT=y 282 - CONFIG_IRQ_DOMAIN_DEBUG=y 283 - CONFIG_PPC_EARLY_DEBUG=y 284 - CONFIG_KEYS_DEBUG_PROC_KEYS=y 285 - CONFIG_CRYPTO_NULL=m 286 - CONFIG_CRYPTO_TEST=m 287 - CONFIG_CRYPTO_CCM=m 288 - CONFIG_CRYPTO_GCM=m 289 - CONFIG_CRYPTO_PCBC=m 290 - CONFIG_CRYPTO_MICHAEL_MIC=m 291 - CONFIG_CRYPTO_SHA256=m 292 - CONFIG_CRYPTO_SHA512=m 293 - CONFIG_CRYPTO_TGR192=m 294 - CONFIG_CRYPTO_WP512=m 295 - CONFIG_CRYPTO_AES=m 296 - CONFIG_CRYPTO_ANUBIS=m 297 - CONFIG_CRYPTO_BLOWFISH=m 298 - CONFIG_CRYPTO_CAST5=m 299 - CONFIG_CRYPTO_CAST6=m 300 - CONFIG_CRYPTO_KHAZAD=m 301 - CONFIG_CRYPTO_SALSA20=m 302 - CONFIG_CRYPTO_SERPENT=m 303 - CONFIG_CRYPTO_TEA=m 304 - CONFIG_CRYPTO_TWOFISH=m 305 - CONFIG_CRYPTO_LZO=m 306 - # CONFIG_CRYPTO_ANSI_CPRNG is not set 307 - CONFIG_VIRTUALIZATION=y
-1
arch/powerpc/include/asm/cpm2.h
··· 489 489 #define FCC_GFMR_TCI ((uint)0x20000000) 490 490 #define FCC_GFMR_TRX ((uint)0x10000000) 491 491 #define FCC_GFMR_TTX ((uint)0x08000000) 492 - #define FCC_GFMR_TTX ((uint)0x08000000) 493 492 #define FCC_GFMR_CDP ((uint)0x04000000) 494 493 #define FCC_GFMR_CTSP ((uint)0x02000000) 495 494 #define FCC_GFMR_CDS ((uint)0x01000000)
+1
arch/powerpc/include/asm/eeh.h
··· 254 254 void *eeh_pe_dev_traverse(struct eeh_pe *root, 255 255 eeh_traverse_func fn, void *flag); 256 256 void eeh_pe_restore_bars(struct eeh_pe *pe); 257 + const char *eeh_pe_loc_get(struct eeh_pe *pe); 257 258 struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe); 258 259 259 260 void *eeh_dev_init(struct device_node *dn, void *data);
+1 -1
arch/powerpc/include/asm/eeh_event.h
··· 33 33 34 34 int eeh_event_init(void); 35 35 int eeh_send_failure_event(struct eeh_pe *pe); 36 - void eeh_remove_event(struct eeh_pe *pe); 36 + void eeh_remove_event(struct eeh_pe *pe, bool force); 37 37 void eeh_handle_event(struct eeh_pe *pe); 38 38 39 39 #endif /* __KERNEL__ */
-4
arch/powerpc/include/asm/mmu-book3e.h
··· 223 223 unsigned int id; 224 224 unsigned int active; 225 225 unsigned long vdso_base; 226 - #ifdef CONFIG_PPC_ICSWX 227 - struct spinlock *cop_lockp; /* guard cop related stuff */ 228 - unsigned long acop; /* mask of enabled coprocessor types */ 229 - #endif /* CONFIG_PPC_ICSWX */ 230 226 #ifdef CONFIG_PPC_MM_SLICES 231 227 u64 low_slices_psize; /* SLB page size encodings */ 232 228 u64 high_slices_psize; /* 4 bits per slice for now */
+51 -51
arch/powerpc/include/asm/opal.h
··· 599 599 }; 600 600 601 601 struct OpalIoPhbErrorCommon { 602 - uint32_t version; 603 - uint32_t ioType; 604 - uint32_t len; 602 + __be32 version; 603 + __be32 ioType; 604 + __be32 len; 605 605 }; 606 606 607 607 struct OpalIoP7IOCPhbErrorData { ··· 666 666 struct OpalIoPhb3ErrorData { 667 667 struct OpalIoPhbErrorCommon common; 668 668 669 - uint32_t brdgCtl; 669 + __be32 brdgCtl; 670 670 671 671 /* PHB3 UTL regs */ 672 - uint32_t portStatusReg; 673 - uint32_t rootCmplxStatus; 674 - uint32_t busAgentStatus; 672 + __be32 portStatusReg; 673 + __be32 rootCmplxStatus; 674 + __be32 busAgentStatus; 675 675 676 676 /* PHB3 cfg regs */ 677 - uint32_t deviceStatus; 678 - uint32_t slotStatus; 679 - uint32_t linkStatus; 680 - uint32_t devCmdStatus; 681 - uint32_t devSecStatus; 677 + __be32 deviceStatus; 678 + __be32 slotStatus; 679 + __be32 linkStatus; 680 + __be32 devCmdStatus; 681 + __be32 devSecStatus; 682 682 683 683 /* cfg AER regs */ 684 - uint32_t rootErrorStatus; 685 - uint32_t uncorrErrorStatus; 686 - uint32_t corrErrorStatus; 687 - uint32_t tlpHdr1; 688 - uint32_t tlpHdr2; 689 - uint32_t tlpHdr3; 690 - uint32_t tlpHdr4; 691 - uint32_t sourceId; 684 + __be32 rootErrorStatus; 685 + __be32 uncorrErrorStatus; 686 + __be32 corrErrorStatus; 687 + __be32 tlpHdr1; 688 + __be32 tlpHdr2; 689 + __be32 tlpHdr3; 690 + __be32 tlpHdr4; 691 + __be32 sourceId; 692 692 693 - uint32_t rsv3; 693 + __be32 rsv3; 694 694 695 695 /* Record data about the call to allocate a buffer */ 696 - uint64_t errorClass; 697 - uint64_t correlator; 696 + __be64 errorClass; 697 + __be64 correlator; 698 698 699 - uint64_t nFir; /* 000 */ 700 - uint64_t nFirMask; /* 003 */ 701 - uint64_t nFirWOF; /* 008 */ 699 + __be64 nFir; /* 000 */ 700 + __be64 nFirMask; /* 003 */ 701 + __be64 nFirWOF; /* 008 */ 702 702 703 703 /* PHB3 MMIO Error Regs */ 704 - uint64_t phbPlssr; /* 120 */ 705 - uint64_t phbCsr; /* 110 */ 706 - uint64_t lemFir; /* C00 */ 707 - uint64_t lemErrorMask; /* C18 */ 708 - uint64_t lemWOF; /* C40 */ 709 - uint64_t phbErrorStatus; /* C80 */ 710 - uint64_t phbFirstErrorStatus; /* C88 */ 711 - uint64_t phbErrorLog0; /* CC0 */ 712 - uint64_t phbErrorLog1; /* CC8 */ 713 - uint64_t mmioErrorStatus; /* D00 */ 714 - uint64_t mmioFirstErrorStatus; /* D08 */ 715 - uint64_t mmioErrorLog0; /* D40 */ 716 - uint64_t mmioErrorLog1; /* D48 */ 717 - uint64_t dma0ErrorStatus; /* D80 */ 718 - uint64_t dma0FirstErrorStatus; /* D88 */ 719 - uint64_t dma0ErrorLog0; /* DC0 */ 720 - uint64_t dma0ErrorLog1; /* DC8 */ 721 - uint64_t dma1ErrorStatus; /* E00 */ 722 - uint64_t dma1FirstErrorStatus; /* E08 */ 723 - uint64_t dma1ErrorLog0; /* E40 */ 724 - uint64_t dma1ErrorLog1; /* E48 */ 725 - uint64_t pestA[OPAL_PHB3_NUM_PEST_REGS]; 726 - uint64_t pestB[OPAL_PHB3_NUM_PEST_REGS]; 704 + __be64 phbPlssr; /* 120 */ 705 + __be64 phbCsr; /* 110 */ 706 + __be64 lemFir; /* C00 */ 707 + __be64 lemErrorMask; /* C18 */ 708 + __be64 lemWOF; /* C40 */ 709 + __be64 phbErrorStatus; /* C80 */ 710 + __be64 phbFirstErrorStatus; /* C88 */ 711 + __be64 phbErrorLog0; /* CC0 */ 712 + __be64 phbErrorLog1; /* CC8 */ 713 + __be64 mmioErrorStatus; /* D00 */ 714 + __be64 mmioFirstErrorStatus; /* D08 */ 715 + __be64 mmioErrorLog0; /* D40 */ 716 + __be64 mmioErrorLog1; /* D48 */ 717 + __be64 dma0ErrorStatus; /* D80 */ 718 + __be64 dma0FirstErrorStatus; /* D88 */ 719 + __be64 dma0ErrorLog0; /* DC0 */ 720 + __be64 dma0ErrorLog1; /* DC8 */ 721 + __be64 dma1ErrorStatus; /* E00 */ 722 + __be64 dma1FirstErrorStatus; /* E08 */ 723 + __be64 dma1ErrorLog0; /* E40 */ 724 + __be64 dma1ErrorLog1; /* E48 */ 725 + __be64 pestA[OPAL_PHB3_NUM_PEST_REGS]; 726 + __be64 pestB[OPAL_PHB3_NUM_PEST_REGS]; 727 727 }; 728 728 729 729 enum { ··· 851 851 int64_t opal_set_slot_led_status(uint64_t phb_id, uint64_t slot_id, uint8_t led_type, uint8_t led_action); 852 852 int64_t opal_get_epow_status(__be64 *status); 853 853 int64_t opal_set_system_attention_led(uint8_t led_action); 854 - int64_t opal_pci_next_error(uint64_t phb_id, uint64_t *first_frozen_pe, 855 - uint16_t *pci_error_type, uint16_t *severity); 854 + int64_t opal_pci_next_error(uint64_t phb_id, __be64 *first_frozen_pe, 855 + __be16 *pci_error_type, __be16 *severity); 856 856 int64_t opal_pci_poll(uint64_t phb_id); 857 857 int64_t opal_return_cpu(void); 858 858 int64_t opal_reinit_cpus(uint64_t flags);
-9
arch/powerpc/include/asm/reg_a2.h
··· 110 110 #define TLB1_UR ASM_CONST(0x0000000000000002) 111 111 #define TLB1_SR ASM_CONST(0x0000000000000001) 112 112 113 - #ifdef CONFIG_PPC_EARLY_DEBUG_WSP 114 - #define WSP_UART_PHYS 0xffc000c000 115 - /* This needs to be careful chosen to hit a !0 congruence class 116 - * in the TLB since we bolt it in way 3, which is already occupied 117 - * by our linear mapping primary bolted entry in CC 0. 118 - */ 119 - #define WSP_UART_VIRT 0xf000000000001000 120 - #endif 121 - 122 113 /* A2 erativax attributes definitions */ 123 114 #define ERATIVAX_RS_IS_ALL 0x000 124 115 #define ERATIVAX_RS_IS_TID 0x040
+6 -2
arch/powerpc/include/asm/switch_to.h
··· 16 16 extern struct task_struct *_switch(struct thread_struct *prev, 17 17 struct thread_struct *next); 18 18 #ifdef CONFIG_PPC_BOOK3S_64 19 - static inline void save_tar(struct thread_struct *prev) 19 + static inline void save_early_sprs(struct thread_struct *prev) 20 20 { 21 21 if (cpu_has_feature(CPU_FTR_ARCH_207S)) 22 22 prev->tar = mfspr(SPRN_TAR); 23 + if (cpu_has_feature(CPU_FTR_DSCR)) 24 + prev->dscr = mfspr(SPRN_DSCR); 23 25 } 24 26 #else 25 - static inline void save_tar(struct thread_struct *prev) {} 27 + static inline void save_early_sprs(struct thread_struct *prev) {} 26 28 #endif 27 29 28 30 extern void enable_kernel_fp(void); ··· 86 84 { 87 85 #ifdef CONFIG_PPC_BOOK3S_64 88 86 /* EBB perf events are not inherited, so clear all EBB state. */ 87 + t->thread.ebbrr = 0; 88 + t->thread.ebbhr = 0; 89 89 t->thread.bescr = 0; 90 90 t->thread.mmcr2 = 0; 91 91 t->thread.mmcr0 = 0;
-14
arch/powerpc/include/asm/wsp.h
··· 1 - /* 2 - * Copyright 2011 Michael Ellerman, IBM Corp. 3 - * 4 - * This program is free software; you can redistribute it and/or 5 - * modify it under the terms of the GNU General Public License 6 - * as published by the Free Software Foundation; either version 7 - * 2 of the License, or (at your option) any later version. 8 - */ 9 - #ifndef __ASM_POWERPC_WSP_H 10 - #define __ASM_POWERPC_WSP_H 11 - 12 - extern int wsp_get_chip_id(struct device_node *dn); 13 - 14 - #endif /* __ASM_POWERPC_WSP_H */
+1
arch/powerpc/include/uapi/asm/cputable.h
··· 41 41 #define PPC_FEATURE2_EBB 0x10000000 42 42 #define PPC_FEATURE2_ISEL 0x08000000 43 43 #define PPC_FEATURE2_TAR 0x04000000 44 + #define PPC_FEATURE2_VEC_CRYPTO 0x02000000 44 45 45 46 #endif /* _UAPI__ASM_POWERPC_CPUTABLE_H */
-1
arch/powerpc/kernel/Makefile
··· 43 43 obj-$(CONFIG_PPC_BOOK3S_64) += mce.o mce_power.o 44 44 obj64-$(CONFIG_RELOCATABLE) += reloc_64.o 45 45 obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o idle_book3e.o 46 - obj-$(CONFIG_PPC_A2) += cpu_setup_a2.o 47 46 obj-$(CONFIG_PPC64) += vdso64/ 48 47 obj-$(CONFIG_ALTIVEC) += vecemu.o 49 48 obj-$(CONFIG_PPC_970_NAP) += idle_power4.o
-120
arch/powerpc/kernel/cpu_setup_a2.S
··· 1 - /* 2 - * A2 specific assembly support code 3 - * 4 - * Copyright 2009 Ben Herrenschmidt, IBM Corp. 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of the GNU General Public License 8 - * as published by the Free Software Foundation; either version 9 - * 2 of the License, or (at your option) any later version. 10 - */ 11 - 12 - #include <asm/asm-offsets.h> 13 - #include <asm/ppc_asm.h> 14 - #include <asm/ppc-opcode.h> 15 - #include <asm/processor.h> 16 - #include <asm/reg_a2.h> 17 - #include <asm/reg.h> 18 - #include <asm/thread_info.h> 19 - 20 - /* 21 - * Disable thdid and class fields in ERATs to bump PID to full 14 bits capacity. 22 - * This also prevents external LPID accesses but that isn't a problem when not a 23 - * guest. Under PV, this setting will be ignored and MMUCR will return the right 24 - * number of PID bits we can use. 25 - */ 26 - #define MMUCR1_EXTEND_PID \ 27 - (MMUCR1_ICTID | MMUCR1_ITTID | MMUCR1_DCTID | \ 28 - MMUCR1_DTTID | MMUCR1_DCCD) 29 - 30 - /* 31 - * Use extended PIDs if enabled. 32 - * Don't clear the ERATs on context sync events and enable I & D LRU. 33 - * Enable ERAT back invalidate when tlbwe overwrites an entry. 34 - */ 35 - #define INITIAL_MMUCR1 \ 36 - (MMUCR1_EXTEND_PID | MMUCR1_CSINV_NEVER | MMUCR1_IRRE | \ 37 - MMUCR1_DRRE | MMUCR1_TLBWE_BINV) 38 - 39 - _GLOBAL(__setup_cpu_a2) 40 - /* Some of these are actually thread local and some are 41 - * core local but doing it always won't hurt 42 - */ 43 - 44 - #ifdef CONFIG_PPC_ICSWX 45 - /* Make sure ACOP starts out as zero */ 46 - li r3,0 47 - mtspr SPRN_ACOP,r3 48 - 49 - /* Skip the following if we are in Guest mode */ 50 - mfmsr r3 51 - andis. r0,r3,MSR_GS@h 52 - bne _icswx_skip_guest 53 - 54 - /* Enable icswx instruction */ 55 - mfspr r3,SPRN_A2_CCR2 56 - ori r3,r3,A2_CCR2_ENABLE_ICSWX 57 - mtspr SPRN_A2_CCR2,r3 58 - 59 - /* Unmask all CTs in HACOP */ 60 - li r3,-1 61 - mtspr SPRN_HACOP,r3 62 - _icswx_skip_guest: 63 - #endif /* CONFIG_PPC_ICSWX */ 64 - 65 - /* Enable doorbell */ 66 - mfspr r3,SPRN_A2_CCR2 67 - oris r3,r3,A2_CCR2_ENABLE_PC@h 68 - mtspr SPRN_A2_CCR2,r3 69 - isync 70 - 71 - /* Setup CCR0 to disable power saving for now as it's busted 72 - * in the current implementations. Setup CCR1 to wake on 73 - * interrupts normally (we write the default value but who 74 - * knows what FW may have clobbered...) 75 - */ 76 - li r3,0 77 - mtspr SPRN_A2_CCR0, r3 78 - LOAD_REG_IMMEDIATE(r3,0x0f0f0f0f) 79 - mtspr SPRN_A2_CCR1, r3 80 - 81 - /* Initialise MMUCR1 */ 82 - lis r3,INITIAL_MMUCR1@h 83 - ori r3,r3,INITIAL_MMUCR1@l 84 - mtspr SPRN_MMUCR1,r3 85 - 86 - /* Set MMUCR2 to enable 4K, 64K, 1M, 16M and 1G pages */ 87 - LOAD_REG_IMMEDIATE(r3, 0x000a7531) 88 - mtspr SPRN_MMUCR2,r3 89 - 90 - /* Set MMUCR3 to write all thids bit to the TLB */ 91 - LOAD_REG_IMMEDIATE(r3, 0x0000000f) 92 - mtspr SPRN_MMUCR3,r3 93 - 94 - /* Don't do ERAT stuff if running guest mode */ 95 - mfmsr r3 96 - andis. r0,r3,MSR_GS@h 97 - bne 1f 98 - 99 - /* Now set the I-ERAT watermark to 15 */ 100 - lis r4,(MMUCR0_TLBSEL_I|MMUCR0_ECL)@h 101 - mtspr SPRN_MMUCR0, r4 102 - li r4,A2_IERAT_SIZE-1 103 - PPC_ERATWE(R4,R4,3) 104 - 105 - /* Now set the D-ERAT watermark to 31 */ 106 - lis r4,(MMUCR0_TLBSEL_D|MMUCR0_ECL)@h 107 - mtspr SPRN_MMUCR0, r4 108 - li r4,A2_DERAT_SIZE-1 109 - PPC_ERATWE(R4,R4,3) 110 - 111 - /* And invalidate the beast just in case. That won't get rid of 112 - * a bolted entry though it will be in LRU and so will go away eventually 113 - * but let's not bother for now 114 - */ 115 - PPC_ERATILX(0,0,R0) 116 - 1: 117 - blr 118 - 119 - _GLOBAL(__restore_cpu_a2) 120 - b __setup_cpu_a2
+2
arch/powerpc/kernel/cpu_setup_power.S
··· 56 56 li r0,0 57 57 mtspr SPRN_LPID,r0 58 58 mfspr r3,SPRN_LPCR 59 + ori r3, r3, LPCR_PECEDH 59 60 bl __init_LPCR 60 61 bl __init_HFSCR 61 62 bl __init_tlb_power8 ··· 75 74 li r0,0 76 75 mtspr SPRN_LPID,r0 77 76 mfspr r3,SPRN_LPCR 77 + ori r3, r3, LPCR_PECEDH 78 78 bl __init_LPCR 79 79 bl __init_HFSCR 80 80 bl __init_tlb_power8
+2 -39
arch/powerpc/kernel/cputable.c
··· 109 109 PPC_FEATURE_PSERIES_PERFMON_COMPAT) 110 110 #define COMMON_USER2_POWER8 (PPC_FEATURE2_ARCH_2_07 | \ 111 111 PPC_FEATURE2_HTM_COMP | PPC_FEATURE2_DSCR | \ 112 - PPC_FEATURE2_ISEL | PPC_FEATURE2_TAR) 112 + PPC_FEATURE2_ISEL | PPC_FEATURE2_TAR | \ 113 + PPC_FEATURE2_VEC_CRYPTO) 113 114 #define COMMON_USER_PA6T (COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\ 114 115 PPC_FEATURE_TRUE_LE | \ 115 116 PPC_FEATURE_HAS_ALTIVEC_COMP) ··· 2149 2148 } 2150 2149 #endif /* CONFIG_PPC32 */ 2151 2150 #endif /* CONFIG_E500 */ 2152 - 2153 - #ifdef CONFIG_PPC_A2 2154 - { /* Standard A2 (>= DD2) + FPU core */ 2155 - .pvr_mask = 0xffff0000, 2156 - .pvr_value = 0x00480000, 2157 - .cpu_name = "A2 (>= DD2)", 2158 - .cpu_features = CPU_FTRS_A2, 2159 - .cpu_user_features = COMMON_USER_PPC64, 2160 - .mmu_features = MMU_FTRS_A2, 2161 - .icache_bsize = 64, 2162 - .dcache_bsize = 64, 2163 - .num_pmcs = 0, 2164 - .cpu_setup = __setup_cpu_a2, 2165 - .cpu_restore = __restore_cpu_a2, 2166 - .machine_check = machine_check_generic, 2167 - .platform = "ppca2", 2168 - }, 2169 - { /* This is a default entry to get going, to be replaced by 2170 - * a real one at some stage 2171 - */ 2172 - #define CPU_FTRS_BASE_BOOK3E (CPU_FTR_USE_TB | \ 2173 - CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_SMT | \ 2174 - CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE) 2175 - .pvr_mask = 0x00000000, 2176 - .pvr_value = 0x00000000, 2177 - .cpu_name = "Book3E", 2178 - .cpu_features = CPU_FTRS_BASE_BOOK3E, 2179 - .cpu_user_features = COMMON_USER_PPC64, 2180 - .mmu_features = MMU_FTR_TYPE_3E | MMU_FTR_USE_TLBILX | 2181 - MMU_FTR_USE_TLBIVAX_BCAST | 2182 - MMU_FTR_LOCK_BCAST_INVAL, 2183 - .icache_bsize = 64, 2184 - .dcache_bsize = 64, 2185 - .num_pmcs = 0, 2186 - .machine_check = machine_check_generic, 2187 - .platform = "power6", 2188 - }, 2189 - #endif /* CONFIG_PPC_A2 */ 2190 2151 }; 2191 2152 2192 2153 static struct cpu_spec the_cpu_spec;
+31 -7
arch/powerpc/kernel/eeh.c
··· 330 330 eeh_pe_state_mark(phb_pe, EEH_PE_ISOLATED); 331 331 eeh_serialize_unlock(flags); 332 332 333 - pr_err("EEH: PHB#%x failure detected\n", 334 - phb_pe->phb->global_number); 333 + pr_err("EEH: PHB#%x failure detected, location: %s\n", 334 + phb_pe->phb->global_number, eeh_pe_loc_get(phb_pe)); 335 335 dump_stack(); 336 336 eeh_send_failure_event(phb_pe); 337 337 ··· 358 358 int eeh_dev_check_failure(struct eeh_dev *edev) 359 359 { 360 360 int ret; 361 + int active_flags = (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE); 361 362 unsigned long flags; 362 363 struct device_node *dn; 363 364 struct pci_dev *dev; 364 - struct eeh_pe *pe; 365 + struct eeh_pe *pe, *parent_pe, *phb_pe; 365 366 int rc = 0; 366 367 const char *location; 367 368 ··· 440 439 */ 441 440 if ((ret < 0) || 442 441 (ret == EEH_STATE_NOT_SUPPORT) || 443 - (ret & (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) == 444 - (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) { 442 + ((ret & active_flags) == active_flags)) { 445 443 eeh_stats.false_positives++; 446 444 pe->false_positives++; 447 445 rc = 0; 448 446 goto dn_unlock; 447 + } 448 + 449 + /* 450 + * It should be corner case that the parent PE has been 451 + * put into frozen state as well. We should take care 452 + * that at first. 453 + */ 454 + parent_pe = pe->parent; 455 + while (parent_pe) { 456 + /* Hit the ceiling ? */ 457 + if (parent_pe->type & EEH_PE_PHB) 458 + break; 459 + 460 + /* Frozen parent PE ? */ 461 + ret = eeh_ops->get_state(parent_pe, NULL); 462 + if (ret > 0 && 463 + (ret & active_flags) != active_flags) 464 + pe = parent_pe; 465 + 466 + /* Next parent level */ 467 + parent_pe = parent_pe->parent; 449 468 } 450 469 451 470 eeh_stats.slot_resets++; ··· 481 460 * a stack trace will help the device-driver authors figure 482 461 * out what happened. So print that out. 483 462 */ 484 - pr_err("EEH: Frozen PE#%x detected on PHB#%x\n", 485 - pe->addr, pe->phb->global_number); 463 + phb_pe = eeh_phb_pe_get(pe->phb); 464 + pr_err("EEH: Frozen PHB#%x-PE#%x detected\n", 465 + pe->phb->global_number, pe->addr); 466 + pr_err("EEH: PE location: %s, PHB location: %s\n", 467 + eeh_pe_loc_get(pe), eeh_pe_loc_get(phb_pe)); 486 468 dump_stack(); 487 469 488 470 eeh_send_failure_event(pe);
+18 -6
arch/powerpc/kernel/eeh_driver.c
··· 447 447 * PE reset (for 3 times), we try to clear the frozen state 448 448 * for 3 times as well. 449 449 */ 450 - static int eeh_clear_pe_frozen_state(struct eeh_pe *pe) 450 + static void *__eeh_clear_pe_frozen_state(void *data, void *flag) 451 451 { 452 + struct eeh_pe *pe = (struct eeh_pe *)data; 452 453 int i, rc; 453 454 454 455 for (i = 0; i < 3; i++) { ··· 462 461 } 463 462 464 463 /* The PE has been isolated, clear it */ 465 - if (rc) 464 + if (rc) { 466 465 pr_warn("%s: Can't clear frozen PHB#%x-PE#%x (%d)\n", 467 466 __func__, pe->phb->global_number, pe->addr, rc); 468 - else 467 + return (void *)pe; 468 + } 469 + 470 + return NULL; 471 + } 472 + 473 + static int eeh_clear_pe_frozen_state(struct eeh_pe *pe) 474 + { 475 + void *rc; 476 + 477 + rc = eeh_pe_traverse(pe, __eeh_clear_pe_frozen_state, NULL); 478 + if (!rc) 469 479 eeh_pe_state_clear(pe, EEH_PE_ISOLATED); 470 480 471 - return rc; 481 + return rc ? -EIO : 0; 472 482 } 473 483 474 484 /** ··· 770 758 eeh_serialize_lock(&flags); 771 759 772 760 /* Purge all events */ 773 - eeh_remove_event(NULL); 761 + eeh_remove_event(NULL, true); 774 762 775 763 list_for_each_entry(hose, &hose_list, list_node) { 776 764 phb_pe = eeh_phb_pe_get(hose); ··· 789 777 eeh_serialize_lock(&flags); 790 778 791 779 /* Purge all events of the PHB */ 792 - eeh_remove_event(pe); 780 + eeh_remove_event(pe, true); 793 781 794 782 if (rc == EEH_NEXT_ERR_DEAD_PHB) 795 783 eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
+15 -6
arch/powerpc/kernel/eeh_event.c
··· 152 152 /** 153 153 * eeh_remove_event - Remove EEH event from the queue 154 154 * @pe: Event binding to the PE 155 + * @force: Event will be removed unconditionally 155 156 * 156 157 * On PowerNV platform, we might have subsequent coming events 157 158 * is part of the former one. For that case, those subsequent 158 159 * coming events are totally duplicated and unnecessary, thus 159 160 * they should be removed. 160 161 */ 161 - void eeh_remove_event(struct eeh_pe *pe) 162 + void eeh_remove_event(struct eeh_pe *pe, bool force) 162 163 { 163 164 unsigned long flags; 164 165 struct eeh_event *event, *tmp; 165 166 167 + /* 168 + * If we have NULL PE passed in, we have dead IOC 169 + * or we're sure we can report all existing errors 170 + * by the caller. 171 + * 172 + * With "force", the event with associated PE that 173 + * have been isolated, the event won't be removed 174 + * to avoid event lost. 175 + */ 166 176 spin_lock_irqsave(&eeh_eventlist_lock, flags); 167 177 list_for_each_entry_safe(event, tmp, &eeh_eventlist, list) { 168 - /* 169 - * If we don't have valid PE passed in, that means 170 - * we already have event corresponding to dead IOC 171 - * and all events should be purged. 172 - */ 178 + if (!force && event->pe && 179 + (event->pe->state & EEH_PE_ISOLATED)) 180 + continue; 181 + 173 182 if (!pe) { 174 183 list_del(&event->list); 175 184 kfree(event);
+60
arch/powerpc/kernel/eeh_pe.c
··· 792 792 } 793 793 794 794 /** 795 + * eeh_pe_loc_get - Retrieve location code binding to the given PE 796 + * @pe: EEH PE 797 + * 798 + * Retrieve the location code of the given PE. If the primary PE bus 799 + * is root bus, we will grab location code from PHB device tree node 800 + * or root port. Otherwise, the upstream bridge's device tree node 801 + * of the primary PE bus will be checked for the location code. 802 + */ 803 + const char *eeh_pe_loc_get(struct eeh_pe *pe) 804 + { 805 + struct pci_controller *hose; 806 + struct pci_bus *bus = eeh_pe_bus_get(pe); 807 + struct pci_dev *pdev; 808 + struct device_node *dn; 809 + const char *loc; 810 + 811 + if (!bus) 812 + return "N/A"; 813 + 814 + /* PHB PE or root PE ? */ 815 + if (pci_is_root_bus(bus)) { 816 + hose = pci_bus_to_host(bus); 817 + loc = of_get_property(hose->dn, 818 + "ibm,loc-code", NULL); 819 + if (loc) 820 + return loc; 821 + loc = of_get_property(hose->dn, 822 + "ibm,io-base-loc-code", NULL); 823 + if (loc) 824 + return loc; 825 + 826 + pdev = pci_get_slot(bus, 0x0); 827 + } else { 828 + pdev = bus->self; 829 + } 830 + 831 + if (!pdev) { 832 + loc = "N/A"; 833 + goto out; 834 + } 835 + 836 + dn = pci_device_to_OF_node(pdev); 837 + if (!dn) { 838 + loc = "N/A"; 839 + goto out; 840 + } 841 + 842 + loc = of_get_property(dn, "ibm,loc-code", NULL); 843 + if (!loc) 844 + loc = of_get_property(dn, "ibm,slot-location-code", NULL); 845 + if (!loc) 846 + loc = "N/A"; 847 + 848 + out: 849 + if (pci_is_root_bus(bus) && pdev) 850 + pci_dev_put(pdev); 851 + return loc; 852 + } 853 + 854 + /** 795 855 * eeh_pe_bus_get - Retrieve PCI bus according to the given PE 796 856 * @pe: EEH PE 797 857 *
-6
arch/powerpc/kernel/entry_64.S
··· 428 428 std r24,THREAD_VRSAVE(r3) 429 429 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 430 430 #endif /* CONFIG_ALTIVEC */ 431 - #ifdef CONFIG_PPC64 432 - BEGIN_FTR_SECTION 433 - mfspr r25,SPRN_DSCR 434 - std r25,THREAD_DSCR(r3) 435 - END_FTR_SECTION_IFSET(CPU_FTR_DSCR) 436 - #endif 437 431 and. r0,r0,r22 438 432 beq+ 1f 439 433 andc r22,r22,r0
-16
arch/powerpc/kernel/exceptions-64e.S
··· 1467 1467 .globl a2_tlbinit_after_iprot_flush 1468 1468 a2_tlbinit_after_iprot_flush: 1469 1469 1470 - #ifdef CONFIG_PPC_EARLY_DEBUG_WSP 1471 - /* Now establish early debug mappings if applicable */ 1472 - /* Restore the MAS0 we used for linear mapping load */ 1473 - mtspr SPRN_MAS0,r11 1474 - 1475 - lis r3,(MAS1_VALID | MAS1_IPROT)@h 1476 - ori r3,r3,(BOOK3E_PAGESZ_4K << MAS1_TSIZE_SHIFT) 1477 - mtspr SPRN_MAS1,r3 1478 - LOAD_REG_IMMEDIATE(r3, WSP_UART_VIRT | MAS2_I | MAS2_G) 1479 - mtspr SPRN_MAS2,r3 1480 - LOAD_REG_IMMEDIATE(r3, WSP_UART_PHYS | MAS3_SR | MAS3_SW) 1481 - mtspr SPRN_MAS7_MAS3,r3 1482 - /* re-use the MAS8 value from the linear mapping */ 1483 - tlbwe 1484 - #endif /* CONFIG_PPC_EARLY_DEBUG_WSP */ 1485 - 1486 1470 PPC_TLBILX(0,0,R0) 1487 1471 sync 1488 1472 isync
+57 -7
arch/powerpc/kernel/exceptions-64s.S
··· 439 439 * R9 = CR 440 440 * Original R9 to R13 is saved on PACA_EXMC 441 441 * 442 - * Switch to mc_emergency stack and handle re-entrancy (though we 443 - * currently don't test for overflow). Save MCE registers srr1, 444 - * srr0, dar and dsisr and then set ME=1 442 + * Switch to mc_emergency stack and handle re-entrancy (we limit 443 + * the nested MCE upto level 4 to avoid stack overflow). 444 + * Save MCE registers srr1, srr0, dar and dsisr and then set ME=1 445 445 * 446 446 * We use paca->in_mce to check whether this is the first entry or 447 447 * nested machine check. We increment paca->in_mce to track nested ··· 464 464 0: subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ 465 465 addi r10,r10,1 /* increment paca->in_mce */ 466 466 sth r10,PACA_IN_MCE(r13) 467 + /* Limit nested MCE to level 4 to avoid stack overflow */ 468 + cmpwi r10,4 469 + bgt 2f /* Check if we hit limit of 4 */ 467 470 std r11,GPR1(r1) /* Save r1 on the stack. */ 468 471 std r11,0(r1) /* make stack chain pointer */ 469 472 mfspr r11,SPRN_SRR0 /* Save SRR0 */ ··· 485 482 ori r11,r11,MSR_RI /* turn on RI bit */ 486 483 ld r12,PACAKBASE(r13) /* get high part of &label */ 487 484 LOAD_HANDLER(r12, machine_check_handle_early) 488 - mtspr SPRN_SRR0,r12 485 + 1: mtspr SPRN_SRR0,r12 489 486 mtspr SPRN_SRR1,r11 490 487 rfid 488 + b . /* prevent speculative execution */ 489 + 2: 490 + /* Stack overflow. Stay on emergency stack and panic. 491 + * Keep the ME bit off while panic-ing, so that if we hit 492 + * another machine check we checkstop. 493 + */ 494 + addi r1,r1,INT_FRAME_SIZE /* go back to previous stack frame */ 495 + ld r11,PACAKMSR(r13) 496 + ld r12,PACAKBASE(r13) 497 + LOAD_HANDLER(r12, unrecover_mce) 498 + li r10,MSR_ME 499 + andc r11,r11,r10 /* Turn off MSR_ME */ 500 + b 1b 491 501 b . /* prevent speculative execution */ 492 502 END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) 493 503 ··· 1405 1389 bl save_nvgprs 1406 1390 addi r3,r1,STACK_FRAME_OVERHEAD 1407 1391 bl machine_check_early 1392 + std r3,RESULT(r1) /* Save result */ 1408 1393 ld r12,_MSR(r1) 1409 1394 #ifdef CONFIG_PPC_P7_NAP 1410 1395 /* ··· 1460 1443 */ 1461 1444 andi. r11,r12,MSR_RI 1462 1445 bne 2f 1463 - 1: addi r3,r1,STACK_FRAME_OVERHEAD 1464 - bl unrecoverable_exception 1465 - b 1b 1446 + 1: mfspr r11,SPRN_SRR0 1447 + ld r10,PACAKBASE(r13) 1448 + LOAD_HANDLER(r10,unrecover_mce) 1449 + mtspr SPRN_SRR0,r10 1450 + ld r10,PACAKMSR(r13) 1451 + /* 1452 + * We are going down. But there are chances that we might get hit by 1453 + * another MCE during panic path and we may run into unstable state 1454 + * with no way out. Hence, turn ME bit off while going down, so that 1455 + * when another MCE is hit during panic path, system will checkstop 1456 + * and hypervisor will get restarted cleanly by SP. 1457 + */ 1458 + li r3,MSR_ME 1459 + andc r10,r10,r3 /* Turn off MSR_ME */ 1460 + mtspr SPRN_SRR1,r10 1461 + rfid 1462 + b . 1466 1463 2: 1464 + /* 1465 + * Check if we have successfully handled/recovered from error, if not 1466 + * then stay on emergency stack and panic. 1467 + */ 1468 + ld r3,RESULT(r1) /* Load result */ 1469 + cmpdi r3,0 /* see if we handled MCE successfully */ 1470 + 1471 + beq 1b /* if !handled then panic */ 1467 1472 /* 1468 1473 * Return from MC interrupt. 1469 1474 * Queue up the MCE event so that we can log it later, while ··· 1499 1460 MACHINE_CHECK_HANDLER_WINDUP 1500 1461 b machine_check_pSeries 1501 1462 1463 + unrecover_mce: 1464 + /* Invoke machine_check_exception to print MCE event and panic. */ 1465 + addi r3,r1,STACK_FRAME_OVERHEAD 1466 + bl machine_check_exception 1467 + /* 1468 + * We will not reach here. Even if we did, there is no way out. Call 1469 + * unrecoverable_exception and die. 1470 + */ 1471 + 1: addi r3,r1,STACK_FRAME_OVERHEAD 1472 + bl unrecoverable_exception 1473 + b 1b 1502 1474 /* 1503 1475 * r13 points to the PACA, r9 contains the saved CR, 1504 1476 * r12 contain the saved SRR1, SRR0 is still ready for return
-19
arch/powerpc/kernel/head_40x.S
··· 930 930 tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */ 931 931 tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */ 932 932 933 - #if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(SERIAL_DEBUG_IO_BASE) 934 - 935 - /* Load a TLB entry for the UART, so that ppc4xx_progress() can use 936 - * the UARTs nice and early. We use a 4k real==virtual mapping. */ 937 - 938 - lis r3,SERIAL_DEBUG_IO_BASE@h 939 - ori r3,r3,SERIAL_DEBUG_IO_BASE@l 940 - mr r4,r3 941 - clrrwi r4,r4,12 942 - ori r4,r4,(TLB_WR|TLB_I|TLB_M|TLB_G) 943 - 944 - clrrwi r3,r3,12 945 - ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_4K)) 946 - 947 - li r0,0 /* TLB slot 0 */ 948 - tlbwe r4,r0,TLB_DATA 949 - tlbwe r3,r0,TLB_TAG 950 - #endif /* CONFIG_SERIAL_DEBUG_TEXT && SERIAL_DEBUG_IO_BASE */ 951 - 952 933 isync 953 934 954 935 /* Establish the exception vector base
+4 -4
arch/powerpc/kernel/process.c
··· 755 755 756 756 WARN_ON(!irqs_disabled()); 757 757 758 - /* Back up the TAR across context switches. 758 + /* Back up the TAR and DSCR across context switches. 759 759 * Note that the TAR is not available for use in the kernel. (To 760 760 * provide this, the TAR should be backed up/restored on exception 761 761 * entry/exit instead, and be in pt_regs. FIXME, this should be in 762 762 * pt_regs anyway (for debug).) 763 - * Save the TAR here before we do treclaim/trecheckpoint as these 764 - * will change the TAR. 763 + * Save the TAR and DSCR here before we do treclaim/trecheckpoint as 764 + * these will change them. 765 765 */ 766 - save_tar(&prev->thread); 766 + save_early_sprs(&prev->thread); 767 767 768 768 __switch_to_tm(prev); 769 769
+1 -1
arch/powerpc/kernel/setup-common.c
··· 471 471 for (j = 0; j < nthreads && cpu < nr_cpu_ids; j++) { 472 472 DBG(" thread %d -> cpu %d (hard id %d)\n", 473 473 j, cpu, be32_to_cpu(intserv[j])); 474 - set_cpu_present(cpu, true); 474 + set_cpu_present(cpu, of_device_is_available(dn)); 475 475 set_hard_smp_processor_id(cpu, be32_to_cpu(intserv[j])); 476 476 set_cpu_possible(cpu, true); 477 477 cpu++;
+1 -1
arch/powerpc/kernel/time.c
··· 551 551 may_hard_irq_enable(); 552 552 553 553 554 - #if defined(CONFIG_PPC32) && defined(CONFIG_PMAC) 554 + #if defined(CONFIG_PPC32) && defined(CONFIG_PPC_PMAC) 555 555 if (atomic_read(&ppc_n_lost_interrupts) != 0) 556 556 do_IRQ(regs); 557 557 #endif
+2
arch/powerpc/kernel/traps.c
··· 295 295 { 296 296 long handled = 0; 297 297 298 + __get_cpu_var(irq_stat).mce_exceptions++; 299 + 298 300 if (cur_cpu_spec && cur_cpu_spec->machine_check_early) 299 301 handled = cur_cpu_spec->machine_check_early(regs); 300 302 return handled;
-2
arch/powerpc/kernel/udbg.c
··· 62 62 udbg_init_cpm(); 63 63 #elif defined(CONFIG_PPC_EARLY_DEBUG_USBGECKO) 64 64 udbg_init_usbgecko(); 65 - #elif defined(CONFIG_PPC_EARLY_DEBUG_WSP) 66 - udbg_init_wsp(); 67 65 #elif defined(CONFIG_PPC_EARLY_DEBUG_MEMCONS) 68 66 /* In memory console */ 69 67 udbg_init_memcons();
-11
arch/powerpc/kernel/udbg_16550.c
··· 296 296 } 297 297 298 298 #endif /* CONFIG_PPC_EARLY_DEBUG_40x */ 299 - 300 - 301 - #ifdef CONFIG_PPC_EARLY_DEBUG_WSP 302 - 303 - void __init udbg_init_wsp(void) 304 - { 305 - udbg_uart_init_mmio((void *)WSP_UART_VIRT, 1); 306 - udbg_uart_setup(57600, 50000000); 307 - } 308 - 309 - #endif /* CONFIG_PPC_EARLY_DEBUG_WSP */
+7 -8
arch/powerpc/kvm/book3s_hv_ras.c
··· 113 113 * We assume that if the condition is recovered then linux host 114 114 * will have generated an error log event that we will pick 115 115 * up and log later. 116 - * Don't release mce event now. In case if condition is not 117 - * recovered we do guest exit and go back to linux host machine 118 - * check handler. Hence we need make sure that current mce event 119 - * is available for linux host to consume. 116 + * Don't release mce event now. We will queue up the event so that 117 + * we can log the MCE event info on host console. 120 118 */ 121 119 if (!get_mce_event(&mce_evt, MCE_EVENT_DONTRELEASE)) 122 120 goto out; ··· 126 128 127 129 out: 128 130 /* 129 - * If we have handled the error, then release the mce event because 130 - * we will be delivering machine check to guest. 131 + * We are now going enter guest either through machine check 132 + * interrupt (for unhandled errors) or will continue from 133 + * current HSRR0 (for handled errors) in guest. Hence 134 + * queue up the event so that we can log it from host console later. 131 135 */ 132 - if (handled) 133 - release_mce_event(); 136 + machine_check_queue_event(); 134 137 135 138 return handled; 136 139 }
+16 -3
arch/powerpc/kvm/book3s_hv_rmhandlers.S
··· 2257 2257 mr r3, r9 /* get vcpu pointer */ 2258 2258 bl kvmppc_realmode_machine_check 2259 2259 nop 2260 - cmpdi r3, 0 /* continue exiting from guest? */ 2260 + cmpdi r3, 0 /* Did we handle MCE ? */ 2261 2261 ld r9, HSTATE_KVM_VCPU(r13) 2262 2262 li r12, BOOK3S_INTERRUPT_MACHINE_CHECK 2263 - beq mc_cont 2263 + /* 2264 + * Deliver unhandled/fatal (e.g. UE) MCE errors to guest through 2265 + * machine check interrupt (set HSRR0 to 0x200). And for handled 2266 + * errors (no-fatal), just go back to guest execution with current 2267 + * HSRR0 instead of exiting guest. This new approach will inject 2268 + * machine check to guest for fatal error causing guest to crash. 2269 + * 2270 + * The old code used to return to host for unhandled errors which 2271 + * was causing guest to hang with soft lockups inside guest and 2272 + * makes it difficult to recover guest instance. 2273 + */ 2274 + ld r10, VCPU_PC(r9) 2275 + ld r11, VCPU_MSR(r9) 2276 + bne 2f /* Continue guest execution. */ 2264 2277 /* If not, deliver a machine check. SRR0/1 are already set */ 2265 2278 li r10, BOOK3S_INTERRUPT_MACHINE_CHECK 2266 2279 ld r11, VCPU_MSR(r9) 2267 2280 bl kvmppc_msr_interrupt 2268 - b fast_interrupt_c_return 2281 + 2: b fast_interrupt_c_return 2269 2282 2270 2283 /* 2271 2284 * Check the reason we woke from nap, and take appropriate action.
+1 -1
arch/powerpc/lib/sstep.c
··· 1470 1470 regs->gpr[rd] = byterev_4(val); 1471 1471 goto ldst_done; 1472 1472 1473 - #ifdef CONFIG_PPC_CPU 1473 + #ifdef CONFIG_PPC_FPU 1474 1474 case 535: /* lfsx */ 1475 1475 case 567: /* lfsux */ 1476 1476 if (!(regs->msr & MSR_FP))
-1
arch/powerpc/platforms/Kconfig
··· 19 19 source "arch/powerpc/platforms/44x/Kconfig" 20 20 source "arch/powerpc/platforms/40x/Kconfig" 21 21 source "arch/powerpc/platforms/amigaone/Kconfig" 22 - source "arch/powerpc/platforms/wsp/Kconfig" 23 22 24 23 config KVM_GUEST 25 24 bool "KVM Guest support"
+1 -5
arch/powerpc/platforms/Kconfig.cputype
··· 148 148 depends on PPC64 && PPC_BOOK3S 149 149 def_bool y 150 150 151 - config PPC_A2 152 - bool 153 - depends on PPC_BOOK3E_64 154 - 155 151 config TUNE_CELL 156 152 bool "Optimize for Cell Broadband Engine" 157 153 depends on PPC64 && PPC_BOOK3S ··· 276 280 277 281 config PPC_ICSWX 278 282 bool "Support for PowerPC icswx coprocessor instruction" 279 - depends on POWER4 || PPC_A2 283 + depends on POWER4 280 284 default n 281 285 ---help--- 282 286
-1
arch/powerpc/platforms/Makefile
··· 22 22 obj-$(CONFIG_PPC_PS3) += ps3/ 23 23 obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/ 24 24 obj-$(CONFIG_AMIGAONE) += amigaone/ 25 - obj-$(CONFIG_PPC_WSP) += wsp/
-1
arch/powerpc/platforms/cell/spufs/spufs.h
··· 35 35 #define SPUFS_PS_MAP_SIZE 0x20000 36 36 #define SPUFS_MFC_MAP_SIZE 0x1000 37 37 #define SPUFS_CNTL_MAP_SIZE 0x1000 38 - #define SPUFS_CNTL_MAP_SIZE 0x1000 39 38 #define SPUFS_SIGNAL_MAP_SIZE PAGE_SIZE 40 39 #define SPUFS_MSS_MAP_SIZE 0x1000 41 40
+1
arch/powerpc/platforms/powernv/Kconfig
··· 17 17 select CPU_FREQ_GOV_USERSPACE 18 18 select CPU_FREQ_GOV_ONDEMAND 19 19 select CPU_FREQ_GOV_CONSERVATIVE 20 + select PPC_DOORBELL 20 21 default y 21 22 22 23 config PPC_POWERNV_RTAS
+2 -2
arch/powerpc/platforms/powernv/Makefile
··· 1 1 obj-y += setup.o opal-takeover.o opal-wrappers.o opal.o opal-async.o 2 2 obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o 3 3 obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o 4 - obj-y += opal-msglog.o subcore.o subcore-asm.o 4 + obj-y += opal-msglog.o 5 5 6 - obj-$(CONFIG_SMP) += smp.o 6 + obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o 7 7 obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o 8 8 obj-$(CONFIG_EEH) += eeh-ioda.o eeh-powernv.o 9 9 obj-$(CONFIG_PPC_SCOM) += opal-xscom.o
+70 -39
arch/powerpc/platforms/powernv/eeh-ioda.c
··· 267 267 { 268 268 s64 ret = 0; 269 269 u8 fstate; 270 - u16 pcierr; 270 + __be16 pcierr; 271 271 u32 pe_no; 272 272 int result; 273 273 struct pci_controller *hose = pe->phb; ··· 316 316 result = 0; 317 317 result &= ~EEH_STATE_RESET_ACTIVE; 318 318 319 - if (pcierr != OPAL_EEH_PHB_ERROR) { 319 + if (be16_to_cpu(pcierr) != OPAL_EEH_PHB_ERROR) { 320 320 result |= EEH_STATE_MMIO_ACTIVE; 321 321 result |= EEH_STATE_DMA_ACTIVE; 322 322 result |= EEH_STATE_MMIO_ENABLED; ··· 705 705 { 706 706 struct pci_controller *hose; 707 707 struct pnv_phb *phb; 708 - struct eeh_pe *phb_pe; 709 - u64 frozen_pe_no; 710 - u16 err_type, severity; 708 + struct eeh_pe *phb_pe, *parent_pe; 709 + __be64 frozen_pe_no; 710 + __be16 err_type, severity; 711 + int active_flags = (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE); 711 712 long rc; 712 - int ret = EEH_NEXT_ERR_NONE; 713 + int state, ret = EEH_NEXT_ERR_NONE; 713 714 714 715 /* 715 716 * While running here, it's safe to purge the event queue. 716 717 * And we should keep the cached OPAL notifier event sychronized 717 718 * between the kernel and firmware. 718 719 */ 719 - eeh_remove_event(NULL); 720 + eeh_remove_event(NULL, false); 720 721 opal_notifier_update_evt(OPAL_EVENT_PCI_ERROR, 0x0ul); 721 722 722 723 list_for_each_entry(hose, &hose_list, list_node) { ··· 743 742 } 744 743 745 744 /* If the PHB doesn't have error, stop processing */ 746 - if (err_type == OPAL_EEH_NO_ERROR || 747 - severity == OPAL_EEH_SEV_NO_ERROR) { 745 + if (be16_to_cpu(err_type) == OPAL_EEH_NO_ERROR || 746 + be16_to_cpu(severity) == OPAL_EEH_SEV_NO_ERROR) { 748 747 pr_devel("%s: No error found on PHB#%x\n", 749 748 __func__, hose->global_number); 750 749 continue; ··· 756 755 * specific PHB. 757 756 */ 758 757 pr_devel("%s: Error (%d, %d, %llu) on PHB#%x\n", 759 - __func__, err_type, severity, 760 - frozen_pe_no, hose->global_number); 761 - switch (err_type) { 758 + __func__, be16_to_cpu(err_type), be16_to_cpu(severity), 759 + be64_to_cpu(frozen_pe_no), hose->global_number); 760 + switch (be16_to_cpu(err_type)) { 762 761 case OPAL_EEH_IOC_ERROR: 763 - if (severity == OPAL_EEH_SEV_IOC_DEAD) { 762 + if (be16_to_cpu(severity) == OPAL_EEH_SEV_IOC_DEAD) { 764 763 pr_err("EEH: dead IOC detected\n"); 765 764 ret = EEH_NEXT_ERR_DEAD_IOC; 766 - } else if (severity == OPAL_EEH_SEV_INF) { 765 + } else if (be16_to_cpu(severity) == OPAL_EEH_SEV_INF) { 767 766 pr_info("EEH: IOC informative error " 768 767 "detected\n"); 769 768 ioda_eeh_hub_diag(hose); ··· 772 771 773 772 break; 774 773 case OPAL_EEH_PHB_ERROR: 775 - if (severity == OPAL_EEH_SEV_PHB_DEAD) { 774 + if (be16_to_cpu(severity) == OPAL_EEH_SEV_PHB_DEAD) { 776 775 *pe = phb_pe; 777 - pr_err("EEH: dead PHB#%x detected\n", 778 - hose->global_number); 776 + pr_err("EEH: dead PHB#%x detected, " 777 + "location: %s\n", 778 + hose->global_number, 779 + eeh_pe_loc_get(phb_pe)); 779 780 ret = EEH_NEXT_ERR_DEAD_PHB; 780 - } else if (severity == OPAL_EEH_SEV_PHB_FENCED) { 781 + } else if (be16_to_cpu(severity) == 782 + OPAL_EEH_SEV_PHB_FENCED) { 781 783 *pe = phb_pe; 782 - pr_err("EEH: fenced PHB#%x detected\n", 783 - hose->global_number); 784 + pr_err("EEH: Fenced PHB#%x detected, " 785 + "location: %s\n", 786 + hose->global_number, 787 + eeh_pe_loc_get(phb_pe)); 784 788 ret = EEH_NEXT_ERR_FENCED_PHB; 785 - } else if (severity == OPAL_EEH_SEV_INF) { 789 + } else if (be16_to_cpu(severity) == OPAL_EEH_SEV_INF) { 786 790 pr_info("EEH: PHB#%x informative error " 787 - "detected\n", 788 - hose->global_number); 791 + "detected, location: %s\n", 792 + hose->global_number, 793 + eeh_pe_loc_get(phb_pe)); 789 794 ioda_eeh_phb_diag(hose); 790 795 ret = EEH_NEXT_ERR_NONE; 791 796 } ··· 799 792 break; 800 793 case OPAL_EEH_PE_ERROR: 801 794 /* 802 - * If we can't find the corresponding PE, the 803 - * PEEV / PEST would be messy. So we force an 804 - * fenced PHB so that it can be recovered. 805 - * 806 - * If the PE has been marked as isolated, that 807 - * should have been removed permanently or in 808 - * progress with recovery. We needn't report 809 - * it again. 795 + * If we can't find the corresponding PE, we 796 + * just try to unfreeze. 810 797 */ 811 - if (ioda_eeh_get_pe(hose, frozen_pe_no, pe)) { 812 - *pe = phb_pe; 813 - pr_err("EEH: Escalated fenced PHB#%x " 814 - "detected for PE#%llx\n", 815 - hose->global_number, 816 - frozen_pe_no); 817 - ret = EEH_NEXT_ERR_FENCED_PHB; 798 + if (ioda_eeh_get_pe(hose, 799 + be64_to_cpu(frozen_pe_no), pe)) { 800 + /* Try best to clear it */ 801 + pr_info("EEH: Clear non-existing PHB#%x-PE#%llx\n", 802 + hose->global_number, frozen_pe_no); 803 + pr_info("EEH: PHB location: %s\n", 804 + eeh_pe_loc_get(phb_pe)); 805 + opal_pci_eeh_freeze_clear(phb->opal_id, frozen_pe_no, 806 + OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); 807 + ret = EEH_NEXT_ERR_NONE; 818 808 } else if ((*pe)->state & EEH_PE_ISOLATED) { 819 809 ret = EEH_NEXT_ERR_NONE; 820 810 } else { 821 811 pr_err("EEH: Frozen PE#%x on PHB#%x detected\n", 822 812 (*pe)->addr, (*pe)->phb->global_number); 813 + pr_err("EEH: PE location: %s, PHB location: %s\n", 814 + eeh_pe_loc_get(*pe), eeh_pe_loc_get(phb_pe)); 823 815 ret = EEH_NEXT_ERR_FROZEN_PE; 824 816 } 825 817 826 818 break; 827 819 default: 828 820 pr_warn("%s: Unexpected error type %d\n", 829 - __func__, err_type); 821 + __func__, be16_to_cpu(err_type)); 830 822 } 831 823 832 824 /* ··· 840 834 !((*pe)->state & EEH_PE_ISOLATED)) { 841 835 eeh_pe_state_mark(*pe, EEH_PE_ISOLATED); 842 836 ioda_eeh_phb_diag(hose); 837 + } 838 + 839 + /* 840 + * We probably have the frozen parent PE out there and 841 + * we need have to handle frozen parent PE firstly. 842 + */ 843 + if (ret == EEH_NEXT_ERR_FROZEN_PE) { 844 + parent_pe = (*pe)->parent; 845 + while (parent_pe) { 846 + /* Hit the ceiling ? */ 847 + if (parent_pe->type & EEH_PE_PHB) 848 + break; 849 + 850 + /* Frozen parent PE ? */ 851 + state = ioda_eeh_get_state(parent_pe); 852 + if (state > 0 && 853 + (state & active_flags) != active_flags) 854 + *pe = parent_pe; 855 + 856 + /* Next parent level */ 857 + parent_pe = parent_pe->parent; 858 + } 859 + 860 + /* We possibly migrate to another PE */ 861 + eeh_pe_state_mark(*pe, EEH_PE_ISOLATED); 843 862 } 844 863 845 864 /*
+5 -1
arch/powerpc/platforms/powernv/opal-msglog.c
··· 37 37 { 38 38 struct memcons *mc = bin_attr->private; 39 39 const char *conbuf; 40 - size_t ret, first_read = 0; 40 + ssize_t ret; 41 + size_t first_read = 0; 41 42 uint32_t out_pos, avail; 42 43 43 44 if (!mc) ··· 70 69 to += first_read; 71 70 count -= first_read; 72 71 pos -= avail; 72 + 73 + if (count <= 0) 74 + goto out; 73 75 } 74 76 75 77 /* Sanity check. The firmware should not do this to us. */
+2 -2
arch/powerpc/platforms/powernv/opal-sysparam.c
··· 260 260 attr[i].kobj_attr.attr.mode = S_IRUGO; 261 261 break; 262 262 case OPAL_SYSPARAM_WRITE: 263 - attr[i].kobj_attr.attr.mode = S_IWUGO; 263 + attr[i].kobj_attr.attr.mode = S_IWUSR; 264 264 break; 265 265 case OPAL_SYSPARAM_RW: 266 - attr[i].kobj_attr.attr.mode = S_IRUGO | S_IWUGO; 266 + attr[i].kobj_attr.attr.mode = S_IRUGO | S_IWUSR; 267 267 break; 268 268 default: 269 269 break;
+50 -31
arch/powerpc/platforms/powernv/pci.c
··· 206 206 207 207 data = (struct OpalIoPhb3ErrorData*)common; 208 208 pr_info("PHB3 PHB#%d Diag-data (Version: %d)\n", 209 - hose->global_number, common->version); 209 + hose->global_number, be32_to_cpu(common->version)); 210 210 if (data->brdgCtl) 211 211 pr_info("brdgCtl: %08x\n", 212 - data->brdgCtl); 212 + be32_to_cpu(data->brdgCtl)); 213 213 if (data->portStatusReg || data->rootCmplxStatus || 214 214 data->busAgentStatus) 215 215 pr_info("UtlSts: %08x %08x %08x\n", 216 - data->portStatusReg, data->rootCmplxStatus, 217 - data->busAgentStatus); 216 + be32_to_cpu(data->portStatusReg), 217 + be32_to_cpu(data->rootCmplxStatus), 218 + be32_to_cpu(data->busAgentStatus)); 218 219 if (data->deviceStatus || data->slotStatus || 219 220 data->linkStatus || data->devCmdStatus || 220 221 data->devSecStatus) 221 222 pr_info("RootSts: %08x %08x %08x %08x %08x\n", 222 - data->deviceStatus, data->slotStatus, 223 - data->linkStatus, data->devCmdStatus, 224 - data->devSecStatus); 223 + be32_to_cpu(data->deviceStatus), 224 + be32_to_cpu(data->slotStatus), 225 + be32_to_cpu(data->linkStatus), 226 + be32_to_cpu(data->devCmdStatus), 227 + be32_to_cpu(data->devSecStatus)); 225 228 if (data->rootErrorStatus || data->uncorrErrorStatus || 226 229 data->corrErrorStatus) 227 230 pr_info("RootErrSts: %08x %08x %08x\n", 228 - data->rootErrorStatus, data->uncorrErrorStatus, 229 - data->corrErrorStatus); 231 + be32_to_cpu(data->rootErrorStatus), 232 + be32_to_cpu(data->uncorrErrorStatus), 233 + be32_to_cpu(data->corrErrorStatus)); 230 234 if (data->tlpHdr1 || data->tlpHdr2 || 231 235 data->tlpHdr3 || data->tlpHdr4) 232 236 pr_info("RootErrLog: %08x %08x %08x %08x\n", 233 - data->tlpHdr1, data->tlpHdr2, 234 - data->tlpHdr3, data->tlpHdr4); 237 + be32_to_cpu(data->tlpHdr1), 238 + be32_to_cpu(data->tlpHdr2), 239 + be32_to_cpu(data->tlpHdr3), 240 + be32_to_cpu(data->tlpHdr4)); 235 241 if (data->sourceId || data->errorClass || 236 242 data->correlator) 237 243 pr_info("RootErrLog1: %08x %016llx %016llx\n", 238 - data->sourceId, data->errorClass, 239 - data->correlator); 244 + be32_to_cpu(data->sourceId), 245 + be64_to_cpu(data->errorClass), 246 + be64_to_cpu(data->correlator)); 240 247 if (data->nFir) 241 248 pr_info("nFir: %016llx %016llx %016llx\n", 242 - data->nFir, data->nFirMask, 243 - data->nFirWOF); 249 + be64_to_cpu(data->nFir), 250 + be64_to_cpu(data->nFirMask), 251 + be64_to_cpu(data->nFirWOF)); 244 252 if (data->phbPlssr || data->phbCsr) 245 253 pr_info("PhbSts: %016llx %016llx\n", 246 - data->phbPlssr, data->phbCsr); 254 + be64_to_cpu(data->phbPlssr), 255 + be64_to_cpu(data->phbCsr)); 247 256 if (data->lemFir) 248 257 pr_info("Lem: %016llx %016llx %016llx\n", 249 - data->lemFir, data->lemErrorMask, 250 - data->lemWOF); 258 + be64_to_cpu(data->lemFir), 259 + be64_to_cpu(data->lemErrorMask), 260 + be64_to_cpu(data->lemWOF)); 251 261 if (data->phbErrorStatus) 252 262 pr_info("PhbErr: %016llx %016llx %016llx %016llx\n", 253 - data->phbErrorStatus, data->phbFirstErrorStatus, 254 - data->phbErrorLog0, data->phbErrorLog1); 263 + be64_to_cpu(data->phbErrorStatus), 264 + be64_to_cpu(data->phbFirstErrorStatus), 265 + be64_to_cpu(data->phbErrorLog0), 266 + be64_to_cpu(data->phbErrorLog1)); 255 267 if (data->mmioErrorStatus) 256 268 pr_info("OutErr: %016llx %016llx %016llx %016llx\n", 257 - data->mmioErrorStatus, data->mmioFirstErrorStatus, 258 - data->mmioErrorLog0, data->mmioErrorLog1); 269 + be64_to_cpu(data->mmioErrorStatus), 270 + be64_to_cpu(data->mmioFirstErrorStatus), 271 + be64_to_cpu(data->mmioErrorLog0), 272 + be64_to_cpu(data->mmioErrorLog1)); 259 273 if (data->dma0ErrorStatus) 260 274 pr_info("InAErr: %016llx %016llx %016llx %016llx\n", 261 - data->dma0ErrorStatus, data->dma0FirstErrorStatus, 262 - data->dma0ErrorLog0, data->dma0ErrorLog1); 275 + be64_to_cpu(data->dma0ErrorStatus), 276 + be64_to_cpu(data->dma0FirstErrorStatus), 277 + be64_to_cpu(data->dma0ErrorLog0), 278 + be64_to_cpu(data->dma0ErrorLog1)); 263 279 if (data->dma1ErrorStatus) 264 280 pr_info("InBErr: %016llx %016llx %016llx %016llx\n", 265 - data->dma1ErrorStatus, data->dma1FirstErrorStatus, 266 - data->dma1ErrorLog0, data->dma1ErrorLog1); 281 + be64_to_cpu(data->dma1ErrorStatus), 282 + be64_to_cpu(data->dma1FirstErrorStatus), 283 + be64_to_cpu(data->dma1ErrorLog0), 284 + be64_to_cpu(data->dma1ErrorLog1)); 267 285 268 286 for (i = 0; i < OPAL_PHB3_NUM_PEST_REGS; i++) { 269 - if ((data->pestA[i] >> 63) == 0 && 270 - (data->pestB[i] >> 63) == 0) 287 + if ((be64_to_cpu(data->pestA[i]) >> 63) == 0 && 288 + (be64_to_cpu(data->pestB[i]) >> 63) == 0) 271 289 continue; 272 290 273 291 pr_info("PE[%3d] A/B: %016llx %016llx\n", 274 - i, data->pestA[i], data->pestB[i]); 292 + i, be64_to_cpu(data->pestA[i]), 293 + be64_to_cpu(data->pestB[i])); 275 294 } 276 295 } 277 296 ··· 303 284 return; 304 285 305 286 common = (struct OpalIoPhbErrorCommon *)log_buff; 306 - switch (common->ioType) { 287 + switch (be32_to_cpu(common->ioType)) { 307 288 case OPAL_PHB_ERROR_DATA_TYPE_P7IOC: 308 289 pnv_pci_dump_p7ioc_diag_data(hose, common); 309 290 break; ··· 312 293 break; 313 294 default: 314 295 pr_warn("%s: Unrecognized ioType %d\n", 315 - __func__, common->ioType); 296 + __func__, be32_to_cpu(common->ioType)); 316 297 } 317 298 } 318 299
+3
arch/powerpc/platforms/powernv/setup.c
··· 35 35 #include <asm/rtas.h> 36 36 #include <asm/opal.h> 37 37 #include <asm/kexec.h> 38 + #include <asm/smp.h> 38 39 39 40 #include "powernv.h" 40 41 41 42 static void __init pnv_setup_arch(void) 42 43 { 44 + set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT); 45 + 43 46 /* Initialize SMP */ 44 47 pnv_smp_init(); 45 48
+6
arch/powerpc/platforms/powernv/smp.c
··· 32 32 #include <asm/opal.h> 33 33 #include <asm/runlatch.h> 34 34 #include <asm/code-patching.h> 35 + #include <asm/dbell.h> 35 36 36 37 #include "powernv.h" 37 38 ··· 47 46 { 48 47 if (cpu != boot_cpuid) 49 48 xics_setup_cpu(); 49 + 50 + #ifdef CONFIG_PPC_DOORBELL 51 + if (cpu_has_feature(CPU_FTR_DBELL)) 52 + doorbell_setup_this_cpu(); 53 + #endif 50 54 } 51 55 52 56 int pnv_smp_kick_cpu(int nr)
+1
arch/powerpc/platforms/pseries/Kconfig
··· 21 21 select HAVE_CONTEXT_TRACKING 22 22 select HOTPLUG_CPU if SMP 23 23 select ARCH_RANDOM 24 + select PPC_DOORBELL 24 25 default y 25 26 26 27 config PPC_SPLPAR
-30
arch/powerpc/platforms/wsp/Kconfig
··· 1 - config PPC_WSP 2 - bool 3 - select PPC_A2 4 - select GENERIC_TBSYNC 5 - select PPC_ICSWX 6 - select PPC_SCOM 7 - select PPC_XICS 8 - select PPC_ICP_NATIVE 9 - select PCI 10 - select PPC_IO_WORKAROUNDS if PCI 11 - select PPC_INDIRECT_PIO if PCI 12 - default n 13 - 14 - menu "WSP platform selection" 15 - depends on PPC_BOOK3E_64 16 - 17 - config PPC_PSR2 18 - bool "PowerEN System Reference Platform 2" 19 - select EPAPR_BOOT 20 - select PPC_WSP 21 - default y 22 - 23 - config PPC_CHROMA 24 - bool "PowerEN PCIe Chroma Card" 25 - select EPAPR_BOOT 26 - select PPC_WSP 27 - select OF_DYNAMIC 28 - default y 29 - 30 - endmenu
-10
arch/powerpc/platforms/wsp/Makefile
··· 1 - ccflags-y += $(NO_MINIMAL_TOC) 2 - 3 - obj-y += setup.o ics.o wsp.o 4 - obj-$(CONFIG_PPC_PSR2) += psr2.o 5 - obj-$(CONFIG_PPC_CHROMA) += chroma.o h8.o 6 - obj-$(CONFIG_PPC_WSP) += opb_pic.o 7 - obj-$(CONFIG_PPC_WSP) += scom_wsp.o 8 - obj-$(CONFIG_SMP) += smp.o scom_smp.o 9 - obj-$(CONFIG_PCI) += wsp_pci.o 10 - obj-$(CONFIG_PCI_MSI) += msi.o
-56
arch/powerpc/platforms/wsp/chroma.c
··· 1 - /* 2 - * Copyright 2008-2011, IBM Corporation 3 - * 4 - * This program is free software; you can redistribute it and/or 5 - * modify it under the terms of the GNU General Public License 6 - * as published by the Free Software Foundation; either version 7 - * 2 of the License, or (at your option) any later version. 8 - */ 9 - 10 - #include <linux/delay.h> 11 - #include <linux/init.h> 12 - #include <linux/irq.h> 13 - #include <linux/kernel.h> 14 - #include <linux/mm.h> 15 - #include <linux/of.h> 16 - #include <linux/smp.h> 17 - #include <linux/time.h> 18 - #include <linux/of_fdt.h> 19 - 20 - #include <asm/machdep.h> 21 - #include <asm/udbg.h> 22 - 23 - #include "ics.h" 24 - #include "wsp.h" 25 - 26 - void __init chroma_setup_arch(void) 27 - { 28 - wsp_setup_arch(); 29 - wsp_setup_h8(); 30 - 31 - } 32 - 33 - static int __init chroma_probe(void) 34 - { 35 - unsigned long root = of_get_flat_dt_root(); 36 - 37 - if (!of_flat_dt_is_compatible(root, "ibm,wsp-chroma")) 38 - return 0; 39 - 40 - return 1; 41 - } 42 - 43 - define_machine(chroma_md) { 44 - .name = "Chroma PCIe", 45 - .probe = chroma_probe, 46 - .setup_arch = chroma_setup_arch, 47 - .restart = wsp_h8_restart, 48 - .power_off = wsp_h8_power_off, 49 - .halt = wsp_halt, 50 - .calibrate_decr = generic_calibrate_decr, 51 - .init_IRQ = wsp_setup_irq, 52 - .progress = udbg_progress, 53 - .power_save = book3e_idle, 54 - }; 55 - 56 - machine_arch_initcall(chroma_md, wsp_probe_devices);
-135
arch/powerpc/platforms/wsp/h8.c
··· 1 - /* 2 - * Copyright 2008-2011, IBM Corporation 3 - * 4 - * This program is free software; you can redistribute it and/or 5 - * modify it under the terms of the GNU General Public License 6 - * as published by the Free Software Foundation; either version 7 - * 2 of the License, or (at your option) any later version. 8 - */ 9 - 10 - #include <linux/kernel.h> 11 - #include <linux/of.h> 12 - #include <linux/io.h> 13 - #include <linux/of_address.h> 14 - 15 - #include "wsp.h" 16 - 17 - /* 18 - * The UART connection to the H8 is over ttyS1 which is just a 16550. 19 - * We assume that FW has it setup right and no one messes with it. 20 - */ 21 - 22 - 23 - static u8 __iomem *h8; 24 - 25 - #define RBR 0 /* Receiver Buffer Register */ 26 - #define THR 0 /* Transmitter Holding Register */ 27 - #define LSR 5 /* Line Status Register */ 28 - #define LSR_DR 0x01 /* LSR value for Data-Ready */ 29 - #define LSR_THRE 0x20 /* LSR value for Transmitter-Holding-Register-Empty */ 30 - static void wsp_h8_putc(int c) 31 - { 32 - u8 lsr; 33 - 34 - do { 35 - lsr = readb(h8 + LSR); 36 - } while ((lsr & LSR_THRE) != LSR_THRE); 37 - writeb(c, h8 + THR); 38 - } 39 - 40 - static int wsp_h8_getc(void) 41 - { 42 - u8 lsr; 43 - 44 - do { 45 - lsr = readb(h8 + LSR); 46 - } while ((lsr & LSR_DR) != LSR_DR); 47 - 48 - return readb(h8 + RBR); 49 - } 50 - 51 - static void wsp_h8_puts(const char *s, int sz) 52 - { 53 - int i; 54 - 55 - for (i = 0; i < sz; i++) { 56 - wsp_h8_putc(s[i]); 57 - 58 - /* no flow control so wait for echo */ 59 - wsp_h8_getc(); 60 - } 61 - wsp_h8_putc('\r'); 62 - wsp_h8_putc('\n'); 63 - } 64 - 65 - static void wsp_h8_terminal_cmd(const char *cmd, int sz) 66 - { 67 - hard_irq_disable(); 68 - wsp_h8_puts(cmd, sz); 69 - /* should never return, but just in case */ 70 - for (;;) 71 - continue; 72 - } 73 - 74 - 75 - void wsp_h8_restart(char *cmd) 76 - { 77 - static const char restart[] = "warm-reset"; 78 - 79 - (void)cmd; 80 - wsp_h8_terminal_cmd(restart, sizeof(restart) - 1); 81 - } 82 - 83 - void wsp_h8_power_off(void) 84 - { 85 - static const char off[] = "power-off"; 86 - 87 - wsp_h8_terminal_cmd(off, sizeof(off) - 1); 88 - } 89 - 90 - static void __iomem *wsp_h8_getaddr(void) 91 - { 92 - struct device_node *aliases; 93 - struct device_node *uart; 94 - struct property *path; 95 - void __iomem *va = NULL; 96 - 97 - /* 98 - * there is nothing in the devtree to tell us which is mapped 99 - * to the H8, but se know it is the second serial port. 100 - */ 101 - 102 - aliases = of_find_node_by_path("/aliases"); 103 - if (aliases == NULL) 104 - return NULL; 105 - 106 - path = of_find_property(aliases, "serial1", NULL); 107 - if (path == NULL) 108 - goto out; 109 - 110 - uart = of_find_node_by_path(path->value); 111 - if (uart == NULL) 112 - goto out; 113 - 114 - va = of_iomap(uart, 0); 115 - 116 - /* remove it so no one messes with it */ 117 - of_detach_node(uart); 118 - of_node_put(uart); 119 - 120 - out: 121 - of_node_put(aliases); 122 - 123 - return va; 124 - } 125 - 126 - void __init wsp_setup_h8(void) 127 - { 128 - h8 = wsp_h8_getaddr(); 129 - 130 - /* Devtree change? lets hard map it anyway */ 131 - if (h8 == NULL) { 132 - pr_warn("UART to H8 could not be found"); 133 - h8 = ioremap(0xffc0008000ULL, 0x100); 134 - } 135 - }
-762
arch/powerpc/platforms/wsp/ics.c
··· 1 - /* 2 - * Copyright 2008-2011 IBM Corporation. 3 - * 4 - * This program is free software; you can redistribute it and/or 5 - * modify it under the terms of the GNU General Public License 6 - * as published by the Free Software Foundation; either version 7 - * 2 of the License, or (at your option) any later version. 8 - */ 9 - 10 - #include <linux/cpu.h> 11 - #include <linux/init.h> 12 - #include <linux/interrupt.h> 13 - #include <linux/irq.h> 14 - #include <linux/kernel.h> 15 - #include <linux/msi.h> 16 - #include <linux/of.h> 17 - #include <linux/slab.h> 18 - #include <linux/smp.h> 19 - #include <linux/spinlock.h> 20 - #include <linux/types.h> 21 - #include <linux/of_address.h> 22 - #include <linux/of_irq.h> 23 - 24 - #include <asm/io.h> 25 - #include <asm/irq.h> 26 - #include <asm/xics.h> 27 - 28 - #include "wsp.h" 29 - #include "ics.h" 30 - 31 - 32 - /* WSP ICS */ 33 - 34 - struct wsp_ics { 35 - struct ics ics; 36 - struct device_node *dn; 37 - void __iomem *regs; 38 - spinlock_t lock; 39 - unsigned long *bitmap; 40 - u32 chip_id; 41 - u32 lsi_base; 42 - u32 lsi_count; 43 - u64 hwirq_start; 44 - u64 count; 45 - #ifdef CONFIG_SMP 46 - int *hwirq_cpu_map; 47 - #endif 48 - }; 49 - 50 - #define to_wsp_ics(ics) container_of(ics, struct wsp_ics, ics) 51 - 52 - #define INT_SRC_LAYER_BUID_REG(base) ((base) + 0x00) 53 - #define IODA_TBL_ADDR_REG(base) ((base) + 0x18) 54 - #define IODA_TBL_DATA_REG(base) ((base) + 0x20) 55 - #define XIVE_UPDATE_REG(base) ((base) + 0x28) 56 - #define ICS_INT_CAPS_REG(base) ((base) + 0x30) 57 - 58 - #define TBL_AUTO_INCREMENT ((1UL << 63) | (1UL << 15)) 59 - #define TBL_SELECT_XIST (1UL << 48) 60 - #define TBL_SELECT_XIVT (1UL << 49) 61 - 62 - #define IODA_IRQ(irq) ((irq) & (0x7FFULL)) /* HRM 5.1.3.4 */ 63 - 64 - #define XIST_REQUIRED 0x8 65 - #define XIST_REJECTED 0x4 66 - #define XIST_PRESENTED 0x2 67 - #define XIST_PENDING 0x1 68 - 69 - #define XIVE_SERVER_SHIFT 42 70 - #define XIVE_SERVER_MASK 0xFFFFULL 71 - #define XIVE_PRIORITY_MASK 0xFFULL 72 - #define XIVE_PRIORITY_SHIFT 32 73 - #define XIVE_WRITE_ENABLE (1ULL << 63) 74 - 75 - /* 76 - * The docs refer to a 6 bit field called ChipID, which consists of a 77 - * 3 bit NodeID and a 3 bit ChipID. On WSP the ChipID is always zero 78 - * so we ignore it, and every where we use "chip id" in this code we 79 - * mean the NodeID. 80 - */ 81 - #define WSP_ICS_CHIP_SHIFT 17 82 - 83 - 84 - static struct wsp_ics *ics_list; 85 - static int num_ics; 86 - 87 - /* ICS Source controller accessors */ 88 - 89 - static u64 wsp_ics_get_xive(struct wsp_ics *ics, unsigned int irq) 90 - { 91 - unsigned long flags; 92 - u64 xive; 93 - 94 - spin_lock_irqsave(&ics->lock, flags); 95 - out_be64(IODA_TBL_ADDR_REG(ics->regs), TBL_SELECT_XIVT | IODA_IRQ(irq)); 96 - xive = in_be64(IODA_TBL_DATA_REG(ics->regs)); 97 - spin_unlock_irqrestore(&ics->lock, flags); 98 - 99 - return xive; 100 - } 101 - 102 - static void wsp_ics_set_xive(struct wsp_ics *ics, unsigned int irq, u64 xive) 103 - { 104 - xive &= ~XIVE_ADDR_MASK; 105 - xive |= (irq & XIVE_ADDR_MASK); 106 - xive |= XIVE_WRITE_ENABLE; 107 - 108 - out_be64(XIVE_UPDATE_REG(ics->regs), xive); 109 - } 110 - 111 - static u64 xive_set_server(u64 xive, unsigned int server) 112 - { 113 - u64 mask = ~(XIVE_SERVER_MASK << XIVE_SERVER_SHIFT); 114 - 115 - xive &= mask; 116 - xive |= (server & XIVE_SERVER_MASK) << XIVE_SERVER_SHIFT; 117 - 118 - return xive; 119 - } 120 - 121 - static u64 xive_set_priority(u64 xive, unsigned int priority) 122 - { 123 - u64 mask = ~(XIVE_PRIORITY_MASK << XIVE_PRIORITY_SHIFT); 124 - 125 - xive &= mask; 126 - xive |= (priority & XIVE_PRIORITY_MASK) << XIVE_PRIORITY_SHIFT; 127 - 128 - return xive; 129 - } 130 - 131 - 132 - #ifdef CONFIG_SMP 133 - /* Find logical CPUs within mask on a given chip and store result in ret */ 134 - void cpus_on_chip(int chip_id, cpumask_t *mask, cpumask_t *ret) 135 - { 136 - int cpu, chip; 137 - struct device_node *cpu_dn, *dn; 138 - const u32 *prop; 139 - 140 - cpumask_clear(ret); 141 - for_each_cpu(cpu, mask) { 142 - cpu_dn = of_get_cpu_node(cpu, NULL); 143 - if (!cpu_dn) 144 - continue; 145 - 146 - prop = of_get_property(cpu_dn, "at-node", NULL); 147 - if (!prop) { 148 - of_node_put(cpu_dn); 149 - continue; 150 - } 151 - 152 - dn = of_find_node_by_phandle(*prop); 153 - of_node_put(cpu_dn); 154 - 155 - chip = wsp_get_chip_id(dn); 156 - if (chip == chip_id) 157 - cpumask_set_cpu(cpu, ret); 158 - 159 - of_node_put(dn); 160 - } 161 - } 162 - 163 - /* Store a suitable CPU to handle a hwirq in the ics->hwirq_cpu_map cache */ 164 - static int cache_hwirq_map(struct wsp_ics *ics, unsigned int hwirq, 165 - const cpumask_t *affinity) 166 - { 167 - cpumask_var_t avail, newmask; 168 - int ret = -ENOMEM, cpu, cpu_rover = 0, target; 169 - int index = hwirq - ics->hwirq_start; 170 - unsigned int nodeid; 171 - 172 - BUG_ON(index < 0 || index >= ics->count); 173 - 174 - if (!ics->hwirq_cpu_map) 175 - return -ENOMEM; 176 - 177 - if (!distribute_irqs) { 178 - ics->hwirq_cpu_map[hwirq - ics->hwirq_start] = xics_default_server; 179 - return 0; 180 - } 181 - 182 - /* Allocate needed CPU masks */ 183 - if (!alloc_cpumask_var(&avail, GFP_KERNEL)) 184 - goto ret; 185 - if (!alloc_cpumask_var(&newmask, GFP_KERNEL)) 186 - goto freeavail; 187 - 188 - /* Find PBus attached to the source of this IRQ */ 189 - nodeid = (hwirq >> WSP_ICS_CHIP_SHIFT) & 0x3; /* 12:14 */ 190 - 191 - /* Find CPUs that could handle this IRQ */ 192 - if (affinity) 193 - cpumask_and(avail, cpu_online_mask, affinity); 194 - else 195 - cpumask_copy(avail, cpu_online_mask); 196 - 197 - /* Narrow selection down to logical CPUs on the same chip */ 198 - cpus_on_chip(nodeid, avail, newmask); 199 - 200 - /* Ensure we haven't narrowed it down to 0 */ 201 - if (unlikely(cpumask_empty(newmask))) { 202 - if (unlikely(cpumask_empty(avail))) { 203 - ret = -1; 204 - goto out; 205 - } 206 - cpumask_copy(newmask, avail); 207 - } 208 - 209 - /* Choose a CPU out of those we narrowed it down to in round robin */ 210 - target = hwirq % cpumask_weight(newmask); 211 - for_each_cpu(cpu, newmask) { 212 - if (cpu_rover++ >= target) { 213 - ics->hwirq_cpu_map[index] = get_hard_smp_processor_id(cpu); 214 - ret = 0; 215 - goto out; 216 - } 217 - } 218 - 219 - /* Shouldn't happen */ 220 - WARN_ON(1); 221 - 222 - out: 223 - free_cpumask_var(newmask); 224 - freeavail: 225 - free_cpumask_var(avail); 226 - ret: 227 - if (ret < 0) { 228 - ics->hwirq_cpu_map[index] = cpumask_first(cpu_online_mask); 229 - pr_warning("Error, falling hwirq 0x%x routing back to CPU %i\n", 230 - hwirq, ics->hwirq_cpu_map[index]); 231 - } 232 - return ret; 233 - } 234 - 235 - static void alloc_irq_map(struct wsp_ics *ics) 236 - { 237 - int i; 238 - 239 - ics->hwirq_cpu_map = kmalloc(sizeof(int) * ics->count, GFP_KERNEL); 240 - if (!ics->hwirq_cpu_map) { 241 - pr_warning("Allocate hwirq_cpu_map failed, " 242 - "IRQ balancing disabled\n"); 243 - return; 244 - } 245 - 246 - for (i=0; i < ics->count; i++) 247 - ics->hwirq_cpu_map[i] = xics_default_server; 248 - } 249 - 250 - static int get_irq_server(struct wsp_ics *ics, unsigned int hwirq) 251 - { 252 - int index = hwirq - ics->hwirq_start; 253 - 254 - BUG_ON(index < 0 || index >= ics->count); 255 - 256 - if (!ics->hwirq_cpu_map) 257 - return xics_default_server; 258 - 259 - return ics->hwirq_cpu_map[index]; 260 - } 261 - #else /* !CONFIG_SMP */ 262 - static int cache_hwirq_map(struct wsp_ics *ics, unsigned int hwirq, 263 - const cpumask_t *affinity) 264 - { 265 - return 0; 266 - } 267 - 268 - static int get_irq_server(struct wsp_ics *ics, unsigned int hwirq) 269 - { 270 - return xics_default_server; 271 - } 272 - 273 - static void alloc_irq_map(struct wsp_ics *ics) { } 274 - #endif 275 - 276 - static void wsp_chip_unmask_irq(struct irq_data *d) 277 - { 278 - unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); 279 - struct wsp_ics *ics; 280 - int server; 281 - u64 xive; 282 - 283 - if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS) 284 - return; 285 - 286 - ics = d->chip_data; 287 - if (WARN_ON(!ics)) 288 - return; 289 - 290 - server = get_irq_server(ics, hw_irq); 291 - 292 - xive = wsp_ics_get_xive(ics, hw_irq); 293 - xive = xive_set_server(xive, server); 294 - xive = xive_set_priority(xive, DEFAULT_PRIORITY); 295 - wsp_ics_set_xive(ics, hw_irq, xive); 296 - } 297 - 298 - static unsigned int wsp_chip_startup(struct irq_data *d) 299 - { 300 - /* unmask it */ 301 - wsp_chip_unmask_irq(d); 302 - return 0; 303 - } 304 - 305 - static void wsp_mask_real_irq(unsigned int hw_irq, struct wsp_ics *ics) 306 - { 307 - u64 xive; 308 - 309 - if (hw_irq == XICS_IPI) 310 - return; 311 - 312 - if (WARN_ON(!ics)) 313 - return; 314 - xive = wsp_ics_get_xive(ics, hw_irq); 315 - xive = xive_set_server(xive, xics_default_server); 316 - xive = xive_set_priority(xive, LOWEST_PRIORITY); 317 - wsp_ics_set_xive(ics, hw_irq, xive); 318 - } 319 - 320 - static void wsp_chip_mask_irq(struct irq_data *d) 321 - { 322 - unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); 323 - struct wsp_ics *ics = d->chip_data; 324 - 325 - if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS) 326 - return; 327 - 328 - wsp_mask_real_irq(hw_irq, ics); 329 - } 330 - 331 - static int wsp_chip_set_affinity(struct irq_data *d, 332 - const struct cpumask *cpumask, bool force) 333 - { 334 - unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); 335 - struct wsp_ics *ics; 336 - int ret; 337 - u64 xive; 338 - 339 - if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS) 340 - return -1; 341 - 342 - ics = d->chip_data; 343 - if (WARN_ON(!ics)) 344 - return -1; 345 - xive = wsp_ics_get_xive(ics, hw_irq); 346 - 347 - /* 348 - * For the moment only implement delivery to all cpus or one cpu. 349 - * Get current irq_server for the given irq 350 - */ 351 - ret = cache_hwirq_map(ics, hw_irq, cpumask); 352 - if (ret == -1) { 353 - char cpulist[128]; 354 - cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask); 355 - pr_warning("%s: No online cpus in the mask %s for irq %d\n", 356 - __func__, cpulist, d->irq); 357 - return -1; 358 - } else if (ret == -ENOMEM) { 359 - pr_warning("%s: Out of memory\n", __func__); 360 - return -1; 361 - } 362 - 363 - xive = xive_set_server(xive, get_irq_server(ics, hw_irq)); 364 - wsp_ics_set_xive(ics, hw_irq, xive); 365 - 366 - return IRQ_SET_MASK_OK; 367 - } 368 - 369 - static struct irq_chip wsp_irq_chip = { 370 - .name = "WSP ICS", 371 - .irq_startup = wsp_chip_startup, 372 - .irq_mask = wsp_chip_mask_irq, 373 - .irq_unmask = wsp_chip_unmask_irq, 374 - .irq_set_affinity = wsp_chip_set_affinity 375 - }; 376 - 377 - static int wsp_ics_host_match(struct ics *ics, struct device_node *dn) 378 - { 379 - /* All ICSs in the system implement a global irq number space, 380 - * so match against them all. */ 381 - return of_device_is_compatible(dn, "ibm,ppc-xics"); 382 - } 383 - 384 - static int wsp_ics_match_hwirq(struct wsp_ics *wsp_ics, unsigned int hwirq) 385 - { 386 - if (hwirq >= wsp_ics->hwirq_start && 387 - hwirq < wsp_ics->hwirq_start + wsp_ics->count) 388 - return 1; 389 - 390 - return 0; 391 - } 392 - 393 - static int wsp_ics_map(struct ics *ics, unsigned int virq) 394 - { 395 - struct wsp_ics *wsp_ics = to_wsp_ics(ics); 396 - unsigned int hw_irq = virq_to_hw(virq); 397 - unsigned long flags; 398 - 399 - if (!wsp_ics_match_hwirq(wsp_ics, hw_irq)) 400 - return -ENOENT; 401 - 402 - irq_set_chip_and_handler(virq, &wsp_irq_chip, handle_fasteoi_irq); 403 - 404 - irq_set_chip_data(virq, wsp_ics); 405 - 406 - spin_lock_irqsave(&wsp_ics->lock, flags); 407 - bitmap_allocate_region(wsp_ics->bitmap, hw_irq - wsp_ics->hwirq_start, 0); 408 - spin_unlock_irqrestore(&wsp_ics->lock, flags); 409 - 410 - return 0; 411 - } 412 - 413 - static void wsp_ics_mask_unknown(struct ics *ics, unsigned long hw_irq) 414 - { 415 - struct wsp_ics *wsp_ics = to_wsp_ics(ics); 416 - 417 - if (!wsp_ics_match_hwirq(wsp_ics, hw_irq)) 418 - return; 419 - 420 - pr_err("%s: IRQ %lu (real) is invalid, disabling it.\n", __func__, hw_irq); 421 - wsp_mask_real_irq(hw_irq, wsp_ics); 422 - } 423 - 424 - static long wsp_ics_get_server(struct ics *ics, unsigned long hw_irq) 425 - { 426 - struct wsp_ics *wsp_ics = to_wsp_ics(ics); 427 - 428 - if (!wsp_ics_match_hwirq(wsp_ics, hw_irq)) 429 - return -ENOENT; 430 - 431 - return get_irq_server(wsp_ics, hw_irq); 432 - } 433 - 434 - /* HW Number allocation API */ 435 - 436 - static struct wsp_ics *wsp_ics_find_dn_ics(struct device_node *dn) 437 - { 438 - struct device_node *iparent; 439 - int i; 440 - 441 - iparent = of_irq_find_parent(dn); 442 - if (!iparent) { 443 - pr_err("wsp_ics: Failed to find interrupt parent!\n"); 444 - return NULL; 445 - } 446 - 447 - for(i = 0; i < num_ics; i++) { 448 - if(ics_list[i].dn == iparent) 449 - break; 450 - } 451 - 452 - if (i >= num_ics) { 453 - pr_err("wsp_ics: Unable to find parent bitmap!\n"); 454 - return NULL; 455 - } 456 - 457 - return &ics_list[i]; 458 - } 459 - 460 - int wsp_ics_alloc_irq(struct device_node *dn, int num) 461 - { 462 - struct wsp_ics *ics; 463 - int order, offset; 464 - 465 - ics = wsp_ics_find_dn_ics(dn); 466 - if (!ics) 467 - return -ENODEV; 468 - 469 - /* Fast, but overly strict if num isn't a power of two */ 470 - order = get_count_order(num); 471 - 472 - spin_lock_irq(&ics->lock); 473 - offset = bitmap_find_free_region(ics->bitmap, ics->count, order); 474 - spin_unlock_irq(&ics->lock); 475 - 476 - if (offset < 0) 477 - return offset; 478 - 479 - return offset + ics->hwirq_start; 480 - } 481 - 482 - void wsp_ics_free_irq(struct device_node *dn, unsigned int irq) 483 - { 484 - struct wsp_ics *ics; 485 - 486 - ics = wsp_ics_find_dn_ics(dn); 487 - if (WARN_ON(!ics)) 488 - return; 489 - 490 - spin_lock_irq(&ics->lock); 491 - bitmap_release_region(ics->bitmap, irq, 0); 492 - spin_unlock_irq(&ics->lock); 493 - } 494 - 495 - /* Initialisation */ 496 - 497 - static int __init wsp_ics_bitmap_setup(struct wsp_ics *ics, 498 - struct device_node *dn) 499 - { 500 - int len, i, j, size; 501 - u32 start, count; 502 - const u32 *p; 503 - 504 - size = BITS_TO_LONGS(ics->count) * sizeof(long); 505 - ics->bitmap = kzalloc(size, GFP_KERNEL); 506 - if (!ics->bitmap) { 507 - pr_err("wsp_ics: ENOMEM allocating IRQ bitmap!\n"); 508 - return -ENOMEM; 509 - } 510 - 511 - spin_lock_init(&ics->lock); 512 - 513 - p = of_get_property(dn, "available-ranges", &len); 514 - if (!p || !len) { 515 - /* FIXME this should be a WARN() once mambo is updated */ 516 - pr_err("wsp_ics: No available-ranges defined for %s\n", 517 - dn->full_name); 518 - return 0; 519 - } 520 - 521 - if (len % (2 * sizeof(u32)) != 0) { 522 - /* FIXME this should be a WARN() once mambo is updated */ 523 - pr_err("wsp_ics: Invalid available-ranges for %s\n", 524 - dn->full_name); 525 - return 0; 526 - } 527 - 528 - bitmap_fill(ics->bitmap, ics->count); 529 - 530 - for (i = 0; i < len / sizeof(u32); i += 2) { 531 - start = of_read_number(p + i, 1); 532 - count = of_read_number(p + i + 1, 1); 533 - 534 - pr_devel("%s: start: %d count: %d\n", __func__, start, count); 535 - 536 - if ((start + count) > (ics->hwirq_start + ics->count) || 537 - start < ics->hwirq_start) { 538 - pr_err("wsp_ics: Invalid range! -> %d to %d\n", 539 - start, start + count); 540 - break; 541 - } 542 - 543 - for (j = 0; j < count; j++) 544 - bitmap_release_region(ics->bitmap, 545 - (start + j) - ics->hwirq_start, 0); 546 - } 547 - 548 - /* Ensure LSIs are not available for allocation */ 549 - bitmap_allocate_region(ics->bitmap, ics->lsi_base, 550 - get_count_order(ics->lsi_count)); 551 - 552 - return 0; 553 - } 554 - 555 - static int __init wsp_ics_setup(struct wsp_ics *ics, struct device_node *dn) 556 - { 557 - u32 lsi_buid, msi_buid, msi_base, msi_count; 558 - void __iomem *regs; 559 - const u32 *p; 560 - int rc, len, i; 561 - u64 caps, buid; 562 - 563 - p = of_get_property(dn, "interrupt-ranges", &len); 564 - if (!p || len < (2 * sizeof(u32))) { 565 - pr_err("wsp_ics: No/bad interrupt-ranges found on %s\n", 566 - dn->full_name); 567 - return -ENOENT; 568 - } 569 - 570 - if (len > (2 * sizeof(u32))) { 571 - pr_err("wsp_ics: Multiple ics ranges not supported.\n"); 572 - return -EINVAL; 573 - } 574 - 575 - regs = of_iomap(dn, 0); 576 - if (!regs) { 577 - pr_err("wsp_ics: of_iomap(%s) failed\n", dn->full_name); 578 - return -ENXIO; 579 - } 580 - 581 - ics->hwirq_start = of_read_number(p, 1); 582 - ics->count = of_read_number(p + 1, 1); 583 - ics->regs = regs; 584 - 585 - ics->chip_id = wsp_get_chip_id(dn); 586 - if (WARN_ON(ics->chip_id < 0)) 587 - ics->chip_id = 0; 588 - 589 - /* Get some informations about the critter */ 590 - caps = in_be64(ICS_INT_CAPS_REG(ics->regs)); 591 - buid = in_be64(INT_SRC_LAYER_BUID_REG(ics->regs)); 592 - ics->lsi_count = caps >> 56; 593 - msi_count = (caps >> 44) & 0x7ff; 594 - 595 - /* Note: LSI BUID is 9 bits, but really only 3 are BUID and the 596 - * rest is mixed in the interrupt number. We store the whole 597 - * thing though 598 - */ 599 - lsi_buid = (buid >> 48) & 0x1ff; 600 - ics->lsi_base = (ics->chip_id << WSP_ICS_CHIP_SHIFT) | lsi_buid << 5; 601 - msi_buid = (buid >> 37) & 0x7; 602 - msi_base = (ics->chip_id << WSP_ICS_CHIP_SHIFT) | msi_buid << 11; 603 - 604 - pr_info("wsp_ics: Found %s\n", dn->full_name); 605 - pr_info("wsp_ics: irq range : 0x%06llx..0x%06llx\n", 606 - ics->hwirq_start, ics->hwirq_start + ics->count - 1); 607 - pr_info("wsp_ics: %4d LSIs : 0x%06x..0x%06x\n", 608 - ics->lsi_count, ics->lsi_base, 609 - ics->lsi_base + ics->lsi_count - 1); 610 - pr_info("wsp_ics: %4d MSIs : 0x%06x..0x%06x\n", 611 - msi_count, msi_base, 612 - msi_base + msi_count - 1); 613 - 614 - /* Let's check the HW config is sane */ 615 - if (ics->lsi_base < ics->hwirq_start || 616 - (ics->lsi_base + ics->lsi_count) > (ics->hwirq_start + ics->count)) 617 - pr_warning("wsp_ics: WARNING ! LSIs out of interrupt-ranges !\n"); 618 - if (msi_base < ics->hwirq_start || 619 - (msi_base + msi_count) > (ics->hwirq_start + ics->count)) 620 - pr_warning("wsp_ics: WARNING ! MSIs out of interrupt-ranges !\n"); 621 - 622 - /* We don't check for overlap between LSI and MSI, which will happen 623 - * if we use the same BUID, I'm not sure yet how legit that is. 624 - */ 625 - 626 - rc = wsp_ics_bitmap_setup(ics, dn); 627 - if (rc) { 628 - iounmap(regs); 629 - return rc; 630 - } 631 - 632 - ics->dn = of_node_get(dn); 633 - alloc_irq_map(ics); 634 - 635 - for(i = 0; i < ics->count; i++) 636 - wsp_mask_real_irq(ics->hwirq_start + i, ics); 637 - 638 - ics->ics.map = wsp_ics_map; 639 - ics->ics.mask_unknown = wsp_ics_mask_unknown; 640 - ics->ics.get_server = wsp_ics_get_server; 641 - ics->ics.host_match = wsp_ics_host_match; 642 - 643 - xics_register_ics(&ics->ics); 644 - 645 - return 0; 646 - } 647 - 648 - static void __init wsp_ics_set_default_server(void) 649 - { 650 - struct device_node *np; 651 - u32 hwid; 652 - 653 - /* Find the server number for the boot cpu. */ 654 - np = of_get_cpu_node(boot_cpuid, NULL); 655 - BUG_ON(!np); 656 - 657 - hwid = get_hard_smp_processor_id(boot_cpuid); 658 - 659 - pr_info("wsp_ics: default server is %#x, CPU %s\n", hwid, np->full_name); 660 - xics_default_server = hwid; 661 - 662 - of_node_put(np); 663 - } 664 - 665 - static int __init wsp_ics_init(void) 666 - { 667 - struct device_node *dn; 668 - struct wsp_ics *ics; 669 - int rc, found; 670 - 671 - wsp_ics_set_default_server(); 672 - 673 - found = 0; 674 - for_each_compatible_node(dn, NULL, "ibm,ppc-xics") 675 - found++; 676 - 677 - if (found == 0) { 678 - pr_err("wsp_ics: No ICS's found!\n"); 679 - return -ENODEV; 680 - } 681 - 682 - ics_list = kmalloc(sizeof(*ics) * found, GFP_KERNEL); 683 - if (!ics_list) { 684 - pr_err("wsp_ics: No memory for structs.\n"); 685 - return -ENOMEM; 686 - } 687 - 688 - num_ics = 0; 689 - ics = ics_list; 690 - for_each_compatible_node(dn, NULL, "ibm,wsp-xics") { 691 - rc = wsp_ics_setup(ics, dn); 692 - if (rc == 0) { 693 - ics++; 694 - num_ics++; 695 - } 696 - } 697 - 698 - if (found != num_ics) { 699 - pr_err("wsp_ics: Failed setting up %d ICS's\n", 700 - found - num_ics); 701 - return -1; 702 - } 703 - 704 - return 0; 705 - } 706 - 707 - void __init wsp_init_irq(void) 708 - { 709 - wsp_ics_init(); 710 - xics_init(); 711 - 712 - /* We need to patch our irq chip's EOI to point to the right ICP */ 713 - wsp_irq_chip.irq_eoi = icp_ops->eoi; 714 - } 715 - 716 - #ifdef CONFIG_PCI_MSI 717 - static void wsp_ics_msi_unmask_irq(struct irq_data *d) 718 - { 719 - wsp_chip_unmask_irq(d); 720 - unmask_msi_irq(d); 721 - } 722 - 723 - static unsigned int wsp_ics_msi_startup(struct irq_data *d) 724 - { 725 - wsp_ics_msi_unmask_irq(d); 726 - return 0; 727 - } 728 - 729 - static void wsp_ics_msi_mask_irq(struct irq_data *d) 730 - { 731 - mask_msi_irq(d); 732 - wsp_chip_mask_irq(d); 733 - } 734 - 735 - /* 736 - * we do it this way because we reassinge default EOI handling in 737 - * irq_init() above 738 - */ 739 - static void wsp_ics_eoi(struct irq_data *data) 740 - { 741 - wsp_irq_chip.irq_eoi(data); 742 - } 743 - 744 - static struct irq_chip wsp_ics_msi = { 745 - .name = "WSP ICS MSI", 746 - .irq_startup = wsp_ics_msi_startup, 747 - .irq_mask = wsp_ics_msi_mask_irq, 748 - .irq_unmask = wsp_ics_msi_unmask_irq, 749 - .irq_eoi = wsp_ics_eoi, 750 - .irq_set_affinity = wsp_chip_set_affinity 751 - }; 752 - 753 - void wsp_ics_set_msi_chip(unsigned int irq) 754 - { 755 - irq_set_chip(irq, &wsp_ics_msi); 756 - } 757 - 758 - void wsp_ics_set_std_chip(unsigned int irq) 759 - { 760 - irq_set_chip(irq, &wsp_irq_chip); 761 - } 762 - #endif /* CONFIG_PCI_MSI */
-25
arch/powerpc/platforms/wsp/ics.h
··· 1 - /* 2 - * Copyright 2009 IBM Corporation. 3 - * 4 - * This program is free software; you can redistribute it and/or 5 - * modify it under the terms of the GNU General Public License 6 - * as published by the Free Software Foundation; either version 7 - * 2 of the License, or (at your option) any later version. 8 - */ 9 - 10 - #ifndef __ICS_H 11 - #define __ICS_H 12 - 13 - #define XIVE_ADDR_MASK 0x7FFULL 14 - 15 - extern void wsp_init_irq(void); 16 - 17 - extern int wsp_ics_alloc_irq(struct device_node *dn, int num); 18 - extern void wsp_ics_free_irq(struct device_node *dn, unsigned int irq); 19 - 20 - #ifdef CONFIG_PCI_MSI 21 - extern void wsp_ics_set_msi_chip(unsigned int irq); 22 - extern void wsp_ics_set_std_chip(unsigned int irq); 23 - #endif /* CONFIG_PCI_MSI */ 24 - 25 - #endif /* __ICS_H */
-102
arch/powerpc/platforms/wsp/msi.c
··· 1 - /* 2 - * Copyright 2011 Michael Ellerman, IBM Corp. 3 - * 4 - * This program is free software; you can redistribute it and/or 5 - * modify it under the terms of the GNU General Public License 6 - * as published by the Free Software Foundation; either version 7 - * 2 of the License, or (at your option) any later version. 8 - */ 9 - 10 - #include <linux/kernel.h> 11 - #include <linux/pci.h> 12 - #include <linux/msi.h> 13 - #include <linux/irq.h> 14 - #include <linux/interrupt.h> 15 - 16 - #include "msi.h" 17 - #include "ics.h" 18 - #include "wsp_pci.h" 19 - 20 - /* Magic addresses for 32 & 64-bit MSIs with hardcoded MVE 0 */ 21 - #define MSI_ADDR_32 0xFFFF0000ul 22 - #define MSI_ADDR_64 0x1000000000000000ul 23 - 24 - int wsp_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 25 - { 26 - struct pci_controller *phb; 27 - struct msi_desc *entry; 28 - struct msi_msg msg; 29 - unsigned int virq; 30 - int hwirq; 31 - 32 - phb = pci_bus_to_host(dev->bus); 33 - if (!phb) 34 - return -ENOENT; 35 - 36 - entry = list_first_entry(&dev->msi_list, struct msi_desc, list); 37 - if (entry->msi_attrib.is_64) { 38 - msg.address_lo = 0; 39 - msg.address_hi = MSI_ADDR_64 >> 32; 40 - } else { 41 - msg.address_lo = MSI_ADDR_32; 42 - msg.address_hi = 0; 43 - } 44 - 45 - list_for_each_entry(entry, &dev->msi_list, list) { 46 - hwirq = wsp_ics_alloc_irq(phb->dn, 1); 47 - if (hwirq < 0) { 48 - dev_warn(&dev->dev, "wsp_msi: hwirq alloc failed!\n"); 49 - return hwirq; 50 - } 51 - 52 - virq = irq_create_mapping(NULL, hwirq); 53 - if (virq == NO_IRQ) { 54 - dev_warn(&dev->dev, "wsp_msi: virq alloc failed!\n"); 55 - return -1; 56 - } 57 - 58 - dev_dbg(&dev->dev, "wsp_msi: allocated irq %#x/%#x\n", 59 - hwirq, virq); 60 - 61 - wsp_ics_set_msi_chip(virq); 62 - irq_set_msi_desc(virq, entry); 63 - msg.data = hwirq & XIVE_ADDR_MASK; 64 - write_msi_msg(virq, &msg); 65 - } 66 - 67 - return 0; 68 - } 69 - 70 - void wsp_teardown_msi_irqs(struct pci_dev *dev) 71 - { 72 - struct pci_controller *phb; 73 - struct msi_desc *entry; 74 - int hwirq; 75 - 76 - phb = pci_bus_to_host(dev->bus); 77 - 78 - dev_dbg(&dev->dev, "wsp_msi: tearing down msi irqs\n"); 79 - 80 - list_for_each_entry(entry, &dev->msi_list, list) { 81 - if (entry->irq == NO_IRQ) 82 - continue; 83 - 84 - irq_set_msi_desc(entry->irq, NULL); 85 - wsp_ics_set_std_chip(entry->irq); 86 - 87 - hwirq = virq_to_hw(entry->irq); 88 - /* In this order to avoid racing with irq_create_mapping() */ 89 - irq_dispose_mapping(entry->irq); 90 - wsp_ics_free_irq(phb->dn, hwirq); 91 - } 92 - } 93 - 94 - void wsp_setup_phb_msi(struct pci_controller *phb) 95 - { 96 - /* Create a single MVE at offset 0 that matches everything */ 97 - out_be64(phb->cfg_data + PCIE_REG_IODA_ADDR, PCIE_REG_IODA_AD_TBL_MVT); 98 - out_be64(phb->cfg_data + PCIE_REG_IODA_DATA0, 1ull << 63); 99 - 100 - ppc_md.setup_msi_irqs = wsp_setup_msi_irqs; 101 - ppc_md.teardown_msi_irqs = wsp_teardown_msi_irqs; 102 - }
-19
arch/powerpc/platforms/wsp/msi.h
··· 1 - /* 2 - * Copyright 2011 Michael Ellerman, IBM Corp. 3 - * 4 - * This program is free software; you can redistribute it and/or 5 - * modify it under the terms of the GNU General Public License 6 - * as published by the Free Software Foundation; either version 7 - * 2 of the License, or (at your option) any later version. 8 - */ 9 - 10 - #ifndef __WSP_MSI_H 11 - #define __WSP_MSI_H 12 - 13 - #ifdef CONFIG_PCI_MSI 14 - extern void wsp_setup_phb_msi(struct pci_controller *phb); 15 - #else 16 - static inline void wsp_setup_phb_msi(struct pci_controller *phb) { } 17 - #endif 18 - 19 - #endif /* __WSP_MSI_H */
-321
arch/powerpc/platforms/wsp/opb_pic.c
··· 1 - /* 2 - * IBM Onboard Peripheral Bus Interrupt Controller 3 - * 4 - * Copyright 2010 Jack Miller, IBM Corporation. 5 - * 6 - * This program is free software; you can redistribute it and/or modify it 7 - * under the terms of the GNU General Public License as published by the 8 - * Free Software Foundation; either version 2 of the License, or (at your 9 - * option) any later version. 10 - */ 11 - 12 - #include <linux/interrupt.h> 13 - #include <linux/io.h> 14 - #include <linux/irq.h> 15 - #include <linux/of.h> 16 - #include <linux/slab.h> 17 - #include <linux/time.h> 18 - #include <linux/of_address.h> 19 - #include <linux/of_irq.h> 20 - 21 - #include <asm/reg_a2.h> 22 - #include <asm/irq.h> 23 - 24 - #define OPB_NR_IRQS 32 25 - 26 - #define OPB_MLSASIER 0x04 /* MLS Accumulated Status IER */ 27 - #define OPB_MLSIR 0x50 /* MLS Interrupt Register */ 28 - #define OPB_MLSIER 0x54 /* MLS Interrupt Enable Register */ 29 - #define OPB_MLSIPR 0x58 /* MLS Interrupt Polarity Register */ 30 - #define OPB_MLSIIR 0x5c /* MLS Interrupt Inputs Register */ 31 - 32 - static int opb_index = 0; 33 - 34 - struct opb_pic { 35 - struct irq_domain *host; 36 - void *regs; 37 - int index; 38 - spinlock_t lock; 39 - }; 40 - 41 - static u32 opb_in(struct opb_pic *opb, int offset) 42 - { 43 - return in_be32(opb->regs + offset); 44 - } 45 - 46 - static void opb_out(struct opb_pic *opb, int offset, u32 val) 47 - { 48 - out_be32(opb->regs + offset, val); 49 - } 50 - 51 - static void opb_unmask_irq(struct irq_data *d) 52 - { 53 - struct opb_pic *opb; 54 - unsigned long flags; 55 - u32 ier, bitset; 56 - 57 - opb = d->chip_data; 58 - bitset = (1 << (31 - irqd_to_hwirq(d))); 59 - 60 - spin_lock_irqsave(&opb->lock, flags); 61 - 62 - ier = opb_in(opb, OPB_MLSIER); 63 - opb_out(opb, OPB_MLSIER, ier | bitset); 64 - ier = opb_in(opb, OPB_MLSIER); 65 - 66 - spin_unlock_irqrestore(&opb->lock, flags); 67 - } 68 - 69 - static void opb_mask_irq(struct irq_data *d) 70 - { 71 - struct opb_pic *opb; 72 - unsigned long flags; 73 - u32 ier, mask; 74 - 75 - opb = d->chip_data; 76 - mask = ~(1 << (31 - irqd_to_hwirq(d))); 77 - 78 - spin_lock_irqsave(&opb->lock, flags); 79 - 80 - ier = opb_in(opb, OPB_MLSIER); 81 - opb_out(opb, OPB_MLSIER, ier & mask); 82 - ier = opb_in(opb, OPB_MLSIER); // Flush posted writes 83 - 84 - spin_unlock_irqrestore(&opb->lock, flags); 85 - } 86 - 87 - static void opb_ack_irq(struct irq_data *d) 88 - { 89 - struct opb_pic *opb; 90 - unsigned long flags; 91 - u32 bitset; 92 - 93 - opb = d->chip_data; 94 - bitset = (1 << (31 - irqd_to_hwirq(d))); 95 - 96 - spin_lock_irqsave(&opb->lock, flags); 97 - 98 - opb_out(opb, OPB_MLSIR, bitset); 99 - opb_in(opb, OPB_MLSIR); // Flush posted writes 100 - 101 - spin_unlock_irqrestore(&opb->lock, flags); 102 - } 103 - 104 - static void opb_mask_ack_irq(struct irq_data *d) 105 - { 106 - struct opb_pic *opb; 107 - unsigned long flags; 108 - u32 bitset; 109 - u32 ier, ir; 110 - 111 - opb = d->chip_data; 112 - bitset = (1 << (31 - irqd_to_hwirq(d))); 113 - 114 - spin_lock_irqsave(&opb->lock, flags); 115 - 116 - ier = opb_in(opb, OPB_MLSIER); 117 - opb_out(opb, OPB_MLSIER, ier & ~bitset); 118 - ier = opb_in(opb, OPB_MLSIER); // Flush posted writes 119 - 120 - opb_out(opb, OPB_MLSIR, bitset); 121 - ir = opb_in(opb, OPB_MLSIR); // Flush posted writes 122 - 123 - spin_unlock_irqrestore(&opb->lock, flags); 124 - } 125 - 126 - static int opb_set_irq_type(struct irq_data *d, unsigned int flow) 127 - { 128 - struct opb_pic *opb; 129 - unsigned long flags; 130 - int invert, ipr, mask, bit; 131 - 132 - opb = d->chip_data; 133 - 134 - /* The only information we're interested in in the type is whether it's 135 - * a high or low trigger. For high triggered interrupts, the polarity 136 - * set for it in the MLS Interrupt Polarity Register is 0, for low 137 - * interrupts it's 1 so that the proper input in the MLS Interrupt Input 138 - * Register is interrupted as asserting the interrupt. */ 139 - 140 - switch (flow) { 141 - case IRQ_TYPE_NONE: 142 - opb_mask_irq(d); 143 - return 0; 144 - 145 - case IRQ_TYPE_LEVEL_HIGH: 146 - invert = 0; 147 - break; 148 - 149 - case IRQ_TYPE_LEVEL_LOW: 150 - invert = 1; 151 - break; 152 - 153 - default: 154 - return -EINVAL; 155 - } 156 - 157 - bit = (1 << (31 - irqd_to_hwirq(d))); 158 - mask = ~bit; 159 - 160 - spin_lock_irqsave(&opb->lock, flags); 161 - 162 - ipr = opb_in(opb, OPB_MLSIPR); 163 - ipr = (ipr & mask) | (invert ? bit : 0); 164 - opb_out(opb, OPB_MLSIPR, ipr); 165 - ipr = opb_in(opb, OPB_MLSIPR); // Flush posted writes 166 - 167 - spin_unlock_irqrestore(&opb->lock, flags); 168 - 169 - /* Record the type in the interrupt descriptor */ 170 - irqd_set_trigger_type(d, flow); 171 - 172 - return 0; 173 - } 174 - 175 - static struct irq_chip opb_irq_chip = { 176 - .name = "OPB", 177 - .irq_mask = opb_mask_irq, 178 - .irq_unmask = opb_unmask_irq, 179 - .irq_mask_ack = opb_mask_ack_irq, 180 - .irq_ack = opb_ack_irq, 181 - .irq_set_type = opb_set_irq_type 182 - }; 183 - 184 - static int opb_host_map(struct irq_domain *host, unsigned int virq, 185 - irq_hw_number_t hwirq) 186 - { 187 - struct opb_pic *opb; 188 - 189 - opb = host->host_data; 190 - 191 - /* Most of the important stuff is handled by the generic host code, like 192 - * the lookup, so just attach some info to the virtual irq */ 193 - 194 - irq_set_chip_data(virq, opb); 195 - irq_set_chip_and_handler(virq, &opb_irq_chip, handle_level_irq); 196 - irq_set_irq_type(virq, IRQ_TYPE_NONE); 197 - 198 - return 0; 199 - } 200 - 201 - static const struct irq_domain_ops opb_host_ops = { 202 - .map = opb_host_map, 203 - .xlate = irq_domain_xlate_twocell, 204 - }; 205 - 206 - irqreturn_t opb_irq_handler(int irq, void *private) 207 - { 208 - struct opb_pic *opb; 209 - u32 ir, src, subvirq; 210 - 211 - opb = (struct opb_pic *) private; 212 - 213 - /* Read the OPB MLS Interrupt Register for 214 - * asserted interrupts */ 215 - ir = opb_in(opb, OPB_MLSIR); 216 - if (!ir) 217 - return IRQ_NONE; 218 - 219 - do { 220 - /* Get 1 - 32 source, *NOT* bit */ 221 - src = 32 - ffs(ir); 222 - 223 - /* Translate from the OPB's conception of interrupt number to 224 - * Linux's virtual IRQ */ 225 - 226 - subvirq = irq_linear_revmap(opb->host, src); 227 - 228 - generic_handle_irq(subvirq); 229 - } while ((ir = opb_in(opb, OPB_MLSIR))); 230 - 231 - return IRQ_HANDLED; 232 - } 233 - 234 - struct opb_pic *opb_pic_init_one(struct device_node *dn) 235 - { 236 - struct opb_pic *opb; 237 - struct resource res; 238 - 239 - if (of_address_to_resource(dn, 0, &res)) { 240 - printk(KERN_ERR "opb: Couldn't translate resource\n"); 241 - return NULL; 242 - } 243 - 244 - opb = kzalloc(sizeof(struct opb_pic), GFP_KERNEL); 245 - if (!opb) { 246 - printk(KERN_ERR "opb: Failed to allocate opb struct!\n"); 247 - return NULL; 248 - } 249 - 250 - /* Get access to the OPB MMIO registers */ 251 - opb->regs = ioremap(res.start + 0x10000, 0x1000); 252 - if (!opb->regs) { 253 - printk(KERN_ERR "opb: Failed to allocate register space!\n"); 254 - goto free_opb; 255 - } 256 - 257 - /* Allocate an irq domain so that Linux knows that despite only 258 - * having one interrupt to issue, we're the controller for multiple 259 - * hardware IRQs, so later we can lookup their virtual IRQs. */ 260 - 261 - opb->host = irq_domain_add_linear(dn, OPB_NR_IRQS, &opb_host_ops, opb); 262 - if (!opb->host) { 263 - printk(KERN_ERR "opb: Failed to allocate IRQ host!\n"); 264 - goto free_regs; 265 - } 266 - 267 - opb->index = opb_index++; 268 - spin_lock_init(&opb->lock); 269 - 270 - /* Disable all interrupts by default */ 271 - opb_out(opb, OPB_MLSASIER, 0); 272 - opb_out(opb, OPB_MLSIER, 0); 273 - 274 - /* ACK any interrupts left by FW */ 275 - opb_out(opb, OPB_MLSIR, 0xFFFFFFFF); 276 - 277 - return opb; 278 - 279 - free_regs: 280 - iounmap(opb->regs); 281 - free_opb: 282 - kfree(opb); 283 - return NULL; 284 - } 285 - 286 - void __init opb_pic_init(void) 287 - { 288 - struct device_node *dn; 289 - struct opb_pic *opb; 290 - int virq; 291 - int rc; 292 - 293 - /* Call init_one for each OPB device */ 294 - for_each_compatible_node(dn, NULL, "ibm,opb") { 295 - 296 - /* Fill in an OPB struct */ 297 - opb = opb_pic_init_one(dn); 298 - if (!opb) { 299 - printk(KERN_WARNING "opb: Failed to init node, skipped!\n"); 300 - continue; 301 - } 302 - 303 - /* Map / get opb's hardware virtual irq */ 304 - virq = irq_of_parse_and_map(dn, 0); 305 - if (virq <= 0) { 306 - printk("opb: irq_op_parse_and_map failed!\n"); 307 - continue; 308 - } 309 - 310 - /* Attach opb interrupt handler to new virtual IRQ */ 311 - rc = request_irq(virq, opb_irq_handler, IRQF_NO_THREAD, 312 - "OPB LS Cascade", opb); 313 - if (rc) { 314 - printk("opb: request_irq failed: %d\n", rc); 315 - continue; 316 - } 317 - 318 - printk("OPB%d init with %d IRQs at %p\n", opb->index, 319 - OPB_NR_IRQS, opb->regs); 320 - } 321 - }
-67
arch/powerpc/platforms/wsp/psr2.c
··· 1 - /* 2 - * Copyright 2008-2011, IBM Corporation 3 - * 4 - * This program is free software; you can redistribute it and/or 5 - * modify it under the terms of the GNU General Public License 6 - * as published by the Free Software Foundation; either version 7 - * 2 of the License, or (at your option) any later version. 8 - */ 9 - 10 - #include <linux/delay.h> 11 - #include <linux/init.h> 12 - #include <linux/irq.h> 13 - #include <linux/kernel.h> 14 - #include <linux/mm.h> 15 - #include <linux/of.h> 16 - #include <linux/smp.h> 17 - #include <linux/time.h> 18 - #include <linux/of_fdt.h> 19 - 20 - #include <asm/machdep.h> 21 - #include <asm/udbg.h> 22 - 23 - #include "ics.h" 24 - #include "wsp.h" 25 - 26 - 27 - static void psr2_spin(void) 28 - { 29 - hard_irq_disable(); 30 - for (;;) 31 - continue; 32 - } 33 - 34 - static void psr2_restart(char *cmd) 35 - { 36 - psr2_spin(); 37 - } 38 - 39 - static int __init psr2_probe(void) 40 - { 41 - unsigned long root = of_get_flat_dt_root(); 42 - 43 - if (of_flat_dt_is_compatible(root, "ibm,wsp-chroma")) { 44 - /* chroma systems also claim they are psr2s */ 45 - return 0; 46 - } 47 - 48 - if (!of_flat_dt_is_compatible(root, "ibm,psr2")) 49 - return 0; 50 - 51 - return 1; 52 - } 53 - 54 - define_machine(psr2_md) { 55 - .name = "PSR2 A2", 56 - .probe = psr2_probe, 57 - .setup_arch = wsp_setup_arch, 58 - .restart = psr2_restart, 59 - .power_off = psr2_spin, 60 - .halt = psr2_spin, 61 - .calibrate_decr = generic_calibrate_decr, 62 - .init_IRQ = wsp_setup_irq, 63 - .progress = udbg_progress, 64 - .power_save = book3e_idle, 65 - }; 66 - 67 - machine_arch_initcall(psr2_md, wsp_probe_devices);
-435
arch/powerpc/platforms/wsp/scom_smp.c
··· 1 - /* 2 - * SCOM support for A2 platforms 3 - * 4 - * Copyright 2007-2011 Benjamin Herrenschmidt, David Gibson, 5 - * Michael Ellerman, IBM Corp. 6 - * 7 - * This program is free software; you can redistribute it and/or 8 - * modify it under the terms of the GNU General Public License 9 - * as published by the Free Software Foundation; either version 10 - * 2 of the License, or (at your option) any later version. 11 - */ 12 - 13 - #include <linux/cpumask.h> 14 - #include <linux/io.h> 15 - #include <linux/of.h> 16 - #include <linux/spinlock.h> 17 - #include <linux/types.h> 18 - 19 - #include <asm/cputhreads.h> 20 - #include <asm/reg_a2.h> 21 - #include <asm/scom.h> 22 - #include <asm/udbg.h> 23 - #include <asm/code-patching.h> 24 - 25 - #include "wsp.h" 26 - 27 - #define SCOM_RAMC 0x2a /* Ram Command */ 28 - #define SCOM_RAMC_TGT1_EXT 0x80000000 29 - #define SCOM_RAMC_SRC1_EXT 0x40000000 30 - #define SCOM_RAMC_SRC2_EXT 0x20000000 31 - #define SCOM_RAMC_SRC3_EXT 0x10000000 32 - #define SCOM_RAMC_ENABLE 0x00080000 33 - #define SCOM_RAMC_THREADSEL 0x00060000 34 - #define SCOM_RAMC_EXECUTE 0x00010000 35 - #define SCOM_RAMC_MSR_OVERRIDE 0x00008000 36 - #define SCOM_RAMC_MSR_PR 0x00004000 37 - #define SCOM_RAMC_MSR_GS 0x00002000 38 - #define SCOM_RAMC_FORCE 0x00001000 39 - #define SCOM_RAMC_FLUSH 0x00000800 40 - #define SCOM_RAMC_INTERRUPT 0x00000004 41 - #define SCOM_RAMC_ERROR 0x00000002 42 - #define SCOM_RAMC_DONE 0x00000001 43 - #define SCOM_RAMI 0x29 /* Ram Instruction */ 44 - #define SCOM_RAMIC 0x28 /* Ram Instruction and Command */ 45 - #define SCOM_RAMIC_INSN 0xffffffff00000000 46 - #define SCOM_RAMD 0x2d /* Ram Data */ 47 - #define SCOM_RAMDH 0x2e /* Ram Data High */ 48 - #define SCOM_RAMDL 0x2f /* Ram Data Low */ 49 - #define SCOM_PCCR0 0x33 /* PC Configuration Register 0 */ 50 - #define SCOM_PCCR0_ENABLE_DEBUG 0x80000000 51 - #define SCOM_PCCR0_ENABLE_RAM 0x40000000 52 - #define SCOM_THRCTL 0x30 /* Thread Control and Status */ 53 - #define SCOM_THRCTL_T0_STOP 0x80000000 54 - #define SCOM_THRCTL_T1_STOP 0x40000000 55 - #define SCOM_THRCTL_T2_STOP 0x20000000 56 - #define SCOM_THRCTL_T3_STOP 0x10000000 57 - #define SCOM_THRCTL_T0_STEP 0x08000000 58 - #define SCOM_THRCTL_T1_STEP 0x04000000 59 - #define SCOM_THRCTL_T2_STEP 0x02000000 60 - #define SCOM_THRCTL_T3_STEP 0x01000000 61 - #define SCOM_THRCTL_T0_RUN 0x00800000 62 - #define SCOM_THRCTL_T1_RUN 0x00400000 63 - #define SCOM_THRCTL_T2_RUN 0x00200000 64 - #define SCOM_THRCTL_T3_RUN 0x00100000 65 - #define SCOM_THRCTL_T0_PM 0x00080000 66 - #define SCOM_THRCTL_T1_PM 0x00040000 67 - #define SCOM_THRCTL_T2_PM 0x00020000 68 - #define SCOM_THRCTL_T3_PM 0x00010000 69 - #define SCOM_THRCTL_T0_UDE 0x00008000 70 - #define SCOM_THRCTL_T1_UDE 0x00004000 71 - #define SCOM_THRCTL_T2_UDE 0x00002000 72 - #define SCOM_THRCTL_T3_UDE 0x00001000 73 - #define SCOM_THRCTL_ASYNC_DIS 0x00000800 74 - #define SCOM_THRCTL_TB_DIS 0x00000400 75 - #define SCOM_THRCTL_DEC_DIS 0x00000200 76 - #define SCOM_THRCTL_AND 0x31 /* Thread Control and Status */ 77 - #define SCOM_THRCTL_OR 0x32 /* Thread Control and Status */ 78 - 79 - 80 - static DEFINE_PER_CPU(scom_map_t, scom_ptrs); 81 - 82 - static scom_map_t get_scom(int cpu, struct device_node *np, int *first_thread) 83 - { 84 - scom_map_t scom = per_cpu(scom_ptrs, cpu); 85 - int tcpu; 86 - 87 - if (scom_map_ok(scom)) { 88 - *first_thread = 0; 89 - return scom; 90 - } 91 - 92 - *first_thread = 1; 93 - 94 - scom = scom_map_device(np, 0); 95 - 96 - for (tcpu = cpu_first_thread_sibling(cpu); 97 - tcpu <= cpu_last_thread_sibling(cpu); tcpu++) 98 - per_cpu(scom_ptrs, tcpu) = scom; 99 - 100 - /* Hack: for the boot core, this will actually get called on 101 - * the second thread up, not the first so our test above will 102 - * set first_thread incorrectly. */ 103 - if (cpu_first_thread_sibling(cpu) == 0) 104 - *first_thread = 0; 105 - 106 - return scom; 107 - } 108 - 109 - static int a2_scom_ram(scom_map_t scom, int thread, u32 insn, int extmask) 110 - { 111 - u64 cmd, mask, val; 112 - int n = 0; 113 - 114 - cmd = ((u64)insn << 32) | (((u64)extmask & 0xf) << 28) 115 - | ((u64)thread << 17) | SCOM_RAMC_ENABLE | SCOM_RAMC_EXECUTE; 116 - mask = SCOM_RAMC_DONE | SCOM_RAMC_INTERRUPT | SCOM_RAMC_ERROR; 117 - 118 - scom_write(scom, SCOM_RAMIC, cmd); 119 - 120 - for (;;) { 121 - if (scom_read(scom, SCOM_RAMC, &val) != 0) { 122 - pr_err("SCOM error on instruction 0x%08x, thread %d\n", 123 - insn, thread); 124 - return -1; 125 - } 126 - if (val & mask) 127 - break; 128 - pr_devel("Waiting on RAMC = 0x%llx\n", val); 129 - if (++n == 3) { 130 - pr_err("RAMC timeout on instruction 0x%08x, thread %d\n", 131 - insn, thread); 132 - return -1; 133 - } 134 - } 135 - 136 - if (val & SCOM_RAMC_INTERRUPT) { 137 - pr_err("RAMC interrupt on instruction 0x%08x, thread %d\n", 138 - insn, thread); 139 - return -SCOM_RAMC_INTERRUPT; 140 - } 141 - 142 - if (val & SCOM_RAMC_ERROR) { 143 - pr_err("RAMC error on instruction 0x%08x, thread %d\n", 144 - insn, thread); 145 - return -SCOM_RAMC_ERROR; 146 - } 147 - 148 - return 0; 149 - } 150 - 151 - static int a2_scom_getgpr(scom_map_t scom, int thread, int gpr, int alt, 152 - u64 *out_gpr) 153 - { 154 - int rc; 155 - 156 - /* or rN, rN, rN */ 157 - u32 insn = 0x7c000378 | (gpr << 21) | (gpr << 16) | (gpr << 11); 158 - rc = a2_scom_ram(scom, thread, insn, alt ? 0xf : 0x0); 159 - if (rc) 160 - return rc; 161 - 162 - return scom_read(scom, SCOM_RAMD, out_gpr); 163 - } 164 - 165 - static int a2_scom_getspr(scom_map_t scom, int thread, int spr, u64 *out_spr) 166 - { 167 - int rc, sprhi, sprlo; 168 - u32 insn; 169 - 170 - sprhi = spr >> 5; 171 - sprlo = spr & 0x1f; 172 - insn = 0x7c2002a6 | (sprlo << 16) | (sprhi << 11); /* mfspr r1,spr */ 173 - 174 - if (spr == 0x0ff0) 175 - insn = 0x7c2000a6; /* mfmsr r1 */ 176 - 177 - rc = a2_scom_ram(scom, thread, insn, 0xf); 178 - if (rc) 179 - return rc; 180 - return a2_scom_getgpr(scom, thread, 1, 1, out_spr); 181 - } 182 - 183 - static int a2_scom_setgpr(scom_map_t scom, int thread, int gpr, 184 - int alt, u64 val) 185 - { 186 - u32 lis = 0x3c000000 | (gpr << 21); 187 - u32 li = 0x38000000 | (gpr << 21); 188 - u32 oris = 0x64000000 | (gpr << 21) | (gpr << 16); 189 - u32 ori = 0x60000000 | (gpr << 21) | (gpr << 16); 190 - u32 rldicr32 = 0x780007c6 | (gpr << 21) | (gpr << 16); 191 - u32 highest = val >> 48; 192 - u32 higher = (val >> 32) & 0xffff; 193 - u32 high = (val >> 16) & 0xffff; 194 - u32 low = val & 0xffff; 195 - int lext = alt ? 0x8 : 0x0; 196 - int oext = alt ? 0xf : 0x0; 197 - int rc = 0; 198 - 199 - if (highest) 200 - rc |= a2_scom_ram(scom, thread, lis | highest, lext); 201 - 202 - if (higher) { 203 - if (highest) 204 - rc |= a2_scom_ram(scom, thread, oris | higher, oext); 205 - else 206 - rc |= a2_scom_ram(scom, thread, li | higher, lext); 207 - } 208 - 209 - if (highest || higher) 210 - rc |= a2_scom_ram(scom, thread, rldicr32, oext); 211 - 212 - if (high) { 213 - if (highest || higher) 214 - rc |= a2_scom_ram(scom, thread, oris | high, oext); 215 - else 216 - rc |= a2_scom_ram(scom, thread, lis | high, lext); 217 - } 218 - 219 - if (highest || higher || high) 220 - rc |= a2_scom_ram(scom, thread, ori | low, oext); 221 - else 222 - rc |= a2_scom_ram(scom, thread, li | low, lext); 223 - 224 - return rc; 225 - } 226 - 227 - static int a2_scom_setspr(scom_map_t scom, int thread, int spr, u64 val) 228 - { 229 - int sprhi = spr >> 5; 230 - int sprlo = spr & 0x1f; 231 - /* mtspr spr, r1 */ 232 - u32 insn = 0x7c2003a6 | (sprlo << 16) | (sprhi << 11); 233 - 234 - if (spr == 0x0ff0) 235 - insn = 0x7c200124; /* mtmsr r1 */ 236 - 237 - if (a2_scom_setgpr(scom, thread, 1, 1, val)) 238 - return -1; 239 - 240 - return a2_scom_ram(scom, thread, insn, 0xf); 241 - } 242 - 243 - static int a2_scom_initial_tlb(scom_map_t scom, int thread) 244 - { 245 - extern u32 a2_tlbinit_code_start[], a2_tlbinit_code_end[]; 246 - extern u32 a2_tlbinit_after_iprot_flush[]; 247 - extern u32 a2_tlbinit_after_linear_map[]; 248 - u32 assoc, entries, i; 249 - u64 epn, tlbcfg; 250 - u32 *p; 251 - int rc; 252 - 253 - /* Invalidate all entries (including iprot) */ 254 - 255 - rc = a2_scom_getspr(scom, thread, SPRN_TLB0CFG, &tlbcfg); 256 - if (rc) 257 - goto scom_fail; 258 - entries = tlbcfg & TLBnCFG_N_ENTRY; 259 - assoc = (tlbcfg & TLBnCFG_ASSOC) >> 24; 260 - epn = 0; 261 - 262 - /* Set MMUCR2 to enable 4K, 64K, 1M, 16M and 1G pages */ 263 - a2_scom_setspr(scom, thread, SPRN_MMUCR2, 0x000a7531); 264 - /* Set MMUCR3 to write all thids bit to the TLB */ 265 - a2_scom_setspr(scom, thread, SPRN_MMUCR3, 0x0000000f); 266 - 267 - /* Set MAS1 for 1G page size, and MAS2 to our initial EPN */ 268 - a2_scom_setspr(scom, thread, SPRN_MAS1, MAS1_TSIZE(BOOK3E_PAGESZ_1GB)); 269 - a2_scom_setspr(scom, thread, SPRN_MAS2, epn); 270 - for (i = 0; i < entries; i++) { 271 - 272 - a2_scom_setspr(scom, thread, SPRN_MAS0, MAS0_ESEL(i % assoc)); 273 - 274 - /* tlbwe */ 275 - rc = a2_scom_ram(scom, thread, 0x7c0007a4, 0); 276 - if (rc) 277 - goto scom_fail; 278 - 279 - /* Next entry is new address? */ 280 - if((i + 1) % assoc == 0) { 281 - epn += (1 << 30); 282 - a2_scom_setspr(scom, thread, SPRN_MAS2, epn); 283 - } 284 - } 285 - 286 - /* Setup args for linear mapping */ 287 - rc = a2_scom_setgpr(scom, thread, 3, 0, MAS0_TLBSEL(0)); 288 - if (rc) 289 - goto scom_fail; 290 - 291 - /* Linear mapping */ 292 - for (p = a2_tlbinit_code_start; p < a2_tlbinit_after_linear_map; p++) { 293 - rc = a2_scom_ram(scom, thread, *p, 0); 294 - if (rc) 295 - goto scom_fail; 296 - } 297 - 298 - /* 299 - * For the boot thread, between the linear mapping and the debug 300 - * mappings there is a loop to flush iprot mappings. Ramming doesn't do 301 - * branches, but the secondary threads don't need to be nearly as smart 302 - * (i.e. we don't need to worry about invalidating the mapping we're 303 - * standing on). 304 - */ 305 - 306 - /* Debug mappings. Expects r11 = MAS0 from linear map (set above) */ 307 - for (p = a2_tlbinit_after_iprot_flush; p < a2_tlbinit_code_end; p++) { 308 - rc = a2_scom_ram(scom, thread, *p, 0); 309 - if (rc) 310 - goto scom_fail; 311 - } 312 - 313 - scom_fail: 314 - if (rc) 315 - pr_err("Setting up initial TLB failed, err %d\n", rc); 316 - 317 - if (rc == -SCOM_RAMC_INTERRUPT) { 318 - /* Interrupt, dump some status */ 319 - int rc[10]; 320 - u64 iar, srr0, srr1, esr, mas0, mas1, mas2, mas7_3, mas8, ccr2; 321 - rc[0] = a2_scom_getspr(scom, thread, SPRN_IAR, &iar); 322 - rc[1] = a2_scom_getspr(scom, thread, SPRN_SRR0, &srr0); 323 - rc[2] = a2_scom_getspr(scom, thread, SPRN_SRR1, &srr1); 324 - rc[3] = a2_scom_getspr(scom, thread, SPRN_ESR, &esr); 325 - rc[4] = a2_scom_getspr(scom, thread, SPRN_MAS0, &mas0); 326 - rc[5] = a2_scom_getspr(scom, thread, SPRN_MAS1, &mas1); 327 - rc[6] = a2_scom_getspr(scom, thread, SPRN_MAS2, &mas2); 328 - rc[7] = a2_scom_getspr(scom, thread, SPRN_MAS7_MAS3, &mas7_3); 329 - rc[8] = a2_scom_getspr(scom, thread, SPRN_MAS8, &mas8); 330 - rc[9] = a2_scom_getspr(scom, thread, SPRN_A2_CCR2, &ccr2); 331 - pr_err(" -> retreived IAR =0x%llx (err %d)\n", iar, rc[0]); 332 - pr_err(" retreived SRR0=0x%llx (err %d)\n", srr0, rc[1]); 333 - pr_err(" retreived SRR1=0x%llx (err %d)\n", srr1, rc[2]); 334 - pr_err(" retreived ESR =0x%llx (err %d)\n", esr, rc[3]); 335 - pr_err(" retreived MAS0=0x%llx (err %d)\n", mas0, rc[4]); 336 - pr_err(" retreived MAS1=0x%llx (err %d)\n", mas1, rc[5]); 337 - pr_err(" retreived MAS2=0x%llx (err %d)\n", mas2, rc[6]); 338 - pr_err(" retreived MS73=0x%llx (err %d)\n", mas7_3, rc[7]); 339 - pr_err(" retreived MAS8=0x%llx (err %d)\n", mas8, rc[8]); 340 - pr_err(" retreived CCR2=0x%llx (err %d)\n", ccr2, rc[9]); 341 - } 342 - 343 - return rc; 344 - } 345 - 346 - int a2_scom_startup_cpu(unsigned int lcpu, int thr_idx, struct device_node *np) 347 - { 348 - u64 init_iar, init_msr, init_ccr2; 349 - unsigned long start_here; 350 - int rc, core_setup; 351 - scom_map_t scom; 352 - u64 pccr0; 353 - 354 - scom = get_scom(lcpu, np, &core_setup); 355 - if (!scom) { 356 - printk(KERN_ERR "Couldn't map SCOM for CPU%d\n", lcpu); 357 - return -1; 358 - } 359 - 360 - pr_devel("Bringing up CPU%d using SCOM...\n", lcpu); 361 - 362 - if (scom_read(scom, SCOM_PCCR0, &pccr0) != 0) { 363 - printk(KERN_ERR "XSCOM failure readng PCCR0 on CPU%d\n", lcpu); 364 - return -1; 365 - } 366 - scom_write(scom, SCOM_PCCR0, pccr0 | SCOM_PCCR0_ENABLE_DEBUG | 367 - SCOM_PCCR0_ENABLE_RAM); 368 - 369 - /* Stop the thead with THRCTL. If we are setting up the TLB we stop all 370 - * threads. We also disable asynchronous interrupts while RAMing. 371 - */ 372 - if (core_setup) 373 - scom_write(scom, SCOM_THRCTL_OR, 374 - SCOM_THRCTL_T0_STOP | 375 - SCOM_THRCTL_T1_STOP | 376 - SCOM_THRCTL_T2_STOP | 377 - SCOM_THRCTL_T3_STOP | 378 - SCOM_THRCTL_ASYNC_DIS); 379 - else 380 - scom_write(scom, SCOM_THRCTL_OR, SCOM_THRCTL_T0_STOP >> thr_idx); 381 - 382 - /* Flush its pipeline just in case */ 383 - scom_write(scom, SCOM_RAMC, ((u64)thr_idx << 17) | 384 - SCOM_RAMC_FLUSH | SCOM_RAMC_ENABLE); 385 - 386 - a2_scom_getspr(scom, thr_idx, SPRN_IAR, &init_iar); 387 - a2_scom_getspr(scom, thr_idx, 0x0ff0, &init_msr); 388 - a2_scom_getspr(scom, thr_idx, SPRN_A2_CCR2, &init_ccr2); 389 - 390 - /* Set MSR to MSR_CM (0x0ff0 is magic value for MSR_CM) */ 391 - rc = a2_scom_setspr(scom, thr_idx, 0x0ff0, MSR_CM); 392 - if (rc) { 393 - pr_err("Failed to set MSR ! err %d\n", rc); 394 - return rc; 395 - } 396 - 397 - /* RAM in an sync/isync for the sake of it */ 398 - a2_scom_ram(scom, thr_idx, 0x7c0004ac, 0); 399 - a2_scom_ram(scom, thr_idx, 0x4c00012c, 0); 400 - 401 - if (core_setup) { 402 - pr_devel("CPU%d is first thread in core, initializing TLB...\n", 403 - lcpu); 404 - rc = a2_scom_initial_tlb(scom, thr_idx); 405 - if (rc) 406 - goto fail; 407 - } 408 - 409 - start_here = ppc_function_entry(core_setup ? generic_secondary_smp_init 410 - : generic_secondary_thread_init); 411 - pr_devel("CPU%d entry point at 0x%lx...\n", lcpu, start_here); 412 - 413 - rc |= a2_scom_setspr(scom, thr_idx, SPRN_IAR, start_here); 414 - rc |= a2_scom_setgpr(scom, thr_idx, 3, 0, 415 - get_hard_smp_processor_id(lcpu)); 416 - /* 417 - * Tell book3e_secondary_core_init not to set up the TLB, we've 418 - * already done that. 419 - */ 420 - rc |= a2_scom_setgpr(scom, thr_idx, 4, 0, 1); 421 - 422 - rc |= a2_scom_setspr(scom, thr_idx, SPRN_TENS, 0x1 << thr_idx); 423 - 424 - scom_write(scom, SCOM_RAMC, 0); 425 - scom_write(scom, SCOM_THRCTL_AND, ~(SCOM_THRCTL_T0_STOP >> thr_idx)); 426 - scom_write(scom, SCOM_PCCR0, pccr0); 427 - fail: 428 - pr_devel(" SCOM initialization %s\n", rc ? "failed" : "succeeded"); 429 - if (rc) { 430 - pr_err("Old IAR=0x%08llx MSR=0x%08llx CCR2=0x%08llx\n", 431 - init_iar, init_msr, init_ccr2); 432 - } 433 - 434 - return rc; 435 - }
-82
arch/powerpc/platforms/wsp/scom_wsp.c
··· 1 - /* 2 - * SCOM backend for WSP 3 - * 4 - * Copyright 2010 Benjamin Herrenschmidt, IBM Corp. 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of the GNU General Public License 8 - * as published by the Free Software Foundation; either version 9 - * 2 of the License, or (at your option) any later version. 10 - */ 11 - 12 - #include <linux/cpumask.h> 13 - #include <linux/io.h> 14 - #include <linux/of.h> 15 - #include <linux/spinlock.h> 16 - #include <linux/types.h> 17 - #include <linux/of_address.h> 18 - 19 - #include <asm/cputhreads.h> 20 - #include <asm/reg_a2.h> 21 - #include <asm/scom.h> 22 - #include <asm/udbg.h> 23 - 24 - #include "wsp.h" 25 - 26 - 27 - static scom_map_t wsp_scom_map(struct device_node *dev, u64 reg, u64 count) 28 - { 29 - struct resource r; 30 - u64 xscom_addr; 31 - 32 - if (!of_get_property(dev, "scom-controller", NULL)) { 33 - pr_err("%s: device %s is not a SCOM controller\n", 34 - __func__, dev->full_name); 35 - return SCOM_MAP_INVALID; 36 - } 37 - 38 - if (of_address_to_resource(dev, 0, &r)) { 39 - pr_debug("Failed to find SCOM controller address\n"); 40 - return 0; 41 - } 42 - 43 - /* Transform the SCOM address into an XSCOM offset */ 44 - xscom_addr = ((reg & 0x7f000000) >> 1) | ((reg & 0xfffff) << 3); 45 - 46 - return (scom_map_t)ioremap(r.start + xscom_addr, count << 3); 47 - } 48 - 49 - static void wsp_scom_unmap(scom_map_t map) 50 - { 51 - iounmap((void *)map); 52 - } 53 - 54 - static int wsp_scom_read(scom_map_t map, u64 reg, u64 *value) 55 - { 56 - u64 __iomem *addr = (u64 __iomem *)map; 57 - 58 - *value = in_be64(addr + reg); 59 - 60 - return 0; 61 - } 62 - 63 - static int wsp_scom_write(scom_map_t map, u64 reg, u64 value) 64 - { 65 - u64 __iomem *addr = (u64 __iomem *)map; 66 - 67 - out_be64(addr + reg, value); 68 - 69 - return 0; 70 - } 71 - 72 - static const struct scom_controller wsp_scom_controller = { 73 - .map = wsp_scom_map, 74 - .unmap = wsp_scom_unmap, 75 - .read = wsp_scom_read, 76 - .write = wsp_scom_write 77 - }; 78 - 79 - void scom_init_wsp(void) 80 - { 81 - scom_init(&wsp_scom_controller); 82 - }
-36
arch/powerpc/platforms/wsp/setup.c
··· 1 - /* 2 - * Copyright 2010 Michael Ellerman, IBM Corporation 3 - * 4 - * This program is free software; you can redistribute it and/or 5 - * modify it under the terms of the GNU General Public License 6 - * as published by the Free Software Foundation; either version 7 - * 2 of the License, or (at your option) any later version. 8 - */ 9 - 10 - #include <linux/kernel.h> 11 - #include <linux/of_platform.h> 12 - 13 - #include "wsp.h" 14 - 15 - /* 16 - * Find chip-id by walking up device tree looking for ibm,wsp-chip-id property. 17 - * Won't work for nodes that are not a descendant of a wsp node. 18 - */ 19 - int wsp_get_chip_id(struct device_node *dn) 20 - { 21 - const u32 *p; 22 - int rc; 23 - 24 - /* Start looking at the specified node, not its parent */ 25 - dn = of_node_get(dn); 26 - while (dn && !(p = of_get_property(dn, "ibm,wsp-chip-id", NULL))) 27 - dn = of_get_next_parent(dn); 28 - 29 - if (!dn) 30 - return -1; 31 - 32 - rc = *p; 33 - of_node_put(dn); 34 - 35 - return rc; 36 - }
-88
arch/powerpc/platforms/wsp/smp.c
··· 1 - /* 2 - * SMP Support for A2 platforms 3 - * 4 - * Copyright 2007 Benjamin Herrenschmidt, IBM Corp. 5 - * 6 - * This program is free software; you can redistribute it and/or 7 - * modify it under the terms of the GNU General Public License 8 - * as published by the Free Software Foundation; either version 9 - * 2 of the License, or (at your option) any later version. 10 - * 11 - */ 12 - 13 - #include <linux/cpumask.h> 14 - #include <linux/init.h> 15 - #include <linux/kernel.h> 16 - #include <linux/of.h> 17 - #include <linux/smp.h> 18 - 19 - #include <asm/dbell.h> 20 - #include <asm/machdep.h> 21 - #include <asm/xics.h> 22 - 23 - #include "ics.h" 24 - #include "wsp.h" 25 - 26 - static void smp_a2_setup_cpu(int cpu) 27 - { 28 - doorbell_setup_this_cpu(); 29 - 30 - if (cpu != boot_cpuid) 31 - xics_setup_cpu(); 32 - } 33 - 34 - int smp_a2_kick_cpu(int nr) 35 - { 36 - const char *enable_method; 37 - struct device_node *np; 38 - int thr_idx; 39 - 40 - if (nr < 0 || nr >= NR_CPUS) 41 - return -ENOENT; 42 - 43 - np = of_get_cpu_node(nr, &thr_idx); 44 - if (!np) 45 - return -ENODEV; 46 - 47 - enable_method = of_get_property(np, "enable-method", NULL); 48 - pr_devel("CPU%d has enable-method: \"%s\"\n", nr, enable_method); 49 - 50 - if (!enable_method) { 51 - printk(KERN_ERR "CPU%d has no enable-method\n", nr); 52 - return -ENOENT; 53 - } else if (strcmp(enable_method, "ibm,a2-scom") == 0) { 54 - if (a2_scom_startup_cpu(nr, thr_idx, np)) 55 - return -1; 56 - } else { 57 - printk(KERN_ERR "CPU%d: Don't understand enable-method \"%s\"\n", 58 - nr, enable_method); 59 - return -EINVAL; 60 - } 61 - 62 - /* 63 - * The processor is currently spinning, waiting for the 64 - * cpu_start field to become non-zero After we set cpu_start, 65 - * the processor will continue on to secondary_start 66 - */ 67 - paca[nr].cpu_start = 1; 68 - 69 - return 0; 70 - } 71 - 72 - static int __init smp_a2_probe(void) 73 - { 74 - return num_possible_cpus(); 75 - } 76 - 77 - static struct smp_ops_t a2_smp_ops = { 78 - .message_pass = NULL, /* Use smp_muxed_ipi_message_pass */ 79 - .cause_ipi = doorbell_cause_ipi, 80 - .probe = smp_a2_probe, 81 - .kick_cpu = smp_a2_kick_cpu, 82 - .setup_cpu = smp_a2_setup_cpu, 83 - }; 84 - 85 - void __init a2_setup_smp(void) 86 - { 87 - smp_ops = &a2_smp_ops; 88 - }
-117
arch/powerpc/platforms/wsp/wsp.c
··· 1 - /* 2 - * Copyright 2008-2011, IBM Corporation 3 - * 4 - * This program is free software; you can redistribute it and/or 5 - * modify it under the terms of the GNU General Public License 6 - * as published by the Free Software Foundation; either version 7 - * 2 of the License, or (at your option) any later version. 8 - */ 9 - 10 - #include <linux/kernel.h> 11 - #include <linux/of.h> 12 - #include <linux/of_device.h> 13 - #include <linux/smp.h> 14 - #include <linux/delay.h> 15 - #include <linux/time.h> 16 - #include <linux/of_address.h> 17 - 18 - #include <asm/scom.h> 19 - 20 - #include "wsp.h" 21 - #include "ics.h" 22 - 23 - #define WSP_SOC_COMPATIBLE "ibm,wsp-soc" 24 - #define PBIC_COMPATIBLE "ibm,wsp-pbic" 25 - #define COPRO_COMPATIBLE "ibm,wsp-coprocessor" 26 - 27 - static int __init wsp_probe_buses(void) 28 - { 29 - static __initdata struct of_device_id bus_ids[] = { 30 - /* 31 - * every node in between needs to be here or you won't 32 - * find it 33 - */ 34 - { .compatible = WSP_SOC_COMPATIBLE, }, 35 - { .compatible = PBIC_COMPATIBLE, }, 36 - { .compatible = COPRO_COMPATIBLE, }, 37 - {}, 38 - }; 39 - of_platform_bus_probe(NULL, bus_ids, NULL); 40 - 41 - return 0; 42 - } 43 - 44 - void __init wsp_setup_arch(void) 45 - { 46 - /* init to some ~sane value until calibrate_delay() runs */ 47 - loops_per_jiffy = 50000000; 48 - 49 - scom_init_wsp(); 50 - 51 - /* Setup SMP callback */ 52 - #ifdef CONFIG_SMP 53 - a2_setup_smp(); 54 - #endif 55 - #ifdef CONFIG_PCI 56 - wsp_setup_pci(); 57 - #endif 58 - } 59 - 60 - void __init wsp_setup_irq(void) 61 - { 62 - wsp_init_irq(); 63 - opb_pic_init(); 64 - } 65 - 66 - 67 - int __init wsp_probe_devices(void) 68 - { 69 - struct device_node *np; 70 - 71 - /* Our RTC is a ds1500. It seems to be programatically compatible 72 - * with the ds1511 for which we have a driver so let's use that 73 - */ 74 - np = of_find_compatible_node(NULL, NULL, "dallas,ds1500"); 75 - if (np != NULL) { 76 - struct resource res; 77 - if (of_address_to_resource(np, 0, &res) == 0) 78 - platform_device_register_simple("ds1511", 0, &res, 1); 79 - } 80 - 81 - wsp_probe_buses(); 82 - 83 - return 0; 84 - } 85 - 86 - void wsp_halt(void) 87 - { 88 - u64 val; 89 - scom_map_t m; 90 - struct device_node *dn; 91 - struct device_node *mine; 92 - struct device_node *me; 93 - int rc; 94 - 95 - me = of_get_cpu_node(smp_processor_id(), NULL); 96 - mine = scom_find_parent(me); 97 - 98 - /* This will halt all the A2s but not power off the chip */ 99 - for_each_node_with_property(dn, "scom-controller") { 100 - if (dn == mine) 101 - continue; 102 - m = scom_map(dn, 0, 1); 103 - 104 - /* read-modify-write it so the HW probe does not get 105 - * confused */ 106 - rc = scom_read(m, 0, &val); 107 - if (rc == 0) 108 - scom_write(m, 0, val | 1); 109 - scom_unmap(m); 110 - } 111 - m = scom_map(mine, 0, 1); 112 - rc = scom_read(m, 0, &val); 113 - if (rc == 0) 114 - scom_write(m, 0, val | 1); 115 - /* should never return */ 116 - scom_unmap(m); 117 - }
-29
arch/powerpc/platforms/wsp/wsp.h
··· 1 - #ifndef __WSP_H 2 - #define __WSP_H 3 - 4 - #include <asm/wsp.h> 5 - 6 - /* Devtree compatible strings for major devices */ 7 - #define PCIE_COMPATIBLE "ibm,wsp-pciex" 8 - 9 - extern void wsp_setup_arch(void); 10 - extern void wsp_setup_irq(void); 11 - extern int wsp_probe_devices(void); 12 - extern void wsp_halt(void); 13 - 14 - extern void wsp_setup_pci(void); 15 - extern void scom_init_wsp(void); 16 - 17 - extern void a2_setup_smp(void); 18 - extern int a2_scom_startup_cpu(unsigned int lcpu, int thr_idx, 19 - struct device_node *np); 20 - extern int smp_a2_kick_cpu(int nr); 21 - 22 - extern void opb_pic_init(void); 23 - 24 - /* chroma specific managment */ 25 - extern void wsp_h8_restart(char *cmd); 26 - extern void wsp_h8_power_off(void); 27 - extern void __init wsp_setup_h8(void); 28 - 29 - #endif /* __WSP_H */
-1134
arch/powerpc/platforms/wsp/wsp_pci.c
··· 1 - /* 2 - * Copyright 2010 Ben Herrenschmidt, IBM Corporation 3 - * 4 - * This program is free software; you can redistribute it and/or 5 - * modify it under the terms of the GNU General Public License 6 - * as published by the Free Software Foundation; either version 7 - * 2 of the License, or (at your option) any later version. 8 - */ 9 - 10 - #define DEBUG 11 - 12 - #include <linux/kernel.h> 13 - #include <linux/pci.h> 14 - #include <linux/delay.h> 15 - #include <linux/string.h> 16 - #include <linux/init.h> 17 - #include <linux/bootmem.h> 18 - #include <linux/irq.h> 19 - #include <linux/interrupt.h> 20 - #include <linux/debugfs.h> 21 - 22 - #include <asm/sections.h> 23 - #include <asm/io.h> 24 - #include <asm/prom.h> 25 - #include <asm/pci-bridge.h> 26 - #include <asm/machdep.h> 27 - #include <asm/ppc-pci.h> 28 - #include <asm/iommu.h> 29 - #include <asm/io-workarounds.h> 30 - #include <asm/debug.h> 31 - 32 - #include "wsp.h" 33 - #include "wsp_pci.h" 34 - #include "msi.h" 35 - 36 - 37 - /* Max number of TVTs for one table. Only 32-bit tables can use 38 - * multiple TVTs and so the max currently supported is thus 8 39 - * since only 2G of DMA space is supported 40 - */ 41 - #define MAX_TABLE_TVT_COUNT 8 42 - 43 - struct wsp_dma_table { 44 - struct list_head link; 45 - struct iommu_table table; 46 - struct wsp_phb *phb; 47 - struct page *tces[MAX_TABLE_TVT_COUNT]; 48 - }; 49 - 50 - /* We support DMA regions from 0...2G in 32bit space (no support for 51 - * 64-bit DMA just yet). Each device gets a separate TCE table (TVT 52 - * entry) with validation enabled (though not supported by SimiCS 53 - * just yet). 54 - * 55 - * To simplify things, we divide this 2G space into N regions based 56 - * on the constant below which could be turned into a tunable eventually 57 - * 58 - * We then assign dynamically those regions to devices as they show up. 59 - * 60 - * We use a bitmap as an allocator for these. 61 - * 62 - * Tables are allocated/created dynamically as devices are discovered, 63 - * multiple TVT entries are used if needed 64 - * 65 - * When 64-bit DMA support is added we should simply use a separate set 66 - * of larger regions (the HW supports 64 TVT entries). We can 67 - * additionally create a bypass region in 64-bit space for performances 68 - * though that would have a cost in term of security. 69 - * 70 - * If you set NUM_DMA32_REGIONS to 1, then a single table is shared 71 - * for all devices and bus/dev/fn validation is disabled 72 - * 73 - * Note that a DMA32 region cannot be smaller than 256M so the max 74 - * supported here for now is 8. We don't yet support sharing regions 75 - * between multiple devices so the max number of devices supported 76 - * is MAX_TABLE_TVT_COUNT. 77 - */ 78 - #define NUM_DMA32_REGIONS 1 79 - 80 - struct wsp_phb { 81 - struct pci_controller *hose; 82 - 83 - /* Lock controlling access to the list of dma tables. 84 - * It does -not- protect against dma_* operations on 85 - * those tables, those should be stopped before an entry 86 - * is removed from the list. 87 - * 88 - * The lock is also used for error handling operations 89 - */ 90 - spinlock_t lock; 91 - struct list_head dma_tables; 92 - unsigned long dma32_map; 93 - unsigned long dma32_base; 94 - unsigned int dma32_num_regions; 95 - unsigned long dma32_region_size; 96 - 97 - /* Debugfs stuff */ 98 - struct dentry *ddir; 99 - 100 - struct list_head all; 101 - }; 102 - static LIST_HEAD(wsp_phbs); 103 - 104 - //#define cfg_debug(fmt...) pr_debug(fmt) 105 - #define cfg_debug(fmt...) 106 - 107 - 108 - static int wsp_pcie_read_config(struct pci_bus *bus, unsigned int devfn, 109 - int offset, int len, u32 *val) 110 - { 111 - struct pci_controller *hose; 112 - int suboff; 113 - u64 addr; 114 - 115 - hose = pci_bus_to_host(bus); 116 - if (hose == NULL) 117 - return PCIBIOS_DEVICE_NOT_FOUND; 118 - if (offset >= 0x1000) 119 - return PCIBIOS_BAD_REGISTER_NUMBER; 120 - addr = PCIE_REG_CA_ENABLE | 121 - ((u64)bus->number) << PCIE_REG_CA_BUS_SHIFT | 122 - ((u64)devfn) << PCIE_REG_CA_FUNC_SHIFT | 123 - ((u64)offset & ~3) << PCIE_REG_CA_REG_SHIFT; 124 - suboff = offset & 3; 125 - 126 - /* 127 - * Note: the caller has already checked that offset is 128 - * suitably aligned and that len is 1, 2 or 4. 129 - */ 130 - 131 - switch (len) { 132 - case 1: 133 - addr |= (0x8ul >> suboff) << PCIE_REG_CA_BE_SHIFT; 134 - out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr); 135 - *val = (in_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA) 136 - >> (suboff << 3)) & 0xff; 137 - cfg_debug("read 1 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%02x\n", 138 - bus->number, devfn >> 3, devfn & 7, 139 - offset, suboff, addr, *val); 140 - break; 141 - case 2: 142 - addr |= (0xcul >> suboff) << PCIE_REG_CA_BE_SHIFT; 143 - out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr); 144 - *val = (in_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA) 145 - >> (suboff << 3)) & 0xffff; 146 - cfg_debug("read 2 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%04x\n", 147 - bus->number, devfn >> 3, devfn & 7, 148 - offset, suboff, addr, *val); 149 - break; 150 - default: 151 - addr |= 0xful << PCIE_REG_CA_BE_SHIFT; 152 - out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr); 153 - *val = in_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA); 154 - cfg_debug("read 4 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%08x\n", 155 - bus->number, devfn >> 3, devfn & 7, 156 - offset, suboff, addr, *val); 157 - break; 158 - } 159 - return PCIBIOS_SUCCESSFUL; 160 - } 161 - 162 - static int wsp_pcie_write_config(struct pci_bus *bus, unsigned int devfn, 163 - int offset, int len, u32 val) 164 - { 165 - struct pci_controller *hose; 166 - int suboff; 167 - u64 addr; 168 - 169 - hose = pci_bus_to_host(bus); 170 - if (hose == NULL) 171 - return PCIBIOS_DEVICE_NOT_FOUND; 172 - if (offset >= 0x1000) 173 - return PCIBIOS_BAD_REGISTER_NUMBER; 174 - addr = PCIE_REG_CA_ENABLE | 175 - ((u64)bus->number) << PCIE_REG_CA_BUS_SHIFT | 176 - ((u64)devfn) << PCIE_REG_CA_FUNC_SHIFT | 177 - ((u64)offset & ~3) << PCIE_REG_CA_REG_SHIFT; 178 - suboff = offset & 3; 179 - 180 - /* 181 - * Note: the caller has already checked that offset is 182 - * suitably aligned and that len is 1, 2 or 4. 183 - */ 184 - switch (len) { 185 - case 1: 186 - addr |= (0x8ul >> suboff) << PCIE_REG_CA_BE_SHIFT; 187 - val <<= suboff << 3; 188 - out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr); 189 - out_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA, val); 190 - cfg_debug("write 1 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%02x\n", 191 - bus->number, devfn >> 3, devfn & 7, 192 - offset, suboff, addr, val); 193 - break; 194 - case 2: 195 - addr |= (0xcul >> suboff) << PCIE_REG_CA_BE_SHIFT; 196 - val <<= suboff << 3; 197 - out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr); 198 - out_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA, val); 199 - cfg_debug("write 2 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%04x\n", 200 - bus->number, devfn >> 3, devfn & 7, 201 - offset, suboff, addr, val); 202 - break; 203 - default: 204 - addr |= 0xful << PCIE_REG_CA_BE_SHIFT; 205 - out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr); 206 - out_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA, val); 207 - cfg_debug("write 4 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%08x\n", 208 - bus->number, devfn >> 3, devfn & 7, 209 - offset, suboff, addr, val); 210 - break; 211 - } 212 - return PCIBIOS_SUCCESSFUL; 213 - } 214 - 215 - static struct pci_ops wsp_pcie_pci_ops = 216 - { 217 - .read = wsp_pcie_read_config, 218 - .write = wsp_pcie_write_config, 219 - }; 220 - 221 - #define TCE_SHIFT 12 222 - #define TCE_PAGE_SIZE (1 << TCE_SHIFT) 223 - #define TCE_PCI_WRITE 0x2 /* write from PCI allowed */ 224 - #define TCE_PCI_READ 0x1 /* read from PCI allowed */ 225 - #define TCE_RPN_MASK 0x3fffffffffful /* 42-bit RPN (4K pages) */ 226 - #define TCE_RPN_SHIFT 12 227 - 228 - //#define dma_debug(fmt...) pr_debug(fmt) 229 - #define dma_debug(fmt...) 230 - 231 - static int tce_build_wsp(struct iommu_table *tbl, long index, long npages, 232 - unsigned long uaddr, enum dma_data_direction direction, 233 - struct dma_attrs *attrs) 234 - { 235 - struct wsp_dma_table *ptbl = container_of(tbl, 236 - struct wsp_dma_table, 237 - table); 238 - u64 proto_tce; 239 - u64 *tcep; 240 - u64 rpn; 241 - 242 - proto_tce = TCE_PCI_READ; 243 - #ifdef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS 244 - proto_tce |= TCE_PCI_WRITE; 245 - #else 246 - if (direction != DMA_TO_DEVICE) 247 - proto_tce |= TCE_PCI_WRITE; 248 - #endif 249 - 250 - /* XXX Make this faster by factoring out the page address for 251 - * within a TCE table 252 - */ 253 - while (npages--) { 254 - /* We don't use it->base as the table can be scattered */ 255 - tcep = (u64 *)page_address(ptbl->tces[index >> 16]); 256 - tcep += (index & 0xffff); 257 - 258 - /* can't move this out since we might cross LMB boundary */ 259 - rpn = __pa(uaddr) >> TCE_SHIFT; 260 - *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; 261 - 262 - dma_debug("[DMA] TCE %p set to 0x%016llx (dma addr: 0x%lx)\n", 263 - tcep, *tcep, (tbl->it_offset + index) << IOMMU_PAGE_SHIFT_4K); 264 - 265 - uaddr += TCE_PAGE_SIZE; 266 - index++; 267 - } 268 - return 0; 269 - } 270 - 271 - static void tce_free_wsp(struct iommu_table *tbl, long index, long npages) 272 - { 273 - struct wsp_dma_table *ptbl = container_of(tbl, 274 - struct wsp_dma_table, 275 - table); 276 - #ifndef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS 277 - struct pci_controller *hose = ptbl->phb->hose; 278 - #endif 279 - u64 *tcep; 280 - 281 - /* XXX Make this faster by factoring out the page address for 282 - * within a TCE table. Also use line-kill option to kill multiple 283 - * TCEs at once 284 - */ 285 - while (npages--) { 286 - /* We don't use it->base as the table can be scattered */ 287 - tcep = (u64 *)page_address(ptbl->tces[index >> 16]); 288 - tcep += (index & 0xffff); 289 - dma_debug("[DMA] TCE %p cleared\n", tcep); 290 - *tcep = 0; 291 - #ifndef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS 292 - /* Don't write there since it would pollute other MMIO accesses */ 293 - out_be64(hose->cfg_data + PCIE_REG_TCE_KILL, 294 - PCIE_REG_TCEKILL_SINGLE | PCIE_REG_TCEKILL_PS_4K | 295 - (__pa(tcep) & PCIE_REG_TCEKILL_ADDR_MASK)); 296 - #endif 297 - index++; 298 - } 299 - } 300 - 301 - static struct wsp_dma_table *wsp_pci_create_dma32_table(struct wsp_phb *phb, 302 - unsigned int region, 303 - struct pci_dev *validate) 304 - { 305 - struct pci_controller *hose = phb->hose; 306 - unsigned long size = phb->dma32_region_size; 307 - unsigned long addr = phb->dma32_region_size * region + phb->dma32_base; 308 - struct wsp_dma_table *tbl; 309 - int tvts_per_table, i, tvt, nid; 310 - unsigned long flags; 311 - 312 - nid = of_node_to_nid(phb->hose->dn); 313 - 314 - /* Calculate how many TVTs are needed */ 315 - tvts_per_table = size / 0x10000000; 316 - if (tvts_per_table == 0) 317 - tvts_per_table = 1; 318 - 319 - /* Calculate the base TVT index. We know all tables have the same 320 - * size so we just do a simple multiply here 321 - */ 322 - tvt = region * tvts_per_table; 323 - 324 - pr_debug(" Region : %d\n", region); 325 - pr_debug(" DMA range : 0x%08lx..0x%08lx\n", addr, addr + size - 1); 326 - pr_debug(" Number of TVTs : %d\n", tvts_per_table); 327 - pr_debug(" Base TVT : %d\n", tvt); 328 - pr_debug(" Node : %d\n", nid); 329 - 330 - tbl = kzalloc_node(sizeof(struct wsp_dma_table), GFP_KERNEL, nid); 331 - if (!tbl) 332 - return ERR_PTR(-ENOMEM); 333 - tbl->phb = phb; 334 - 335 - /* Create as many TVTs as needed, each represents 256M at most */ 336 - for (i = 0; i < tvts_per_table; i++) { 337 - u64 tvt_data1, tvt_data0; 338 - 339 - /* Allocate table. We use a 4K TCE size for now always so 340 - * one table is always 8 * (258M / 4K) == 512K 341 - */ 342 - tbl->tces[i] = alloc_pages_node(nid, GFP_KERNEL, get_order(0x80000)); 343 - if (tbl->tces[i] == NULL) 344 - goto fail; 345 - memset(page_address(tbl->tces[i]), 0, 0x80000); 346 - 347 - pr_debug(" TCE table %d at : %p\n", i, page_address(tbl->tces[i])); 348 - 349 - /* Table size. We currently set it to be the whole 256M region */ 350 - tvt_data0 = 2ull << IODA_TVT0_TCE_TABLE_SIZE_SHIFT; 351 - /* IO page size set to 4K */ 352 - tvt_data1 = 1ull << IODA_TVT1_IO_PAGE_SIZE_SHIFT; 353 - /* Shift in the address */ 354 - tvt_data0 |= __pa(page_address(tbl->tces[i])) << IODA_TVT0_TTA_SHIFT; 355 - 356 - /* Validation stuff. We only validate fully bus/dev/fn for now 357 - * one day maybe we can group devices but that isn't the case 358 - * at the moment 359 - */ 360 - if (validate) { 361 - tvt_data0 |= IODA_TVT0_BUSNUM_VALID_MASK; 362 - tvt_data0 |= validate->bus->number; 363 - tvt_data1 |= IODA_TVT1_DEVNUM_VALID; 364 - tvt_data1 |= ((u64)PCI_SLOT(validate->devfn)) 365 - << IODA_TVT1_DEVNUM_VALUE_SHIFT; 366 - tvt_data1 |= IODA_TVT1_FUNCNUM_VALID; 367 - tvt_data1 |= ((u64)PCI_FUNC(validate->devfn)) 368 - << IODA_TVT1_FUNCNUM_VALUE_SHIFT; 369 - } 370 - 371 - /* XX PE number is always 0 for now */ 372 - 373 - /* Program the values using the PHB lock */ 374 - spin_lock_irqsave(&phb->lock, flags); 375 - out_be64(hose->cfg_data + PCIE_REG_IODA_ADDR, 376 - (tvt + i) | PCIE_REG_IODA_AD_TBL_TVT); 377 - out_be64(hose->cfg_data + PCIE_REG_IODA_DATA1, tvt_data1); 378 - out_be64(hose->cfg_data + PCIE_REG_IODA_DATA0, tvt_data0); 379 - spin_unlock_irqrestore(&phb->lock, flags); 380 - } 381 - 382 - /* Init bits and pieces */ 383 - tbl->table.it_blocksize = 16; 384 - tbl->table.it_page_shift = IOMMU_PAGE_SHIFT_4K; 385 - tbl->table.it_offset = addr >> tbl->table.it_page_shift; 386 - tbl->table.it_size = size >> tbl->table.it_page_shift; 387 - 388 - /* 389 - * It's already blank but we clear it anyway. 390 - * Consider an aditiona interface that makes cleaing optional 391 - */ 392 - iommu_init_table(&tbl->table, nid); 393 - 394 - list_add(&tbl->link, &phb->dma_tables); 395 - return tbl; 396 - 397 - fail: 398 - pr_debug(" Failed to allocate a 256M TCE table !\n"); 399 - for (i = 0; i < tvts_per_table; i++) 400 - if (tbl->tces[i]) 401 - __free_pages(tbl->tces[i], get_order(0x80000)); 402 - kfree(tbl); 403 - return ERR_PTR(-ENOMEM); 404 - } 405 - 406 - static void wsp_pci_dma_dev_setup(struct pci_dev *pdev) 407 - { 408 - struct dev_archdata *archdata = &pdev->dev.archdata; 409 - struct pci_controller *hose = pci_bus_to_host(pdev->bus); 410 - struct wsp_phb *phb = hose->private_data; 411 - struct wsp_dma_table *table = NULL; 412 - unsigned long flags; 413 - int i; 414 - 415 - /* Don't assign an iommu table to a bridge */ 416 - if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE) 417 - return; 418 - 419 - pr_debug("%s: Setting up DMA...\n", pci_name(pdev)); 420 - 421 - spin_lock_irqsave(&phb->lock, flags); 422 - 423 - /* If only one region, check if it already exist */ 424 - if (phb->dma32_num_regions == 1) { 425 - spin_unlock_irqrestore(&phb->lock, flags); 426 - if (list_empty(&phb->dma_tables)) 427 - table = wsp_pci_create_dma32_table(phb, 0, NULL); 428 - else 429 - table = list_first_entry(&phb->dma_tables, 430 - struct wsp_dma_table, 431 - link); 432 - } else { 433 - /* else find a free region */ 434 - for (i = 0; i < phb->dma32_num_regions && !table; i++) { 435 - if (__test_and_set_bit(i, &phb->dma32_map)) 436 - continue; 437 - spin_unlock_irqrestore(&phb->lock, flags); 438 - table = wsp_pci_create_dma32_table(phb, i, pdev); 439 - } 440 - } 441 - 442 - /* Check if we got an error */ 443 - if (IS_ERR(table)) { 444 - pr_err("%s: Failed to create DMA table, err %ld !\n", 445 - pci_name(pdev), PTR_ERR(table)); 446 - return; 447 - } 448 - 449 - /* Or a valid table */ 450 - if (table) { 451 - pr_info("%s: Setup iommu: 32-bit DMA region 0x%08lx..0x%08lx\n", 452 - pci_name(pdev), 453 - table->table.it_offset << IOMMU_PAGE_SHIFT_4K, 454 - (table->table.it_offset << IOMMU_PAGE_SHIFT_4K) 455 - + phb->dma32_region_size - 1); 456 - archdata->dma_data.iommu_table_base = &table->table; 457 - return; 458 - } 459 - 460 - /* Or no room */ 461 - spin_unlock_irqrestore(&phb->lock, flags); 462 - pr_err("%s: Out of DMA space !\n", pci_name(pdev)); 463 - } 464 - 465 - static void __init wsp_pcie_configure_hw(struct pci_controller *hose) 466 - { 467 - u64 val; 468 - int i; 469 - 470 - #define DUMP_REG(x) \ 471 - pr_debug("%-30s : 0x%016llx\n", #x, in_be64(hose->cfg_data + x)) 472 - 473 - /* 474 - * Some WSP variants has a bogus class code by default in the PCI-E 475 - * root complex's built-in P2P bridge 476 - */ 477 - val = in_be64(hose->cfg_data + PCIE_REG_SYS_CFG1); 478 - pr_debug("PCI-E SYS_CFG1 : 0x%llx\n", val); 479 - out_be64(hose->cfg_data + PCIE_REG_SYS_CFG1, 480 - (val & ~PCIE_REG_SYS_CFG1_CLASS_CODE) | (PCI_CLASS_BRIDGE_PCI << 8)); 481 - pr_debug("PCI-E SYS_CFG1 : 0x%llx\n", in_be64(hose->cfg_data + PCIE_REG_SYS_CFG1)); 482 - 483 - #ifdef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS 484 - /* XXX Disable TCE caching, it doesn't work on DD1 */ 485 - out_be64(hose->cfg_data + 0xe50, 486 - in_be64(hose->cfg_data + 0xe50) | (3ull << 62)); 487 - printk("PCI-E DEBUG CONTROL 5 = 0x%llx\n", in_be64(hose->cfg_data + 0xe50)); 488 - #endif 489 - 490 - /* Configure M32A and IO. IO is hard wired to be 1M for now */ 491 - out_be64(hose->cfg_data + PCIE_REG_IO_BASE_ADDR, hose->io_base_phys); 492 - out_be64(hose->cfg_data + PCIE_REG_IO_BASE_MASK, 493 - (~(hose->io_resource.end - hose->io_resource.start)) & 494 - 0x3fffffff000ul); 495 - out_be64(hose->cfg_data + PCIE_REG_IO_START_ADDR, 0 | 1); 496 - 497 - out_be64(hose->cfg_data + PCIE_REG_M32A_BASE_ADDR, 498 - hose->mem_resources[0].start); 499 - printk("Want to write to M32A_BASE_MASK : 0x%llx\n", 500 - (~(hose->mem_resources[0].end - 501 - hose->mem_resources[0].start)) & 0x3ffffff0000ul); 502 - out_be64(hose->cfg_data + PCIE_REG_M32A_BASE_MASK, 503 - (~(hose->mem_resources[0].end - 504 - hose->mem_resources[0].start)) & 0x3ffffff0000ul); 505 - out_be64(hose->cfg_data + PCIE_REG_M32A_START_ADDR, 506 - (hose->mem_resources[0].start - hose->mem_offset[0]) | 1); 507 - 508 - /* Clear all TVT entries 509 - * 510 - * XX Might get TVT count from device-tree 511 - */ 512 - for (i = 0; i < IODA_TVT_COUNT; i++) { 513 - out_be64(hose->cfg_data + PCIE_REG_IODA_ADDR, 514 - PCIE_REG_IODA_AD_TBL_TVT | i); 515 - out_be64(hose->cfg_data + PCIE_REG_IODA_DATA1, 0); 516 - out_be64(hose->cfg_data + PCIE_REG_IODA_DATA0, 0); 517 - } 518 - 519 - /* Kill the TCE cache */ 520 - out_be64(hose->cfg_data + PCIE_REG_PHB_CONFIG, 521 - in_be64(hose->cfg_data + PCIE_REG_PHB_CONFIG) | 522 - PCIE_REG_PHBC_64B_TCE_EN); 523 - 524 - /* Enable 32 & 64-bit MSIs, IO space and M32A */ 525 - val = PCIE_REG_PHBC_32BIT_MSI_EN | 526 - PCIE_REG_PHBC_IO_EN | 527 - PCIE_REG_PHBC_64BIT_MSI_EN | 528 - PCIE_REG_PHBC_M32A_EN; 529 - if (iommu_is_off) 530 - val |= PCIE_REG_PHBC_DMA_XLATE_BYPASS; 531 - pr_debug("Will write config: 0x%llx\n", val); 532 - out_be64(hose->cfg_data + PCIE_REG_PHB_CONFIG, val); 533 - 534 - /* Enable error reporting */ 535 - out_be64(hose->cfg_data + 0xe00, 536 - in_be64(hose->cfg_data + 0xe00) | 0x0008000000000000ull); 537 - 538 - /* Mask an error that's generated when doing config space probe 539 - * 540 - * XXX Maybe we should only mask it around config space cycles... that or 541 - * ignore it when we know we had a config space cycle recently ? 542 - */ 543 - out_be64(hose->cfg_data + PCIE_REG_DMA_ERR_STATUS_MASK, 0x8000000000000000ull); 544 - out_be64(hose->cfg_data + PCIE_REG_DMA_ERR1_STATUS_MASK, 0x8000000000000000ull); 545 - 546 - /* Enable UTL errors, for now, all of them got to UTL irq 1 547 - * 548 - * We similarily mask one UTL error caused apparently during normal 549 - * probing. We also mask the link up error 550 - */ 551 - out_be64(hose->cfg_data + PCIE_UTL_SYS_BUS_AGENT_ERR_SEV, 0); 552 - out_be64(hose->cfg_data + PCIE_UTL_RC_ERR_SEVERITY, 0); 553 - out_be64(hose->cfg_data + PCIE_UTL_PCIE_PORT_ERROR_SEV, 0); 554 - out_be64(hose->cfg_data + PCIE_UTL_SYS_BUS_AGENT_IRQ_EN, 0xffffffff00000000ull); 555 - out_be64(hose->cfg_data + PCIE_UTL_PCIE_PORT_IRQ_EN, 0xff5fffff00000000ull); 556 - out_be64(hose->cfg_data + PCIE_UTL_EP_ERR_IRQ_EN, 0xffffffff00000000ull); 557 - 558 - DUMP_REG(PCIE_REG_IO_BASE_ADDR); 559 - DUMP_REG(PCIE_REG_IO_BASE_MASK); 560 - DUMP_REG(PCIE_REG_IO_START_ADDR); 561 - DUMP_REG(PCIE_REG_M32A_BASE_ADDR); 562 - DUMP_REG(PCIE_REG_M32A_BASE_MASK); 563 - DUMP_REG(PCIE_REG_M32A_START_ADDR); 564 - DUMP_REG(PCIE_REG_M32B_BASE_ADDR); 565 - DUMP_REG(PCIE_REG_M32B_BASE_MASK); 566 - DUMP_REG(PCIE_REG_M32B_START_ADDR); 567 - DUMP_REG(PCIE_REG_M64_BASE_ADDR); 568 - DUMP_REG(PCIE_REG_M64_BASE_MASK); 569 - DUMP_REG(PCIE_REG_M64_START_ADDR); 570 - DUMP_REG(PCIE_REG_PHB_CONFIG); 571 - } 572 - 573 - static void wsp_pci_wait_io_idle(struct wsp_phb *phb, unsigned long port) 574 - { 575 - u64 val; 576 - int i; 577 - 578 - for (i = 0; i < 10000; i++) { 579 - val = in_be64(phb->hose->cfg_data + 0xe08); 580 - if ((val & 0x1900000000000000ull) == 0x0100000000000000ull) 581 - return; 582 - udelay(1); 583 - } 584 - pr_warning("PCI IO timeout on domain %d port 0x%lx\n", 585 - phb->hose->global_number, port); 586 - } 587 - 588 - #define DEF_PCI_AC_RET_pio(name, ret, at, al, aa) \ 589 - static ret wsp_pci_##name at \ 590 - { \ 591 - struct iowa_bus *bus; \ 592 - struct wsp_phb *phb; \ 593 - unsigned long flags; \ 594 - ret rval; \ 595 - bus = iowa_pio_find_bus(aa); \ 596 - WARN_ON(!bus); \ 597 - phb = bus->private; \ 598 - spin_lock_irqsave(&phb->lock, flags); \ 599 - wsp_pci_wait_io_idle(phb, aa); \ 600 - rval = __do_##name al; \ 601 - spin_unlock_irqrestore(&phb->lock, flags); \ 602 - return rval; \ 603 - } 604 - 605 - #define DEF_PCI_AC_NORET_pio(name, at, al, aa) \ 606 - static void wsp_pci_##name at \ 607 - { \ 608 - struct iowa_bus *bus; \ 609 - struct wsp_phb *phb; \ 610 - unsigned long flags; \ 611 - bus = iowa_pio_find_bus(aa); \ 612 - WARN_ON(!bus); \ 613 - phb = bus->private; \ 614 - spin_lock_irqsave(&phb->lock, flags); \ 615 - wsp_pci_wait_io_idle(phb, aa); \ 616 - __do_##name al; \ 617 - spin_unlock_irqrestore(&phb->lock, flags); \ 618 - } 619 - 620 - #define DEF_PCI_AC_RET_mem(name, ret, at, al, aa) 621 - #define DEF_PCI_AC_NORET_mem(name, at, al, aa) 622 - 623 - #define DEF_PCI_AC_RET(name, ret, at, al, space, aa) \ 624 - DEF_PCI_AC_RET_##space(name, ret, at, al, aa) 625 - 626 - #define DEF_PCI_AC_NORET(name, at, al, space, aa) \ 627 - DEF_PCI_AC_NORET_##space(name, at, al, aa) \ 628 - 629 - 630 - #include <asm/io-defs.h> 631 - 632 - #undef DEF_PCI_AC_RET 633 - #undef DEF_PCI_AC_NORET 634 - 635 - static struct ppc_pci_io wsp_pci_iops = { 636 - .inb = wsp_pci_inb, 637 - .inw = wsp_pci_inw, 638 - .inl = wsp_pci_inl, 639 - .outb = wsp_pci_outb, 640 - .outw = wsp_pci_outw, 641 - .outl = wsp_pci_outl, 642 - .insb = wsp_pci_insb, 643 - .insw = wsp_pci_insw, 644 - .insl = wsp_pci_insl, 645 - .outsb = wsp_pci_outsb, 646 - .outsw = wsp_pci_outsw, 647 - .outsl = wsp_pci_outsl, 648 - }; 649 - 650 - static int __init wsp_setup_one_phb(struct device_node *np) 651 - { 652 - struct pci_controller *hose; 653 - struct wsp_phb *phb; 654 - 655 - pr_info("PCI: Setting up PCIe host bridge 0x%s\n", np->full_name); 656 - 657 - phb = zalloc_maybe_bootmem(sizeof(struct wsp_phb), GFP_KERNEL); 658 - if (!phb) 659 - return -ENOMEM; 660 - hose = pcibios_alloc_controller(np); 661 - if (!hose) { 662 - /* Can't really free the phb */ 663 - return -ENOMEM; 664 - } 665 - hose->private_data = phb; 666 - phb->hose = hose; 667 - 668 - INIT_LIST_HEAD(&phb->dma_tables); 669 - spin_lock_init(&phb->lock); 670 - 671 - /* XXX Use bus-range property ? */ 672 - hose->first_busno = 0; 673 - hose->last_busno = 0xff; 674 - 675 - /* We use cfg_data as the address for the whole bridge MMIO space 676 - */ 677 - hose->cfg_data = of_iomap(hose->dn, 0); 678 - 679 - pr_debug("PCIe registers mapped at 0x%p\n", hose->cfg_data); 680 - 681 - /* Get the ranges of the device-tree */ 682 - pci_process_bridge_OF_ranges(hose, np, 0); 683 - 684 - /* XXX Force re-assigning of everything for now */ 685 - pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC | 686 - PCI_ENABLE_PROC_DOMAINS); 687 - 688 - /* Calculate how the TCE space is divided */ 689 - phb->dma32_base = 0; 690 - phb->dma32_num_regions = NUM_DMA32_REGIONS; 691 - if (phb->dma32_num_regions > MAX_TABLE_TVT_COUNT) { 692 - pr_warning("IOMMU: Clamped to %d DMA32 regions\n", 693 - MAX_TABLE_TVT_COUNT); 694 - phb->dma32_num_regions = MAX_TABLE_TVT_COUNT; 695 - } 696 - phb->dma32_region_size = 0x80000000 / phb->dma32_num_regions; 697 - 698 - BUG_ON(!is_power_of_2(phb->dma32_region_size)); 699 - 700 - /* Setup config ops */ 701 - hose->ops = &wsp_pcie_pci_ops; 702 - 703 - /* Configure the HW */ 704 - wsp_pcie_configure_hw(hose); 705 - 706 - /* Instanciate IO workarounds */ 707 - iowa_register_bus(hose, &wsp_pci_iops, NULL, phb); 708 - #ifdef CONFIG_PCI_MSI 709 - wsp_setup_phb_msi(hose); 710 - #endif 711 - 712 - /* Add to global list */ 713 - list_add(&phb->all, &wsp_phbs); 714 - 715 - return 0; 716 - } 717 - 718 - void __init wsp_setup_pci(void) 719 - { 720 - struct device_node *np; 721 - int rc; 722 - 723 - /* Find host bridges */ 724 - for_each_compatible_node(np, "pciex", PCIE_COMPATIBLE) { 725 - rc = wsp_setup_one_phb(np); 726 - if (rc) 727 - pr_err("Failed to setup PCIe bridge %s, rc=%d\n", 728 - np->full_name, rc); 729 - } 730 - 731 - /* Establish device-tree linkage */ 732 - pci_devs_phb_init(); 733 - 734 - /* Set DMA ops to use TCEs */ 735 - if (iommu_is_off) { 736 - pr_info("PCI-E: Disabled TCEs, using direct DMA\n"); 737 - set_pci_dma_ops(&dma_direct_ops); 738 - } else { 739 - ppc_md.pci_dma_dev_setup = wsp_pci_dma_dev_setup; 740 - ppc_md.tce_build = tce_build_wsp; 741 - ppc_md.tce_free = tce_free_wsp; 742 - set_pci_dma_ops(&dma_iommu_ops); 743 - } 744 - } 745 - 746 - #define err_debug(fmt...) pr_debug(fmt) 747 - //#define err_debug(fmt...) 748 - 749 - static int __init wsp_pci_get_err_irq_no_dt(struct device_node *np) 750 - { 751 - const u32 *prop; 752 - int hw_irq; 753 - 754 - /* Ok, no interrupts property, let's try to find our child P2P */ 755 - np = of_get_next_child(np, NULL); 756 - if (np == NULL) 757 - return 0; 758 - 759 - /* Grab it's interrupt map */ 760 - prop = of_get_property(np, "interrupt-map", NULL); 761 - if (prop == NULL) 762 - return 0; 763 - 764 - /* Grab one of the interrupts in there, keep the low 4 bits */ 765 - hw_irq = prop[5] & 0xf; 766 - 767 - /* 0..4 for PHB 0 and 5..9 for PHB 1 */ 768 - if (hw_irq < 5) 769 - hw_irq = 4; 770 - else 771 - hw_irq = 9; 772 - hw_irq |= prop[5] & ~0xf; 773 - 774 - err_debug("PCI: Using 0x%x as error IRQ for %s\n", 775 - hw_irq, np->parent->full_name); 776 - return irq_create_mapping(NULL, hw_irq); 777 - } 778 - 779 - static const struct { 780 - u32 offset; 781 - const char *name; 782 - } wsp_pci_regs[] = { 783 - #define DREG(x) { PCIE_REG_##x, #x } 784 - #define DUTL(x) { PCIE_UTL_##x, "UTL_" #x } 785 - /* Architected registers except CONFIG_ and IODA 786 - * to avoid side effects 787 - */ 788 - DREG(DMA_CHAN_STATUS), 789 - DREG(CPU_LOADSTORE_STATUS), 790 - DREG(LOCK0), 791 - DREG(LOCK1), 792 - DREG(PHB_CONFIG), 793 - DREG(IO_BASE_ADDR), 794 - DREG(IO_BASE_MASK), 795 - DREG(IO_START_ADDR), 796 - DREG(M32A_BASE_ADDR), 797 - DREG(M32A_BASE_MASK), 798 - DREG(M32A_START_ADDR), 799 - DREG(M32B_BASE_ADDR), 800 - DREG(M32B_BASE_MASK), 801 - DREG(M32B_START_ADDR), 802 - DREG(M64_BASE_ADDR), 803 - DREG(M64_BASE_MASK), 804 - DREG(M64_START_ADDR), 805 - DREG(TCE_KILL), 806 - DREG(LOCK2), 807 - DREG(PHB_GEN_CAP), 808 - DREG(PHB_TCE_CAP), 809 - DREG(PHB_IRQ_CAP), 810 - DREG(PHB_EEH_CAP), 811 - DREG(PAPR_ERR_INJ_CONTROL), 812 - DREG(PAPR_ERR_INJ_ADDR), 813 - DREG(PAPR_ERR_INJ_MASK), 814 - 815 - /* UTL core regs */ 816 - DUTL(SYS_BUS_CONTROL), 817 - DUTL(STATUS), 818 - DUTL(SYS_BUS_AGENT_STATUS), 819 - DUTL(SYS_BUS_AGENT_ERR_SEV), 820 - DUTL(SYS_BUS_AGENT_IRQ_EN), 821 - DUTL(SYS_BUS_BURST_SZ_CONF), 822 - DUTL(REVISION_ID), 823 - DUTL(OUT_POST_HDR_BUF_ALLOC), 824 - DUTL(OUT_POST_DAT_BUF_ALLOC), 825 - DUTL(IN_POST_HDR_BUF_ALLOC), 826 - DUTL(IN_POST_DAT_BUF_ALLOC), 827 - DUTL(OUT_NP_BUF_ALLOC), 828 - DUTL(IN_NP_BUF_ALLOC), 829 - DUTL(PCIE_TAGS_ALLOC), 830 - DUTL(GBIF_READ_TAGS_ALLOC), 831 - 832 - DUTL(PCIE_PORT_CONTROL), 833 - DUTL(PCIE_PORT_STATUS), 834 - DUTL(PCIE_PORT_ERROR_SEV), 835 - DUTL(PCIE_PORT_IRQ_EN), 836 - DUTL(RC_STATUS), 837 - DUTL(RC_ERR_SEVERITY), 838 - DUTL(RC_IRQ_EN), 839 - DUTL(EP_STATUS), 840 - DUTL(EP_ERR_SEVERITY), 841 - DUTL(EP_ERR_IRQ_EN), 842 - DUTL(PCI_PM_CTRL1), 843 - DUTL(PCI_PM_CTRL2), 844 - 845 - /* PCIe stack regs */ 846 - DREG(SYSTEM_CONFIG1), 847 - DREG(SYSTEM_CONFIG2), 848 - DREG(EP_SYSTEM_CONFIG), 849 - DREG(EP_FLR), 850 - DREG(EP_BAR_CONFIG), 851 - DREG(LINK_CONFIG), 852 - DREG(PM_CONFIG), 853 - DREG(DLP_CONTROL), 854 - DREG(DLP_STATUS), 855 - DREG(ERR_REPORT_CONTROL), 856 - DREG(SLOT_CONTROL1), 857 - DREG(SLOT_CONTROL2), 858 - DREG(UTL_CONFIG), 859 - DREG(BUFFERS_CONFIG), 860 - DREG(ERROR_INJECT), 861 - DREG(SRIOV_CONFIG), 862 - DREG(PF0_SRIOV_STATUS), 863 - DREG(PF1_SRIOV_STATUS), 864 - DREG(PORT_NUMBER), 865 - DREG(POR_SYSTEM_CONFIG), 866 - 867 - /* Internal logic regs */ 868 - DREG(PHB_VERSION), 869 - DREG(RESET), 870 - DREG(PHB_CONTROL), 871 - DREG(PHB_TIMEOUT_CONTROL1), 872 - DREG(PHB_QUIESCE_DMA), 873 - DREG(PHB_DMA_READ_TAG_ACTV), 874 - DREG(PHB_TCE_READ_TAG_ACTV), 875 - 876 - /* FIR registers */ 877 - DREG(LEM_FIR_ACCUM), 878 - DREG(LEM_FIR_AND_MASK), 879 - DREG(LEM_FIR_OR_MASK), 880 - DREG(LEM_ACTION0), 881 - DREG(LEM_ACTION1), 882 - DREG(LEM_ERROR_MASK), 883 - DREG(LEM_ERROR_AND_MASK), 884 - DREG(LEM_ERROR_OR_MASK), 885 - 886 - /* Error traps registers */ 887 - DREG(PHB_ERR_STATUS), 888 - DREG(PHB_ERR_STATUS), 889 - DREG(PHB_ERR1_STATUS), 890 - DREG(PHB_ERR_INJECT), 891 - DREG(PHB_ERR_LEM_ENABLE), 892 - DREG(PHB_ERR_IRQ_ENABLE), 893 - DREG(PHB_ERR_FREEZE_ENABLE), 894 - DREG(PHB_ERR_SIDE_ENABLE), 895 - DREG(PHB_ERR_LOG_0), 896 - DREG(PHB_ERR_LOG_1), 897 - DREG(PHB_ERR_STATUS_MASK), 898 - DREG(PHB_ERR1_STATUS_MASK), 899 - DREG(MMIO_ERR_STATUS), 900 - DREG(MMIO_ERR1_STATUS), 901 - DREG(MMIO_ERR_INJECT), 902 - DREG(MMIO_ERR_LEM_ENABLE), 903 - DREG(MMIO_ERR_IRQ_ENABLE), 904 - DREG(MMIO_ERR_FREEZE_ENABLE), 905 - DREG(MMIO_ERR_SIDE_ENABLE), 906 - DREG(MMIO_ERR_LOG_0), 907 - DREG(MMIO_ERR_LOG_1), 908 - DREG(MMIO_ERR_STATUS_MASK), 909 - DREG(MMIO_ERR1_STATUS_MASK), 910 - DREG(DMA_ERR_STATUS), 911 - DREG(DMA_ERR1_STATUS), 912 - DREG(DMA_ERR_INJECT), 913 - DREG(DMA_ERR_LEM_ENABLE), 914 - DREG(DMA_ERR_IRQ_ENABLE), 915 - DREG(DMA_ERR_FREEZE_ENABLE), 916 - DREG(DMA_ERR_SIDE_ENABLE), 917 - DREG(DMA_ERR_LOG_0), 918 - DREG(DMA_ERR_LOG_1), 919 - DREG(DMA_ERR_STATUS_MASK), 920 - DREG(DMA_ERR1_STATUS_MASK), 921 - 922 - /* Debug and Trace registers */ 923 - DREG(PHB_DEBUG_CONTROL0), 924 - DREG(PHB_DEBUG_STATUS0), 925 - DREG(PHB_DEBUG_CONTROL1), 926 - DREG(PHB_DEBUG_STATUS1), 927 - DREG(PHB_DEBUG_CONTROL2), 928 - DREG(PHB_DEBUG_STATUS2), 929 - DREG(PHB_DEBUG_CONTROL3), 930 - DREG(PHB_DEBUG_STATUS3), 931 - DREG(PHB_DEBUG_CONTROL4), 932 - DREG(PHB_DEBUG_STATUS4), 933 - DREG(PHB_DEBUG_CONTROL5), 934 - DREG(PHB_DEBUG_STATUS5), 935 - 936 - /* Don't seem to exist ... 937 - DREG(PHB_DEBUG_CONTROL6), 938 - DREG(PHB_DEBUG_STATUS6), 939 - */ 940 - }; 941 - 942 - static int wsp_pci_regs_show(struct seq_file *m, void *private) 943 - { 944 - struct wsp_phb *phb = m->private; 945 - struct pci_controller *hose = phb->hose; 946 - int i; 947 - 948 - for (i = 0; i < ARRAY_SIZE(wsp_pci_regs); i++) { 949 - /* Skip write-only regs */ 950 - if (wsp_pci_regs[i].offset == 0xc08 || 951 - wsp_pci_regs[i].offset == 0xc10 || 952 - wsp_pci_regs[i].offset == 0xc38 || 953 - wsp_pci_regs[i].offset == 0xc40) 954 - continue; 955 - seq_printf(m, "0x%03x: 0x%016llx %s\n", 956 - wsp_pci_regs[i].offset, 957 - in_be64(hose->cfg_data + wsp_pci_regs[i].offset), 958 - wsp_pci_regs[i].name); 959 - } 960 - return 0; 961 - } 962 - 963 - static int wsp_pci_regs_open(struct inode *inode, struct file *file) 964 - { 965 - return single_open(file, wsp_pci_regs_show, inode->i_private); 966 - } 967 - 968 - static const struct file_operations wsp_pci_regs_fops = { 969 - .open = wsp_pci_regs_open, 970 - .read = seq_read, 971 - .llseek = seq_lseek, 972 - .release = single_release, 973 - }; 974 - 975 - static int wsp_pci_reg_set(void *data, u64 val) 976 - { 977 - out_be64((void __iomem *)data, val); 978 - return 0; 979 - } 980 - 981 - static int wsp_pci_reg_get(void *data, u64 *val) 982 - { 983 - *val = in_be64((void __iomem *)data); 984 - return 0; 985 - } 986 - 987 - DEFINE_SIMPLE_ATTRIBUTE(wsp_pci_reg_fops, wsp_pci_reg_get, wsp_pci_reg_set, "0x%llx\n"); 988 - 989 - static irqreturn_t wsp_pci_err_irq(int irq, void *dev_id) 990 - { 991 - struct wsp_phb *phb = dev_id; 992 - struct pci_controller *hose = phb->hose; 993 - irqreturn_t handled = IRQ_NONE; 994 - struct wsp_pcie_err_log_data ed; 995 - 996 - pr_err("PCI: Error interrupt on %s (PHB %d)\n", 997 - hose->dn->full_name, hose->global_number); 998 - again: 999 - memset(&ed, 0, sizeof(ed)); 1000 - 1001 - /* Read and clear UTL errors */ 1002 - ed.utl_sys_err = in_be64(hose->cfg_data + PCIE_UTL_SYS_BUS_AGENT_STATUS); 1003 - if (ed.utl_sys_err) 1004 - out_be64(hose->cfg_data + PCIE_UTL_SYS_BUS_AGENT_STATUS, ed.utl_sys_err); 1005 - ed.utl_port_err = in_be64(hose->cfg_data + PCIE_UTL_PCIE_PORT_STATUS); 1006 - if (ed.utl_port_err) 1007 - out_be64(hose->cfg_data + PCIE_UTL_PCIE_PORT_STATUS, ed.utl_port_err); 1008 - ed.utl_rc_err = in_be64(hose->cfg_data + PCIE_UTL_RC_STATUS); 1009 - if (ed.utl_rc_err) 1010 - out_be64(hose->cfg_data + PCIE_UTL_RC_STATUS, ed.utl_rc_err); 1011 - 1012 - /* Read and clear main trap errors */ 1013 - ed.phb_err = in_be64(hose->cfg_data + PCIE_REG_PHB_ERR_STATUS); 1014 - if (ed.phb_err) { 1015 - ed.phb_err1 = in_be64(hose->cfg_data + PCIE_REG_PHB_ERR1_STATUS); 1016 - ed.phb_log0 = in_be64(hose->cfg_data + PCIE_REG_PHB_ERR_LOG_0); 1017 - ed.phb_log1 = in_be64(hose->cfg_data + PCIE_REG_PHB_ERR_LOG_1); 1018 - out_be64(hose->cfg_data + PCIE_REG_PHB_ERR1_STATUS, 0); 1019 - out_be64(hose->cfg_data + PCIE_REG_PHB_ERR_STATUS, 0); 1020 - } 1021 - ed.mmio_err = in_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_STATUS); 1022 - if (ed.mmio_err) { 1023 - ed.mmio_err1 = in_be64(hose->cfg_data + PCIE_REG_MMIO_ERR1_STATUS); 1024 - ed.mmio_log0 = in_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_LOG_0); 1025 - ed.mmio_log1 = in_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_LOG_1); 1026 - out_be64(hose->cfg_data + PCIE_REG_MMIO_ERR1_STATUS, 0); 1027 - out_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_STATUS, 0); 1028 - } 1029 - ed.dma_err = in_be64(hose->cfg_data + PCIE_REG_DMA_ERR_STATUS); 1030 - if (ed.dma_err) { 1031 - ed.dma_err1 = in_be64(hose->cfg_data + PCIE_REG_DMA_ERR1_STATUS); 1032 - ed.dma_log0 = in_be64(hose->cfg_data + PCIE_REG_DMA_ERR_LOG_0); 1033 - ed.dma_log1 = in_be64(hose->cfg_data + PCIE_REG_DMA_ERR_LOG_1); 1034 - out_be64(hose->cfg_data + PCIE_REG_DMA_ERR1_STATUS, 0); 1035 - out_be64(hose->cfg_data + PCIE_REG_DMA_ERR_STATUS, 0); 1036 - } 1037 - 1038 - /* Now print things out */ 1039 - if (ed.phb_err) { 1040 - pr_err(" PHB Error Status : 0x%016llx\n", ed.phb_err); 1041 - pr_err(" PHB First Error Status: 0x%016llx\n", ed.phb_err1); 1042 - pr_err(" PHB Error Log 0 : 0x%016llx\n", ed.phb_log0); 1043 - pr_err(" PHB Error Log 1 : 0x%016llx\n", ed.phb_log1); 1044 - } 1045 - if (ed.mmio_err) { 1046 - pr_err(" MMIO Error Status : 0x%016llx\n", ed.mmio_err); 1047 - pr_err(" MMIO First Error Status: 0x%016llx\n", ed.mmio_err1); 1048 - pr_err(" MMIO Error Log 0 : 0x%016llx\n", ed.mmio_log0); 1049 - pr_err(" MMIO Error Log 1 : 0x%016llx\n", ed.mmio_log1); 1050 - } 1051 - if (ed.dma_err) { 1052 - pr_err(" DMA Error Status : 0x%016llx\n", ed.dma_err); 1053 - pr_err(" DMA First Error Status: 0x%016llx\n", ed.dma_err1); 1054 - pr_err(" DMA Error Log 0 : 0x%016llx\n", ed.dma_log0); 1055 - pr_err(" DMA Error Log 1 : 0x%016llx\n", ed.dma_log1); 1056 - } 1057 - if (ed.utl_sys_err) 1058 - pr_err(" UTL Sys Error Status : 0x%016llx\n", ed.utl_sys_err); 1059 - if (ed.utl_port_err) 1060 - pr_err(" UTL Port Error Status : 0x%016llx\n", ed.utl_port_err); 1061 - if (ed.utl_rc_err) 1062 - pr_err(" UTL RC Error Status : 0x%016llx\n", ed.utl_rc_err); 1063 - 1064 - /* Interrupts are caused by the error traps. If we had any error there 1065 - * we loop again in case the UTL buffered some new stuff between 1066 - * going there and going to the traps 1067 - */ 1068 - if (ed.dma_err || ed.mmio_err || ed.phb_err) { 1069 - handled = IRQ_HANDLED; 1070 - goto again; 1071 - } 1072 - return handled; 1073 - } 1074 - 1075 - static void __init wsp_setup_pci_err_reporting(struct wsp_phb *phb) 1076 - { 1077 - struct pci_controller *hose = phb->hose; 1078 - int err_irq, i, rc; 1079 - char fname[16]; 1080 - 1081 - /* Create a debugfs file for that PHB */ 1082 - sprintf(fname, "phb%d", phb->hose->global_number); 1083 - phb->ddir = debugfs_create_dir(fname, powerpc_debugfs_root); 1084 - 1085 - /* Some useful debug output */ 1086 - if (phb->ddir) { 1087 - struct dentry *d = debugfs_create_dir("regs", phb->ddir); 1088 - char tmp[64]; 1089 - 1090 - for (i = 0; i < ARRAY_SIZE(wsp_pci_regs); i++) { 1091 - sprintf(tmp, "%03x_%s", wsp_pci_regs[i].offset, 1092 - wsp_pci_regs[i].name); 1093 - debugfs_create_file(tmp, 0600, d, 1094 - hose->cfg_data + wsp_pci_regs[i].offset, 1095 - &wsp_pci_reg_fops); 1096 - } 1097 - debugfs_create_file("all_regs", 0600, phb->ddir, phb, &wsp_pci_regs_fops); 1098 - } 1099 - 1100 - /* Find the IRQ number for that PHB */ 1101 - err_irq = irq_of_parse_and_map(hose->dn, 0); 1102 - if (err_irq == 0) 1103 - /* XXX Error IRQ lacking from device-tree */ 1104 - err_irq = wsp_pci_get_err_irq_no_dt(hose->dn); 1105 - if (err_irq == 0) { 1106 - pr_err("PCI: Failed to fetch error interrupt for %s\n", 1107 - hose->dn->full_name); 1108 - return; 1109 - } 1110 - /* Request it */ 1111 - rc = request_irq(err_irq, wsp_pci_err_irq, 0, "wsp_pci error", phb); 1112 - if (rc) { 1113 - pr_err("PCI: Failed to request interrupt for %s\n", 1114 - hose->dn->full_name); 1115 - } 1116 - /* Enable interrupts for all errors for now */ 1117 - out_be64(hose->cfg_data + PCIE_REG_PHB_ERR_IRQ_ENABLE, 0xffffffffffffffffull); 1118 - out_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_IRQ_ENABLE, 0xffffffffffffffffull); 1119 - out_be64(hose->cfg_data + PCIE_REG_DMA_ERR_IRQ_ENABLE, 0xffffffffffffffffull); 1120 - } 1121 - 1122 - /* 1123 - * This is called later to hookup with the error interrupt 1124 - */ 1125 - static int __init wsp_setup_pci_late(void) 1126 - { 1127 - struct wsp_phb *phb; 1128 - 1129 - list_for_each_entry(phb, &wsp_phbs, all) 1130 - wsp_setup_pci_err_reporting(phb); 1131 - 1132 - return 0; 1133 - } 1134 - arch_initcall(wsp_setup_pci_late);
-268
arch/powerpc/platforms/wsp/wsp_pci.h
··· 1 - /* 2 - * Copyright 2010 Ben Herrenschmidt, IBM Corporation 3 - * 4 - * This program is free software; you can redistribute it and/or 5 - * modify it under the terms of the GNU General Public License 6 - * as published by the Free Software Foundation; either version 7 - * 2 of the License, or (at your option) any later version. 8 - */ 9 - 10 - #ifndef __WSP_PCI_H 11 - #define __WSP_PCI_H 12 - 13 - /* Architected registers */ 14 - #define PCIE_REG_DMA_CHAN_STATUS 0x110 15 - #define PCIE_REG_CPU_LOADSTORE_STATUS 0x120 16 - 17 - #define PCIE_REG_CONFIG_DATA 0x130 18 - #define PCIE_REG_LOCK0 0x138 19 - #define PCIE_REG_CONFIG_ADDRESS 0x140 20 - #define PCIE_REG_CA_ENABLE 0x8000000000000000ull 21 - #define PCIE_REG_CA_BUS_MASK 0x0ff0000000000000ull 22 - #define PCIE_REG_CA_BUS_SHIFT (20+32) 23 - #define PCIE_REG_CA_DEV_MASK 0x000f800000000000ull 24 - #define PCIE_REG_CA_DEV_SHIFT (15+32) 25 - #define PCIE_REG_CA_FUNC_MASK 0x0000700000000000ull 26 - #define PCIE_REG_CA_FUNC_SHIFT (12+32) 27 - #define PCIE_REG_CA_REG_MASK 0x00000fff00000000ull 28 - #define PCIE_REG_CA_REG_SHIFT ( 0+32) 29 - #define PCIE_REG_CA_BE_MASK 0x00000000f0000000ull 30 - #define PCIE_REG_CA_BE_SHIFT ( 28) 31 - #define PCIE_REG_LOCK1 0x148 32 - 33 - #define PCIE_REG_PHB_CONFIG 0x160 34 - #define PCIE_REG_PHBC_64B_TCE_EN 0x2000000000000000ull 35 - #define PCIE_REG_PHBC_MMIO_DMA_FREEZE_EN 0x1000000000000000ull 36 - #define PCIE_REG_PHBC_32BIT_MSI_EN 0x0080000000000000ull 37 - #define PCIE_REG_PHBC_M64_EN 0x0040000000000000ull 38 - #define PCIE_REG_PHBC_IO_EN 0x0008000000000000ull 39 - #define PCIE_REG_PHBC_64BIT_MSI_EN 0x0002000000000000ull 40 - #define PCIE_REG_PHBC_M32A_EN 0x0000800000000000ull 41 - #define PCIE_REG_PHBC_M32B_EN 0x0000400000000000ull 42 - #define PCIE_REG_PHBC_MSI_PE_VALIDATE 0x0000200000000000ull 43 - #define PCIE_REG_PHBC_DMA_XLATE_BYPASS 0x0000100000000000ull 44 - 45 - #define PCIE_REG_IO_BASE_ADDR 0x170 46 - #define PCIE_REG_IO_BASE_MASK 0x178 47 - #define PCIE_REG_IO_START_ADDR 0x180 48 - 49 - #define PCIE_REG_M32A_BASE_ADDR 0x190 50 - #define PCIE_REG_M32A_BASE_MASK 0x198 51 - #define PCIE_REG_M32A_START_ADDR 0x1a0 52 - 53 - #define PCIE_REG_M32B_BASE_ADDR 0x1b0 54 - #define PCIE_REG_M32B_BASE_MASK 0x1b8 55 - #define PCIE_REG_M32B_START_ADDR 0x1c0 56 - 57 - #define PCIE_REG_M64_BASE_ADDR 0x1e0 58 - #define PCIE_REG_M64_BASE_MASK 0x1e8 59 - #define PCIE_REG_M64_START_ADDR 0x1f0 60 - 61 - #define PCIE_REG_TCE_KILL 0x210 62 - #define PCIE_REG_TCEKILL_SINGLE 0x8000000000000000ull 63 - #define PCIE_REG_TCEKILL_ADDR_MASK 0x000003fffffffff8ull 64 - #define PCIE_REG_TCEKILL_PS_4K 0 65 - #define PCIE_REG_TCEKILL_PS_64K 1 66 - #define PCIE_REG_TCEKILL_PS_16M 2 67 - #define PCIE_REG_TCEKILL_PS_16G 3 68 - 69 - #define PCIE_REG_IODA_ADDR 0x220 70 - #define PCIE_REG_IODA_AD_AUTOINC 0x8000000000000000ull 71 - #define PCIE_REG_IODA_AD_TBL_MVT 0x0005000000000000ull 72 - #define PCIE_REG_IODA_AD_TBL_PELT 0x0006000000000000ull 73 - #define PCIE_REG_IODA_AD_TBL_PESTA 0x0007000000000000ull 74 - #define PCIE_REG_IODA_AD_TBL_PESTB 0x0008000000000000ull 75 - #define PCIE_REG_IODA_AD_TBL_TVT 0x0009000000000000ull 76 - #define PCIE_REG_IODA_AD_TBL_TCE 0x000a000000000000ull 77 - #define PCIE_REG_IODA_DATA0 0x228 78 - #define PCIE_REG_IODA_DATA1 0x230 79 - 80 - #define PCIE_REG_LOCK2 0x240 81 - 82 - #define PCIE_REG_PHB_GEN_CAP 0x250 83 - #define PCIE_REG_PHB_TCE_CAP 0x258 84 - #define PCIE_REG_PHB_IRQ_CAP 0x260 85 - #define PCIE_REG_PHB_EEH_CAP 0x268 86 - 87 - #define PCIE_REG_PAPR_ERR_INJ_CONTROL 0x2b0 88 - #define PCIE_REG_PAPR_ERR_INJ_ADDR 0x2b8 89 - #define PCIE_REG_PAPR_ERR_INJ_MASK 0x2c0 90 - 91 - 92 - #define PCIE_REG_SYS_CFG1 0x600 93 - #define PCIE_REG_SYS_CFG1_CLASS_CODE 0x0000000000ffffffull 94 - 95 - #define IODA_TVT0_TTA_MASK 0x000fffffffff0000ull 96 - #define IODA_TVT0_TTA_SHIFT 4 97 - #define IODA_TVT0_BUSNUM_VALID_MASK 0x000000000000e000ull 98 - #define IODA_TVT0_TCE_TABLE_SIZE_MASK 0x0000000000001f00ull 99 - #define IODA_TVT0_TCE_TABLE_SIZE_SHIFT 8 100 - #define IODA_TVT0_BUSNUM_VALUE_MASK 0x00000000000000ffull 101 - #define IODA_TVT0_BUSNUM_VALID_SHIFT 0 102 - #define IODA_TVT1_DEVNUM_VALID 0x2000000000000000ull 103 - #define IODA_TVT1_DEVNUM_VALUE_MASK 0x1f00000000000000ull 104 - #define IODA_TVT1_DEVNUM_VALUE_SHIFT 56 105 - #define IODA_TVT1_FUNCNUM_VALID 0x0008000000000000ull 106 - #define IODA_TVT1_FUNCNUM_VALUE_MASK 0x0007000000000000ull 107 - #define IODA_TVT1_FUNCNUM_VALUE_SHIFT 48 108 - #define IODA_TVT1_IO_PAGE_SIZE_MASK 0x00001f0000000000ull 109 - #define IODA_TVT1_IO_PAGE_SIZE_SHIFT 40 110 - #define IODA_TVT1_PE_NUMBER_MASK 0x000000000000003full 111 - #define IODA_TVT1_PE_NUMBER_SHIFT 0 112 - 113 - #define IODA_TVT_COUNT 64 114 - 115 - /* UTL Core registers */ 116 - #define PCIE_UTL_SYS_BUS_CONTROL 0x400 117 - #define PCIE_UTL_STATUS 0x408 118 - #define PCIE_UTL_SYS_BUS_AGENT_STATUS 0x410 119 - #define PCIE_UTL_SYS_BUS_AGENT_ERR_SEV 0x418 120 - #define PCIE_UTL_SYS_BUS_AGENT_IRQ_EN 0x420 121 - #define PCIE_UTL_SYS_BUS_BURST_SZ_CONF 0x440 122 - #define PCIE_UTL_REVISION_ID 0x448 123 - 124 - #define PCIE_UTL_OUT_POST_HDR_BUF_ALLOC 0x4c0 125 - #define PCIE_UTL_OUT_POST_DAT_BUF_ALLOC 0x4d0 126 - #define PCIE_UTL_IN_POST_HDR_BUF_ALLOC 0x4e0 127 - #define PCIE_UTL_IN_POST_DAT_BUF_ALLOC 0x4f0 128 - #define PCIE_UTL_OUT_NP_BUF_ALLOC 0x500 129 - #define PCIE_UTL_IN_NP_BUF_ALLOC 0x510 130 - #define PCIE_UTL_PCIE_TAGS_ALLOC 0x520 131 - #define PCIE_UTL_GBIF_READ_TAGS_ALLOC 0x530 132 - 133 - #define PCIE_UTL_PCIE_PORT_CONTROL 0x540 134 - #define PCIE_UTL_PCIE_PORT_STATUS 0x548 135 - #define PCIE_UTL_PCIE_PORT_ERROR_SEV 0x550 136 - #define PCIE_UTL_PCIE_PORT_IRQ_EN 0x558 137 - #define PCIE_UTL_RC_STATUS 0x560 138 - #define PCIE_UTL_RC_ERR_SEVERITY 0x568 139 - #define PCIE_UTL_RC_IRQ_EN 0x570 140 - #define PCIE_UTL_EP_STATUS 0x578 141 - #define PCIE_UTL_EP_ERR_SEVERITY 0x580 142 - #define PCIE_UTL_EP_ERR_IRQ_EN 0x588 143 - 144 - #define PCIE_UTL_PCI_PM_CTRL1 0x590 145 - #define PCIE_UTL_PCI_PM_CTRL2 0x598 146 - 147 - /* PCIe stack registers */ 148 - #define PCIE_REG_SYSTEM_CONFIG1 0x600 149 - #define PCIE_REG_SYSTEM_CONFIG2 0x608 150 - #define PCIE_REG_EP_SYSTEM_CONFIG 0x618 151 - #define PCIE_REG_EP_FLR 0x620 152 - #define PCIE_REG_EP_BAR_CONFIG 0x628 153 - #define PCIE_REG_LINK_CONFIG 0x630 154 - #define PCIE_REG_PM_CONFIG 0x640 155 - #define PCIE_REG_DLP_CONTROL 0x650 156 - #define PCIE_REG_DLP_STATUS 0x658 157 - #define PCIE_REG_ERR_REPORT_CONTROL 0x660 158 - #define PCIE_REG_SLOT_CONTROL1 0x670 159 - #define PCIE_REG_SLOT_CONTROL2 0x678 160 - #define PCIE_REG_UTL_CONFIG 0x680 161 - #define PCIE_REG_BUFFERS_CONFIG 0x690 162 - #define PCIE_REG_ERROR_INJECT 0x698 163 - #define PCIE_REG_SRIOV_CONFIG 0x6a0 164 - #define PCIE_REG_PF0_SRIOV_STATUS 0x6a8 165 - #define PCIE_REG_PF1_SRIOV_STATUS 0x6b0 166 - #define PCIE_REG_PORT_NUMBER 0x700 167 - #define PCIE_REG_POR_SYSTEM_CONFIG 0x708 168 - 169 - /* PHB internal logic registers */ 170 - #define PCIE_REG_PHB_VERSION 0x800 171 - #define PCIE_REG_RESET 0x808 172 - #define PCIE_REG_PHB_CONTROL 0x810 173 - #define PCIE_REG_PHB_TIMEOUT_CONTROL1 0x878 174 - #define PCIE_REG_PHB_QUIESCE_DMA 0x888 175 - #define PCIE_REG_PHB_DMA_READ_TAG_ACTV 0x900 176 - #define PCIE_REG_PHB_TCE_READ_TAG_ACTV 0x908 177 - 178 - /* FIR registers */ 179 - #define PCIE_REG_LEM_FIR_ACCUM 0xc00 180 - #define PCIE_REG_LEM_FIR_AND_MASK 0xc08 181 - #define PCIE_REG_LEM_FIR_OR_MASK 0xc10 182 - #define PCIE_REG_LEM_ACTION0 0xc18 183 - #define PCIE_REG_LEM_ACTION1 0xc20 184 - #define PCIE_REG_LEM_ERROR_MASK 0xc30 185 - #define PCIE_REG_LEM_ERROR_AND_MASK 0xc38 186 - #define PCIE_REG_LEM_ERROR_OR_MASK 0xc40 187 - 188 - /* PHB Error registers */ 189 - #define PCIE_REG_PHB_ERR_STATUS 0xc80 190 - #define PCIE_REG_PHB_ERR1_STATUS 0xc88 191 - #define PCIE_REG_PHB_ERR_INJECT 0xc90 192 - #define PCIE_REG_PHB_ERR_LEM_ENABLE 0xc98 193 - #define PCIE_REG_PHB_ERR_IRQ_ENABLE 0xca0 194 - #define PCIE_REG_PHB_ERR_FREEZE_ENABLE 0xca8 195 - #define PCIE_REG_PHB_ERR_SIDE_ENABLE 0xcb8 196 - #define PCIE_REG_PHB_ERR_LOG_0 0xcc0 197 - #define PCIE_REG_PHB_ERR_LOG_1 0xcc8 198 - #define PCIE_REG_PHB_ERR_STATUS_MASK 0xcd0 199 - #define PCIE_REG_PHB_ERR1_STATUS_MASK 0xcd8 200 - 201 - #define PCIE_REG_MMIO_ERR_STATUS 0xd00 202 - #define PCIE_REG_MMIO_ERR1_STATUS 0xd08 203 - #define PCIE_REG_MMIO_ERR_INJECT 0xd10 204 - #define PCIE_REG_MMIO_ERR_LEM_ENABLE 0xd18 205 - #define PCIE_REG_MMIO_ERR_IRQ_ENABLE 0xd20 206 - #define PCIE_REG_MMIO_ERR_FREEZE_ENABLE 0xd28 207 - #define PCIE_REG_MMIO_ERR_SIDE_ENABLE 0xd38 208 - #define PCIE_REG_MMIO_ERR_LOG_0 0xd40 209 - #define PCIE_REG_MMIO_ERR_LOG_1 0xd48 210 - #define PCIE_REG_MMIO_ERR_STATUS_MASK 0xd50 211 - #define PCIE_REG_MMIO_ERR1_STATUS_MASK 0xd58 212 - 213 - #define PCIE_REG_DMA_ERR_STATUS 0xd80 214 - #define PCIE_REG_DMA_ERR1_STATUS 0xd88 215 - #define PCIE_REG_DMA_ERR_INJECT 0xd90 216 - #define PCIE_REG_DMA_ERR_LEM_ENABLE 0xd98 217 - #define PCIE_REG_DMA_ERR_IRQ_ENABLE 0xda0 218 - #define PCIE_REG_DMA_ERR_FREEZE_ENABLE 0xda8 219 - #define PCIE_REG_DMA_ERR_SIDE_ENABLE 0xdb8 220 - #define PCIE_REG_DMA_ERR_LOG_0 0xdc0 221 - #define PCIE_REG_DMA_ERR_LOG_1 0xdc8 222 - #define PCIE_REG_DMA_ERR_STATUS_MASK 0xdd0 223 - #define PCIE_REG_DMA_ERR1_STATUS_MASK 0xdd8 224 - 225 - /* Shortcuts for access to the above using the PHB definitions 226 - * with an offset 227 - */ 228 - #define PCIE_REG_ERR_PHB_OFFSET 0x0 229 - #define PCIE_REG_ERR_MMIO_OFFSET 0x80 230 - #define PCIE_REG_ERR_DMA_OFFSET 0x100 231 - 232 - /* Debug and Trace registers */ 233 - #define PCIE_REG_PHB_DEBUG_CONTROL0 0xe00 234 - #define PCIE_REG_PHB_DEBUG_STATUS0 0xe08 235 - #define PCIE_REG_PHB_DEBUG_CONTROL1 0xe10 236 - #define PCIE_REG_PHB_DEBUG_STATUS1 0xe18 237 - #define PCIE_REG_PHB_DEBUG_CONTROL2 0xe20 238 - #define PCIE_REG_PHB_DEBUG_STATUS2 0xe28 239 - #define PCIE_REG_PHB_DEBUG_CONTROL3 0xe30 240 - #define PCIE_REG_PHB_DEBUG_STATUS3 0xe38 241 - #define PCIE_REG_PHB_DEBUG_CONTROL4 0xe40 242 - #define PCIE_REG_PHB_DEBUG_STATUS4 0xe48 243 - #define PCIE_REG_PHB_DEBUG_CONTROL5 0xe50 244 - #define PCIE_REG_PHB_DEBUG_STATUS5 0xe58 245 - #define PCIE_REG_PHB_DEBUG_CONTROL6 0xe60 246 - #define PCIE_REG_PHB_DEBUG_STATUS6 0xe68 247 - 248 - /* Definition for PCIe errors */ 249 - struct wsp_pcie_err_log_data { 250 - __u64 phb_err; 251 - __u64 phb_err1; 252 - __u64 phb_log0; 253 - __u64 phb_log1; 254 - __u64 mmio_err; 255 - __u64 mmio_err1; 256 - __u64 mmio_log0; 257 - __u64 mmio_log1; 258 - __u64 dma_err; 259 - __u64 dma_err1; 260 - __u64 dma_log0; 261 - __u64 dma_log1; 262 - __u64 utl_sys_err; 263 - __u64 utl_port_err; 264 - __u64 utl_rc_err; 265 - __u64 unused; 266 - }; 267 - 268 - #endif /* __WSP_PCI_H */
+8 -1
arch/powerpc/sysdev/xics/icp-native.c
··· 26 26 #include <asm/errno.h> 27 27 #include <asm/xics.h> 28 28 #include <asm/kvm_ppc.h> 29 + #include <asm/dbell.h> 29 30 30 31 struct icp_ipl { 31 32 union { ··· 146 145 static void icp_native_cause_ipi(int cpu, unsigned long data) 147 146 { 148 147 kvmppc_set_host_ipi(cpu, 1); 149 - icp_native_set_qirr(cpu, IPI_PRIORITY); 148 + #ifdef CONFIG_PPC_DOORBELL 149 + if (cpu_has_feature(CPU_FTR_DBELL) && 150 + (cpumask_test_cpu(cpu, cpu_sibling_mask(smp_processor_id())))) 151 + doorbell_cause_ipi(cpu, data); 152 + else 153 + #endif 154 + icp_native_set_qirr(cpu, IPI_PRIORITY); 150 155 } 151 156 152 157 void xics_wake_cpu(int cpu)
+1 -1
arch/powerpc/xmon/nonstdio.c
··· 122 122 123 123 if (n && rc == 0) { 124 124 /* No udbg hooks, fallback to printk() - dangerous */ 125 - printk(xmon_outbuf); 125 + printk("%s", xmon_outbuf); 126 126 } 127 127 } 128 128
+3 -5
drivers/cpuidle/cpuidle-powernv.c
··· 73 73 return index; 74 74 75 75 new_lpcr = old_lpcr; 76 - new_lpcr &= ~(LPCR_MER | LPCR_PECE); /* lpcr[mer] must be 0 */ 77 - 78 - /* exit powersave upon external interrupt, but not decrementer 79 - * interrupt. 76 + /* Do not exit powersave upon decrementer as we've setup the timer 77 + * offload. 80 78 */ 81 - new_lpcr |= LPCR_PECE0; 79 + new_lpcr &= ~LPCR_PECE1; 82 80 83 81 mtspr(SPRN_LPCR, new_lpcr); 84 82 power7_sleep();
+1 -1
drivers/crypto/Kconfig
··· 313 313 314 314 config CRYPTO_DEV_NX 315 315 bool "Support for IBM Power7+ in-Nest cryptographic acceleration" 316 - depends on PPC64 && IBMVIO 316 + depends on PPC64 && IBMVIO && !CPU_LITTLE_ENDIAN 317 317 default n 318 318 help 319 319 Support for Power7+ in-Nest cryptographic acceleration.
+1 -1
tools/testing/selftests/powerpc/Makefile
··· 13 13 14 14 export CC CFLAGS 15 15 16 - TARGETS = pmu copyloops mm 16 + TARGETS = pmu copyloops mm tm 17 17 18 18 endif 19 19
+12 -3
tools/testing/selftests/powerpc/harness.c
··· 30 30 31 31 pid = fork(); 32 32 if (pid == 0) { 33 + setpgid(0, 0); 33 34 exit(test_function()); 34 35 } else if (pid == -1) { 35 36 perror("fork"); 36 37 return 1; 37 38 } 39 + 40 + setpgid(pid, pid); 38 41 39 42 /* Wake us up in timeout seconds */ 40 43 alarm(TIMEOUT); ··· 53 50 54 51 if (terminated) { 55 52 printf("!! force killing %s\n", name); 56 - kill(pid, SIGKILL); 53 + kill(-pid, SIGKILL); 57 54 return 1; 58 55 } else { 59 56 printf("!! killing %s\n", name); 60 - kill(pid, SIGTERM); 57 + kill(-pid, SIGTERM); 61 58 terminated = true; 62 59 alarm(KILL_TIMEOUT); 63 60 goto wait; 64 61 } 65 62 } 63 + 64 + /* Kill anything else in the process group that is still running */ 65 + kill(-pid, SIGTERM); 66 66 67 67 if (WIFEXITED(status)) 68 68 status = WEXITSTATUS(status); ··· 105 99 106 100 rc = run_test(test_function, name); 107 101 108 - test_finish(name, rc); 102 + if (rc == MAGIC_SKIP_RETURN_VALUE) 103 + test_skip(name); 104 + else 105 + test_finish(name, rc); 109 106 110 107 return rc; 111 108 }
+22 -4
tools/testing/selftests/powerpc/pmu/Makefile
··· 4 4 PROGS := count_instructions 5 5 EXTRA_SOURCES := ../harness.c event.c 6 6 7 - all: $(PROGS) 7 + all: $(PROGS) sub_all 8 8 9 9 $(PROGS): $(EXTRA_SOURCES) 10 10 ··· 12 12 count_instructions: loop.S count_instructions.c $(EXTRA_SOURCES) 13 13 $(CC) $(CFLAGS) -m64 -o $@ $^ 14 14 15 - run_tests: all 15 + run_tests: all sub_run_tests 16 16 @-for PROG in $(PROGS); do \ 17 17 ./$$PROG; \ 18 18 done; 19 19 20 - clean: 20 + clean: sub_clean 21 21 rm -f $(PROGS) loop.o 22 22 23 - .PHONY: all run_tests clean 23 + 24 + SUB_TARGETS = ebb 25 + 26 + sub_all: 27 + @for TARGET in $(SUB_TARGETS); do \ 28 + $(MAKE) -C $$TARGET all; \ 29 + done; 30 + 31 + sub_run_tests: all 32 + @for TARGET in $(SUB_TARGETS); do \ 33 + $(MAKE) -C $$TARGET run_tests; \ 34 + done; 35 + 36 + sub_clean: 37 + @for TARGET in $(SUB_TARGETS); do \ 38 + $(MAKE) -C $$TARGET clean; \ 39 + done; 40 + 41 + .PHONY: all run_tests clean sub_all sub_run_tests sub_clean
+32
tools/testing/selftests/powerpc/pmu/ebb/Makefile
··· 1 + noarg: 2 + $(MAKE) -C ../../ 3 + 4 + # The EBB handler is 64-bit code and everything links against it 5 + CFLAGS += -m64 6 + 7 + PROGS := reg_access_test event_attributes_test cycles_test \ 8 + cycles_with_freeze_test pmc56_overflow_test \ 9 + ebb_vs_cpu_event_test cpu_event_vs_ebb_test \ 10 + cpu_event_pinned_vs_ebb_test task_event_vs_ebb_test \ 11 + task_event_pinned_vs_ebb_test multi_ebb_procs_test \ 12 + multi_counter_test pmae_handling_test \ 13 + close_clears_pmcc_test instruction_count_test \ 14 + fork_cleanup_test ebb_on_child_test \ 15 + ebb_on_willing_child_test back_to_back_ebbs_test \ 16 + lost_exception_test no_handler_test 17 + 18 + all: $(PROGS) 19 + 20 + $(PROGS): ../../harness.c ../event.c ../lib.c ebb.c ebb_handler.S trace.c 21 + 22 + instruction_count_test: ../loop.S 23 + 24 + lost_exception_test: ../lib.c 25 + 26 + run_tests: all 27 + @-for PROG in $(PROGS); do \ 28 + ./$$PROG; \ 29 + done; 30 + 31 + clean: 32 + rm -f $(PROGS)
+106
tools/testing/selftests/powerpc/pmu/ebb/back_to_back_ebbs_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <stdbool.h> 7 + #include <stdio.h> 8 + #include <stdlib.h> 9 + 10 + #include "ebb.h" 11 + 12 + 13 + #define NUMBER_OF_EBBS 50 14 + 15 + /* 16 + * Test that if we overflow the counter while in the EBB handler, we take 17 + * another EBB on exiting from the handler. 18 + * 19 + * We do this by counting with a stupidly low sample period, causing us to 20 + * overflow the PMU while we're still in the EBB handler, leading to another 21 + * EBB. 22 + * 23 + * We get out of what would otherwise be an infinite loop by leaving the 24 + * counter frozen once we've taken enough EBBs. 25 + */ 26 + 27 + static void ebb_callee(void) 28 + { 29 + uint64_t siar, val; 30 + 31 + val = mfspr(SPRN_BESCR); 32 + if (!(val & BESCR_PMEO)) { 33 + ebb_state.stats.spurious++; 34 + goto out; 35 + } 36 + 37 + ebb_state.stats.ebb_count++; 38 + trace_log_counter(ebb_state.trace, ebb_state.stats.ebb_count); 39 + 40 + /* Resets the PMC */ 41 + count_pmc(1, sample_period); 42 + 43 + out: 44 + if (ebb_state.stats.ebb_count == NUMBER_OF_EBBS) 45 + /* Reset but leave counters frozen */ 46 + reset_ebb_with_clear_mask(MMCR0_PMAO); 47 + else 48 + /* Unfreezes */ 49 + reset_ebb(); 50 + 51 + /* Do some stuff to chew some cycles and pop the counter */ 52 + siar = mfspr(SPRN_SIAR); 53 + trace_log_reg(ebb_state.trace, SPRN_SIAR, siar); 54 + 55 + val = mfspr(SPRN_PMC1); 56 + trace_log_reg(ebb_state.trace, SPRN_PMC1, val); 57 + 58 + val = mfspr(SPRN_MMCR0); 59 + trace_log_reg(ebb_state.trace, SPRN_MMCR0, val); 60 + } 61 + 62 + int back_to_back_ebbs(void) 63 + { 64 + struct event event; 65 + 66 + event_init_named(&event, 0x1001e, "cycles"); 67 + event_leader_ebb_init(&event); 68 + 69 + event.attr.exclude_kernel = 1; 70 + event.attr.exclude_hv = 1; 71 + event.attr.exclude_idle = 1; 72 + 73 + FAIL_IF(event_open(&event)); 74 + 75 + setup_ebb_handler(ebb_callee); 76 + 77 + FAIL_IF(ebb_event_enable(&event)); 78 + 79 + sample_period = 5; 80 + 81 + ebb_freeze_pmcs(); 82 + mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); 83 + ebb_global_enable(); 84 + ebb_unfreeze_pmcs(); 85 + 86 + while (ebb_state.stats.ebb_count < NUMBER_OF_EBBS) 87 + FAIL_IF(core_busy_loop()); 88 + 89 + ebb_global_disable(); 90 + ebb_freeze_pmcs(); 91 + 92 + count_pmc(1, sample_period); 93 + 94 + dump_ebb_state(); 95 + 96 + event_close(&event); 97 + 98 + FAIL_IF(ebb_state.stats.ebb_count != NUMBER_OF_EBBS); 99 + 100 + return 0; 101 + } 102 + 103 + int main(void) 104 + { 105 + return test_harness(back_to_back_ebbs, "back_to_back_ebbs"); 106 + }
+59
tools/testing/selftests/powerpc/pmu/ebb/close_clears_pmcc_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + #include <setjmp.h> 9 + #include <signal.h> 10 + 11 + #include "ebb.h" 12 + 13 + 14 + /* 15 + * Test that closing the EBB event clears MMCR0_PMCC, preventing further access 16 + * by userspace to the PMU hardware. 17 + */ 18 + 19 + int close_clears_pmcc(void) 20 + { 21 + struct event event; 22 + 23 + event_init_named(&event, 0x1001e, "cycles"); 24 + event_leader_ebb_init(&event); 25 + 26 + FAIL_IF(event_open(&event)); 27 + 28 + ebb_enable_pmc_counting(1); 29 + setup_ebb_handler(standard_ebb_callee); 30 + ebb_global_enable(); 31 + FAIL_IF(ebb_event_enable(&event)); 32 + 33 + mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); 34 + 35 + while (ebb_state.stats.ebb_count < 1) 36 + FAIL_IF(core_busy_loop()); 37 + 38 + ebb_global_disable(); 39 + event_close(&event); 40 + 41 + FAIL_IF(ebb_state.stats.ebb_count == 0); 42 + 43 + /* The real test is here, do we take a SIGILL when writing PMU regs now 44 + * that we have closed the event. We expect that we will. */ 45 + 46 + FAIL_IF(catch_sigill(write_pmc1)); 47 + 48 + /* We should still be able to read EBB regs though */ 49 + mfspr(SPRN_EBBHR); 50 + mfspr(SPRN_EBBRR); 51 + mfspr(SPRN_BESCR); 52 + 53 + return 0; 54 + } 55 + 56 + int main(void) 57 + { 58 + return test_harness(close_clears_pmcc, "close_clears_pmcc"); 59 + }
+93
tools/testing/selftests/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <signal.h> 7 + #include <stdio.h> 8 + #include <stdlib.h> 9 + #include <stdbool.h> 10 + #include <sys/types.h> 11 + #include <sys/wait.h> 12 + #include <unistd.h> 13 + 14 + #include "ebb.h" 15 + 16 + 17 + /* 18 + * Tests a pinned cpu event vs an EBB - in that order. The pinned cpu event 19 + * should remain and the EBB event should fail to enable. 20 + */ 21 + 22 + static int setup_cpu_event(struct event *event, int cpu) 23 + { 24 + event_init_named(event, 0x400FA, "PM_RUN_INST_CMPL"); 25 + 26 + event->attr.pinned = 1; 27 + 28 + event->attr.exclude_kernel = 1; 29 + event->attr.exclude_hv = 1; 30 + event->attr.exclude_idle = 1; 31 + 32 + SKIP_IF(require_paranoia_below(1)); 33 + FAIL_IF(event_open_with_cpu(event, cpu)); 34 + FAIL_IF(event_enable(event)); 35 + 36 + return 0; 37 + } 38 + 39 + int cpu_event_pinned_vs_ebb(void) 40 + { 41 + union pipe read_pipe, write_pipe; 42 + struct event event; 43 + int cpu, rc; 44 + pid_t pid; 45 + 46 + cpu = pick_online_cpu(); 47 + FAIL_IF(cpu < 0); 48 + FAIL_IF(bind_to_cpu(cpu)); 49 + 50 + FAIL_IF(pipe(read_pipe.fds) == -1); 51 + FAIL_IF(pipe(write_pipe.fds) == -1); 52 + 53 + pid = fork(); 54 + if (pid == 0) { 55 + /* NB order of pipes looks reversed */ 56 + exit(ebb_child(write_pipe, read_pipe)); 57 + } 58 + 59 + /* We setup the cpu event first */ 60 + rc = setup_cpu_event(&event, cpu); 61 + if (rc) { 62 + kill_child_and_wait(pid); 63 + return rc; 64 + } 65 + 66 + /* Signal the child to install its EBB event and wait */ 67 + if (sync_with_child(read_pipe, write_pipe)) 68 + /* If it fails, wait for it to exit */ 69 + goto wait; 70 + 71 + /* Signal the child to run */ 72 + FAIL_IF(sync_with_child(read_pipe, write_pipe)); 73 + 74 + wait: 75 + /* We expect it to fail to read the event */ 76 + FAIL_IF(wait_for_child(pid) != 2); 77 + 78 + FAIL_IF(event_disable(&event)); 79 + FAIL_IF(event_read(&event)); 80 + 81 + event_report(&event); 82 + 83 + /* The cpu event should have run */ 84 + FAIL_IF(event.result.value == 0); 85 + FAIL_IF(event.result.enabled != event.result.running); 86 + 87 + return 0; 88 + } 89 + 90 + int main(void) 91 + { 92 + return test_harness(cpu_event_pinned_vs_ebb, "cpu_event_pinned_vs_ebb"); 93 + }
+89
tools/testing/selftests/powerpc/pmu/ebb/cpu_event_vs_ebb_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <signal.h> 7 + #include <stdio.h> 8 + #include <stdlib.h> 9 + #include <stdbool.h> 10 + #include <sys/types.h> 11 + #include <sys/wait.h> 12 + #include <unistd.h> 13 + 14 + #include "ebb.h" 15 + 16 + 17 + /* 18 + * Tests a cpu event vs an EBB - in that order. The EBB should force the cpu 19 + * event off the PMU. 20 + */ 21 + 22 + static int setup_cpu_event(struct event *event, int cpu) 23 + { 24 + event_init_named(event, 0x400FA, "PM_RUN_INST_CMPL"); 25 + 26 + event->attr.exclude_kernel = 1; 27 + event->attr.exclude_hv = 1; 28 + event->attr.exclude_idle = 1; 29 + 30 + SKIP_IF(require_paranoia_below(1)); 31 + FAIL_IF(event_open_with_cpu(event, cpu)); 32 + FAIL_IF(event_enable(event)); 33 + 34 + return 0; 35 + } 36 + 37 + int cpu_event_vs_ebb(void) 38 + { 39 + union pipe read_pipe, write_pipe; 40 + struct event event; 41 + int cpu, rc; 42 + pid_t pid; 43 + 44 + cpu = pick_online_cpu(); 45 + FAIL_IF(cpu < 0); 46 + FAIL_IF(bind_to_cpu(cpu)); 47 + 48 + FAIL_IF(pipe(read_pipe.fds) == -1); 49 + FAIL_IF(pipe(write_pipe.fds) == -1); 50 + 51 + pid = fork(); 52 + if (pid == 0) { 53 + /* NB order of pipes looks reversed */ 54 + exit(ebb_child(write_pipe, read_pipe)); 55 + } 56 + 57 + /* We setup the cpu event first */ 58 + rc = setup_cpu_event(&event, cpu); 59 + if (rc) { 60 + kill_child_and_wait(pid); 61 + return rc; 62 + } 63 + 64 + /* Signal the child to install its EBB event and wait */ 65 + if (sync_with_child(read_pipe, write_pipe)) 66 + /* If it fails, wait for it to exit */ 67 + goto wait; 68 + 69 + /* Signal the child to run */ 70 + FAIL_IF(sync_with_child(read_pipe, write_pipe)); 71 + 72 + wait: 73 + /* We expect the child to succeed */ 74 + FAIL_IF(wait_for_child(pid)); 75 + 76 + FAIL_IF(event_disable(&event)); 77 + FAIL_IF(event_read(&event)); 78 + 79 + event_report(&event); 80 + 81 + /* The cpu event may have run */ 82 + 83 + return 0; 84 + } 85 + 86 + int main(void) 87 + { 88 + return test_harness(cpu_event_vs_ebb, "cpu_event_vs_ebb"); 89 + }
+58
tools/testing/selftests/powerpc/pmu/ebb/cycles_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "ebb.h" 10 + 11 + 12 + /* 13 + * Basic test that counts user cycles and takes EBBs. 14 + */ 15 + int cycles(void) 16 + { 17 + struct event event; 18 + 19 + event_init_named(&event, 0x1001e, "cycles"); 20 + event_leader_ebb_init(&event); 21 + 22 + event.attr.exclude_kernel = 1; 23 + event.attr.exclude_hv = 1; 24 + event.attr.exclude_idle = 1; 25 + 26 + FAIL_IF(event_open(&event)); 27 + 28 + ebb_enable_pmc_counting(1); 29 + setup_ebb_handler(standard_ebb_callee); 30 + ebb_global_enable(); 31 + FAIL_IF(ebb_event_enable(&event)); 32 + 33 + mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); 34 + 35 + while (ebb_state.stats.ebb_count < 10) { 36 + FAIL_IF(core_busy_loop()); 37 + FAIL_IF(ebb_check_mmcr0()); 38 + } 39 + 40 + ebb_global_disable(); 41 + ebb_freeze_pmcs(); 42 + 43 + count_pmc(1, sample_period); 44 + 45 + dump_ebb_state(); 46 + 47 + event_close(&event); 48 + 49 + FAIL_IF(ebb_state.stats.ebb_count == 0); 50 + FAIL_IF(!ebb_check_count(1, sample_period, 100)); 51 + 52 + return 0; 53 + } 54 + 55 + int main(void) 56 + { 57 + return test_harness(cycles, "cycles"); 58 + }
+117
tools/testing/selftests/powerpc/pmu/ebb/cycles_with_freeze_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + #include <stdbool.h> 9 + 10 + #include "ebb.h" 11 + 12 + 13 + /* 14 + * Test of counting cycles while using MMCR0_FC (freeze counters) to only count 15 + * parts of the code. This is complicated by the fact that FC is set by the 16 + * hardware when the event overflows. We may take the EBB after we have set FC, 17 + * so we have to be careful about whether we clear FC at the end of the EBB 18 + * handler or not. 19 + */ 20 + 21 + static bool counters_frozen = false; 22 + static int ebbs_while_frozen = 0; 23 + 24 + static void ebb_callee(void) 25 + { 26 + uint64_t mask, val; 27 + 28 + mask = MMCR0_PMAO | MMCR0_FC; 29 + 30 + val = mfspr(SPRN_BESCR); 31 + if (!(val & BESCR_PMEO)) { 32 + ebb_state.stats.spurious++; 33 + goto out; 34 + } 35 + 36 + ebb_state.stats.ebb_count++; 37 + trace_log_counter(ebb_state.trace, ebb_state.stats.ebb_count); 38 + 39 + val = mfspr(SPRN_MMCR0); 40 + trace_log_reg(ebb_state.trace, SPRN_MMCR0, val); 41 + 42 + if (counters_frozen) { 43 + trace_log_string(ebb_state.trace, "frozen"); 44 + ebbs_while_frozen++; 45 + mask &= ~MMCR0_FC; 46 + } 47 + 48 + count_pmc(1, sample_period); 49 + out: 50 + reset_ebb_with_clear_mask(mask); 51 + } 52 + 53 + int cycles_with_freeze(void) 54 + { 55 + struct event event; 56 + uint64_t val; 57 + bool fc_cleared; 58 + 59 + event_init_named(&event, 0x1001e, "cycles"); 60 + event_leader_ebb_init(&event); 61 + 62 + event.attr.exclude_kernel = 1; 63 + event.attr.exclude_hv = 1; 64 + event.attr.exclude_idle = 1; 65 + 66 + FAIL_IF(event_open(&event)); 67 + 68 + setup_ebb_handler(ebb_callee); 69 + ebb_global_enable(); 70 + FAIL_IF(ebb_event_enable(&event)); 71 + 72 + mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); 73 + 74 + fc_cleared = false; 75 + 76 + /* Make sure we loop until we take at least one EBB */ 77 + while ((ebb_state.stats.ebb_count < 20 && !fc_cleared) || 78 + ebb_state.stats.ebb_count < 1) 79 + { 80 + counters_frozen = false; 81 + mb(); 82 + mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_FC); 83 + 84 + FAIL_IF(core_busy_loop()); 85 + 86 + counters_frozen = true; 87 + mb(); 88 + mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | MMCR0_FC); 89 + 90 + val = mfspr(SPRN_MMCR0); 91 + if (! (val & MMCR0_FC)) { 92 + printf("Outside of loop, FC NOT set MMCR0 0x%lx\n", val); 93 + fc_cleared = true; 94 + } 95 + } 96 + 97 + ebb_global_disable(); 98 + ebb_freeze_pmcs(); 99 + 100 + count_pmc(1, sample_period); 101 + 102 + dump_ebb_state(); 103 + 104 + printf("EBBs while frozen %d\n", ebbs_while_frozen); 105 + 106 + event_close(&event); 107 + 108 + FAIL_IF(ebb_state.stats.ebb_count == 0); 109 + FAIL_IF(fc_cleared); 110 + 111 + return 0; 112 + } 113 + 114 + int main(void) 115 + { 116 + return test_harness(cycles_with_freeze, "cycles_with_freeze"); 117 + }
+727
tools/testing/selftests/powerpc/pmu/ebb/ebb.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #define _GNU_SOURCE /* For CPU_ZERO etc. */ 7 + 8 + #include <sched.h> 9 + #include <sys/wait.h> 10 + #include <setjmp.h> 11 + #include <signal.h> 12 + #include <stdio.h> 13 + #include <stdlib.h> 14 + #include <string.h> 15 + #include <sys/ioctl.h> 16 + 17 + #include "trace.h" 18 + #include "reg.h" 19 + #include "ebb.h" 20 + 21 + 22 + void (*ebb_user_func)(void); 23 + 24 + void ebb_hook(void) 25 + { 26 + if (ebb_user_func) 27 + ebb_user_func(); 28 + } 29 + 30 + struct ebb_state ebb_state; 31 + 32 + u64 sample_period = 0x40000000ull; 33 + 34 + void reset_ebb_with_clear_mask(unsigned long mmcr0_clear_mask) 35 + { 36 + u64 val; 37 + 38 + /* 2) clear MMCR0[PMAO] - docs say BESCR[PMEO] should do this */ 39 + /* 3) set MMCR0[PMAE] - docs say BESCR[PME] should do this */ 40 + val = mfspr(SPRN_MMCR0); 41 + mtspr(SPRN_MMCR0, (val & ~mmcr0_clear_mask) | MMCR0_PMAE); 42 + 43 + /* 4) clear BESCR[PMEO] */ 44 + mtspr(SPRN_BESCRR, BESCR_PMEO); 45 + 46 + /* 5) set BESCR[PME] */ 47 + mtspr(SPRN_BESCRS, BESCR_PME); 48 + 49 + /* 6) rfebb 1 - done in our caller */ 50 + } 51 + 52 + void reset_ebb(void) 53 + { 54 + reset_ebb_with_clear_mask(MMCR0_PMAO | MMCR0_FC); 55 + } 56 + 57 + /* Called outside of the EBB handler to check MMCR0 is sane */ 58 + int ebb_check_mmcr0(void) 59 + { 60 + u64 val; 61 + 62 + val = mfspr(SPRN_MMCR0); 63 + if ((val & (MMCR0_FC | MMCR0_PMAO)) == MMCR0_FC) { 64 + /* It's OK if we see FC & PMAO, but not FC by itself */ 65 + printf("Outside of loop, only FC set 0x%llx\n", val); 66 + return 1; 67 + } 68 + 69 + return 0; 70 + } 71 + 72 + bool ebb_check_count(int pmc, u64 sample_period, int fudge) 73 + { 74 + u64 count, upper, lower; 75 + 76 + count = ebb_state.stats.pmc_count[PMC_INDEX(pmc)]; 77 + 78 + lower = ebb_state.stats.ebb_count * (sample_period - fudge); 79 + 80 + if (count < lower) { 81 + printf("PMC%d count (0x%llx) below lower limit 0x%llx (-0x%llx)\n", 82 + pmc, count, lower, lower - count); 83 + return false; 84 + } 85 + 86 + upper = ebb_state.stats.ebb_count * (sample_period + fudge); 87 + 88 + if (count > upper) { 89 + printf("PMC%d count (0x%llx) above upper limit 0x%llx (+0x%llx)\n", 90 + pmc, count, upper, count - upper); 91 + return false; 92 + } 93 + 94 + printf("PMC%d count (0x%llx) is between 0x%llx and 0x%llx delta +0x%llx/-0x%llx\n", 95 + pmc, count, lower, upper, count - lower, upper - count); 96 + 97 + return true; 98 + } 99 + 100 + void standard_ebb_callee(void) 101 + { 102 + int found, i; 103 + u64 val; 104 + 105 + val = mfspr(SPRN_BESCR); 106 + if (!(val & BESCR_PMEO)) { 107 + ebb_state.stats.spurious++; 108 + goto out; 109 + } 110 + 111 + ebb_state.stats.ebb_count++; 112 + trace_log_counter(ebb_state.trace, ebb_state.stats.ebb_count); 113 + 114 + val = mfspr(SPRN_MMCR0); 115 + trace_log_reg(ebb_state.trace, SPRN_MMCR0, val); 116 + 117 + found = 0; 118 + for (i = 1; i <= 6; i++) { 119 + if (ebb_state.pmc_enable[PMC_INDEX(i)]) 120 + found += count_pmc(i, sample_period); 121 + } 122 + 123 + if (!found) 124 + ebb_state.stats.no_overflow++; 125 + 126 + out: 127 + reset_ebb(); 128 + } 129 + 130 + extern void ebb_handler(void); 131 + 132 + void setup_ebb_handler(void (*callee)(void)) 133 + { 134 + u64 entry; 135 + 136 + #if defined(_CALL_ELF) && _CALL_ELF == 2 137 + entry = (u64)ebb_handler; 138 + #else 139 + struct opd 140 + { 141 + u64 entry; 142 + u64 toc; 143 + } *opd; 144 + 145 + opd = (struct opd *)ebb_handler; 146 + entry = opd->entry; 147 + #endif 148 + printf("EBB Handler is at %#llx\n", entry); 149 + 150 + ebb_user_func = callee; 151 + 152 + /* Ensure ebb_user_func is set before we set the handler */ 153 + mb(); 154 + mtspr(SPRN_EBBHR, entry); 155 + 156 + /* Make sure the handler is set before we return */ 157 + mb(); 158 + } 159 + 160 + void clear_ebb_stats(void) 161 + { 162 + memset(&ebb_state.stats, 0, sizeof(ebb_state.stats)); 163 + } 164 + 165 + void dump_summary_ebb_state(void) 166 + { 167 + printf("ebb_state:\n" \ 168 + " ebb_count = %d\n" \ 169 + " spurious = %d\n" \ 170 + " negative = %d\n" \ 171 + " no_overflow = %d\n" \ 172 + " pmc[1] count = 0x%llx\n" \ 173 + " pmc[2] count = 0x%llx\n" \ 174 + " pmc[3] count = 0x%llx\n" \ 175 + " pmc[4] count = 0x%llx\n" \ 176 + " pmc[5] count = 0x%llx\n" \ 177 + " pmc[6] count = 0x%llx\n", 178 + ebb_state.stats.ebb_count, ebb_state.stats.spurious, 179 + ebb_state.stats.negative, ebb_state.stats.no_overflow, 180 + ebb_state.stats.pmc_count[0], ebb_state.stats.pmc_count[1], 181 + ebb_state.stats.pmc_count[2], ebb_state.stats.pmc_count[3], 182 + ebb_state.stats.pmc_count[4], ebb_state.stats.pmc_count[5]); 183 + } 184 + 185 + static char *decode_mmcr0(u32 value) 186 + { 187 + static char buf[16]; 188 + 189 + buf[0] = '\0'; 190 + 191 + if (value & (1 << 31)) 192 + strcat(buf, "FC "); 193 + if (value & (1 << 26)) 194 + strcat(buf, "PMAE "); 195 + if (value & (1 << 7)) 196 + strcat(buf, "PMAO "); 197 + 198 + return buf; 199 + } 200 + 201 + static char *decode_bescr(u64 value) 202 + { 203 + static char buf[16]; 204 + 205 + buf[0] = '\0'; 206 + 207 + if (value & (1ull << 63)) 208 + strcat(buf, "GE "); 209 + if (value & (1ull << 32)) 210 + strcat(buf, "PMAE "); 211 + if (value & 1) 212 + strcat(buf, "PMAO "); 213 + 214 + return buf; 215 + } 216 + 217 + void dump_ebb_hw_state(void) 218 + { 219 + u64 bescr; 220 + u32 mmcr0; 221 + 222 + mmcr0 = mfspr(SPRN_MMCR0); 223 + bescr = mfspr(SPRN_BESCR); 224 + 225 + printf("HW state:\n" \ 226 + "MMCR0 0x%016x %s\n" \ 227 + "EBBHR 0x%016lx\n" \ 228 + "BESCR 0x%016llx %s\n" \ 229 + "PMC1 0x%016lx\n" \ 230 + "PMC2 0x%016lx\n" \ 231 + "PMC3 0x%016lx\n" \ 232 + "PMC4 0x%016lx\n" \ 233 + "PMC5 0x%016lx\n" \ 234 + "PMC6 0x%016lx\n" \ 235 + "SIAR 0x%016lx\n", 236 + mmcr0, decode_mmcr0(mmcr0), mfspr(SPRN_EBBHR), bescr, 237 + decode_bescr(bescr), mfspr(SPRN_PMC1), mfspr(SPRN_PMC2), 238 + mfspr(SPRN_PMC3), mfspr(SPRN_PMC4), mfspr(SPRN_PMC5), 239 + mfspr(SPRN_PMC6), mfspr(SPRN_SIAR)); 240 + } 241 + 242 + void dump_ebb_state(void) 243 + { 244 + dump_summary_ebb_state(); 245 + 246 + dump_ebb_hw_state(); 247 + 248 + trace_buffer_print(ebb_state.trace); 249 + } 250 + 251 + int count_pmc(int pmc, uint32_t sample_period) 252 + { 253 + uint32_t start_value; 254 + u64 val; 255 + 256 + /* 0) Read PMC */ 257 + start_value = pmc_sample_period(sample_period); 258 + 259 + val = read_pmc(pmc); 260 + if (val < start_value) 261 + ebb_state.stats.negative++; 262 + else 263 + ebb_state.stats.pmc_count[PMC_INDEX(pmc)] += val - start_value; 264 + 265 + trace_log_reg(ebb_state.trace, SPRN_PMC1 + pmc - 1, val); 266 + 267 + /* 1) Reset PMC */ 268 + write_pmc(pmc, start_value); 269 + 270 + /* Report if we overflowed */ 271 + return val >= COUNTER_OVERFLOW; 272 + } 273 + 274 + int ebb_event_enable(struct event *e) 275 + { 276 + int rc; 277 + 278 + /* Ensure any SPR writes are ordered vs us */ 279 + mb(); 280 + 281 + rc = ioctl(e->fd, PERF_EVENT_IOC_ENABLE); 282 + if (rc) 283 + return rc; 284 + 285 + rc = event_read(e); 286 + 287 + /* Ditto */ 288 + mb(); 289 + 290 + return rc; 291 + } 292 + 293 + void ebb_freeze_pmcs(void) 294 + { 295 + mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | MMCR0_FC); 296 + mb(); 297 + } 298 + 299 + void ebb_unfreeze_pmcs(void) 300 + { 301 + /* Unfreeze counters */ 302 + mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_FC); 303 + mb(); 304 + } 305 + 306 + void ebb_global_enable(void) 307 + { 308 + /* Enable EBBs globally and PMU EBBs */ 309 + mtspr(SPRN_BESCR, 0x8000000100000000ull); 310 + mb(); 311 + } 312 + 313 + void ebb_global_disable(void) 314 + { 315 + /* Disable EBBs & freeze counters, events are still scheduled */ 316 + mtspr(SPRN_BESCRR, BESCR_PME); 317 + mb(); 318 + } 319 + 320 + void event_ebb_init(struct event *e) 321 + { 322 + e->attr.config |= (1ull << 63); 323 + } 324 + 325 + void event_bhrb_init(struct event *e, unsigned ifm) 326 + { 327 + e->attr.config |= (1ull << 62) | ((u64)ifm << 60); 328 + } 329 + 330 + void event_leader_ebb_init(struct event *e) 331 + { 332 + event_ebb_init(e); 333 + 334 + e->attr.exclusive = 1; 335 + e->attr.pinned = 1; 336 + } 337 + 338 + int core_busy_loop(void) 339 + { 340 + int rc; 341 + 342 + asm volatile ( 343 + "li 3, 0x3030\n" 344 + "std 3, -96(1)\n" 345 + "li 4, 0x4040\n" 346 + "std 4, -104(1)\n" 347 + "li 5, 0x5050\n" 348 + "std 5, -112(1)\n" 349 + "li 6, 0x6060\n" 350 + "std 6, -120(1)\n" 351 + "li 7, 0x7070\n" 352 + "std 7, -128(1)\n" 353 + "li 8, 0x0808\n" 354 + "std 8, -136(1)\n" 355 + "li 9, 0x0909\n" 356 + "std 9, -144(1)\n" 357 + "li 10, 0x1010\n" 358 + "std 10, -152(1)\n" 359 + "li 11, 0x1111\n" 360 + "std 11, -160(1)\n" 361 + "li 14, 0x1414\n" 362 + "std 14, -168(1)\n" 363 + "li 15, 0x1515\n" 364 + "std 15, -176(1)\n" 365 + "li 16, 0x1616\n" 366 + "std 16, -184(1)\n" 367 + "li 17, 0x1717\n" 368 + "std 17, -192(1)\n" 369 + "li 18, 0x1818\n" 370 + "std 18, -200(1)\n" 371 + "li 19, 0x1919\n" 372 + "std 19, -208(1)\n" 373 + "li 20, 0x2020\n" 374 + "std 20, -216(1)\n" 375 + "li 21, 0x2121\n" 376 + "std 21, -224(1)\n" 377 + "li 22, 0x2222\n" 378 + "std 22, -232(1)\n" 379 + "li 23, 0x2323\n" 380 + "std 23, -240(1)\n" 381 + "li 24, 0x2424\n" 382 + "std 24, -248(1)\n" 383 + "li 25, 0x2525\n" 384 + "std 25, -256(1)\n" 385 + "li 26, 0x2626\n" 386 + "std 26, -264(1)\n" 387 + "li 27, 0x2727\n" 388 + "std 27, -272(1)\n" 389 + "li 28, 0x2828\n" 390 + "std 28, -280(1)\n" 391 + "li 29, 0x2929\n" 392 + "std 29, -288(1)\n" 393 + "li 30, 0x3030\n" 394 + "li 31, 0x3131\n" 395 + 396 + "li 3, 0\n" 397 + "0: " 398 + "addi 3, 3, 1\n" 399 + "cmpwi 3, 100\n" 400 + "blt 0b\n" 401 + 402 + /* Return 1 (fail) unless we get through all the checks */ 403 + "li 0, 1\n" 404 + 405 + /* Check none of our registers have been corrupted */ 406 + "cmpwi 4, 0x4040\n" 407 + "bne 1f\n" 408 + "cmpwi 5, 0x5050\n" 409 + "bne 1f\n" 410 + "cmpwi 6, 0x6060\n" 411 + "bne 1f\n" 412 + "cmpwi 7, 0x7070\n" 413 + "bne 1f\n" 414 + "cmpwi 8, 0x0808\n" 415 + "bne 1f\n" 416 + "cmpwi 9, 0x0909\n" 417 + "bne 1f\n" 418 + "cmpwi 10, 0x1010\n" 419 + "bne 1f\n" 420 + "cmpwi 11, 0x1111\n" 421 + "bne 1f\n" 422 + "cmpwi 14, 0x1414\n" 423 + "bne 1f\n" 424 + "cmpwi 15, 0x1515\n" 425 + "bne 1f\n" 426 + "cmpwi 16, 0x1616\n" 427 + "bne 1f\n" 428 + "cmpwi 17, 0x1717\n" 429 + "bne 1f\n" 430 + "cmpwi 18, 0x1818\n" 431 + "bne 1f\n" 432 + "cmpwi 19, 0x1919\n" 433 + "bne 1f\n" 434 + "cmpwi 20, 0x2020\n" 435 + "bne 1f\n" 436 + "cmpwi 21, 0x2121\n" 437 + "bne 1f\n" 438 + "cmpwi 22, 0x2222\n" 439 + "bne 1f\n" 440 + "cmpwi 23, 0x2323\n" 441 + "bne 1f\n" 442 + "cmpwi 24, 0x2424\n" 443 + "bne 1f\n" 444 + "cmpwi 25, 0x2525\n" 445 + "bne 1f\n" 446 + "cmpwi 26, 0x2626\n" 447 + "bne 1f\n" 448 + "cmpwi 27, 0x2727\n" 449 + "bne 1f\n" 450 + "cmpwi 28, 0x2828\n" 451 + "bne 1f\n" 452 + "cmpwi 29, 0x2929\n" 453 + "bne 1f\n" 454 + "cmpwi 30, 0x3030\n" 455 + "bne 1f\n" 456 + "cmpwi 31, 0x3131\n" 457 + "bne 1f\n" 458 + 459 + /* Load junk into all our registers before we reload them from the stack. */ 460 + "li 3, 0xde\n" 461 + "li 4, 0xad\n" 462 + "li 5, 0xbe\n" 463 + "li 6, 0xef\n" 464 + "li 7, 0xde\n" 465 + "li 8, 0xad\n" 466 + "li 9, 0xbe\n" 467 + "li 10, 0xef\n" 468 + "li 11, 0xde\n" 469 + "li 14, 0xad\n" 470 + "li 15, 0xbe\n" 471 + "li 16, 0xef\n" 472 + "li 17, 0xde\n" 473 + "li 18, 0xad\n" 474 + "li 19, 0xbe\n" 475 + "li 20, 0xef\n" 476 + "li 21, 0xde\n" 477 + "li 22, 0xad\n" 478 + "li 23, 0xbe\n" 479 + "li 24, 0xef\n" 480 + "li 25, 0xde\n" 481 + "li 26, 0xad\n" 482 + "li 27, 0xbe\n" 483 + "li 28, 0xef\n" 484 + "li 29, 0xdd\n" 485 + 486 + "ld 3, -96(1)\n" 487 + "cmpwi 3, 0x3030\n" 488 + "bne 1f\n" 489 + "ld 4, -104(1)\n" 490 + "cmpwi 4, 0x4040\n" 491 + "bne 1f\n" 492 + "ld 5, -112(1)\n" 493 + "cmpwi 5, 0x5050\n" 494 + "bne 1f\n" 495 + "ld 6, -120(1)\n" 496 + "cmpwi 6, 0x6060\n" 497 + "bne 1f\n" 498 + "ld 7, -128(1)\n" 499 + "cmpwi 7, 0x7070\n" 500 + "bne 1f\n" 501 + "ld 8, -136(1)\n" 502 + "cmpwi 8, 0x0808\n" 503 + "bne 1f\n" 504 + "ld 9, -144(1)\n" 505 + "cmpwi 9, 0x0909\n" 506 + "bne 1f\n" 507 + "ld 10, -152(1)\n" 508 + "cmpwi 10, 0x1010\n" 509 + "bne 1f\n" 510 + "ld 11, -160(1)\n" 511 + "cmpwi 11, 0x1111\n" 512 + "bne 1f\n" 513 + "ld 14, -168(1)\n" 514 + "cmpwi 14, 0x1414\n" 515 + "bne 1f\n" 516 + "ld 15, -176(1)\n" 517 + "cmpwi 15, 0x1515\n" 518 + "bne 1f\n" 519 + "ld 16, -184(1)\n" 520 + "cmpwi 16, 0x1616\n" 521 + "bne 1f\n" 522 + "ld 17, -192(1)\n" 523 + "cmpwi 17, 0x1717\n" 524 + "bne 1f\n" 525 + "ld 18, -200(1)\n" 526 + "cmpwi 18, 0x1818\n" 527 + "bne 1f\n" 528 + "ld 19, -208(1)\n" 529 + "cmpwi 19, 0x1919\n" 530 + "bne 1f\n" 531 + "ld 20, -216(1)\n" 532 + "cmpwi 20, 0x2020\n" 533 + "bne 1f\n" 534 + "ld 21, -224(1)\n" 535 + "cmpwi 21, 0x2121\n" 536 + "bne 1f\n" 537 + "ld 22, -232(1)\n" 538 + "cmpwi 22, 0x2222\n" 539 + "bne 1f\n" 540 + "ld 23, -240(1)\n" 541 + "cmpwi 23, 0x2323\n" 542 + "bne 1f\n" 543 + "ld 24, -248(1)\n" 544 + "cmpwi 24, 0x2424\n" 545 + "bne 1f\n" 546 + "ld 25, -256(1)\n" 547 + "cmpwi 25, 0x2525\n" 548 + "bne 1f\n" 549 + "ld 26, -264(1)\n" 550 + "cmpwi 26, 0x2626\n" 551 + "bne 1f\n" 552 + "ld 27, -272(1)\n" 553 + "cmpwi 27, 0x2727\n" 554 + "bne 1f\n" 555 + "ld 28, -280(1)\n" 556 + "cmpwi 28, 0x2828\n" 557 + "bne 1f\n" 558 + "ld 29, -288(1)\n" 559 + "cmpwi 29, 0x2929\n" 560 + "bne 1f\n" 561 + 562 + /* Load 0 (success) to return */ 563 + "li 0, 0\n" 564 + 565 + "1: mr %0, 0\n" 566 + 567 + : "=r" (rc) 568 + : /* no inputs */ 569 + : "3", "4", "5", "6", "7", "8", "9", "10", "11", "14", 570 + "15", "16", "17", "18", "19", "20", "21", "22", "23", 571 + "24", "25", "26", "27", "28", "29", "30", "31", 572 + "memory" 573 + ); 574 + 575 + return rc; 576 + } 577 + 578 + int core_busy_loop_with_freeze(void) 579 + { 580 + int rc; 581 + 582 + mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_FC); 583 + rc = core_busy_loop(); 584 + mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | MMCR0_FC); 585 + 586 + return rc; 587 + } 588 + 589 + int ebb_child(union pipe read_pipe, union pipe write_pipe) 590 + { 591 + struct event event; 592 + uint64_t val; 593 + 594 + FAIL_IF(wait_for_parent(read_pipe)); 595 + 596 + event_init_named(&event, 0x1001e, "cycles"); 597 + event_leader_ebb_init(&event); 598 + 599 + event.attr.exclude_kernel = 1; 600 + event.attr.exclude_hv = 1; 601 + event.attr.exclude_idle = 1; 602 + 603 + FAIL_IF(event_open(&event)); 604 + 605 + ebb_enable_pmc_counting(1); 606 + setup_ebb_handler(standard_ebb_callee); 607 + ebb_global_enable(); 608 + 609 + FAIL_IF(event_enable(&event)); 610 + 611 + if (event_read(&event)) { 612 + /* 613 + * Some tests expect to fail here, so don't report an error on 614 + * this line, and return a distinguisable error code. Tell the 615 + * parent an error happened. 616 + */ 617 + notify_parent_of_error(write_pipe); 618 + return 2; 619 + } 620 + 621 + mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); 622 + 623 + FAIL_IF(notify_parent(write_pipe)); 624 + FAIL_IF(wait_for_parent(read_pipe)); 625 + FAIL_IF(notify_parent(write_pipe)); 626 + 627 + while (ebb_state.stats.ebb_count < 20) { 628 + FAIL_IF(core_busy_loop()); 629 + 630 + /* To try and hit SIGILL case */ 631 + val = mfspr(SPRN_MMCRA); 632 + val |= mfspr(SPRN_MMCR2); 633 + val |= mfspr(SPRN_MMCR0); 634 + } 635 + 636 + ebb_global_disable(); 637 + ebb_freeze_pmcs(); 638 + 639 + count_pmc(1, sample_period); 640 + 641 + dump_ebb_state(); 642 + 643 + event_close(&event); 644 + 645 + FAIL_IF(ebb_state.stats.ebb_count == 0); 646 + 647 + return 0; 648 + } 649 + 650 + static jmp_buf setjmp_env; 651 + 652 + static void sigill_handler(int signal) 653 + { 654 + printf("Took sigill\n"); 655 + longjmp(setjmp_env, 1); 656 + } 657 + 658 + static struct sigaction sigill_action = { 659 + .sa_handler = sigill_handler, 660 + }; 661 + 662 + int catch_sigill(void (*func)(void)) 663 + { 664 + if (sigaction(SIGILL, &sigill_action, NULL)) { 665 + perror("sigaction"); 666 + return 1; 667 + } 668 + 669 + if (setjmp(setjmp_env) == 0) { 670 + func(); 671 + return 1; 672 + } 673 + 674 + return 0; 675 + } 676 + 677 + void write_pmc1(void) 678 + { 679 + mtspr(SPRN_PMC1, 0); 680 + } 681 + 682 + void write_pmc(int pmc, u64 value) 683 + { 684 + switch (pmc) { 685 + case 1: mtspr(SPRN_PMC1, value); break; 686 + case 2: mtspr(SPRN_PMC2, value); break; 687 + case 3: mtspr(SPRN_PMC3, value); break; 688 + case 4: mtspr(SPRN_PMC4, value); break; 689 + case 5: mtspr(SPRN_PMC5, value); break; 690 + case 6: mtspr(SPRN_PMC6, value); break; 691 + } 692 + } 693 + 694 + u64 read_pmc(int pmc) 695 + { 696 + switch (pmc) { 697 + case 1: return mfspr(SPRN_PMC1); 698 + case 2: return mfspr(SPRN_PMC2); 699 + case 3: return mfspr(SPRN_PMC3); 700 + case 4: return mfspr(SPRN_PMC4); 701 + case 5: return mfspr(SPRN_PMC5); 702 + case 6: return mfspr(SPRN_PMC6); 703 + } 704 + 705 + return 0; 706 + } 707 + 708 + static void term_handler(int signal) 709 + { 710 + dump_summary_ebb_state(); 711 + dump_ebb_hw_state(); 712 + abort(); 713 + } 714 + 715 + struct sigaction term_action = { 716 + .sa_handler = term_handler, 717 + }; 718 + 719 + static void __attribute__((constructor)) ebb_init(void) 720 + { 721 + clear_ebb_stats(); 722 + 723 + if (sigaction(SIGTERM, &term_action, NULL)) 724 + perror("sigaction"); 725 + 726 + ebb_state.trace = trace_buffer_allocate(1 * 1024 * 1024); 727 + }
+78
tools/testing/selftests/powerpc/pmu/ebb/ebb.h
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #ifndef _SELFTESTS_POWERPC_PMU_EBB_EBB_H 7 + #define _SELFTESTS_POWERPC_PMU_EBB_EBB_H 8 + 9 + #include "../event.h" 10 + #include "../lib.h" 11 + #include "trace.h" 12 + #include "reg.h" 13 + 14 + #define PMC_INDEX(pmc) ((pmc)-1) 15 + 16 + #define NUM_PMC_VALUES 128 17 + 18 + struct ebb_state 19 + { 20 + struct { 21 + u64 pmc_count[6]; 22 + volatile int ebb_count; 23 + int spurious; 24 + int negative; 25 + int no_overflow; 26 + } stats; 27 + 28 + bool pmc_enable[6]; 29 + struct trace_buffer *trace; 30 + }; 31 + 32 + extern struct ebb_state ebb_state; 33 + 34 + #define COUNTER_OVERFLOW 0x80000000ull 35 + 36 + static inline uint32_t pmc_sample_period(uint32_t value) 37 + { 38 + return COUNTER_OVERFLOW - value; 39 + } 40 + 41 + static inline void ebb_enable_pmc_counting(int pmc) 42 + { 43 + ebb_state.pmc_enable[PMC_INDEX(pmc)] = true; 44 + } 45 + 46 + bool ebb_check_count(int pmc, u64 sample_period, int fudge); 47 + void event_leader_ebb_init(struct event *e); 48 + void event_ebb_init(struct event *e); 49 + void event_bhrb_init(struct event *e, unsigned ifm); 50 + void setup_ebb_handler(void (*callee)(void)); 51 + void standard_ebb_callee(void); 52 + int ebb_event_enable(struct event *e); 53 + void ebb_global_enable(void); 54 + void ebb_global_disable(void); 55 + void ebb_freeze_pmcs(void); 56 + void ebb_unfreeze_pmcs(void); 57 + void event_ebb_init(struct event *e); 58 + void event_leader_ebb_init(struct event *e); 59 + int count_pmc(int pmc, uint32_t sample_period); 60 + void dump_ebb_state(void); 61 + void dump_summary_ebb_state(void); 62 + void dump_ebb_hw_state(void); 63 + void clear_ebb_stats(void); 64 + void write_pmc(int pmc, u64 value); 65 + u64 read_pmc(int pmc); 66 + void reset_ebb_with_clear_mask(unsigned long mmcr0_clear_mask); 67 + void reset_ebb(void); 68 + int ebb_check_mmcr0(void); 69 + 70 + extern u64 sample_period; 71 + 72 + int core_busy_loop(void); 73 + int core_busy_loop_with_freeze(void); 74 + int ebb_child(union pipe read_pipe, union pipe write_pipe); 75 + int catch_sigill(void (*func)(void)); 76 + void write_pmc1(void); 77 + 78 + #endif /* _SELFTESTS_POWERPC_PMU_EBB_EBB_H */
+365
tools/testing/selftests/powerpc/pmu/ebb/ebb_handler.S
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <ppc-asm.h> 7 + #include "reg.h" 8 + 9 + 10 + /* ppc-asm.h defines most of the reg aliases, but not r1/r2. */ 11 + #define r1 1 12 + #define r2 2 13 + 14 + #define RFEBB .long 0x4c000924 15 + 16 + /* Stack layout: 17 + * 18 + * ^ 19 + * User stack | 20 + * Back chain ------+ <- r1 <-------+ 21 + * ... | 22 + * Red zone / ABI Gap | 23 + * ... | 24 + * vr63 <+ | 25 + * vr0 | | 26 + * VSCR | | 27 + * FSCR | | 28 + * r31 | Save area | 29 + * r0 | | 30 + * XER | | 31 + * CTR | | 32 + * LR | | 33 + * CCR <+ | 34 + * ... <+ | 35 + * LR | Caller frame | 36 + * CCR | | 37 + * Back chain <+ <- updated r1 --------+ 38 + * 39 + */ 40 + 41 + #if defined(_CALL_ELF) && _CALL_ELF == 2 42 + #define ABIGAP 512 43 + #else 44 + #define ABIGAP 288 45 + #endif 46 + 47 + #define NR_GPR 32 48 + #define NR_SPR 6 49 + #define NR_VSR 64 50 + 51 + #define SAVE_AREA ((NR_GPR + NR_SPR) * 8 + (NR_VSR * 16)) 52 + #define CALLER_FRAME 112 53 + 54 + #define STACK_FRAME (ABIGAP + SAVE_AREA + CALLER_FRAME) 55 + 56 + #define CCR_SAVE (CALLER_FRAME) 57 + #define LR_SAVE (CCR_SAVE + 8) 58 + #define CTR_SAVE (LR_SAVE + 8) 59 + #define XER_SAVE (CTR_SAVE + 8) 60 + #define GPR_SAVE(n) (XER_SAVE + 8 + (8 * n)) 61 + #define FSCR_SAVE (GPR_SAVE(31) + 8) 62 + #define VSCR_SAVE (FSCR_SAVE + 8) 63 + #define VSR_SAVE(n) (VSCR_SAVE + 8 + (16 * n)) 64 + 65 + #define SAVE_GPR(n) std n,GPR_SAVE(n)(r1) 66 + #define REST_GPR(n) ld n,GPR_SAVE(n)(r1) 67 + #define TRASH_GPR(n) lis n,0xaaaa 68 + 69 + #define SAVE_VSR(n, b) li b, VSR_SAVE(n); stxvd2x n,b,r1 70 + #define LOAD_VSR(n, b) li b, VSR_SAVE(n); lxvd2x n,b,r1 71 + 72 + #define LOAD_REG_IMMEDIATE(reg,expr) \ 73 + lis reg,(expr)@highest; \ 74 + ori reg,reg,(expr)@higher; \ 75 + rldicr reg,reg,32,31; \ 76 + oris reg,reg,(expr)@h; \ 77 + ori reg,reg,(expr)@l; 78 + 79 + 80 + #if defined(_CALL_ELF) && _CALL_ELF == 2 81 + #define ENTRY_POINT(name) \ 82 + .type FUNC_NAME(name),@function; \ 83 + .globl FUNC_NAME(name); \ 84 + FUNC_NAME(name): 85 + 86 + #define RESTORE_TOC(name) \ 87 + /* Restore our TOC pointer using our entry point */ \ 88 + LOAD_REG_IMMEDIATE(r12, name) \ 89 + 0: addis r2,r12,(.TOC.-0b)@ha; \ 90 + addi r2,r2,(.TOC.-0b)@l; 91 + 92 + #else 93 + #define ENTRY_POINT(name) FUNC_START(name) 94 + #define RESTORE_TOC(name) \ 95 + /* Restore our TOC pointer via our opd entry */ \ 96 + LOAD_REG_IMMEDIATE(r2, name) \ 97 + ld r2,8(r2); 98 + #endif 99 + 100 + .text 101 + 102 + ENTRY_POINT(ebb_handler) 103 + stdu r1,-STACK_FRAME(r1) 104 + SAVE_GPR(0) 105 + mflr r0 106 + std r0,LR_SAVE(r1) 107 + mfcr r0 108 + std r0,CCR_SAVE(r1) 109 + mfctr r0 110 + std r0,CTR_SAVE(r1) 111 + mfxer r0 112 + std r0,XER_SAVE(r1) 113 + SAVE_GPR(2) 114 + SAVE_GPR(3) 115 + SAVE_GPR(4) 116 + SAVE_GPR(5) 117 + SAVE_GPR(6) 118 + SAVE_GPR(7) 119 + SAVE_GPR(8) 120 + SAVE_GPR(9) 121 + SAVE_GPR(10) 122 + SAVE_GPR(11) 123 + SAVE_GPR(12) 124 + SAVE_GPR(13) 125 + SAVE_GPR(14) 126 + SAVE_GPR(15) 127 + SAVE_GPR(16) 128 + SAVE_GPR(17) 129 + SAVE_GPR(18) 130 + SAVE_GPR(19) 131 + SAVE_GPR(20) 132 + SAVE_GPR(21) 133 + SAVE_GPR(22) 134 + SAVE_GPR(23) 135 + SAVE_GPR(24) 136 + SAVE_GPR(25) 137 + SAVE_GPR(26) 138 + SAVE_GPR(27) 139 + SAVE_GPR(28) 140 + SAVE_GPR(29) 141 + SAVE_GPR(30) 142 + SAVE_GPR(31) 143 + SAVE_VSR(0, r3) 144 + mffs f0 145 + stfd f0, FSCR_SAVE(r1) 146 + mfvscr f0 147 + stfd f0, VSCR_SAVE(r1) 148 + SAVE_VSR(1, r3) 149 + SAVE_VSR(2, r3) 150 + SAVE_VSR(3, r3) 151 + SAVE_VSR(4, r3) 152 + SAVE_VSR(5, r3) 153 + SAVE_VSR(6, r3) 154 + SAVE_VSR(7, r3) 155 + SAVE_VSR(8, r3) 156 + SAVE_VSR(9, r3) 157 + SAVE_VSR(10, r3) 158 + SAVE_VSR(11, r3) 159 + SAVE_VSR(12, r3) 160 + SAVE_VSR(13, r3) 161 + SAVE_VSR(14, r3) 162 + SAVE_VSR(15, r3) 163 + SAVE_VSR(16, r3) 164 + SAVE_VSR(17, r3) 165 + SAVE_VSR(18, r3) 166 + SAVE_VSR(19, r3) 167 + SAVE_VSR(20, r3) 168 + SAVE_VSR(21, r3) 169 + SAVE_VSR(22, r3) 170 + SAVE_VSR(23, r3) 171 + SAVE_VSR(24, r3) 172 + SAVE_VSR(25, r3) 173 + SAVE_VSR(26, r3) 174 + SAVE_VSR(27, r3) 175 + SAVE_VSR(28, r3) 176 + SAVE_VSR(29, r3) 177 + SAVE_VSR(30, r3) 178 + SAVE_VSR(31, r3) 179 + SAVE_VSR(32, r3) 180 + SAVE_VSR(33, r3) 181 + SAVE_VSR(34, r3) 182 + SAVE_VSR(35, r3) 183 + SAVE_VSR(36, r3) 184 + SAVE_VSR(37, r3) 185 + SAVE_VSR(38, r3) 186 + SAVE_VSR(39, r3) 187 + SAVE_VSR(40, r3) 188 + SAVE_VSR(41, r3) 189 + SAVE_VSR(42, r3) 190 + SAVE_VSR(43, r3) 191 + SAVE_VSR(44, r3) 192 + SAVE_VSR(45, r3) 193 + SAVE_VSR(46, r3) 194 + SAVE_VSR(47, r3) 195 + SAVE_VSR(48, r3) 196 + SAVE_VSR(49, r3) 197 + SAVE_VSR(50, r3) 198 + SAVE_VSR(51, r3) 199 + SAVE_VSR(52, r3) 200 + SAVE_VSR(53, r3) 201 + SAVE_VSR(54, r3) 202 + SAVE_VSR(55, r3) 203 + SAVE_VSR(56, r3) 204 + SAVE_VSR(57, r3) 205 + SAVE_VSR(58, r3) 206 + SAVE_VSR(59, r3) 207 + SAVE_VSR(60, r3) 208 + SAVE_VSR(61, r3) 209 + SAVE_VSR(62, r3) 210 + SAVE_VSR(63, r3) 211 + 212 + TRASH_GPR(2) 213 + TRASH_GPR(3) 214 + TRASH_GPR(4) 215 + TRASH_GPR(5) 216 + TRASH_GPR(6) 217 + TRASH_GPR(7) 218 + TRASH_GPR(8) 219 + TRASH_GPR(9) 220 + TRASH_GPR(10) 221 + TRASH_GPR(11) 222 + TRASH_GPR(12) 223 + TRASH_GPR(14) 224 + TRASH_GPR(15) 225 + TRASH_GPR(16) 226 + TRASH_GPR(17) 227 + TRASH_GPR(18) 228 + TRASH_GPR(19) 229 + TRASH_GPR(20) 230 + TRASH_GPR(21) 231 + TRASH_GPR(22) 232 + TRASH_GPR(23) 233 + TRASH_GPR(24) 234 + TRASH_GPR(25) 235 + TRASH_GPR(26) 236 + TRASH_GPR(27) 237 + TRASH_GPR(28) 238 + TRASH_GPR(29) 239 + TRASH_GPR(30) 240 + TRASH_GPR(31) 241 + 242 + RESTORE_TOC(ebb_handler) 243 + 244 + /* 245 + * r13 is our TLS pointer. We leave whatever value was in there when the 246 + * EBB fired. That seems to be OK because once set the TLS pointer is not 247 + * changed - but presumably that could change in future. 248 + */ 249 + 250 + bl ebb_hook 251 + nop 252 + 253 + /* r2 may be changed here but we don't care */ 254 + 255 + lfd f0, FSCR_SAVE(r1) 256 + mtfsf 0xff,f0 257 + lfd f0, VSCR_SAVE(r1) 258 + mtvscr f0 259 + LOAD_VSR(0, r3) 260 + LOAD_VSR(1, r3) 261 + LOAD_VSR(2, r3) 262 + LOAD_VSR(3, r3) 263 + LOAD_VSR(4, r3) 264 + LOAD_VSR(5, r3) 265 + LOAD_VSR(6, r3) 266 + LOAD_VSR(7, r3) 267 + LOAD_VSR(8, r3) 268 + LOAD_VSR(9, r3) 269 + LOAD_VSR(10, r3) 270 + LOAD_VSR(11, r3) 271 + LOAD_VSR(12, r3) 272 + LOAD_VSR(13, r3) 273 + LOAD_VSR(14, r3) 274 + LOAD_VSR(15, r3) 275 + LOAD_VSR(16, r3) 276 + LOAD_VSR(17, r3) 277 + LOAD_VSR(18, r3) 278 + LOAD_VSR(19, r3) 279 + LOAD_VSR(20, r3) 280 + LOAD_VSR(21, r3) 281 + LOAD_VSR(22, r3) 282 + LOAD_VSR(23, r3) 283 + LOAD_VSR(24, r3) 284 + LOAD_VSR(25, r3) 285 + LOAD_VSR(26, r3) 286 + LOAD_VSR(27, r3) 287 + LOAD_VSR(28, r3) 288 + LOAD_VSR(29, r3) 289 + LOAD_VSR(30, r3) 290 + LOAD_VSR(31, r3) 291 + LOAD_VSR(32, r3) 292 + LOAD_VSR(33, r3) 293 + LOAD_VSR(34, r3) 294 + LOAD_VSR(35, r3) 295 + LOAD_VSR(36, r3) 296 + LOAD_VSR(37, r3) 297 + LOAD_VSR(38, r3) 298 + LOAD_VSR(39, r3) 299 + LOAD_VSR(40, r3) 300 + LOAD_VSR(41, r3) 301 + LOAD_VSR(42, r3) 302 + LOAD_VSR(43, r3) 303 + LOAD_VSR(44, r3) 304 + LOAD_VSR(45, r3) 305 + LOAD_VSR(46, r3) 306 + LOAD_VSR(47, r3) 307 + LOAD_VSR(48, r3) 308 + LOAD_VSR(49, r3) 309 + LOAD_VSR(50, r3) 310 + LOAD_VSR(51, r3) 311 + LOAD_VSR(52, r3) 312 + LOAD_VSR(53, r3) 313 + LOAD_VSR(54, r3) 314 + LOAD_VSR(55, r3) 315 + LOAD_VSR(56, r3) 316 + LOAD_VSR(57, r3) 317 + LOAD_VSR(58, r3) 318 + LOAD_VSR(59, r3) 319 + LOAD_VSR(60, r3) 320 + LOAD_VSR(61, r3) 321 + LOAD_VSR(62, r3) 322 + LOAD_VSR(63, r3) 323 + 324 + ld r0,XER_SAVE(r1) 325 + mtxer r0 326 + ld r0,CTR_SAVE(r1) 327 + mtctr r0 328 + ld r0,LR_SAVE(r1) 329 + mtlr r0 330 + ld r0,CCR_SAVE(r1) 331 + mtcr r0 332 + REST_GPR(0) 333 + REST_GPR(2) 334 + REST_GPR(3) 335 + REST_GPR(4) 336 + REST_GPR(5) 337 + REST_GPR(6) 338 + REST_GPR(7) 339 + REST_GPR(8) 340 + REST_GPR(9) 341 + REST_GPR(10) 342 + REST_GPR(11) 343 + REST_GPR(12) 344 + REST_GPR(13) 345 + REST_GPR(14) 346 + REST_GPR(15) 347 + REST_GPR(16) 348 + REST_GPR(17) 349 + REST_GPR(18) 350 + REST_GPR(19) 351 + REST_GPR(20) 352 + REST_GPR(21) 353 + REST_GPR(22) 354 + REST_GPR(23) 355 + REST_GPR(24) 356 + REST_GPR(25) 357 + REST_GPR(26) 358 + REST_GPR(27) 359 + REST_GPR(28) 360 + REST_GPR(29) 361 + REST_GPR(30) 362 + REST_GPR(31) 363 + addi r1,r1,STACK_FRAME 364 + RFEBB 365 + FUNC_END(ebb_handler)
+86
tools/testing/selftests/powerpc/pmu/ebb/ebb_on_child_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <signal.h> 7 + #include <stdio.h> 8 + #include <stdlib.h> 9 + #include <stdbool.h> 10 + #include <sys/types.h> 11 + #include <sys/wait.h> 12 + #include <unistd.h> 13 + 14 + #include "ebb.h" 15 + 16 + 17 + /* 18 + * Tests we can setup an EBB on our child. Nothing interesting happens, because 19 + * even though the event is enabled and running the child hasn't enabled the 20 + * actual delivery of the EBBs. 21 + */ 22 + 23 + static int victim_child(union pipe read_pipe, union pipe write_pipe) 24 + { 25 + int i; 26 + 27 + FAIL_IF(wait_for_parent(read_pipe)); 28 + FAIL_IF(notify_parent(write_pipe)); 29 + 30 + /* Parent creates EBB event */ 31 + 32 + FAIL_IF(wait_for_parent(read_pipe)); 33 + FAIL_IF(notify_parent(write_pipe)); 34 + 35 + /* Check the EBB is enabled by writing PMC1 */ 36 + write_pmc1(); 37 + 38 + /* EBB event is enabled here */ 39 + for (i = 0; i < 1000000; i++) ; 40 + 41 + return 0; 42 + } 43 + 44 + int ebb_on_child(void) 45 + { 46 + union pipe read_pipe, write_pipe; 47 + struct event event; 48 + pid_t pid; 49 + 50 + FAIL_IF(pipe(read_pipe.fds) == -1); 51 + FAIL_IF(pipe(write_pipe.fds) == -1); 52 + 53 + pid = fork(); 54 + if (pid == 0) { 55 + /* NB order of pipes looks reversed */ 56 + exit(victim_child(write_pipe, read_pipe)); 57 + } 58 + 59 + FAIL_IF(sync_with_child(read_pipe, write_pipe)); 60 + 61 + /* Child is running now */ 62 + 63 + event_init_named(&event, 0x1001e, "cycles"); 64 + event_leader_ebb_init(&event); 65 + 66 + event.attr.exclude_kernel = 1; 67 + event.attr.exclude_hv = 1; 68 + event.attr.exclude_idle = 1; 69 + 70 + FAIL_IF(event_open_with_pid(&event, pid)); 71 + FAIL_IF(ebb_event_enable(&event)); 72 + 73 + FAIL_IF(sync_with_child(read_pipe, write_pipe)); 74 + 75 + /* Child should just exit happily */ 76 + FAIL_IF(wait_for_child(pid)); 77 + 78 + event_close(&event); 79 + 80 + return 0; 81 + } 82 + 83 + int main(void) 84 + { 85 + return test_harness(ebb_on_child, "ebb_on_child"); 86 + }
+92
tools/testing/selftests/powerpc/pmu/ebb/ebb_on_willing_child_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <signal.h> 7 + #include <stdio.h> 8 + #include <stdlib.h> 9 + #include <stdbool.h> 10 + #include <sys/types.h> 11 + #include <sys/wait.h> 12 + #include <unistd.h> 13 + 14 + #include "ebb.h" 15 + 16 + 17 + /* 18 + * Tests we can setup an EBB on our child. The child expects this and enables 19 + * EBBs, which are then delivered to the child, even though the event is 20 + * created by the parent. 21 + */ 22 + 23 + static int victim_child(union pipe read_pipe, union pipe write_pipe) 24 + { 25 + FAIL_IF(wait_for_parent(read_pipe)); 26 + 27 + /* Setup our EBB handler, before the EBB event is created */ 28 + ebb_enable_pmc_counting(1); 29 + setup_ebb_handler(standard_ebb_callee); 30 + ebb_global_enable(); 31 + 32 + FAIL_IF(notify_parent(write_pipe)); 33 + 34 + while (ebb_state.stats.ebb_count < 20) { 35 + FAIL_IF(core_busy_loop()); 36 + } 37 + 38 + ebb_global_disable(); 39 + ebb_freeze_pmcs(); 40 + 41 + count_pmc(1, sample_period); 42 + 43 + dump_ebb_state(); 44 + 45 + FAIL_IF(ebb_state.stats.ebb_count == 0); 46 + 47 + return 0; 48 + } 49 + 50 + /* Tests we can setup an EBB on our child - if it's expecting it */ 51 + int ebb_on_willing_child(void) 52 + { 53 + union pipe read_pipe, write_pipe; 54 + struct event event; 55 + pid_t pid; 56 + 57 + FAIL_IF(pipe(read_pipe.fds) == -1); 58 + FAIL_IF(pipe(write_pipe.fds) == -1); 59 + 60 + pid = fork(); 61 + if (pid == 0) { 62 + /* NB order of pipes looks reversed */ 63 + exit(victim_child(write_pipe, read_pipe)); 64 + } 65 + 66 + /* Signal the child to setup its EBB handler */ 67 + FAIL_IF(sync_with_child(read_pipe, write_pipe)); 68 + 69 + /* Child is running now */ 70 + 71 + event_init_named(&event, 0x1001e, "cycles"); 72 + event_leader_ebb_init(&event); 73 + 74 + event.attr.exclude_kernel = 1; 75 + event.attr.exclude_hv = 1; 76 + event.attr.exclude_idle = 1; 77 + 78 + FAIL_IF(event_open_with_pid(&event, pid)); 79 + FAIL_IF(ebb_event_enable(&event)); 80 + 81 + /* Child show now take EBBs and then exit */ 82 + FAIL_IF(wait_for_child(pid)); 83 + 84 + event_close(&event); 85 + 86 + return 0; 87 + } 88 + 89 + int main(void) 90 + { 91 + return test_harness(ebb_on_willing_child, "ebb_on_willing_child"); 92 + }
+86
tools/testing/selftests/powerpc/pmu/ebb/ebb_vs_cpu_event_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <signal.h> 7 + #include <stdio.h> 8 + #include <stdlib.h> 9 + #include <stdbool.h> 10 + #include <sys/types.h> 11 + #include <sys/wait.h> 12 + #include <unistd.h> 13 + 14 + #include "ebb.h" 15 + 16 + 17 + /* 18 + * Tests an EBB vs a cpu event - in that order. The EBB should force the cpu 19 + * event off the PMU. 20 + */ 21 + 22 + static int setup_cpu_event(struct event *event, int cpu) 23 + { 24 + event_init_named(event, 0x400FA, "PM_RUN_INST_CMPL"); 25 + 26 + event->attr.exclude_kernel = 1; 27 + event->attr.exclude_hv = 1; 28 + event->attr.exclude_idle = 1; 29 + 30 + SKIP_IF(require_paranoia_below(1)); 31 + FAIL_IF(event_open_with_cpu(event, cpu)); 32 + FAIL_IF(event_enable(event)); 33 + 34 + return 0; 35 + } 36 + 37 + int ebb_vs_cpu_event(void) 38 + { 39 + union pipe read_pipe, write_pipe; 40 + struct event event; 41 + int cpu, rc; 42 + pid_t pid; 43 + 44 + cpu = pick_online_cpu(); 45 + FAIL_IF(cpu < 0); 46 + FAIL_IF(bind_to_cpu(cpu)); 47 + 48 + FAIL_IF(pipe(read_pipe.fds) == -1); 49 + FAIL_IF(pipe(write_pipe.fds) == -1); 50 + 51 + pid = fork(); 52 + if (pid == 0) { 53 + /* NB order of pipes looks reversed */ 54 + exit(ebb_child(write_pipe, read_pipe)); 55 + } 56 + 57 + /* Signal the child to install its EBB event and wait */ 58 + FAIL_IF(sync_with_child(read_pipe, write_pipe)); 59 + 60 + /* Now try to install our CPU event */ 61 + rc = setup_cpu_event(&event, cpu); 62 + if (rc) { 63 + kill_child_and_wait(pid); 64 + return rc; 65 + } 66 + 67 + /* Signal the child to run */ 68 + FAIL_IF(sync_with_child(read_pipe, write_pipe)); 69 + 70 + /* .. and wait for it to complete */ 71 + FAIL_IF(wait_for_child(pid)); 72 + FAIL_IF(event_disable(&event)); 73 + FAIL_IF(event_read(&event)); 74 + 75 + event_report(&event); 76 + 77 + /* The cpu event may have run, but we don't expect 100% */ 78 + FAIL_IF(event.result.enabled >= event.result.running); 79 + 80 + return 0; 81 + } 82 + 83 + int main(void) 84 + { 85 + return test_harness(ebb_vs_cpu_event, "ebb_vs_cpu_event"); 86 + }
+131
tools/testing/selftests/powerpc/pmu/ebb/event_attributes_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "ebb.h" 10 + 11 + 12 + /* 13 + * Test various attributes of the EBB event are enforced. 14 + */ 15 + int event_attributes(void) 16 + { 17 + struct event event, leader; 18 + 19 + event_init(&event, 0x1001e); 20 + event_leader_ebb_init(&event); 21 + /* Expected to succeed */ 22 + FAIL_IF(event_open(&event)); 23 + event_close(&event); 24 + 25 + 26 + event_init(&event, 0x001e); /* CYCLES - no PMC specified */ 27 + event_leader_ebb_init(&event); 28 + /* Expected to fail, no PMC specified */ 29 + FAIL_IF(event_open(&event) == 0); 30 + 31 + 32 + event_init(&event, 0x2001e); 33 + event_leader_ebb_init(&event); 34 + event.attr.exclusive = 0; 35 + /* Expected to fail, not exclusive */ 36 + FAIL_IF(event_open(&event) == 0); 37 + 38 + 39 + event_init(&event, 0x3001e); 40 + event_leader_ebb_init(&event); 41 + event.attr.freq = 1; 42 + /* Expected to fail, sets freq */ 43 + FAIL_IF(event_open(&event) == 0); 44 + 45 + 46 + event_init(&event, 0x4001e); 47 + event_leader_ebb_init(&event); 48 + event.attr.sample_period = 1; 49 + /* Expected to fail, sets sample_period */ 50 + FAIL_IF(event_open(&event) == 0); 51 + 52 + 53 + event_init(&event, 0x1001e); 54 + event_leader_ebb_init(&event); 55 + event.attr.enable_on_exec = 1; 56 + /* Expected to fail, sets enable_on_exec */ 57 + FAIL_IF(event_open(&event) == 0); 58 + 59 + 60 + event_init(&event, 0x1001e); 61 + event_leader_ebb_init(&event); 62 + event.attr.inherit = 1; 63 + /* Expected to fail, sets inherit */ 64 + FAIL_IF(event_open(&event) == 0); 65 + 66 + 67 + event_init(&leader, 0x1001e); 68 + event_leader_ebb_init(&leader); 69 + FAIL_IF(event_open(&leader)); 70 + 71 + event_init(&event, 0x20002); 72 + event_ebb_init(&event); 73 + 74 + /* Expected to succeed */ 75 + FAIL_IF(event_open_with_group(&event, leader.fd)); 76 + event_close(&leader); 77 + event_close(&event); 78 + 79 + 80 + event_init(&leader, 0x1001e); 81 + event_leader_ebb_init(&leader); 82 + FAIL_IF(event_open(&leader)); 83 + 84 + event_init(&event, 0x20002); 85 + 86 + /* Expected to fail, event doesn't request EBB, leader does */ 87 + FAIL_IF(event_open_with_group(&event, leader.fd) == 0); 88 + event_close(&leader); 89 + 90 + 91 + event_init(&leader, 0x1001e); 92 + event_leader_ebb_init(&leader); 93 + /* Clear the EBB flag */ 94 + leader.attr.config &= ~(1ull << 63); 95 + 96 + FAIL_IF(event_open(&leader)); 97 + 98 + event_init(&event, 0x20002); 99 + event_ebb_init(&event); 100 + 101 + /* Expected to fail, leader doesn't request EBB */ 102 + FAIL_IF(event_open_with_group(&event, leader.fd) == 0); 103 + event_close(&leader); 104 + 105 + 106 + event_init(&leader, 0x1001e); 107 + event_leader_ebb_init(&leader); 108 + leader.attr.exclusive = 0; 109 + /* Expected to fail, leader isn't exclusive */ 110 + FAIL_IF(event_open(&leader) == 0); 111 + 112 + 113 + event_init(&leader, 0x1001e); 114 + event_leader_ebb_init(&leader); 115 + leader.attr.pinned = 0; 116 + /* Expected to fail, leader isn't pinned */ 117 + FAIL_IF(event_open(&leader) == 0); 118 + 119 + event_init(&event, 0x1001e); 120 + event_leader_ebb_init(&event); 121 + /* Expected to fail, not a task event */ 122 + SKIP_IF(require_paranoia_below(1)); 123 + FAIL_IF(event_open_with_cpu(&event, 0) == 0); 124 + 125 + return 0; 126 + } 127 + 128 + int main(void) 129 + { 130 + return test_harness(event_attributes, "event_attributes"); 131 + }
+43
tools/testing/selftests/powerpc/pmu/ebb/fixed_instruction_loop.S
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <ppc-asm.h> 7 + 8 + .text 9 + 10 + FUNC_START(thirty_two_instruction_loop) 11 + cmpwi r3,0 12 + beqlr 13 + addi r4,r3,1 14 + addi r4,r4,1 15 + addi r4,r4,1 16 + addi r4,r4,1 17 + addi r4,r4,1 18 + addi r4,r4,1 19 + addi r4,r4,1 20 + addi r4,r4,1 21 + addi r4,r4,1 22 + addi r4,r4,1 23 + addi r4,r4,1 24 + addi r4,r4,1 25 + addi r4,r4,1 26 + addi r4,r4,1 27 + addi r4,r4,1 28 + addi r4,r4,1 29 + addi r4,r4,1 30 + addi r4,r4,1 31 + addi r4,r4,1 32 + addi r4,r4,1 33 + addi r4,r4,1 34 + addi r4,r4,1 35 + addi r4,r4,1 36 + addi r4,r4,1 37 + addi r4,r4,1 38 + addi r4,r4,1 39 + addi r4,r4,1 40 + addi r4,r4,1 # 28 addi's 41 + subi r3,r3,1 42 + b FUNC_NAME(thirty_two_instruction_loop) 43 + FUNC_END(thirty_two_instruction_loop)
+79
tools/testing/selftests/powerpc/pmu/ebb/fork_cleanup_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <signal.h> 7 + #include <stdio.h> 8 + #include <stdlib.h> 9 + #include <stdbool.h> 10 + #include <sys/types.h> 11 + #include <sys/wait.h> 12 + #include <unistd.h> 13 + #include <setjmp.h> 14 + #include <signal.h> 15 + 16 + #include "ebb.h" 17 + 18 + 19 + /* 20 + * Test that a fork clears the PMU state of the child. eg. BESCR/EBBHR/EBBRR 21 + * are cleared, and MMCR0_PMCC is reset, preventing the child from accessing 22 + * the PMU. 23 + */ 24 + 25 + static struct event event; 26 + 27 + static int child(void) 28 + { 29 + /* Even though we have EBE=0 we can still see the EBB regs */ 30 + FAIL_IF(mfspr(SPRN_BESCR) != 0); 31 + FAIL_IF(mfspr(SPRN_EBBHR) != 0); 32 + FAIL_IF(mfspr(SPRN_EBBRR) != 0); 33 + 34 + FAIL_IF(catch_sigill(write_pmc1)); 35 + 36 + /* We can still read from the event, though it is on our parent */ 37 + FAIL_IF(event_read(&event)); 38 + 39 + return 0; 40 + } 41 + 42 + /* Tests that fork clears EBB state */ 43 + int fork_cleanup(void) 44 + { 45 + pid_t pid; 46 + 47 + event_init_named(&event, 0x1001e, "cycles"); 48 + event_leader_ebb_init(&event); 49 + 50 + FAIL_IF(event_open(&event)); 51 + 52 + ebb_enable_pmc_counting(1); 53 + setup_ebb_handler(standard_ebb_callee); 54 + ebb_global_enable(); 55 + 56 + FAIL_IF(ebb_event_enable(&event)); 57 + 58 + mtspr(SPRN_MMCR0, MMCR0_FC); 59 + mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); 60 + 61 + /* Don't need to actually take any EBBs */ 62 + 63 + pid = fork(); 64 + if (pid == 0) 65 + exit(child()); 66 + 67 + /* Child does the actual testing */ 68 + FAIL_IF(wait_for_child(pid)); 69 + 70 + /* After fork */ 71 + event_close(&event); 72 + 73 + return 0; 74 + } 75 + 76 + int main(void) 77 + { 78 + return test_harness(fork_cleanup, "fork_cleanup"); 79 + }
+164
tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #define _GNU_SOURCE 7 + 8 + #include <stdio.h> 9 + #include <stdbool.h> 10 + #include <string.h> 11 + #include <sys/prctl.h> 12 + 13 + #include "ebb.h" 14 + 15 + 16 + /* 17 + * Run a calibrated instruction loop and count instructions executed using 18 + * EBBs. Make sure the counts look right. 19 + */ 20 + 21 + extern void thirty_two_instruction_loop(uint64_t loops); 22 + 23 + static bool counters_frozen = true; 24 + 25 + static int do_count_loop(struct event *event, uint64_t instructions, 26 + uint64_t overhead, bool report) 27 + { 28 + int64_t difference, expected; 29 + double percentage; 30 + 31 + clear_ebb_stats(); 32 + 33 + counters_frozen = false; 34 + mb(); 35 + mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_FC); 36 + 37 + thirty_two_instruction_loop(instructions >> 5); 38 + 39 + counters_frozen = true; 40 + mb(); 41 + mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | MMCR0_FC); 42 + 43 + count_pmc(4, sample_period); 44 + 45 + event->result.value = ebb_state.stats.pmc_count[4-1]; 46 + expected = instructions + overhead; 47 + difference = event->result.value - expected; 48 + percentage = (double)difference / event->result.value * 100; 49 + 50 + if (report) { 51 + printf("Looped for %lu instructions, overhead %lu\n", instructions, overhead); 52 + printf("Expected %lu\n", expected); 53 + printf("Actual %llu\n", event->result.value); 54 + printf("Error %ld, %f%%\n", difference, percentage); 55 + printf("Took %d EBBs\n", ebb_state.stats.ebb_count); 56 + } 57 + 58 + if (difference < 0) 59 + difference = -difference; 60 + 61 + /* Tolerate a difference of up to 0.0001 % */ 62 + difference *= 10000 * 100; 63 + if (difference / event->result.value) 64 + return -1; 65 + 66 + return 0; 67 + } 68 + 69 + /* Count how many instructions it takes to do a null loop */ 70 + static uint64_t determine_overhead(struct event *event) 71 + { 72 + uint64_t current, overhead; 73 + int i; 74 + 75 + do_count_loop(event, 0, 0, false); 76 + overhead = event->result.value; 77 + 78 + for (i = 0; i < 100; i++) { 79 + do_count_loop(event, 0, 0, false); 80 + current = event->result.value; 81 + if (current < overhead) { 82 + printf("Replacing overhead %lu with %lu\n", overhead, current); 83 + overhead = current; 84 + } 85 + } 86 + 87 + return overhead; 88 + } 89 + 90 + static void pmc4_ebb_callee(void) 91 + { 92 + uint64_t val; 93 + 94 + val = mfspr(SPRN_BESCR); 95 + if (!(val & BESCR_PMEO)) { 96 + ebb_state.stats.spurious++; 97 + goto out; 98 + } 99 + 100 + ebb_state.stats.ebb_count++; 101 + count_pmc(4, sample_period); 102 + out: 103 + if (counters_frozen) 104 + reset_ebb_with_clear_mask(MMCR0_PMAO); 105 + else 106 + reset_ebb(); 107 + } 108 + 109 + int instruction_count(void) 110 + { 111 + struct event event; 112 + uint64_t overhead; 113 + 114 + event_init_named(&event, 0x400FA, "PM_RUN_INST_CMPL"); 115 + event_leader_ebb_init(&event); 116 + event.attr.exclude_kernel = 1; 117 + event.attr.exclude_hv = 1; 118 + event.attr.exclude_idle = 1; 119 + 120 + FAIL_IF(event_open(&event)); 121 + FAIL_IF(ebb_event_enable(&event)); 122 + 123 + sample_period = COUNTER_OVERFLOW; 124 + 125 + setup_ebb_handler(pmc4_ebb_callee); 126 + mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_FC); 127 + ebb_global_enable(); 128 + 129 + overhead = determine_overhead(&event); 130 + printf("Overhead of null loop: %lu instructions\n", overhead); 131 + 132 + /* Run for 1M instructions */ 133 + FAIL_IF(do_count_loop(&event, 0x100000, overhead, true)); 134 + 135 + /* Run for 10M instructions */ 136 + FAIL_IF(do_count_loop(&event, 0xa00000, overhead, true)); 137 + 138 + /* Run for 100M instructions */ 139 + FAIL_IF(do_count_loop(&event, 0x6400000, overhead, true)); 140 + 141 + /* Run for 1G instructions */ 142 + FAIL_IF(do_count_loop(&event, 0x40000000, overhead, true)); 143 + 144 + /* Run for 16G instructions */ 145 + FAIL_IF(do_count_loop(&event, 0x400000000, overhead, true)); 146 + 147 + /* Run for 64G instructions */ 148 + FAIL_IF(do_count_loop(&event, 0x1000000000, overhead, true)); 149 + 150 + /* Run for 128G instructions */ 151 + FAIL_IF(do_count_loop(&event, 0x2000000000, overhead, true)); 152 + 153 + ebb_global_disable(); 154 + event_close(&event); 155 + 156 + printf("Finished OK\n"); 157 + 158 + return 0; 159 + } 160 + 161 + int main(void) 162 + { 163 + return test_harness(instruction_count, "instruction_count"); 164 + }
+100
tools/testing/selftests/powerpc/pmu/ebb/lost_exception_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <sched.h> 7 + #include <signal.h> 8 + #include <stdio.h> 9 + #include <stdlib.h> 10 + #include <sys/mman.h> 11 + 12 + #include "ebb.h" 13 + 14 + 15 + /* 16 + * Test that tries to trigger CPU_FTR_PMAO_BUG. Which is a hardware defect 17 + * where an exception triggers but we context switch before it is delivered and 18 + * lose the exception. 19 + */ 20 + 21 + static int test_body(void) 22 + { 23 + int i, orig_period, max_period; 24 + struct event event; 25 + 26 + /* We use PMC4 to make sure the kernel switches all counters correctly */ 27 + event_init_named(&event, 0x40002, "instructions"); 28 + event_leader_ebb_init(&event); 29 + 30 + event.attr.exclude_kernel = 1; 31 + event.attr.exclude_hv = 1; 32 + event.attr.exclude_idle = 1; 33 + 34 + FAIL_IF(event_open(&event)); 35 + 36 + ebb_enable_pmc_counting(4); 37 + setup_ebb_handler(standard_ebb_callee); 38 + ebb_global_enable(); 39 + FAIL_IF(ebb_event_enable(&event)); 40 + 41 + /* 42 + * We want a low sample period, but we also want to get out of the EBB 43 + * handler without tripping up again. 44 + * 45 + * This value picked after much experimentation. 46 + */ 47 + orig_period = max_period = sample_period = 400; 48 + 49 + mtspr(SPRN_PMC4, pmc_sample_period(sample_period)); 50 + 51 + while (ebb_state.stats.ebb_count < 1000000) { 52 + /* 53 + * We are trying to get the EBB exception to race exactly with 54 + * us entering the kernel to do the syscall. We then need the 55 + * kernel to decide our timeslice is up and context switch to 56 + * the other thread. When we come back our EBB will have been 57 + * lost and we'll spin in this while loop forever. 58 + */ 59 + 60 + for (i = 0; i < 100000; i++) 61 + sched_yield(); 62 + 63 + /* Change the sample period slightly to try and hit the race */ 64 + if (sample_period >= (orig_period + 200)) 65 + sample_period = orig_period; 66 + else 67 + sample_period++; 68 + 69 + if (sample_period > max_period) 70 + max_period = sample_period; 71 + } 72 + 73 + ebb_freeze_pmcs(); 74 + ebb_global_disable(); 75 + 76 + count_pmc(4, sample_period); 77 + mtspr(SPRN_PMC4, 0xdead); 78 + 79 + dump_summary_ebb_state(); 80 + dump_ebb_hw_state(); 81 + 82 + event_close(&event); 83 + 84 + FAIL_IF(ebb_state.stats.ebb_count == 0); 85 + 86 + /* We vary our sample period so we need extra fudge here */ 87 + FAIL_IF(!ebb_check_count(4, orig_period, 2 * (max_period - orig_period))); 88 + 89 + return 0; 90 + } 91 + 92 + static int lost_exception(void) 93 + { 94 + return eat_cpu(test_body); 95 + } 96 + 97 + int main(void) 98 + { 99 + return test_harness(lost_exception, "lost_exception"); 100 + }
+91
tools/testing/selftests/powerpc/pmu/ebb/multi_counter_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + #include <sys/ioctl.h> 9 + 10 + #include "ebb.h" 11 + 12 + 13 + /* 14 + * Test counting multiple events using EBBs. 15 + */ 16 + int multi_counter(void) 17 + { 18 + struct event events[6]; 19 + int i, group_fd; 20 + 21 + event_init_named(&events[0], 0x1001C, "PM_CMPLU_STALL_THRD"); 22 + event_init_named(&events[1], 0x2D016, "PM_CMPLU_STALL_FXU"); 23 + event_init_named(&events[2], 0x30006, "PM_CMPLU_STALL_OTHER_CMPL"); 24 + event_init_named(&events[3], 0x4000A, "PM_CMPLU_STALL"); 25 + event_init_named(&events[4], 0x600f4, "PM_RUN_CYC"); 26 + event_init_named(&events[5], 0x500fa, "PM_RUN_INST_CMPL"); 27 + 28 + event_leader_ebb_init(&events[0]); 29 + for (i = 1; i < 6; i++) 30 + event_ebb_init(&events[i]); 31 + 32 + group_fd = -1; 33 + for (i = 0; i < 6; i++) { 34 + events[i].attr.exclude_kernel = 1; 35 + events[i].attr.exclude_hv = 1; 36 + events[i].attr.exclude_idle = 1; 37 + 38 + FAIL_IF(event_open_with_group(&events[i], group_fd)); 39 + if (group_fd == -1) 40 + group_fd = events[0].fd; 41 + } 42 + 43 + ebb_enable_pmc_counting(1); 44 + ebb_enable_pmc_counting(2); 45 + ebb_enable_pmc_counting(3); 46 + ebb_enable_pmc_counting(4); 47 + ebb_enable_pmc_counting(5); 48 + ebb_enable_pmc_counting(6); 49 + setup_ebb_handler(standard_ebb_callee); 50 + 51 + FAIL_IF(ioctl(events[0].fd, PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP)); 52 + FAIL_IF(event_read(&events[0])); 53 + 54 + ebb_global_enable(); 55 + 56 + mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); 57 + mtspr(SPRN_PMC2, pmc_sample_period(sample_period)); 58 + mtspr(SPRN_PMC3, pmc_sample_period(sample_period)); 59 + mtspr(SPRN_PMC4, pmc_sample_period(sample_period)); 60 + mtspr(SPRN_PMC5, pmc_sample_period(sample_period)); 61 + mtspr(SPRN_PMC6, pmc_sample_period(sample_period)); 62 + 63 + while (ebb_state.stats.ebb_count < 50) { 64 + FAIL_IF(core_busy_loop()); 65 + FAIL_IF(ebb_check_mmcr0()); 66 + } 67 + 68 + ebb_global_disable(); 69 + ebb_freeze_pmcs(); 70 + 71 + count_pmc(1, sample_period); 72 + count_pmc(2, sample_period); 73 + count_pmc(3, sample_period); 74 + count_pmc(4, sample_period); 75 + count_pmc(5, sample_period); 76 + count_pmc(6, sample_period); 77 + 78 + dump_ebb_state(); 79 + 80 + for (i = 0; i < 6; i++) 81 + event_close(&events[i]); 82 + 83 + FAIL_IF(ebb_state.stats.ebb_count == 0); 84 + 85 + return 0; 86 + } 87 + 88 + int main(void) 89 + { 90 + return test_harness(multi_counter, "multi_counter"); 91 + }
+109
tools/testing/selftests/powerpc/pmu/ebb/multi_ebb_procs_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <stdbool.h> 7 + #include <stdio.h> 8 + #include <stdlib.h> 9 + #include <signal.h> 10 + 11 + #include "ebb.h" 12 + 13 + 14 + /* 15 + * Test running multiple EBB using processes at once on a single CPU. They 16 + * should all run happily without interfering with each other. 17 + */ 18 + 19 + static bool child_should_exit; 20 + 21 + static void sigint_handler(int signal) 22 + { 23 + child_should_exit = true; 24 + } 25 + 26 + struct sigaction sigint_action = { 27 + .sa_handler = sigint_handler, 28 + }; 29 + 30 + static int cycles_child(void) 31 + { 32 + struct event event; 33 + 34 + if (sigaction(SIGINT, &sigint_action, NULL)) { 35 + perror("sigaction"); 36 + return 1; 37 + } 38 + 39 + event_init_named(&event, 0x1001e, "cycles"); 40 + event_leader_ebb_init(&event); 41 + 42 + event.attr.exclude_kernel = 1; 43 + event.attr.exclude_hv = 1; 44 + event.attr.exclude_idle = 1; 45 + 46 + FAIL_IF(event_open(&event)); 47 + 48 + ebb_enable_pmc_counting(1); 49 + setup_ebb_handler(standard_ebb_callee); 50 + ebb_global_enable(); 51 + 52 + FAIL_IF(ebb_event_enable(&event)); 53 + 54 + mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); 55 + 56 + while (!child_should_exit) { 57 + FAIL_IF(core_busy_loop()); 58 + FAIL_IF(ebb_check_mmcr0()); 59 + } 60 + 61 + ebb_global_disable(); 62 + ebb_freeze_pmcs(); 63 + 64 + count_pmc(1, sample_period); 65 + 66 + dump_summary_ebb_state(); 67 + 68 + event_close(&event); 69 + 70 + FAIL_IF(ebb_state.stats.ebb_count == 0); 71 + 72 + return 0; 73 + } 74 + 75 + #define NR_CHILDREN 4 76 + 77 + int multi_ebb_procs(void) 78 + { 79 + pid_t pids[NR_CHILDREN]; 80 + int cpu, rc, i; 81 + 82 + cpu = pick_online_cpu(); 83 + FAIL_IF(cpu < 0); 84 + FAIL_IF(bind_to_cpu(cpu)); 85 + 86 + for (i = 0; i < NR_CHILDREN; i++) { 87 + pids[i] = fork(); 88 + if (pids[i] == 0) 89 + exit(cycles_child()); 90 + } 91 + 92 + /* Have them all run for "a while" */ 93 + sleep(10); 94 + 95 + rc = 0; 96 + for (i = 0; i < NR_CHILDREN; i++) { 97 + /* Tell them to stop */ 98 + kill(pids[i], SIGINT); 99 + /* And wait */ 100 + rc |= wait_for_child(pids[i]); 101 + } 102 + 103 + return rc; 104 + } 105 + 106 + int main(void) 107 + { 108 + return test_harness(multi_ebb_procs, "multi_ebb_procs"); 109 + }
+61
tools/testing/selftests/powerpc/pmu/ebb/no_handler_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + #include <setjmp.h> 9 + #include <signal.h> 10 + 11 + #include "ebb.h" 12 + 13 + 14 + /* Test that things work sanely if we have no handler */ 15 + 16 + static int no_handler_test(void) 17 + { 18 + struct event event; 19 + u64 val; 20 + int i; 21 + 22 + event_init_named(&event, 0x1001e, "cycles"); 23 + event_leader_ebb_init(&event); 24 + 25 + event.attr.exclude_kernel = 1; 26 + event.attr.exclude_hv = 1; 27 + event.attr.exclude_idle = 1; 28 + 29 + FAIL_IF(event_open(&event)); 30 + FAIL_IF(ebb_event_enable(&event)); 31 + 32 + val = mfspr(SPRN_EBBHR); 33 + FAIL_IF(val != 0); 34 + 35 + /* Make sure it overflows quickly */ 36 + sample_period = 1000; 37 + mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); 38 + 39 + /* Spin to make sure the event has time to overflow */ 40 + for (i = 0; i < 1000; i++) 41 + mb(); 42 + 43 + dump_ebb_state(); 44 + 45 + /* We expect to see the PMU frozen & PMAO set */ 46 + val = mfspr(SPRN_MMCR0); 47 + FAIL_IF(val != 0x0000000080000080); 48 + 49 + event_close(&event); 50 + 51 + dump_ebb_state(); 52 + 53 + /* The real test is that we never took an EBB at 0x0 */ 54 + 55 + return 0; 56 + } 57 + 58 + int main(void) 59 + { 60 + return test_harness(no_handler_test,"no_handler_test"); 61 + }
+106
tools/testing/selftests/powerpc/pmu/ebb/pmae_handling_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <sched.h> 7 + #include <signal.h> 8 + #include <stdbool.h> 9 + #include <stdio.h> 10 + #include <stdlib.h> 11 + 12 + #include "ebb.h" 13 + 14 + 15 + /* 16 + * Test that the kernel properly handles PMAE across context switches. 17 + * 18 + * We test this by calling into the kernel inside our EBB handler, where PMAE 19 + * is clear. A cpu eater companion thread is running on the same CPU as us to 20 + * encourage the scheduler to switch us. 21 + * 22 + * The kernel must make sure that when it context switches us back in, it 23 + * honours the fact that we had PMAE clear. 24 + * 25 + * Observed to hit the failing case on the first EBB with a broken kernel. 26 + */ 27 + 28 + static bool mmcr0_mismatch; 29 + static uint64_t before, after; 30 + 31 + static void syscall_ebb_callee(void) 32 + { 33 + uint64_t val; 34 + 35 + val = mfspr(SPRN_BESCR); 36 + if (!(val & BESCR_PMEO)) { 37 + ebb_state.stats.spurious++; 38 + goto out; 39 + } 40 + 41 + ebb_state.stats.ebb_count++; 42 + count_pmc(1, sample_period); 43 + 44 + before = mfspr(SPRN_MMCR0); 45 + 46 + /* Try and get ourselves scheduled, to force a PMU context switch */ 47 + sched_yield(); 48 + 49 + after = mfspr(SPRN_MMCR0); 50 + if (before != after) 51 + mmcr0_mismatch = true; 52 + 53 + out: 54 + reset_ebb(); 55 + } 56 + 57 + static int test_body(void) 58 + { 59 + struct event event; 60 + 61 + event_init_named(&event, 0x1001e, "cycles"); 62 + event_leader_ebb_init(&event); 63 + 64 + event.attr.exclude_kernel = 1; 65 + event.attr.exclude_hv = 1; 66 + event.attr.exclude_idle = 1; 67 + 68 + FAIL_IF(event_open(&event)); 69 + 70 + setup_ebb_handler(syscall_ebb_callee); 71 + ebb_global_enable(); 72 + 73 + FAIL_IF(ebb_event_enable(&event)); 74 + 75 + mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); 76 + 77 + while (ebb_state.stats.ebb_count < 20 && !mmcr0_mismatch) 78 + FAIL_IF(core_busy_loop()); 79 + 80 + ebb_global_disable(); 81 + ebb_freeze_pmcs(); 82 + 83 + count_pmc(1, sample_period); 84 + 85 + dump_ebb_state(); 86 + 87 + if (mmcr0_mismatch) 88 + printf("Saw MMCR0 before 0x%lx after 0x%lx\n", before, after); 89 + 90 + event_close(&event); 91 + 92 + FAIL_IF(ebb_state.stats.ebb_count == 0); 93 + FAIL_IF(mmcr0_mismatch); 94 + 95 + return 0; 96 + } 97 + 98 + int pmae_handling(void) 99 + { 100 + return eat_cpu(test_body); 101 + } 102 + 103 + int main(void) 104 + { 105 + return test_harness(pmae_handling, "pmae_handling"); 106 + }
+93
tools/testing/selftests/powerpc/pmu/ebb/pmc56_overflow_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "ebb.h" 10 + 11 + 12 + /* 13 + * Test that PMC5 & 6 are frozen (ie. don't overflow) when they are not being 14 + * used. Tests the MMCR0_FC56 logic in the kernel. 15 + */ 16 + 17 + static int pmc56_overflowed; 18 + 19 + static void ebb_callee(void) 20 + { 21 + uint64_t val; 22 + 23 + val = mfspr(SPRN_BESCR); 24 + if (!(val & BESCR_PMEO)) { 25 + ebb_state.stats.spurious++; 26 + goto out; 27 + } 28 + 29 + ebb_state.stats.ebb_count++; 30 + count_pmc(2, sample_period); 31 + 32 + val = mfspr(SPRN_PMC5); 33 + if (val >= COUNTER_OVERFLOW) 34 + pmc56_overflowed++; 35 + 36 + count_pmc(5, COUNTER_OVERFLOW); 37 + 38 + val = mfspr(SPRN_PMC6); 39 + if (val >= COUNTER_OVERFLOW) 40 + pmc56_overflowed++; 41 + 42 + count_pmc(6, COUNTER_OVERFLOW); 43 + 44 + out: 45 + reset_ebb(); 46 + } 47 + 48 + int pmc56_overflow(void) 49 + { 50 + struct event event; 51 + 52 + /* Use PMC2 so we set PMCjCE, which enables PMC5/6 */ 53 + event_init(&event, 0x2001e); 54 + event_leader_ebb_init(&event); 55 + 56 + event.attr.exclude_kernel = 1; 57 + event.attr.exclude_hv = 1; 58 + event.attr.exclude_idle = 1; 59 + 60 + FAIL_IF(event_open(&event)); 61 + 62 + setup_ebb_handler(ebb_callee); 63 + ebb_global_enable(); 64 + 65 + FAIL_IF(ebb_event_enable(&event)); 66 + 67 + mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); 68 + mtspr(SPRN_PMC5, 0); 69 + mtspr(SPRN_PMC6, 0); 70 + 71 + while (ebb_state.stats.ebb_count < 10) 72 + FAIL_IF(core_busy_loop()); 73 + 74 + ebb_global_disable(); 75 + ebb_freeze_pmcs(); 76 + 77 + count_pmc(2, sample_period); 78 + 79 + dump_ebb_state(); 80 + 81 + printf("PMC5/6 overflow %d\n", pmc56_overflowed); 82 + 83 + event_close(&event); 84 + 85 + FAIL_IF(ebb_state.stats.ebb_count == 0 || pmc56_overflowed != 0); 86 + 87 + return 0; 88 + } 89 + 90 + int main(void) 91 + { 92 + return test_harness(pmc56_overflow, "pmc56_overflow"); 93 + }
+49
tools/testing/selftests/powerpc/pmu/ebb/reg.h
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #ifndef _SELFTESTS_POWERPC_REG_H 7 + #define _SELFTESTS_POWERPC_REG_H 8 + 9 + #define __stringify_1(x) #x 10 + #define __stringify(x) __stringify_1(x) 11 + 12 + #define mfspr(rn) ({unsigned long rval; \ 13 + asm volatile("mfspr %0," __stringify(rn) \ 14 + : "=r" (rval)); rval; }) 15 + #define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : \ 16 + : "r" ((unsigned long)(v)) \ 17 + : "memory") 18 + 19 + #define mb() asm volatile("sync" : : : "memory"); 20 + 21 + #define SPRN_MMCR2 769 22 + #define SPRN_MMCRA 770 23 + #define SPRN_MMCR0 779 24 + #define MMCR0_PMAO 0x00000080 25 + #define MMCR0_PMAE 0x04000000 26 + #define MMCR0_FC 0x80000000 27 + #define SPRN_EBBHR 804 28 + #define SPRN_EBBRR 805 29 + #define SPRN_BESCR 806 /* Branch event status & control register */ 30 + #define SPRN_BESCRS 800 /* Branch event status & control set (1 bits set to 1) */ 31 + #define SPRN_BESCRSU 801 /* Branch event status & control set upper */ 32 + #define SPRN_BESCRR 802 /* Branch event status & control REset (1 bits set to 0) */ 33 + #define SPRN_BESCRRU 803 /* Branch event status & control REset upper */ 34 + 35 + #define BESCR_PMEO 0x1 /* PMU Event-based exception Occurred */ 36 + #define BESCR_PME (0x1ul << 32) /* PMU Event-based exception Enable */ 37 + 38 + #define SPRN_PMC1 771 39 + #define SPRN_PMC2 772 40 + #define SPRN_PMC3 773 41 + #define SPRN_PMC4 774 42 + #define SPRN_PMC5 775 43 + #define SPRN_PMC6 776 44 + 45 + #define SPRN_SIAR 780 46 + #define SPRN_SDAR 781 47 + #define SPRN_SIER 768 48 + 49 + #endif /* _SELFTESTS_POWERPC_REG_H */
+39
tools/testing/selftests/powerpc/pmu/ebb/reg_access_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + 9 + #include "ebb.h" 10 + #include "reg.h" 11 + 12 + 13 + /* 14 + * Test basic access to the EBB regs, they should be user accessible with no 15 + * kernel interaction required. 16 + */ 17 + int reg_access(void) 18 + { 19 + uint64_t val, expected; 20 + 21 + expected = 0x8000000100000000ull; 22 + mtspr(SPRN_BESCR, expected); 23 + val = mfspr(SPRN_BESCR); 24 + 25 + FAIL_IF(val != expected); 26 + 27 + expected = 0x0000000001000000ull; 28 + mtspr(SPRN_EBBHR, expected); 29 + val = mfspr(SPRN_EBBHR); 30 + 31 + FAIL_IF(val != expected); 32 + 33 + return 0; 34 + } 35 + 36 + int main(void) 37 + { 38 + return test_harness(reg_access, "reg_access"); 39 + }
+91
tools/testing/selftests/powerpc/pmu/ebb/task_event_pinned_vs_ebb_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <signal.h> 7 + #include <stdio.h> 8 + #include <stdlib.h> 9 + #include <stdbool.h> 10 + #include <sys/types.h> 11 + #include <sys/wait.h> 12 + #include <unistd.h> 13 + 14 + #include "ebb.h" 15 + 16 + 17 + /* 18 + * Tests a pinned per-task event vs an EBB - in that order. The pinned per-task 19 + * event should prevent the EBB event from being enabled. 20 + */ 21 + 22 + static int setup_child_event(struct event *event, pid_t child_pid) 23 + { 24 + event_init_named(event, 0x400FA, "PM_RUN_INST_CMPL"); 25 + 26 + event->attr.pinned = 1; 27 + 28 + event->attr.exclude_kernel = 1; 29 + event->attr.exclude_hv = 1; 30 + event->attr.exclude_idle = 1; 31 + 32 + FAIL_IF(event_open_with_pid(event, child_pid)); 33 + FAIL_IF(event_enable(event)); 34 + 35 + return 0; 36 + } 37 + 38 + int task_event_pinned_vs_ebb(void) 39 + { 40 + union pipe read_pipe, write_pipe; 41 + struct event event; 42 + pid_t pid; 43 + int rc; 44 + 45 + FAIL_IF(pipe(read_pipe.fds) == -1); 46 + FAIL_IF(pipe(write_pipe.fds) == -1); 47 + 48 + pid = fork(); 49 + if (pid == 0) { 50 + /* NB order of pipes looks reversed */ 51 + exit(ebb_child(write_pipe, read_pipe)); 52 + } 53 + 54 + /* We setup the task event first */ 55 + rc = setup_child_event(&event, pid); 56 + if (rc) { 57 + kill_child_and_wait(pid); 58 + return rc; 59 + } 60 + 61 + /* Signal the child to install its EBB event and wait */ 62 + if (sync_with_child(read_pipe, write_pipe)) 63 + /* If it fails, wait for it to exit */ 64 + goto wait; 65 + 66 + /* Signal the child to run */ 67 + FAIL_IF(sync_with_child(read_pipe, write_pipe)); 68 + 69 + wait: 70 + /* We expect it to fail to read the event */ 71 + FAIL_IF(wait_for_child(pid) != 2); 72 + FAIL_IF(event_disable(&event)); 73 + FAIL_IF(event_read(&event)); 74 + 75 + event_report(&event); 76 + 77 + FAIL_IF(event.result.value == 0); 78 + /* 79 + * For reasons I don't understand enabled is usually just slightly 80 + * lower than running. Would be good to confirm why. 81 + */ 82 + FAIL_IF(event.result.enabled == 0); 83 + FAIL_IF(event.result.running == 0); 84 + 85 + return 0; 86 + } 87 + 88 + int main(void) 89 + { 90 + return test_harness(task_event_pinned_vs_ebb, "task_event_pinned_vs_ebb"); 91 + }
+83
tools/testing/selftests/powerpc/pmu/ebb/task_event_vs_ebb_test.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <signal.h> 7 + #include <stdio.h> 8 + #include <stdlib.h> 9 + #include <stdbool.h> 10 + #include <sys/types.h> 11 + #include <sys/wait.h> 12 + #include <unistd.h> 13 + 14 + #include "ebb.h" 15 + 16 + 17 + /* 18 + * Tests a per-task event vs an EBB - in that order. The EBB should push the 19 + * per-task event off the PMU. 20 + */ 21 + 22 + static int setup_child_event(struct event *event, pid_t child_pid) 23 + { 24 + event_init_named(event, 0x400FA, "PM_RUN_INST_CMPL"); 25 + 26 + event->attr.exclude_kernel = 1; 27 + event->attr.exclude_hv = 1; 28 + event->attr.exclude_idle = 1; 29 + 30 + FAIL_IF(event_open_with_pid(event, child_pid)); 31 + FAIL_IF(event_enable(event)); 32 + 33 + return 0; 34 + } 35 + 36 + int task_event_vs_ebb(void) 37 + { 38 + union pipe read_pipe, write_pipe; 39 + struct event event; 40 + pid_t pid; 41 + int rc; 42 + 43 + FAIL_IF(pipe(read_pipe.fds) == -1); 44 + FAIL_IF(pipe(write_pipe.fds) == -1); 45 + 46 + pid = fork(); 47 + if (pid == 0) { 48 + /* NB order of pipes looks reversed */ 49 + exit(ebb_child(write_pipe, read_pipe)); 50 + } 51 + 52 + /* We setup the task event first */ 53 + rc = setup_child_event(&event, pid); 54 + if (rc) { 55 + kill_child_and_wait(pid); 56 + return rc; 57 + } 58 + 59 + /* Signal the child to install its EBB event and wait */ 60 + if (sync_with_child(read_pipe, write_pipe)) 61 + /* If it fails, wait for it to exit */ 62 + goto wait; 63 + 64 + /* Signal the child to run */ 65 + FAIL_IF(sync_with_child(read_pipe, write_pipe)); 66 + 67 + wait: 68 + /* The EBB event should push the task event off so the child should succeed */ 69 + FAIL_IF(wait_for_child(pid)); 70 + FAIL_IF(event_disable(&event)); 71 + FAIL_IF(event_read(&event)); 72 + 73 + event_report(&event); 74 + 75 + /* The task event may have run, or not so we can't assert anything about it */ 76 + 77 + return 0; 78 + } 79 + 80 + int main(void) 81 + { 82 + return test_harness(task_event_vs_ebb, "task_event_vs_ebb"); 83 + }
+300
tools/testing/selftests/powerpc/pmu/ebb/trace.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #include <errno.h> 7 + #include <stdio.h> 8 + #include <stdlib.h> 9 + #include <string.h> 10 + #include <sys/mman.h> 11 + 12 + #include "trace.h" 13 + 14 + 15 + struct trace_buffer *trace_buffer_allocate(u64 size) 16 + { 17 + struct trace_buffer *tb; 18 + 19 + if (size < sizeof(*tb)) { 20 + fprintf(stderr, "Error: trace buffer too small\n"); 21 + return NULL; 22 + } 23 + 24 + tb = mmap(NULL, size, PROT_READ | PROT_WRITE, 25 + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 26 + if (tb == MAP_FAILED) { 27 + perror("mmap"); 28 + return NULL; 29 + } 30 + 31 + tb->size = size; 32 + tb->tail = tb->data; 33 + tb->overflow = false; 34 + 35 + return tb; 36 + } 37 + 38 + static bool trace_check_bounds(struct trace_buffer *tb, void *p) 39 + { 40 + return p < ((void *)tb + tb->size); 41 + } 42 + 43 + static bool trace_check_alloc(struct trace_buffer *tb, void *p) 44 + { 45 + /* 46 + * If we ever overflowed don't allow any more input. This prevents us 47 + * from dropping a large item and then later logging a small one. The 48 + * buffer should just stop when overflow happened, not be patchy. If 49 + * you're overflowing, make your buffer bigger. 50 + */ 51 + if (tb->overflow) 52 + return false; 53 + 54 + if (!trace_check_bounds(tb, p)) { 55 + tb->overflow = true; 56 + return false; 57 + } 58 + 59 + return true; 60 + } 61 + 62 + static void *trace_alloc(struct trace_buffer *tb, int bytes) 63 + { 64 + void *p, *newtail; 65 + 66 + p = tb->tail; 67 + newtail = tb->tail + bytes; 68 + if (!trace_check_alloc(tb, newtail)) 69 + return NULL; 70 + 71 + tb->tail = newtail; 72 + 73 + return p; 74 + } 75 + 76 + static struct trace_entry *trace_alloc_entry(struct trace_buffer *tb, int payload_size) 77 + { 78 + struct trace_entry *e; 79 + 80 + e = trace_alloc(tb, sizeof(*e) + payload_size); 81 + if (e) 82 + e->length = payload_size; 83 + 84 + return e; 85 + } 86 + 87 + int trace_log_reg(struct trace_buffer *tb, u64 reg, u64 value) 88 + { 89 + struct trace_entry *e; 90 + u64 *p; 91 + 92 + e = trace_alloc_entry(tb, sizeof(reg) + sizeof(value)); 93 + if (!e) 94 + return -ENOSPC; 95 + 96 + e->type = TRACE_TYPE_REG; 97 + p = (u64 *)e->data; 98 + *p++ = reg; 99 + *p++ = value; 100 + 101 + return 0; 102 + } 103 + 104 + int trace_log_counter(struct trace_buffer *tb, u64 value) 105 + { 106 + struct trace_entry *e; 107 + u64 *p; 108 + 109 + e = trace_alloc_entry(tb, sizeof(value)); 110 + if (!e) 111 + return -ENOSPC; 112 + 113 + e->type = TRACE_TYPE_COUNTER; 114 + p = (u64 *)e->data; 115 + *p++ = value; 116 + 117 + return 0; 118 + } 119 + 120 + int trace_log_string(struct trace_buffer *tb, char *str) 121 + { 122 + struct trace_entry *e; 123 + char *p; 124 + int len; 125 + 126 + len = strlen(str); 127 + 128 + /* We NULL terminate to make printing easier */ 129 + e = trace_alloc_entry(tb, len + 1); 130 + if (!e) 131 + return -ENOSPC; 132 + 133 + e->type = TRACE_TYPE_STRING; 134 + p = (char *)e->data; 135 + memcpy(p, str, len); 136 + p += len; 137 + *p = '\0'; 138 + 139 + return 0; 140 + } 141 + 142 + int trace_log_indent(struct trace_buffer *tb) 143 + { 144 + struct trace_entry *e; 145 + 146 + e = trace_alloc_entry(tb, 0); 147 + if (!e) 148 + return -ENOSPC; 149 + 150 + e->type = TRACE_TYPE_INDENT; 151 + 152 + return 0; 153 + } 154 + 155 + int trace_log_outdent(struct trace_buffer *tb) 156 + { 157 + struct trace_entry *e; 158 + 159 + e = trace_alloc_entry(tb, 0); 160 + if (!e) 161 + return -ENOSPC; 162 + 163 + e->type = TRACE_TYPE_OUTDENT; 164 + 165 + return 0; 166 + } 167 + 168 + static void trace_print_header(int seq, int prefix) 169 + { 170 + printf("%*s[%d]: ", prefix, "", seq); 171 + } 172 + 173 + static char *trace_decode_reg(int reg) 174 + { 175 + switch (reg) { 176 + case 769: return "SPRN_MMCR2"; break; 177 + case 770: return "SPRN_MMCRA"; break; 178 + case 779: return "SPRN_MMCR0"; break; 179 + case 804: return "SPRN_EBBHR"; break; 180 + case 805: return "SPRN_EBBRR"; break; 181 + case 806: return "SPRN_BESCR"; break; 182 + case 800: return "SPRN_BESCRS"; break; 183 + case 801: return "SPRN_BESCRSU"; break; 184 + case 802: return "SPRN_BESCRR"; break; 185 + case 803: return "SPRN_BESCRRU"; break; 186 + case 771: return "SPRN_PMC1"; break; 187 + case 772: return "SPRN_PMC2"; break; 188 + case 773: return "SPRN_PMC3"; break; 189 + case 774: return "SPRN_PMC4"; break; 190 + case 775: return "SPRN_PMC5"; break; 191 + case 776: return "SPRN_PMC6"; break; 192 + case 780: return "SPRN_SIAR"; break; 193 + case 781: return "SPRN_SDAR"; break; 194 + case 768: return "SPRN_SIER"; break; 195 + } 196 + 197 + return NULL; 198 + } 199 + 200 + static void trace_print_reg(struct trace_entry *e) 201 + { 202 + u64 *p, *reg, *value; 203 + char *name; 204 + 205 + p = (u64 *)e->data; 206 + reg = p++; 207 + value = p; 208 + 209 + name = trace_decode_reg(*reg); 210 + if (name) 211 + printf("register %-10s = 0x%016llx\n", name, *value); 212 + else 213 + printf("register %lld = 0x%016llx\n", *reg, *value); 214 + } 215 + 216 + static void trace_print_counter(struct trace_entry *e) 217 + { 218 + u64 *value; 219 + 220 + value = (u64 *)e->data; 221 + printf("counter = %lld\n", *value); 222 + } 223 + 224 + static void trace_print_string(struct trace_entry *e) 225 + { 226 + char *str; 227 + 228 + str = (char *)e->data; 229 + puts(str); 230 + } 231 + 232 + #define BASE_PREFIX 2 233 + #define PREFIX_DELTA 8 234 + 235 + static void trace_print_entry(struct trace_entry *e, int seq, int *prefix) 236 + { 237 + switch (e->type) { 238 + case TRACE_TYPE_REG: 239 + trace_print_header(seq, *prefix); 240 + trace_print_reg(e); 241 + break; 242 + case TRACE_TYPE_COUNTER: 243 + trace_print_header(seq, *prefix); 244 + trace_print_counter(e); 245 + break; 246 + case TRACE_TYPE_STRING: 247 + trace_print_header(seq, *prefix); 248 + trace_print_string(e); 249 + break; 250 + case TRACE_TYPE_INDENT: 251 + trace_print_header(seq, *prefix); 252 + puts("{"); 253 + *prefix += PREFIX_DELTA; 254 + break; 255 + case TRACE_TYPE_OUTDENT: 256 + *prefix -= PREFIX_DELTA; 257 + if (*prefix < BASE_PREFIX) 258 + *prefix = BASE_PREFIX; 259 + trace_print_header(seq, *prefix); 260 + puts("}"); 261 + break; 262 + default: 263 + trace_print_header(seq, *prefix); 264 + printf("entry @ %p type %d\n", e, e->type); 265 + break; 266 + } 267 + } 268 + 269 + void trace_buffer_print(struct trace_buffer *tb) 270 + { 271 + struct trace_entry *e; 272 + int i, prefix; 273 + void *p; 274 + 275 + printf("Trace buffer dump:\n"); 276 + printf(" address %p \n", tb); 277 + printf(" tail %p\n", tb->tail); 278 + printf(" size %llu\n", tb->size); 279 + printf(" overflow %s\n", tb->overflow ? "TRUE" : "false"); 280 + printf(" Content:\n"); 281 + 282 + p = tb->data; 283 + 284 + i = 0; 285 + prefix = BASE_PREFIX; 286 + 287 + while (trace_check_bounds(tb, p) && p < tb->tail) { 288 + e = p; 289 + 290 + trace_print_entry(e, i, &prefix); 291 + 292 + i++; 293 + p = (void *)e + sizeof(*e) + e->length; 294 + } 295 + } 296 + 297 + void trace_print_location(struct trace_buffer *tb) 298 + { 299 + printf("Trace buffer 0x%llx bytes @ %p\n", tb->size, tb); 300 + }
+41
tools/testing/selftests/powerpc/pmu/ebb/trace.h
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #ifndef _SELFTESTS_POWERPC_PMU_EBB_TRACE_H 7 + #define _SELFTESTS_POWERPC_PMU_EBB_TRACE_H 8 + 9 + #include "utils.h" 10 + 11 + #define TRACE_TYPE_REG 1 12 + #define TRACE_TYPE_COUNTER 2 13 + #define TRACE_TYPE_STRING 3 14 + #define TRACE_TYPE_INDENT 4 15 + #define TRACE_TYPE_OUTDENT 5 16 + 17 + struct trace_entry 18 + { 19 + u8 type; 20 + u8 length; 21 + u8 data[0]; 22 + }; 23 + 24 + struct trace_buffer 25 + { 26 + u64 size; 27 + bool overflow; 28 + void *tail; 29 + u8 data[0]; 30 + }; 31 + 32 + struct trace_buffer *trace_buffer_allocate(u64 size); 33 + int trace_log_reg(struct trace_buffer *tb, u64 reg, u64 value); 34 + int trace_log_counter(struct trace_buffer *tb, u64 value); 35 + int trace_log_string(struct trace_buffer *tb, char *str); 36 + int trace_log_indent(struct trace_buffer *tb); 37 + int trace_log_outdent(struct trace_buffer *tb); 38 + void trace_buffer_print(struct trace_buffer *tb); 39 + void trace_print_location(struct trace_buffer *tb); 40 + 41 + #endif /* _SELFTESTS_POWERPC_PMU_EBB_TRACE_H */
+26
tools/testing/selftests/powerpc/pmu/event.c
··· 39 39 event_init_opts(e, config, PERF_TYPE_RAW, name); 40 40 } 41 41 42 + void event_init(struct event *e, u64 config) 43 + { 44 + event_init_opts(e, config, PERF_TYPE_RAW, "event"); 45 + } 46 + 42 47 #define PERF_CURRENT_PID 0 48 + #define PERF_NO_PID -1 43 49 #define PERF_NO_CPU -1 44 50 #define PERF_NO_GROUP -1 45 51 ··· 65 59 return event_open_with_options(e, PERF_CURRENT_PID, PERF_NO_CPU, group_fd); 66 60 } 67 61 62 + int event_open_with_pid(struct event *e, pid_t pid) 63 + { 64 + return event_open_with_options(e, pid, PERF_NO_CPU, PERF_NO_GROUP); 65 + } 66 + 67 + int event_open_with_cpu(struct event *e, int cpu) 68 + { 69 + return event_open_with_options(e, PERF_NO_PID, cpu, PERF_NO_GROUP); 70 + } 71 + 68 72 int event_open(struct event *e) 69 73 { 70 74 return event_open_with_options(e, PERF_CURRENT_PID, PERF_NO_CPU, PERF_NO_GROUP); ··· 83 67 void event_close(struct event *e) 84 68 { 85 69 close(e->fd); 70 + } 71 + 72 + int event_enable(struct event *e) 73 + { 74 + return ioctl(e->fd, PERF_EVENT_IOC_ENABLE); 75 + } 76 + 77 + int event_disable(struct event *e) 78 + { 79 + return ioctl(e->fd, PERF_EVENT_IOC_DISABLE); 86 80 } 87 81 88 82 int event_reset(struct event *e)
+4
tools/testing/selftests/powerpc/pmu/event.h
··· 29 29 void event_init_opts(struct event *e, u64 config, int type, char *name); 30 30 int event_open_with_options(struct event *e, pid_t pid, int cpu, int group_fd); 31 31 int event_open_with_group(struct event *e, int group_fd); 32 + int event_open_with_pid(struct event *e, pid_t pid); 33 + int event_open_with_cpu(struct event *e, int cpu); 32 34 int event_open(struct event *e); 33 35 void event_close(struct event *e); 36 + int event_enable(struct event *e); 37 + int event_disable(struct event *e); 34 38 int event_reset(struct event *e); 35 39 int event_read(struct event *e); 36 40 void event_report_justified(struct event *e, int name_width, int result_width);
+252
tools/testing/selftests/powerpc/pmu/lib.c
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #define _GNU_SOURCE /* For CPU_ZERO etc. */ 7 + 8 + #include <errno.h> 9 + #include <sched.h> 10 + #include <setjmp.h> 11 + #include <stdlib.h> 12 + #include <sys/wait.h> 13 + 14 + #include "utils.h" 15 + #include "lib.h" 16 + 17 + 18 + int pick_online_cpu(void) 19 + { 20 + cpu_set_t mask; 21 + int cpu; 22 + 23 + CPU_ZERO(&mask); 24 + 25 + if (sched_getaffinity(0, sizeof(mask), &mask)) { 26 + perror("sched_getaffinity"); 27 + return -1; 28 + } 29 + 30 + /* We prefer a primary thread, but skip 0 */ 31 + for (cpu = 8; cpu < CPU_SETSIZE; cpu += 8) 32 + if (CPU_ISSET(cpu, &mask)) 33 + return cpu; 34 + 35 + /* Search for anything, but in reverse */ 36 + for (cpu = CPU_SETSIZE - 1; cpu >= 0; cpu--) 37 + if (CPU_ISSET(cpu, &mask)) 38 + return cpu; 39 + 40 + printf("No cpus in affinity mask?!\n"); 41 + return -1; 42 + } 43 + 44 + int bind_to_cpu(int cpu) 45 + { 46 + cpu_set_t mask; 47 + 48 + printf("Binding to cpu %d\n", cpu); 49 + 50 + CPU_ZERO(&mask); 51 + CPU_SET(cpu, &mask); 52 + 53 + return sched_setaffinity(0, sizeof(mask), &mask); 54 + } 55 + 56 + #define PARENT_TOKEN 0xAA 57 + #define CHILD_TOKEN 0x55 58 + 59 + int sync_with_child(union pipe read_pipe, union pipe write_pipe) 60 + { 61 + char c = PARENT_TOKEN; 62 + 63 + FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1); 64 + FAIL_IF(read(read_pipe.read_fd, &c, 1) != 1); 65 + if (c != CHILD_TOKEN) /* sometimes expected */ 66 + return 1; 67 + 68 + return 0; 69 + } 70 + 71 + int wait_for_parent(union pipe read_pipe) 72 + { 73 + char c; 74 + 75 + FAIL_IF(read(read_pipe.read_fd, &c, 1) != 1); 76 + FAIL_IF(c != PARENT_TOKEN); 77 + 78 + return 0; 79 + } 80 + 81 + int notify_parent(union pipe write_pipe) 82 + { 83 + char c = CHILD_TOKEN; 84 + 85 + FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1); 86 + 87 + return 0; 88 + } 89 + 90 + int notify_parent_of_error(union pipe write_pipe) 91 + { 92 + char c = ~CHILD_TOKEN; 93 + 94 + FAIL_IF(write(write_pipe.write_fd, &c, 1) != 1); 95 + 96 + return 0; 97 + } 98 + 99 + int wait_for_child(pid_t child_pid) 100 + { 101 + int rc; 102 + 103 + if (waitpid(child_pid, &rc, 0) == -1) { 104 + perror("waitpid"); 105 + return 1; 106 + } 107 + 108 + if (WIFEXITED(rc)) 109 + rc = WEXITSTATUS(rc); 110 + else 111 + rc = 1; /* Signal or other */ 112 + 113 + return rc; 114 + } 115 + 116 + int kill_child_and_wait(pid_t child_pid) 117 + { 118 + kill(child_pid, SIGTERM); 119 + 120 + return wait_for_child(child_pid); 121 + } 122 + 123 + static int eat_cpu_child(union pipe read_pipe, union pipe write_pipe) 124 + { 125 + volatile int i = 0; 126 + 127 + /* 128 + * We are just here to eat cpu and die. So make sure we can be killed, 129 + * and also don't do any custom SIGTERM handling. 130 + */ 131 + signal(SIGTERM, SIG_DFL); 132 + 133 + notify_parent(write_pipe); 134 + wait_for_parent(read_pipe); 135 + 136 + /* Soak up cpu forever */ 137 + while (1) i++; 138 + 139 + return 0; 140 + } 141 + 142 + pid_t eat_cpu(int (test_function)(void)) 143 + { 144 + union pipe read_pipe, write_pipe; 145 + int cpu, rc; 146 + pid_t pid; 147 + 148 + cpu = pick_online_cpu(); 149 + FAIL_IF(cpu < 0); 150 + FAIL_IF(bind_to_cpu(cpu)); 151 + 152 + if (pipe(read_pipe.fds) == -1) 153 + return -1; 154 + 155 + if (pipe(write_pipe.fds) == -1) 156 + return -1; 157 + 158 + pid = fork(); 159 + if (pid == 0) 160 + exit(eat_cpu_child(write_pipe, read_pipe)); 161 + 162 + if (sync_with_child(read_pipe, write_pipe)) { 163 + rc = -1; 164 + goto out; 165 + } 166 + 167 + printf("main test running as pid %d\n", getpid()); 168 + 169 + rc = test_function(); 170 + out: 171 + kill(pid, SIGKILL); 172 + 173 + return rc; 174 + } 175 + 176 + struct addr_range libc, vdso; 177 + 178 + int parse_proc_maps(void) 179 + { 180 + char execute, name[128]; 181 + uint64_t start, end; 182 + FILE *f; 183 + int rc; 184 + 185 + f = fopen("/proc/self/maps", "r"); 186 + if (!f) { 187 + perror("fopen"); 188 + return -1; 189 + } 190 + 191 + do { 192 + /* This skips line with no executable which is what we want */ 193 + rc = fscanf(f, "%lx-%lx %*c%*c%c%*c %*x %*d:%*d %*d %127s\n", 194 + &start, &end, &execute, name); 195 + if (rc <= 0) 196 + break; 197 + 198 + if (execute != 'x') 199 + continue; 200 + 201 + if (strstr(name, "libc")) { 202 + libc.first = start; 203 + libc.last = end - 1; 204 + } else if (strstr(name, "[vdso]")) { 205 + vdso.first = start; 206 + vdso.last = end - 1; 207 + } 208 + } while(1); 209 + 210 + fclose(f); 211 + 212 + return 0; 213 + } 214 + 215 + #define PARANOID_PATH "/proc/sys/kernel/perf_event_paranoid" 216 + 217 + bool require_paranoia_below(int level) 218 + { 219 + unsigned long current; 220 + char *end, buf[16]; 221 + FILE *f; 222 + int rc; 223 + 224 + rc = -1; 225 + 226 + f = fopen(PARANOID_PATH, "r"); 227 + if (!f) { 228 + perror("fopen"); 229 + goto out; 230 + } 231 + 232 + if (!fgets(buf, sizeof(buf), f)) { 233 + printf("Couldn't read " PARANOID_PATH "?\n"); 234 + goto out_close; 235 + } 236 + 237 + current = strtoul(buf, &end, 10); 238 + 239 + if (end == buf) { 240 + printf("Couldn't parse " PARANOID_PATH "?\n"); 241 + goto out_close; 242 + } 243 + 244 + if (current >= level) 245 + goto out; 246 + 247 + rc = 0; 248 + out_close: 249 + fclose(f); 250 + out: 251 + return rc; 252 + }
+41
tools/testing/selftests/powerpc/pmu/lib.h
··· 1 + /* 2 + * Copyright 2014, Michael Ellerman, IBM Corp. 3 + * Licensed under GPLv2. 4 + */ 5 + 6 + #ifndef __SELFTESTS_POWERPC_PMU_LIB_H 7 + #define __SELFTESTS_POWERPC_PMU_LIB_H 8 + 9 + #include <stdio.h> 10 + #include <stdint.h> 11 + #include <string.h> 12 + #include <unistd.h> 13 + 14 + union pipe { 15 + struct { 16 + int read_fd; 17 + int write_fd; 18 + }; 19 + int fds[2]; 20 + }; 21 + 22 + extern int pick_online_cpu(void); 23 + extern int bind_to_cpu(int cpu); 24 + extern int kill_child_and_wait(pid_t child_pid); 25 + extern int wait_for_child(pid_t child_pid); 26 + extern int sync_with_child(union pipe read_pipe, union pipe write_pipe); 27 + extern int wait_for_parent(union pipe read_pipe); 28 + extern int notify_parent(union pipe write_pipe); 29 + extern int notify_parent_of_error(union pipe write_pipe); 30 + extern pid_t eat_cpu(int (test_function)(void)); 31 + extern bool require_paranoia_below(int level); 32 + 33 + struct addr_range { 34 + uint64_t first, last; 35 + }; 36 + 37 + extern struct addr_range libc, vdso; 38 + 39 + int parse_proc_maps(void); 40 + 41 + #endif /* __SELFTESTS_POWERPC_PMU_LIB_H */
+35 -38
tools/testing/selftests/powerpc/pmu/loop.S
··· 3 3 * Licensed under GPLv2. 4 4 */ 5 5 6 + #include <ppc-asm.h> 7 + 6 8 .text 7 9 8 - .global thirty_two_instruction_loop 9 - .type .thirty_two_instruction_loop,@function 10 - .section ".opd","aw",@progbits 11 - thirty_two_instruction_loop: 12 - .quad .thirty_two_instruction_loop, .TOC.@tocbase, 0 13 - .previous 14 - .thirty_two_instruction_loop: 15 - cmpwi %r3,0 10 + FUNC_START(thirty_two_instruction_loop) 11 + cmpdi r3,0 16 12 beqlr 17 - addi %r4,%r3,1 18 - addi %r4,%r4,1 19 - addi %r4,%r4,1 20 - addi %r4,%r4,1 21 - addi %r4,%r4,1 22 - addi %r4,%r4,1 23 - addi %r4,%r4,1 24 - addi %r4,%r4,1 25 - addi %r4,%r4,1 26 - addi %r4,%r4,1 27 - addi %r4,%r4,1 28 - addi %r4,%r4,1 29 - addi %r4,%r4,1 30 - addi %r4,%r4,1 31 - addi %r4,%r4,1 32 - addi %r4,%r4,1 33 - addi %r4,%r4,1 34 - addi %r4,%r4,1 35 - addi %r4,%r4,1 36 - addi %r4,%r4,1 37 - addi %r4,%r4,1 38 - addi %r4,%r4,1 39 - addi %r4,%r4,1 40 - addi %r4,%r4,1 41 - addi %r4,%r4,1 42 - addi %r4,%r4,1 43 - addi %r4,%r4,1 44 - addi %r4,%r4,1 # 28 addi's 45 - subi %r3,%r3,1 46 - b .thirty_two_instruction_loop 13 + addi r4,r3,1 14 + addi r4,r4,1 15 + addi r4,r4,1 16 + addi r4,r4,1 17 + addi r4,r4,1 18 + addi r4,r4,1 19 + addi r4,r4,1 20 + addi r4,r4,1 21 + addi r4,r4,1 22 + addi r4,r4,1 23 + addi r4,r4,1 24 + addi r4,r4,1 25 + addi r4,r4,1 26 + addi r4,r4,1 27 + addi r4,r4,1 28 + addi r4,r4,1 29 + addi r4,r4,1 30 + addi r4,r4,1 31 + addi r4,r4,1 32 + addi r4,r4,1 33 + addi r4,r4,1 34 + addi r4,r4,1 35 + addi r4,r4,1 36 + addi r4,r4,1 37 + addi r4,r4,1 38 + addi r4,r4,1 39 + addi r4,r4,1 40 + addi r4,r4,1 # 28 addi's 41 + subi r3,r3,1 42 + b FUNC_NAME(thirty_two_instruction_loop) 43 + FUNC_END(thirty_two_instruction_loop)
+5
tools/testing/selftests/powerpc/subunit.h
··· 26 26 printf("error: %s\n", name); 27 27 } 28 28 29 + static inline void test_skip(char *name) 30 + { 31 + printf("skip: %s\n", name); 32 + } 33 + 29 34 static inline void test_success(char *name) 30 35 { 31 36 printf("success: %s\n", name);
+15
tools/testing/selftests/powerpc/tm/Makefile
··· 1 + PROGS := tm-resched-dscr 2 + 3 + all: $(PROGS) 4 + 5 + $(PROGS): 6 + 7 + run_tests: all 8 + @-for PROG in $(PROGS); do \ 9 + ./$$PROG; \ 10 + done; 11 + 12 + clean: 13 + rm -f $(PROGS) *.o 14 + 15 + .PHONY: all run_tests clean
+90
tools/testing/selftests/powerpc/tm/tm-resched-dscr.c
··· 1 + /* Test context switching to see if the DSCR SPR is correctly preserved 2 + * when within a transaction. 3 + * 4 + * Note: We assume that the DSCR has been left at the default value (0) 5 + * for all CPUs. 6 + * 7 + * Method: 8 + * 9 + * Set a value into the DSCR. 10 + * 11 + * Start a transaction, and suspend it (*). 12 + * 13 + * Hard loop checking to see if the transaction has become doomed. 14 + * 15 + * Now that we *may* have been preempted, record the DSCR and TEXASR SPRS. 16 + * 17 + * If the abort was because of a context switch, check the DSCR value. 18 + * Otherwise, try again. 19 + * 20 + * (*) If the transaction is not suspended we can't see the problem because 21 + * the transaction abort handler will restore the DSCR to it's checkpointed 22 + * value before we regain control. 23 + */ 24 + 25 + #include <inttypes.h> 26 + #include <stdio.h> 27 + #include <stdlib.h> 28 + #include <assert.h> 29 + #include <asm/tm.h> 30 + 31 + #define TBEGIN ".long 0x7C00051D ;" 32 + #define TEND ".long 0x7C00055D ;" 33 + #define TCHECK ".long 0x7C00059C ;" 34 + #define TSUSPEND ".long 0x7C0005DD ;" 35 + #define TRESUME ".long 0x7C2005DD ;" 36 + #define SPRN_TEXASR 0x82 37 + #define SPRN_DSCR 0x03 38 + 39 + int main(void) { 40 + uint64_t rv, dscr1 = 1, dscr2, texasr; 41 + 42 + printf("Check DSCR TM context switch: "); 43 + fflush(stdout); 44 + for (;;) { 45 + rv = 1; 46 + asm __volatile__ ( 47 + /* set a known value into the DSCR */ 48 + "ld 3, %[dscr1];" 49 + "mtspr %[sprn_dscr], 3;" 50 + 51 + /* start and suspend a transaction */ 52 + TBEGIN 53 + "beq 1f;" 54 + TSUSPEND 55 + 56 + /* hard loop until the transaction becomes doomed */ 57 + "2: ;" 58 + TCHECK 59 + "bc 4, 0, 2b;" 60 + 61 + /* record DSCR and TEXASR */ 62 + "mfspr 3, %[sprn_dscr];" 63 + "std 3, %[dscr2];" 64 + "mfspr 3, %[sprn_texasr];" 65 + "std 3, %[texasr];" 66 + 67 + TRESUME 68 + TEND 69 + "li %[rv], 0;" 70 + "1: ;" 71 + : [rv]"=r"(rv), [dscr2]"=m"(dscr2), [texasr]"=m"(texasr) 72 + : [dscr1]"m"(dscr1) 73 + , [sprn_dscr]"i"(SPRN_DSCR), [sprn_texasr]"i"(SPRN_TEXASR) 74 + : "memory", "r3" 75 + ); 76 + assert(rv); /* make sure the transaction aborted */ 77 + if ((texasr >> 56) != TM_CAUSE_RESCHED) { 78 + putchar('.'); 79 + fflush(stdout); 80 + continue; 81 + } 82 + if (dscr2 != dscr1) { 83 + printf(" FAIL\n"); 84 + exit(EXIT_FAILURE); 85 + } else { 86 + printf(" OK\n"); 87 + exit(EXIT_SUCCESS); 88 + } 89 + } 90 + }
+12
tools/testing/selftests/powerpc/utils.h
··· 31 31 } \ 32 32 } while (0) 33 33 34 + /* The test harness uses this, yes it's gross */ 35 + #define MAGIC_SKIP_RETURN_VALUE 99 36 + 37 + #define SKIP_IF(x) \ 38 + do { \ 39 + if ((x)) { \ 40 + fprintf(stderr, \ 41 + "[SKIP] Test skipped on line %d\n", __LINE__); \ 42 + return MAGIC_SKIP_RETURN_VALUE; \ 43 + } \ 44 + } while (0) 45 + 34 46 #define _str(s) #s 35 47 #define str(s) _str(s) 36 48