History

Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus

Pull MIPS updates from Ralf Baechle: - three fixes for 3.15 that didn't make it in time - limited Octeon 3 support. - paravirtualization support - improvment to platform support for Netlogix SOCs. - add support for powering down the Malta eval board in software - add many instructions to the in-kernel microassembler. - add support for the BPF JIT. - minor cleanups of the BCM47xx code. - large cleanup of math emu code resulting in significant code size reduction, better readability of the code and more accurate emulation. - improvments to the MIPS CPS code. - support C3 power status for the R4k count/compare clock device. - improvments to the GIO support for older SGI workstations. - increase number of supported CPUs to 256; this can be reached on certain embedded multithreaded ccNUMA configurations. - various small cleanups, updates and fixes * 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (173 commits) MIPS: IP22/IP28: Improve GIO support MIPS: Octeon: Add twsi interrupt initialization for OCTEON 3XXX, 5XXX, 63XX DEC: Document the R4k MB ASIC mini interrupt controller DEC: Add self as the maintainer MIPS: Add microMIPS MSA support. MIPS: Replace calls to obsolete strict_strto call with kstrto* equivalents. MIPS: Replace obsolete strict_strto call with kstrto MIPS: BFP: Simplify code slightly. MIPS: Call find_vma with the mmap_sem held MIPS: Fix 'write_msa_##' inline macro. MIPS: Fix MSA toolchain support detection. mips: Update the email address of Geert Uytterhoeven MIPS: Add minimal defconfig for mips_paravirt MIPS: Enable build for new system 'paravirt' MIPS: paravirt: Add pci controller for virtio MIPS: Add code for new system 'paravirt' MIPS: Add functions for hypervisor call MIPS: OCTEON: Add OCTEON3 to __get_cpu_type MIPS: Add function get_ebase_cpunum MIPS: Add minimal support for OCTEON3 to c-r4k.c ...

Linus Torvalds committed 12 years ago

Commit 82abb272 parents 9b651cc f8647b5256 files · +8562 −7905Browse files

Unified · Split

256 files
  1. MAINTAINERS +9 −0
  2. arch/mips/Kbuild +1 −1
  3. arch/mips/Kbuild.platforms +1 −0
  4. arch/mips/Kconfig +71 −71
  5. arch/mips/Kconfig.debug +0 −9
  6. arch/mips/Makefile +2 −1
  7. arch/mips/alchemy/board-xxs1500.c +1 −1
  8. arch/mips/alchemy/common/setup.c +6 −0
  9. arch/mips/alchemy/common/usb.c +2 −24
  10. arch/mips/alchemy/devboards/pm.c +2 −2
  11. arch/mips/bcm47xx/prom.c +11 −8
  12. arch/mips/cavium-octeon/Kconfig +11 −12
  13. arch/mips/cavium-octeon/executive/cvmx-helper.c +166 −0
  14. arch/mips/cavium-octeon/octeon-irq.c +2 −0
  15. arch/mips/cavium-octeon/setup.c +0 −17
  16. arch/mips/cavium-octeon/smp.c +0 −25
  17. arch/mips/configs/ath79_defconfig +1 −2
  18. arch/mips/configs/db1xxx_defconfig +1 −0
  19. arch/mips/configs/maltasmtc_defconfig +0 −196
  20. arch/mips/configs/maltasmvp_defconfig +1 −2
  21. arch/mips/configs/maltasmvp_eva_defconfig +1 −2
  22. arch/mips/configs/mips_paravirt_defconfig +103 −0
  23. arch/mips/configs/rt305x_defconfig +1 −1
  24. arch/mips/dec/setup.c +5 −0
  25. arch/mips/include/asm/asmmacro.h +34 −28
  26. arch/mips/include/asm/branch.h +30 −0
  27. arch/mips/include/asm/cacheflush.h +6 −0
  28. arch/mips/include/asm/cmp.h +0 −1
  29. arch/mips/include/asm/cpu-features.h +19 −1
  30. arch/mips/include/asm/cpu-info.h +4 −9
  31. arch/mips/include/asm/cpu-type.h +1 −3
  32. arch/mips/include/asm/cpu.h +2 −1
  33. arch/mips/include/asm/dec/kn05.h +12 −3
  34. arch/mips/include/asm/fixmap.h +0 −4
  35. arch/mips/include/asm/fpu.h +4 −3
  36. arch/mips/include/asm/fpu_emulator.h +21 −0
  37. arch/mips/include/asm/gic.h +1 −0
  38. arch/mips/include/asm/gio_device.h +2 −2
  39. arch/mips/include/asm/idle.h +14 −0
  40. arch/mips/include/asm/irq.h +0 −96
  41. arch/mips/include/asm/irqflags.h +3 −29
  42. arch/mips/include/asm/kvm_para.h +109 −0
  43. arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h +0 −1
  44. arch/mips/include/asm/mach-cavium-octeon/irq.h +2 −0
  45. arch/mips/include/asm/mach-ip22/cpu-feature-overrides.h +4 −0
  46. arch/mips/include/asm/mach-malta/kernel-entry-init.h +0 −30
  47. arch/mips/include/asm/mach-malta/malta-pm.h +37 −0
  48. arch/mips/include/asm/mach-netlogic/topology.h +2 −0
  49. arch/mips/include/asm/mach-paravirt/cpu-feature-overrides.h +36 −0
  50. arch/mips/include/asm/mach-paravirt/irq.h +19 −0
  51. arch/mips/include/asm/mach-paravirt/kernel-entry-init.h +50 −0
  52. arch/mips/include/asm/mach-paravirt/war.h +25 −0
  53. arch/mips/include/asm/mach-pmcs-msp71xx/msp_usb.h +0 −4
  54. arch/mips/include/asm/mach-ralink/war.h +0 −1
  55. arch/mips/include/asm/mach-sead3/kernel-entry-init.h +0 −31
  56. arch/mips/include/asm/mips-boards/piix4.h +12 −0
  57. arch/mips/include/asm/mips-cpc.h +33 −1
  58. arch/mips/include/asm/mips_mt.h +2 −3
  59. arch/mips/include/asm/mipsmtregs.h +2 −0
  60. arch/mips/include/asm/mipsregs.h +18 −133
  61. arch/mips/include/asm/mmu_context.h +11 −111
  62. arch/mips/include/asm/module.h +1 −7
  63. arch/mips/include/asm/msa.h +12 −3
  64. arch/mips/include/asm/netlogic/mips-extns.h +3 −2
  65. arch/mips/include/asm/netlogic/xlp-hal/iomap.h +11 −7
  66. arch/mips/include/asm/netlogic/xlp-hal/pcibus.h +14 −0
  67. arch/mips/include/asm/netlogic/xlp-hal/pic.h +4 −0
  68. arch/mips/include/asm/netlogic/xlp-hal/sys.h +35 −0
  69. arch/mips/include/asm/netlogic/xlp-hal/xlp.h +13 −6
  70. arch/mips/include/asm/nile4.h +1 −1
  71. arch/mips/include/asm/octeon/octeon.h +0 −1
  72. arch/mips/include/asm/pgtable.h +2 −0
  73. arch/mips/include/asm/pm-cps.h +51 −0
  74. arch/mips/include/asm/pm.h +159 −0
  75. arch/mips/include/asm/ptrace.h +0 −3
  76. arch/mips/include/asm/r4kcache.h +4 −3
  77. arch/mips/include/asm/sgi/ip22.h +2 −0
  78. arch/mips/include/asm/smp-cps.h +15 −4
  79. arch/mips/include/asm/smp-ops.h +0 −1
  80. arch/mips/include/asm/smp.h +3 −0
  81. arch/mips/include/asm/smtc.h +0 −78
  82. arch/mips/include/asm/smtc_ipi.h +0 −129
  83. arch/mips/include/asm/smtc_proc.h +0 −23
  84. arch/mips/include/asm/stackframe.h +1 −195
  85. arch/mips/include/asm/thread_info.h +1 −10
  86. arch/mips/include/asm/time.h +1 −4
  87. arch/mips/include/asm/timex.h +47 −18
  88. arch/mips/include/asm/uasm.h +23 −0
  89. arch/mips/include/uapi/asm/Kbuild +1 −0
  90. arch/mips/include/uapi/asm/bitfield.h +29 −0
  91. arch/mips/include/uapi/asm/inst.h +35 −29
  92. arch/mips/include/uapi/asm/kvm_para.h +5 −1
  93. arch/mips/include/uapi/asm/types.h +4 −1
  94. arch/mips/kernel/Makefile +4 −3
  95. arch/mips/kernel/asm-offsets.c +24 −8
  96. arch/mips/kernel/branch.c +201 −1
  97. arch/mips/kernel/cevt-gic.c +3 −2
  98. arch/mips/kernel/cevt-r4k.c +3 −21
  99. arch/mips/kernel/cevt-smtc.c +0 −324
  100. arch/mips/kernel/cps-vec.S +312 −16
  101. arch/mips/kernel/cpu-probe.c +4 −17
  102. arch/mips/kernel/entry.S +0 −38
  103. arch/mips/kernel/genex.S +0 −54
  104. arch/mips/kernel/head.S +0 −56
  105. arch/mips/kernel/i8259.c +0 −4
  106. arch/mips/kernel/idle.c +11 −14
  107. arch/mips/kernel/irq-gic.c +15 −0
  108. arch/mips/kernel/irq-msc01.c +0 −5
  109. arch/mips/kernel/irq.c +0 −17
  110. arch/mips/kernel/mips-cpc.c +28 −0
  111. arch/mips/kernel/mips-mt-fpaff.c +1 −1
  112. arch/mips/kernel/mips-mt.c +1 −17
  113. arch/mips/kernel/octeon_switch.S +61 −23
  114. arch/mips/kernel/pm-cps.c +716 −0
  115. arch/mips/kernel/pm.c +99 −0
  116. arch/mips/kernel/process.c +0 −7
  117. arch/mips/kernel/r4k_switch.S +3 −33
  118. arch/mips/kernel/rtlx-mt.c +0 −1
  119. arch/mips/kernel/smp-bmips.c +0 −9
  120. arch/mips/kernel/smp-cmp.c +1 −14
  121. arch/mips/kernel/smp-cps.c +281 −150
  122. arch/mips/kernel/smp-gic.c +11 −0
  123. arch/mips/kernel/smp-mt.c +0 −5
  124. arch/mips/kernel/smp-up.c +0 −6
  125. arch/mips/kernel/smp.c +47 −14
  126. arch/mips/kernel/smtc-asm.S +0 −133
  127. arch/mips/kernel/smtc-proc.c +0 −102
  128. arch/mips/kernel/smtc.c +0 −1528
  129. arch/mips/kernel/sync-r4k.c +0 −18
  130. arch/mips/kernel/time.c +0 −1
  131. arch/mips/kernel/traps.c +54 −68
  132. arch/mips/kernel/vpe-mt.c +7 −9
  133. arch/mips/lantiq/irq.c +2 −2
  134. arch/mips/lib/delay.c +3 −5
  135. arch/mips/lib/mips-atomic.c +6 −40
  136. arch/mips/loongson/Kconfig +3 −2
  137. arch/mips/loongson/loongson-3/smp.c +0 −8
  138. arch/mips/loongson1/Kconfig +1 −0
  139. arch/mips/math-emu/Makefile +9 −7
  140. arch/mips/math-emu/cp1emu.c +340 −594
  141. arch/mips/math-emu/dp_add.c +36 −35
  142. arch/mips/math-emu/dp_cmp.c +11 −13
  143. arch/mips/math-emu/dp_div.c +46 −48
  144. arch/mips/math-emu/dp_fint.c +5 −28
  145. arch/mips/math-emu/dp_flong.c +8 −20
  146. arch/mips/math-emu/dp_frexp.c +0 −52
  147. arch/mips/math-emu/dp_fsp.c +16 −16
  148. arch/mips/math-emu/dp_logb.c +0 −53
  149. arch/mips/math-emu/dp_modf.c +0 −79
  150. arch/mips/math-emu/dp_mul.c +70 −73
  151. arch/mips/math-emu/dp_scalb.c +0 −57
  152. arch/mips/math-emu/dp_simple.c +10 −29
  153. arch/mips/math-emu/dp_sqrt.c +23 −23
  154. arch/mips/math-emu/dp_sub.c +27 −28
  155. arch/mips/math-emu/dp_tint.c +26 −43
  156. arch/mips/math-emu/dp_tlong.c +26 −42
  157. arch/mips/math-emu/dsemul.c +7 −28
  158. arch/mips/math-emu/ieee754.c +54 −92
  159. arch/mips/math-emu/ieee754.h +92 −230
  160. arch/mips/math-emu/ieee754d.c +7 −32
  161. arch/mips/math-emu/ieee754dp.c +42 −80
  162. arch/mips/math-emu/ieee754dp.h +35 −35
  163. arch/mips/math-emu/ieee754int.h +89 −112
  164. arch/mips/math-emu/ieee754m.c +0 −55
  165. arch/mips/math-emu/ieee754sp.c +43 −83
  166. arch/mips/math-emu/ieee754sp.h +39 −40
  167. arch/mips/math-emu/ieee754xcpt.c +0 −47
  168. arch/mips/math-emu/kernel_linkage.c +0 −45
  169. arch/mips/math-emu/me-debugfs.c +67 −0
  170. arch/mips/math-emu/sp_add.c +38 −34
  171. arch/mips/math-emu/sp_cmp.c +11 −13
  172. arch/mips/math-emu/sp_div.c +45 −48
  173. arch/mips/math-emu/sp_fdp.c +28 −28
  174. arch/mips/math-emu/sp_fint.c +8 −22
  175. arch/mips/math-emu/sp_flong.c +8 −22
  176. arch/mips/math-emu/sp_frexp.c +0 −52
  177. arch/mips/math-emu/sp_logb.c +0 −53
  178. arch/mips/math-emu/sp_modf.c +0 −79
  179. arch/mips/math-emu/sp_mul.c +67 −72
  180. arch/mips/math-emu/sp_scalb.c +0 −57
  181. arch/mips/math-emu/sp_simple.c +10 −29
  182. arch/mips/math-emu/sp_sqrt.c +17 −18
  183. arch/mips/math-emu/sp_sub.c +28 −29
  184. arch/mips/math-emu/sp_tint.c +25 −42
  185. arch/mips/math-emu/sp_tlong.c +27 −42
  186. arch/mips/mm/c-octeon.c +2 −0
  187. arch/mips/mm/c-r4k.c +70 −7
  188. arch/mips/mm/init.c +17 −65
  189. arch/mips/mm/tlb-r4k.c +49 −39
  190. arch/mips/mm/tlbex.c +1 −1
  191. arch/mips/mm/uasm-micromips.c +14 −0
  192. arch/mips/mm/uasm-mips.c +15 −0
  193. arch/mips/mm/uasm.c +45 −6
  194. arch/mips/mti-malta/Makefile +1 −2
  195. arch/mips/mti-malta/malta-init.c +0 −6
  196. arch/mips/mti-malta/malta-int.c +0 −19
  197. arch/mips/mti-malta/malta-memory.c +2 −2
  198. arch/mips/mti-malta/malta-pm.c +96 −0
  199. arch/mips/mti-malta/malta-reset.c +10 −4
  200. arch/mips/mti-malta/malta-setup.c +0 −4
  201. arch/mips/mti-malta/malta-smtc.c +0 −162
  202. arch/mips/mti-sead3/sead3-pic32-i2c-drv.c +13 −23
  203. arch/mips/net/Makefile +3 −0
  204. arch/mips/net/bpf_jit.c +1399 −0
  205. arch/mips/net/bpf_jit.h +44 −0
  206. arch/mips/netlogic/common/irq.c +2 −0
  207. arch/mips/netlogic/common/reset.S +30 −9
  208. arch/mips/netlogic/common/smp.c +4 −8
  209. arch/mips/netlogic/common/smpboot.S +8 −4
  210. arch/mips/netlogic/common/time.c +4 −1
  211. arch/mips/netlogic/dts/xlp_gvp.dts +3 −2
  212. arch/mips/netlogic/xlp/Makefile +2 −0
  213. arch/mips/netlogic/xlp/ahci-init-xlp2.c +377 −0
  214. arch/mips/netlogic/xlp/ahci-init.c +209 −0
  215. arch/mips/netlogic/xlp/dt.c +2 −1
  216. arch/mips/netlogic/xlp/nlm_hal.c +204 −79
  217. arch/mips/netlogic/xlp/setup.c +2 −1
  218. arch/mips/netlogic/xlp/wakeup.c +10 −6
  219. arch/mips/paravirt/Kconfig +6 −0
  220. arch/mips/paravirt/Makefile +14 −0
  221. arch/mips/paravirt/Platform +8 −0
  222. arch/mips/paravirt/paravirt-irq.c +368 −0
  223. arch/mips/paravirt/paravirt-smp.c +143 −0
  224. arch/mips/paravirt/serial.c +40 −0
  225. arch/mips/paravirt/setup.c +67 −0
  226. arch/mips/pci/Makefile +1 −1
  227. arch/mips/pci/fixup-malta.c +6 −0
  228. arch/mips/pci/msi-octeon.c +6 −0
  229. arch/mips/pci/msi-xlp.c +135 −49
  230. arch/mips/pci/ops-pmcmsp.c +1 −1
  231. arch/mips/pci/ops-tx3927.c +1 −1
  232. arch/mips/pci/ops-tx4927.c +6 −3
  233. arch/mips/pci/pci-virtio-guest.c +131 −0
  234. arch/mips/pmcs-msp71xx/Makefile +0 −1
  235. arch/mips/pmcs-msp71xx/msp_eth.c +0 −76
  236. arch/mips/pmcs-msp71xx/msp_irq.c +5 −11
  237. arch/mips/pmcs-msp71xx/msp_irq_cic.c +1 −6
  238. arch/mips/pmcs-msp71xx/msp_irq_per.c +0 −3
  239. arch/mips/pmcs-msp71xx/msp_setup.c +1 −16
  240. arch/mips/pmcs-msp71xx/msp_smtc.c +0 −104
  241. arch/mips/pmcs-msp71xx/msp_usb.c +0 −90
  242. arch/mips/pnx833x/common/platform.c +0 −73
  243. arch/mips/sgi-ip22/ip22-gio.c +28 −14
  244. arch/mips/sgi-ip22/ip22-int.c +6 −1
  245. arch/mips/sgi-ip27/ip27-smp.c +0 −5
  246. arch/mips/sibyte/bcm1480/irq.c +0 −11
  247. arch/mips/sibyte/bcm1480/smp.c +0 −8
  248. arch/mips/sibyte/sb1250/smp.c +0 −8
  249. arch/mips/txx9/generic/setup.c +2 −2
  250. drivers/cpuidle/Kconfig +5 −0
  251. drivers/cpuidle/Kconfig.mips +17 −0
  252. drivers/cpuidle/Makefile +4 −0
  253. drivers/cpuidle/cpuidle-cps.c +186 −0
  254. drivers/usb/host/ehci-pmcmsp.c +0 −40
  255. include/linux/cpuidle.h +1 −0
  256. include/uapi/linux/kvm_para.h +3 −0
MAINTAINERS+9−0
@@ -2700,6 +2700,15 @@ S: Orphan · 2699 unmodified lines
27002700 F: Documentation/networking/decnet.txt
27012701 F: net/decnet/
27022702
2703+DECSTATION PLATFORM SUPPORT
2704+M: "Maciej W. Rozycki" <macro@linux-mips.org>
2705+L: linux-mips@linux-mips.org
2706+W: http://www.linux-mips.org/wiki/DECstation
2707+S: Maintained
2708+F: arch/mips/dec/
2709+F: arch/mips/include/asm/dec/
2710+F: arch/mips/include/asm/mach-dec/
2711+
27032712 DEFXX FDDI NETWORK DRIVER
27042713 M: "Maciej W. Rozycki" <macro@linux-mips.org>
27052714 S: Maintained
arch/mips/Kbuild+1−1
@@ -16,7 +16,7 @@ obj- := $(platform-) · 15 unmodified lines
1616
1717 obj-y += kernel/
1818 obj-y += mm/
19−obj-y += math-emu/
19+obj-y += net/
2020
2121 ifdef CONFIG_KVM
2222 obj-y += kvm/
arch/mips/Kbuild.platforms+1−0
@@ -18,6 +18,7 @@ platforms += loongson1 · 17 unmodified lines
1818 platforms += mti-malta
1919 platforms += mti-sead3
2020 platforms += netlogic
21+platforms += paravirt
2122 platforms += pmcs-msp71xx
2223 platforms += pnx833x
2324 platforms += ralink
arch/mips/Kconfig+71−71
@@ -12,6 +12,7 @@ config MIPS · 11 unmodified lines
1212 select HAVE_ARCH_KGDB
1313 select HAVE_ARCH_SECCOMP_FILTER
1414 select HAVE_ARCH_TRACEHOOK
15+ select HAVE_BPF_JIT if !CPU_MICROMIPS
1516 select ARCH_HAVE_CUSTOM_GPIO_H
1617 select HAVE_FUNCTION_TRACER
1718 select HAVE_FUNCTION_TRACE_MCOUNT_TEST
@@ -50,6 +51,8 @@ config MIPS · 32 unmodified lines
5051 select CLONE_BACKWARDS
5152 select HAVE_DEBUG_STACKOVERFLOW
5253 select HAVE_CC_STACKPROTECTOR
54+ select CPU_PM if CPU_IDLE
55+ select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
5356
5457 menu "Machine selection"
5558
@@ -83,6 +86,7 @@ config AR7 · 27 unmodified lines
8386 select SYS_HAS_EARLY_PRINTK
8487 select SYS_SUPPORTS_32BIT_KERNEL
8588 select SYS_SUPPORTS_LITTLE_ENDIAN
89+ select SYS_SUPPORTS_MIPS16
8690 select SYS_SUPPORTS_ZBOOT_UART16550
8791 select ARCH_REQUIRE_GPIOLIB
8892 select VLYNQ
@@ -106,6 +110,7 @@ config ATH79 · 17 unmodified lines
106110 select SYS_HAS_EARLY_PRINTK
107111 select SYS_SUPPORTS_32BIT_KERNEL
108112 select SYS_SUPPORTS_BIG_ENDIAN
113+ select SYS_SUPPORTS_MIPS16
109114 help
110115 Support for the Atheros AR71XX/AR724X/AR913X SoCs.
111116
@@ -122,6 +127,7 @@ config BCM47XX · 10 unmodified lines
122127 select NO_EXCEPT_FILL
123128 select SYS_SUPPORTS_32BIT_KERNEL
124129 select SYS_SUPPORTS_LITTLE_ENDIAN
130+ select SYS_SUPPORTS_MIPS16
125131 select SYS_HAS_EARLY_PRINTK
126132 select USE_GENERIC_EARLY_PRINTK_8250
127133 help
@@ -168,9 +174,9 @@ config MACH_DECSTATION · 40 unmodified lines
168174 bool "DECstations"
169175 select BOOT_ELF32
170176 select CEVT_DS1287
171− select CEVT_R4K
177+ select CEVT_R4K if CPU_R4X00
172178 select CSRC_IOASIC
173− select CSRC_R4K
179+ select CSRC_R4K if CPU_R4X00
174180 select CPU_DADDI_WORKAROUNDS if 64BIT
175181 select CPU_R4000_WORKAROUNDS if 64BIT
176182 select CPU_R4400_WORKAROUNDS if 64BIT
@@ -248,6 +254,7 @@ config LANTIQ · 71 unmodified lines
248254 select SYS_HAS_CPU_MIPS32_R2
249255 select SYS_SUPPORTS_BIG_ENDIAN
250256 select SYS_SUPPORTS_32BIT_KERNEL
257+ select SYS_SUPPORTS_MIPS16
251258 select SYS_SUPPORTS_MULTITHREADING
252259 select SYS_HAS_EARLY_PRINTK
253260 select ARCH_REQUIRE_GPIOLIB
@@ -330,6 +337,7 @@ config MIPS_MALTA · 76 unmodified lines
330337 select SYS_SUPPORTS_LITTLE_ENDIAN
331338 select SYS_SUPPORTS_MIPS_CMP
332339 select SYS_SUPPORTS_MIPS_CPS
340+ select SYS_SUPPORTS_MIPS16
333341 select SYS_SUPPORTS_MULTITHREADING
334342 select SYS_SUPPORTS_SMARTMIPS
335343 select SYS_SUPPORTS_ZBOOT
@@ -361,6 +369,7 @@ config MIPS_SEAD3 · 25 unmodified lines
361369 select SYS_SUPPORTS_LITTLE_ENDIAN
362370 select SYS_SUPPORTS_SMARTMIPS
363371 select SYS_SUPPORTS_MICROMIPS
372+ select SYS_SUPPORTS_MIPS16
364373 select USB_EHCI_BIG_ENDIAN_DESC
365374 select USB_EHCI_BIG_ENDIAN_MMIO
366375 select USE_OF
@@ -380,6 +389,7 @@ config MACH_VR41XX · 13 unmodified lines
380389 select CEVT_R4K
381390 select CSRC_R4K
382391 select SYS_HAS_CPU_VR41XX
392+ select SYS_SUPPORTS_MIPS16
383393 select ARCH_REQUIRE_GPIOLIB
384394
385395 config NXP_STB220
@@ -407,6 +417,7 @@ config PMC_MSP · 21 unmodified lines
407417 select SYS_HAS_CPU_MIPS32_R2
408418 select SYS_SUPPORTS_32BIT_KERNEL
409419 select SYS_SUPPORTS_BIG_ENDIAN
420+ select SYS_SUPPORTS_MIPS16
410421 select IRQ_CPU
411422 select SERIAL_8250
412423 select SERIAL_8250_CONSOLE
@@ -430,6 +441,7 @@ config RALINK · 17 unmodified lines
430441 select SYS_HAS_CPU_MIPS32_R2
431442 select SYS_SUPPORTS_32BIT_KERNEL
432443 select SYS_SUPPORTS_LITTLE_ENDIAN
444+ select SYS_SUPPORTS_MIPS16
433445 select SYS_HAS_EARLY_PRINTK
434446 select HAVE_MACH_CLKDEV
435447 select CLKDEV_LOOKUP
@@ -674,7 +686,6 @@ config SNI_RM · 238 unmodified lines
674686 select SYS_SUPPORTS_BIG_ENDIAN
675687 select SYS_SUPPORTS_HIGHMEM
676688 select SYS_SUPPORTS_LITTLE_ENDIAN
677− select USE_GENERIC_EARLY_PRINTK_8250
678689 help
679690 The SNI RM200/300/400 are MIPS-based machines manufactured by
680691 Siemens Nixdorf Informationssysteme (SNI), parent company of Pyramid
@@ -721,6 +732,11 @@ config CAVIUM_OCTEON_SOC · 40 unmodified lines
721732 select ZONE_DMA32
722733 select HOLES_IN_ZONE
723734 select ARCH_REQUIRE_GPIOLIB
735+ select LIBFDT
736+ select USE_OF
737+ select ARCH_SPARSEMEM_ENABLE
738+ select SYS_SUPPORTS_SMP
739+ select NR_CPUS_DEFAULT_16
724740 help
725741 This option supports all of the Octeon reference boards from Cavium
726742 Networks. It builds a kernel that dynamically determines the Octeon
@@ -789,6 +805,25 @@ config NLM_XLP_BOARD · 62 unmodified lines
789805 This board is based on Netlogic XLP Processor.
790806 Say Y here if you have a XLP based board.
791807
808+config MIPS_PARAVIRT
809+ bool "Para-Virtualized guest system"
810+ select CEVT_R4K
811+ select CSRC_R4K
812+ select DMA_COHERENT
813+ select SYS_SUPPORTS_64BIT_KERNEL
814+ select SYS_SUPPORTS_32BIT_KERNEL
815+ select SYS_SUPPORTS_BIG_ENDIAN
816+ select SYS_SUPPORTS_SMP
817+ select NR_CPUS_DEFAULT_4
818+ select SYS_HAS_EARLY_PRINTK
819+ select SYS_HAS_CPU_MIPS32_R2
820+ select SYS_HAS_CPU_MIPS64_R2
821+ select SYS_HAS_CPU_CAVIUM_OCTEON
822+ select HW_HAS_PCI
823+ select SWAP_IO_SPACE
824+ help
825+ This option supports guest running under ????
826+
792827 endchoice
793828
794829 source "arch/mips/alchemy/Kconfig"
@@ -809,6 +844,7 @@ source "arch/mips/cavium-octeon/Kconfig" · 14 unmodified lines
809844 source "arch/mips/loongson/Kconfig"
810845 source "arch/mips/loongson1/Kconfig"
811846 source "arch/mips/netlogic/Kconfig"
847+source "arch/mips/paravirt/Kconfig"
812848
813849 endmenu
814850
@@ -1059,6 +1095,7 @@ config SOC_PNX833X · 244 unmodified lines
10591095 select SYS_SUPPORTS_32BIT_KERNEL
10601096 select SYS_SUPPORTS_LITTLE_ENDIAN
10611097 select SYS_SUPPORTS_BIG_ENDIAN
1098+ select SYS_SUPPORTS_MIPS16
10621099 select CPU_MIPSR2_IRQ_VI
10631100
10641101 config SOC_PNX8335
@@ -1398,16 +1435,11 @@ config CPU_SB1 · 333 unmodified lines
13981435 config CPU_CAVIUM_OCTEON
13991436 bool "Cavium Octeon processor"
14001437 depends on SYS_HAS_CPU_CAVIUM_OCTEON
1401− select ARCH_SPARSEMEM_ENABLE
14021438 select CPU_HAS_PREFETCH
14031439 select CPU_SUPPORTS_64BIT_KERNEL
1404− select SYS_SUPPORTS_SMP
1405− select NR_CPUS_DEFAULT_16
14061440 select WEAK_ORDERING
14071441 select CPU_SUPPORTS_HIGHMEM
14081442 select CPU_SUPPORTS_HUGEPAGES
1409− select LIBFDT
1410− select USE_OF
14111443 select USB_EHCI_BIG_ENDIAN_MMIO
14121444 select MIPS_L1_CACHE_SHIFT_7
14131445 help
@@ -1659,6 +1691,12 @@ config SYS_HAS_CPU_XLR · 245 unmodified lines
16591691 config SYS_HAS_CPU_XLP
16601692 bool
16611693
1694+config MIPS_MALTA_PM
1695+ depends on MIPS_MALTA
1696+ depends on PCI
1697+ bool
1698+ default y
1699+
16621700 #
16631701 # CPU may reorder R->R, R->W, W->R, W->W
16641702 # Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC
@@ -1842,7 +1880,7 @@ config FORCE_MAX_ZONEORDER · 177 unmodified lines
18421880
18431881 config CEVT_GIC
18441882 bool "Use GIC global counter for clock events"
1845− depends on IRQ_GIC && !(MIPS_SEAD3 || MIPS_MT_SMTC)
1883+ depends on IRQ_GIC && !MIPS_SEAD3
18461884 help
18471885 Use the GIC global counter for the clock events. The R4K clock
18481886 event driver is always present, so if the platform ends up not
@@ -1895,19 +1933,8 @@ config CPU_R4K_CACHE_TLB · 46 unmodified lines
18951933 bool
18961934 default y if !(CPU_R3000 || CPU_R8000 || CPU_SB1 || CPU_TX39XX || CPU_CAVIUM_OCTEON)
18971935
1898−choice
1899− prompt "MIPS MT options"
1900−
1901−config MIPS_MT_DISABLED
1902− bool "Disable multithreading support"
1903− help
1904− Use this option if your platform does not support the MT ASE
1905− which is hardware multithreading support. On systems without
1906− an MT-enabled processor, this will be the only option that is
1907− available in this menu.
1908−
19091936 config MIPS_MT_SMP
1910− bool "Use 1 TC on each available VPE for SMP"
1937+ bool "MIPS MT SMP support (1 TC on each available VPE)"
19111938 depends on SYS_SUPPORTS_MULTITHREADING
19121939 select CPU_MIPSR2_IRQ_VI
19131940 select CPU_MIPSR2_IRQ_EI
@@ -1926,26 +1953,6 @@ config MIPS_MT_SMP · 12 unmodified lines
19261953 Intel Hyperthreading feature. For further information go to
19271954 <http://www.imgtec.com/mips/mips-multithreading.asp>.
19281955
1929−config MIPS_MT_SMTC
1930− bool "Use all TCs on all VPEs for SMP (DEPRECATED)"
1931− depends on CPU_MIPS32_R2
1932− depends on SYS_SUPPORTS_MULTITHREADING
1933− depends on !MIPS_CPS
1934− select CPU_MIPSR2_IRQ_VI
1935− select CPU_MIPSR2_IRQ_EI
1936− select MIPS_MT
1937− select SMP
1938− select SMP_UP
1939− select SYS_SUPPORTS_SMP
1940− select NR_CPUS_DEFAULT_8
1941− help
1942− This is a kernel model which is known as SMTC. This is
1943− supported on cores with the MT ASE and presents all TCs
1944− available on all VPEs to support SMP. For further
1945− information see <http://www.linux-mips.org/wiki/34K#SMTC>.
1946−
1947−endchoice
1948−
19491956 config MIPS_MT
19501957 bool
19511958
@@ -1967,7 +1974,7 @@ config SYS_SUPPORTS_MULTITHREADING · 15 unmodified lines
19671974 config MIPS_MT_FPAFF
19681975 bool "Dynamic FPU affinity for FP-intensive threads"
19691976 default y
1970− depends on MIPS_MT_SMP || MIPS_MT_SMTC
1977+ depends on MIPS_MT_SMP
19711978
19721979 config MIPS_VPE_LOADER
19731980 bool "VPE loader support."
@@ -1989,29 +1996,6 @@ config MIPS_VPE_LOADER_MT · 15 unmodified lines
19891996 default "y"
19901997 depends on MIPS_VPE_LOADER && !MIPS_CMP
19911998
1992−config MIPS_MT_SMTC_IM_BACKSTOP
1993− bool "Use per-TC register bits as backstop for inhibited IM bits"
1994− depends on MIPS_MT_SMTC
1995− default n
1996− help
1997− To support multiple TC microthreads acting as "CPUs" within
1998− a VPE, VPE-wide interrupt mask bits must be specially manipulated
1999− during interrupt handling. To support legacy drivers and interrupt
2000− controller management code, SMTC has a "backstop" to track and
2001− if necessary restore the interrupt mask. This has some performance
2002− impact on interrupt service overhead.
2003−
2004−config MIPS_MT_SMTC_IRQAFF
2005− bool "Support IRQ affinity API"
2006− depends on MIPS_MT_SMTC
2007− default n
2008− help
2009− Enables SMP IRQ affinity API (/proc/irq/*/smp_affinity, etc.)
2010− for SMTC Linux kernel. Requires platform support, of which
2011− an example can be found in the MIPS kernel i8259 and Malta
2012− platform code. Adds some overhead to interrupt dispatch, and
2013− should be used only if you know what you are doing.
2014−
20151999 config MIPS_VPE_LOADER_TOM
20162000 bool "Load VPE program into memory hidden from linux"
20172001 depends on MIPS_VPE_LOADER
@@ -2039,7 +2023,7 @@ config MIPS_VPE_APSP_API_MT · 21 unmodified lines
20392023
20402024 config MIPS_CMP
20412025 bool "MIPS CMP framework support (DEPRECATED)"
2042− depends on SYS_SUPPORTS_MIPS_CMP && !MIPS_MT_SMTC
2026+ depends on SYS_SUPPORTS_MIPS_CMP
20432027 select MIPS_GIC_IPI
20442028 select SYNC_R4K
20452029 select WEAK_ORDERING
@@ -2057,9 +2041,11 @@ config MIPS_CPS · 11 unmodified lines
20572041 depends on SYS_SUPPORTS_MIPS_CPS
20582042 select MIPS_CM
20592043 select MIPS_CPC
2044+ select MIPS_CPS_PM if HOTPLUG_CPU
20602045 select MIPS_GIC_IPI
20612046 select SMP
20622047 select SYNC_R4K if (CEVT_R4K || CSRC_R4K)
2048+ select SYS_SUPPORTS_HOTPLUG_CPU
20632049 select SYS_SUPPORTS_SMP
20642050 select WEAK_ORDERING
20652051 help
@@ -2069,6 +2055,9 @@ config MIPS_CPS · 3 unmodified lines
20692055 no external assistance. It is safe to enable this when hardware
20702056 support is unavailable.
20712057
2058+config MIPS_CPS_PM
2059+ bool
2060+
20722061 config MIPS_GIC_IPI
20732062 bool
20742063
@@ -2199,6 +2188,13 @@ config SYS_SUPPORTS_SMARTMIPS · 124 unmodified lines
21992188 config SYS_SUPPORTS_MICROMIPS
22002189 bool
22012190
2191+config SYS_SUPPORTS_MIPS16
2192+ bool
2193+ help
2194+ This option must be set if a kernel might be executed on a MIPS16-
2195+ enabled CPU even if MIPS16 is not actually being used. In other
2196+ words, it makes the kernel MIPS16-tolerant.
2197+
22022198 config CPU_SUPPORTS_MSA
22032199 bool
22042200
@@ -2239,7 +2235,7 @@ config NODES_SHIFT · 34 unmodified lines
22392235
22402236 config HW_PERF_EVENTS
22412237 bool "Enable hardware performance counter support for perf events"
2242− depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP)
2238+ depends on PERF_EVENTS && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP)
22432239 default y
22442240 help
22452241 Enable hardware performance counter support for perf events. If
@@ -2297,8 +2293,8 @@ config NR_CPUS_DEFAULT_64 · 51 unmodified lines
22972293 bool
22982294
22992295 config NR_CPUS
2300− int "Maximum number of CPUs (2-64)"
2301− range 2 64
2296+ int "Maximum number of CPUs (2-256)"
2297+ range 2 256
23022298 depends on SMP
23032299 default "4" if NR_CPUS_DEFAULT_4
23042300 default "8" if NR_CPUS_DEFAULT_8
@@ -2671,12 +2667,16 @@ endmenu · 366 unmodified lines
26712667 config MIPS_EXTERNAL_TIMER
26722668 bool
26732669
2674−if CPU_SUPPORTS_CPUFREQ && MIPS_EXTERNAL_TIMER
26752670 menu "CPU Power Management"
2671+
2672+if CPU_SUPPORTS_CPUFREQ && MIPS_EXTERNAL_TIMER
26762673 source "drivers/cpufreq/Kconfig"
2677−endmenu
26782674 endif
26792675
2676+source "drivers/cpuidle/Kconfig"
2677+
2678+endmenu
2679+
26802680 source "net/Kconfig"
26812681
26822682 source "drivers/Kconfig"
arch/mips/Kconfig.debug+0−9
@@ -79,15 +79,6 @@ config CMDLINE_OVERRIDE · 78 unmodified lines
7979
8080 Normally, you will choose 'N' here.
8181
82−config SMTC_IDLE_HOOK_DEBUG
83− bool "Enable additional debug checks before going into CPU idle loop"
84− depends on DEBUG_KERNEL && MIPS_MT_SMTC
85− help
86− This option enables Enable additional debug checks before going into
87− CPU idle loop. For details on these checks, see
88− arch/mips/kernel/smtc.c. This debugging option result in significant
89− overhead so should be disabled in production kernels.
90−
9182 config SB1XXX_CORELIS
9283 bool "Corelis Debugger"
9384 depends on SIBYTE_SB1xxx_SOC
arch/mips/Makefile+2−1
@@ -120,7 +120,7 @@ cflags-$(CONFIG_SB1XXX_CORELIS) += $(call cc-option,-mno-sched-prolog) \ · 119 unmodified lines
120120 -fno-omit-frame-pointer
121121
122122 ifeq ($(CONFIG_CPU_HAS_MSA),y)
123−toolchain-msa := $(call cc-option-yn,-mhard-float -mfp64 -mmsa)
123+toolchain-msa := $(call cc-option-yn,-mhard-float -mfp64 -Wa$(comma)-mmsa)
124124 cflags-$(toolchain-msa) += -DTOOLCHAIN_SUPPORTS_MSA
125125 endif
126126
@@ -251,6 +251,7 @@ OBJCOPYFLAGS += --remove-section=.reginfo · 124 unmodified lines
251251 head-y := arch/mips/kernel/head.o
252252
253253 libs-y += arch/mips/lib/
254+libs-y += arch/mips/math-emu/
254255
255256 # See arch/mips/Kbuild for content of core part of the kernel
256257 core-y += arch/mips/
arch/mips/alchemy/board-xxs1500.c+1−1
@@ -49,7 +49,7 @@ void __init prom_init(void) · 48 unmodified lines
4949 prom_init_cmdline();
5050
5151 memsize_str = prom_getenv("memsize");
52− if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize))
52+ if (!memsize_str || kstrtoul(memsize_str, 0, &memsize))
5353 memsize = 0x04000000;
5454
5555 add_memory_region(0, memsize, BOOT_MEM_RAM);
arch/mips/alchemy/common/setup.c+6−0
@@ -67,6 +67,12 @@ void __init plat_mem_setup(void) · 66 unmodified lines
6767 case ALCHEMY_CPU_AU1500:
6868 case ALCHEMY_CPU_AU1100:
6969 coherentio = 0;
70+ break;
71+ case ALCHEMY_CPU_AU1200:
72+ /* Au1200 AB USB does not support coherent memory */
73+ if (0 == (read_c0_prid() & PRID_REV_MASK))
74+ coherentio = 0;
75+ break;
7076 }
7177
7278 board_setup(); /* board specific setup */
arch/mips/alchemy/common/usb.c+2−24
@@ -355,47 +355,25 @@ static inline void __au1200_udc_control(void __iomem *base, int enable) · 354 unmodified lines
355355 }
356356 }
357357
358−static inline int au1200_coherency_bug(void)
359−{
360−#if defined(CONFIG_DMA_COHERENT)
361− /* Au1200 AB USB does not support coherent memory */
362− if (!(read_c0_prid() & PRID_REV_MASK)) {
363− printk(KERN_INFO "Au1200 USB: this is chip revision AB !!\n");
364− printk(KERN_INFO "Au1200 USB: update your board or re-configure"
365− " the kernel\n");
366− return -ENODEV;
367− }
368−#endif
369− return 0;
370−}
371−
372358 static inline int au1200_usb_control(int block, int enable)
373359 {
374360 void __iomem *base =
375361 (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR);
376− int ret = 0;
377362
378363 switch (block) {
379364 case ALCHEMY_USB_OHCI0:
380− ret = au1200_coherency_bug();
381− if (ret && enable)
382− goto out;
383365 __au1200_ohci_control(base, enable);
384366 break;
385367 case ALCHEMY_USB_UDC0:
386368 __au1200_udc_control(base, enable);
387369 break;
388370 case ALCHEMY_USB_EHCI0:
389− ret = au1200_coherency_bug();
390− if (ret && enable)
391− goto out;
392371 __au1200_ehci_control(base, enable);
393372 break;
394373 default:
395− ret = -ENODEV;
374+ return -ENODEV;
396375 }
397−out:
398− return ret;
376+ return 0;
399377 }
400378
401379
arch/mips/alchemy/devboards/pm.c+2−2
@@ -158,7 +158,7 @@ static ssize_t db1x_pmattr_store(struct kobject *kobj, · 157 unmodified lines
158158 int tmp;
159159
160160 if (ATTRCMP(timer_timeout)) {
161− tmp = strict_strtoul(instr, 0, &l);
161+ tmp = kstrtoul(instr, 0, &l);
162162 if (tmp)
163163 return tmp;
164164
@@ -181,7 +181,7 @@ static ssize_t db1x_pmattr_store(struct kobject *kobj, · 16 unmodified lines
181181 }
182182
183183 } else if (ATTRCMP(wakemsk)) {
184− tmp = strict_strtoul(instr, 0, &l);
184+ tmp = kstrtoul(instr, 0, &l);
185185 if (tmp)
186186 return tmp;
187187
arch/mips/bcm47xx/prom.c+11−8
@@ -69,15 +69,18 @@ static __init void prom_init_mem(void) · 68 unmodified lines
6969 * BCM47XX uses 128MB for addressing the ram, if the system contains
7070 * less that that amount of ram it remaps the ram more often into the
7171 * available space.
72− * Accessing memory after 128MB will cause an exception.
73− * max contains the biggest possible address supported by the platform.
74− * If the method wants to try something above we assume 128MB ram.
7572 */
76− off = (unsigned long)prom_init;
77− max = off | ((128 << 20) - 1);
78− for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) {
79− if ((off + mem) > max) {
80− mem = (128 << 20);
73+
74+ /* Physical address, without mapping to any kernel segment */
75+ off = CPHYSADDR((unsigned long)prom_init);
76+
77+ /* Accessing memory after 128 MiB will cause an exception */
78+ max = 128 << 20;
79+
80+ for (mem = 1 << 20; mem < max; mem += 1 << 20) {
81+ /* Loop condition may be not enough, off may be over 1 MiB */
82+ if (off + mem >= max) {
83+ mem = max;
8184 printk(KERN_DEBUG "assume 128MB RAM\n");
8285 break;
8386 }
arch/mips/cavium-octeon/Kconfig+11−12
@@ -10,6 +10,17 @@ config CAVIUM_CN63XXP1 · 9 unmodified lines
1010 non-CN63XXP1 hardware, so it is recommended to select "n"
1111 unless it is known the workarounds are needed.
1212
13+config CAVIUM_OCTEON_CVMSEG_SIZE
14+ int "Number of L1 cache lines reserved for CVMSEG memory"
15+ range 0 54
16+ default 1
17+ help
18+ CVMSEG LM is a segment that accesses portions of the dcache as a
19+ local memory; the larger CVMSEG is, the smaller the cache is.
20+ This selects the size of CVMSEG LM, which is in cache blocks. The
21+ legally range is from zero to 54 cache blocks (i.e. CVMSEG LM is
22+ between zero and 6192 bytes).
23+
1324 endif # CPU_CAVIUM_OCTEON
1425
1526 if CAVIUM_OCTEON_SOC
@@ -23,17 +34,6 @@ config CAVIUM_OCTEON_2ND_KERNEL · 7 unmodified lines
2334 with this option to be run at the same time as one built without this
2435 option.
2536
26−config CAVIUM_OCTEON_CVMSEG_SIZE
27− int "Number of L1 cache lines reserved for CVMSEG memory"
28− range 0 54
29− default 1
30− help
31− CVMSEG LM is a segment that accesses portions of the dcache as a
32− local memory; the larger CVMSEG is, the smaller the cache is.
33− This selects the size of CVMSEG LM, which is in cache blocks. The
34− legally range is from zero to 54 cache blocks (i.e. CVMSEG LM is
35− between zero and 6192 bytes).
36−
3737 config CAVIUM_OCTEON_LOCK_L2
3838 bool "Lock often used kernel code in the L2"
3939 default "y"
@@ -86,7 +86,6 @@ config SWIOTLB · 46 unmodified lines
8686 select IOMMU_HELPER
8787 select NEED_SG_DMA_LENGTH
8888
89−
9089 config OCTEON_ILM
9190 tristate "Module to measure interrupt latency using Octeon CIU Timer"
9291 help
arch/mips/cavium-octeon/executive/cvmx-helper.c+166−0
@@ -105,6 +105,158 @@ int cvmx_helper_ports_on_interface(int interface) · 104 unmodified lines
105105 }
106106 EXPORT_SYMBOL_GPL(cvmx_helper_ports_on_interface);
107107
108+/**
109+ * @INTERNAL
110+ * Return interface mode for CN68xx.
111+ */
112+static cvmx_helper_interface_mode_t __cvmx_get_mode_cn68xx(int interface)
113+{
114+ union cvmx_mio_qlmx_cfg qlm_cfg;
115+ switch (interface) {
116+ case 0:
117+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
118+ /* QLM is disabled when QLM SPD is 15. */
119+ if (qlm_cfg.s.qlm_spd == 15)
120+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
121+
122+ if (qlm_cfg.s.qlm_cfg == 2)
123+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
124+ else if (qlm_cfg.s.qlm_cfg == 3)
125+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
126+ else
127+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
128+ case 2:
129+ case 3:
130+ case 4:
131+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(interface));
132+ /* QLM is disabled when QLM SPD is 15. */
133+ if (qlm_cfg.s.qlm_spd == 15)
134+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
135+
136+ if (qlm_cfg.s.qlm_cfg == 2)
137+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
138+ else if (qlm_cfg.s.qlm_cfg == 3)
139+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
140+ else
141+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
142+ case 7:
143+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(3));
144+ /* QLM is disabled when QLM SPD is 15. */
145+ if (qlm_cfg.s.qlm_spd == 15) {
146+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
147+ } else if (qlm_cfg.s.qlm_cfg != 0) {
148+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1));
149+ if (qlm_cfg.s.qlm_cfg != 0)
150+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
151+ }
152+ return CVMX_HELPER_INTERFACE_MODE_NPI;
153+ case 8:
154+ return CVMX_HELPER_INTERFACE_MODE_LOOP;
155+ default:
156+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
157+ }
158+}
159+
160+/**
161+ * @INTERNAL
162+ * Return interface mode for an Octeon II
163+ */
164+static cvmx_helper_interface_mode_t __cvmx_get_mode_octeon2(int interface)
165+{
166+ union cvmx_gmxx_inf_mode mode;
167+
168+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
169+ return __cvmx_get_mode_cn68xx(interface);
170+
171+ if (interface == 2)
172+ return CVMX_HELPER_INTERFACE_MODE_NPI;
173+
174+ if (interface == 3)
175+ return CVMX_HELPER_INTERFACE_MODE_LOOP;
176+
177+ /* Only present in CN63XX & CN66XX Octeon model */
178+ if ((OCTEON_IS_MODEL(OCTEON_CN63XX) &&
179+ (interface == 4 || interface == 5)) ||
180+ (OCTEON_IS_MODEL(OCTEON_CN66XX) &&
181+ interface >= 4 && interface <= 7)) {
182+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
183+ }
184+
185+ if (OCTEON_IS_MODEL(OCTEON_CN66XX)) {
186+ union cvmx_mio_qlmx_cfg mio_qlm_cfg;
187+
188+ /* QLM2 is SGMII0 and QLM1 is SGMII1 */
189+ if (interface == 0)
190+ mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2));
191+ else if (interface == 1)
192+ mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1));
193+ else
194+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
195+
196+ if (mio_qlm_cfg.s.qlm_spd == 15)
197+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
198+
199+ if (mio_qlm_cfg.s.qlm_cfg == 9)
200+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
201+ else if (mio_qlm_cfg.s.qlm_cfg == 11)
202+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
203+ else
204+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
205+ } else if (OCTEON_IS_MODEL(OCTEON_CN61XX)) {
206+ union cvmx_mio_qlmx_cfg qlm_cfg;
207+
208+ if (interface == 0) {
209+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2));
210+ if (qlm_cfg.s.qlm_cfg == 2)
211+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
212+ else if (qlm_cfg.s.qlm_cfg == 3)
213+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
214+ else
215+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
216+ } else if (interface == 1) {
217+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
218+ if (qlm_cfg.s.qlm_cfg == 2)
219+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
220+ else if (qlm_cfg.s.qlm_cfg == 3)
221+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
222+ else
223+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
224+ }
225+ } else if (OCTEON_IS_MODEL(OCTEON_CNF71XX)) {
226+ if (interface == 0) {
227+ union cvmx_mio_qlmx_cfg qlm_cfg;
228+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
229+ if (qlm_cfg.s.qlm_cfg == 2)
230+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
231+ }
232+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
233+ }
234+
235+ if (interface == 1 && OCTEON_IS_MODEL(OCTEON_CN63XX))
236+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
237+
238+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
239+
240+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
241+ switch (mode.cn63xx.mode) {
242+ case 0:
243+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
244+ case 1:
245+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
246+ default:
247+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
248+ }
249+ } else {
250+ if (!mode.s.en)
251+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
252+
253+ if (mode.s.type)
254+ return CVMX_HELPER_INTERFACE_MODE_GMII;
255+ else
256+ return CVMX_HELPER_INTERFACE_MODE_RGMII;
257+ }
258+}
259+
108260 /**
109261 * Get the operating mode of an interface. Depending on the Octeon
110262 * chip and configuration, this function returns an enumeration
@@ -118,6 +270,20 @@ EXPORT_SYMBOL_GPL(cvmx_helper_ports_on_interface); · 7 unmodified lines
118270 cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
119271 {
120272 union cvmx_gmxx_inf_mode mode;
273+
274+ if (interface < 0 ||
275+ interface >= cvmx_helper_get_number_of_interfaces())
276+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
277+
278+ /*
279+ * Octeon II models
280+ */
281+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF71XX))
282+ return __cvmx_get_mode_octeon2(interface);
283+
284+ /*
285+ * Octeon and Octeon Plus models
286+ */
121287 if (interface == 2)
122288 return CVMX_HELPER_INTERFACE_MODE_NPI;
123289
arch/mips/cavium-octeon/octeon-irq.c+2−0
@@ -1260,11 +1260,13 @@ static void __init octeon_irq_init_ciu(void) · 1259 unmodified lines
12601260 for (i = 0; i < 4; i++)
12611261 octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_MSI0, 0, i + 40);
12621262
1263+ octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_TWSI, 0, 45);
12631264 octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_RML, 0, 46);
12641265 for (i = 0; i < 4; i++)
12651266 octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_TIMER0, 0, i + 52);
12661267
12671268 octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB0, 0, 56);
1269+ octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_TWSI2, 0, 59);
12681270
12691271 /* CIU_1 */
12701272 for (i = 0; i < 16; i++)
arch/mips/cavium-octeon/setup.c+0−17
@@ -729,17 +729,6 @@ void __init prom_init(void) · 728 unmodified lines
729729 octeon_write_lcd("Linux");
730730 #endif
731731
732−#ifdef CONFIG_CAVIUM_GDB
733− /*
734− * When debugging the linux kernel, force the cores to enter
735− * the debug exception handler to break in.
736− */
737− if (octeon_get_boot_debug_flag()) {
738− cvmx_write_csr(CVMX_CIU_DINT, 1 << cvmx_get_core_num());
739− cvmx_read_csr(CVMX_CIU_DINT);
740− }
741−#endif
742−
743732 octeon_setup_delays();
744733
745734 /*
@@ -779,12 +768,6 @@ void __init prom_init(void) · 33 unmodified lines
779768 MAX_MEMORY = 32ull << 30;
780769 if (*p == '@')
781770 RESERVE_LOW_MEM = memparse(p + 1, &p);
782− } else if (strcmp(arg, "ecc_verbose") == 0) {
783−#ifdef CONFIG_CAVIUM_REPORT_SINGLE_BIT_ECC
784− __cvmx_interrupt_ecc_report_single_bit_errors = 1;
785− pr_notice("Reporting of single bit ECC errors is "
786− "turned on\n");
787−#endif
788771 #ifdef CONFIG_KEXEC
789772 } else if (strncmp(arg, "crashkernel=", 12) == 0) {
790773 crashk_size = memparse(arg+12, &p);
arch/mips/cavium-octeon/smp.c+0−25
@@ -218,15 +218,6 @@ void octeon_prepare_cpus(unsigned int max_cpus) · 217 unmodified lines
218218 */
219219 static void octeon_smp_finish(void)
220220 {
221−#ifdef CONFIG_CAVIUM_GDB
222− unsigned long tmp;
223− /* Pulse MCD0 signal on Ctrl-C to stop all the cores. Also set the MCD0
224− to be not masked by this core so we know the signal is received by
225− someone */
226− asm volatile ("dmfc0 %0, $22\n"
227− "ori %0, %0, 0x9100\n" "dmtc0 %0, $22\n" : "=r" (tmp));
228−#endif
229−
230221 octeon_user_io_init();
231222
232223 /* to generate the first CPU timer interrupt */
@@ -234,21 +225,6 @@ static void octeon_smp_finish(void) · 1 unmodified line
234225 local_irq_enable();
235226 }
236227
237−/**
238− * Hook for after all CPUs are online
239− */
240−static void octeon_cpus_done(void)
241−{
242−#ifdef CONFIG_CAVIUM_GDB
243− unsigned long tmp;
244− /* Pulse MCD0 signal on Ctrl-C to stop all the cores. Also set the MCD0
245− to be not masked by this core so we know the signal is received by
246− someone */
247− asm volatile ("dmfc0 %0, $22\n"
248− "ori %0, %0, 0x9100\n" "dmtc0 %0, $22\n" : "=r" (tmp));
249−#endif
250−}
251−
252228 #ifdef CONFIG_HOTPLUG_CPU
253229
254230 /* State of each CPU. */
@@ -405,7 +381,6 @@ struct plat_smp_ops octeon_smp_ops = { · 150 unmodified lines
405381 .send_ipi_mask = octeon_send_ipi_mask,
406382 .init_secondary = octeon_init_secondary,
407383 .smp_finish = octeon_smp_finish,
408− .cpus_done = octeon_cpus_done,
409384 .boot_secondary = octeon_boot_secondary,
410385 .smp_setup = octeon_smp_setup,
411386 .prepare_cpus = octeon_prepare_cpus,
arch/mips/configs/ath79_defconfig+1−2
@@ -46,7 +46,6 @@ CONFIG_MTD=y · 45 unmodified lines
4646 CONFIG_MTD_REDBOOT_PARTS=y
4747 CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-2
4848 CONFIG_MTD_CMDLINE_PARTS=y
49−CONFIG_MTD_CHAR=y
5049 CONFIG_MTD_BLOCK=y
5150 CONFIG_MTD_CFI=y
5251 CONFIG_MTD_JEDECPROBE=y
@@ -54,7 +53,7 @@ CONFIG_MTD_CFI_AMDSTD=y · 1 unmodified line
5453 CONFIG_MTD_COMPLEX_MAPPINGS=y
5554 CONFIG_MTD_PHYSMAP=y
5655 CONFIG_MTD_M25P80=y
57−# CONFIG_M25PXX_USE_FAST_READ is not set
56+CONFIG_MTD_SPI_NOR=y
5857 CONFIG_NETDEVICES=y
5958 # CONFIG_NET_PACKET_ENGINE is not set
6059 CONFIG_ATH_COMMON=m
arch/mips/configs/db1xxx_defconfig+1−0
@@ -113,6 +113,7 @@ CONFIG_MTD_NAND=y · 112 unmodified lines
113113 CONFIG_MTD_NAND_ECC_BCH=y
114114 CONFIG_MTD_NAND_AU1550=y
115115 CONFIG_MTD_NAND_PLATFORM=y
116+CONFIG_MTD_SPI_NOR=y
116117 CONFIG_EEPROM_AT24=y
117118 CONFIG_EEPROM_AT25=y
118119 CONFIG_SCSI_TGT=y
arch/mips/configs/maltasmtc_defconfig+0−196
@@ -1,196 +0,0 @@
1−CONFIG_MIPS_MALTA=y
2−CONFIG_CPU_LITTLE_ENDIAN=y
3−CONFIG_CPU_MIPS32_R2=y
4−CONFIG_PAGE_SIZE_16KB=y
5−CONFIG_MIPS_MT_SMTC=y
6−# CONFIG_MIPS_MT_FPAFF is not set
7−CONFIG_NR_CPUS=9
8−CONFIG_HZ_48=y
9−CONFIG_LOCALVERSION="smtc"
10−CONFIG_SYSVIPC=y
11−CONFIG_POSIX_MQUEUE=y
12−CONFIG_AUDIT=y
13−CONFIG_IKCONFIG=y
14−CONFIG_IKCONFIG_PROC=y
15−CONFIG_LOG_BUF_SHIFT=15
16−CONFIG_SYSCTL_SYSCALL=y
17−CONFIG_EMBEDDED=y
18−CONFIG_SLAB=y
19−CONFIG_MODULES=y
20−CONFIG_MODULE_UNLOAD=y
21−CONFIG_MODVERSIONS=y
22−CONFIG_MODULE_SRCVERSION_ALL=y
23−# CONFIG_BLK_DEV_BSG is not set
24−CONFIG_PCI=y
25−# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
26−CONFIG_NET=y
27−CONFIG_PACKET=y
28−CONFIG_UNIX=y
29−CONFIG_XFRM_USER=m
30−CONFIG_NET_KEY=y
31−CONFIG_INET=y
32−CONFIG_IP_MULTICAST=y
33−CONFIG_IP_ADVANCED_ROUTER=y
34−CONFIG_IP_MULTIPLE_TABLES=y
35−CONFIG_IP_ROUTE_MULTIPATH=y
36−CONFIG_IP_ROUTE_VERBOSE=y
37−CONFIG_IP_PNP=y
38−CONFIG_IP_PNP_DHCP=y
39−CONFIG_IP_PNP_BOOTP=y
40−CONFIG_NET_IPIP=m
41−CONFIG_IP_MROUTE=y
42−CONFIG_IP_PIMSM_V1=y
43−CONFIG_IP_PIMSM_V2=y
44−CONFIG_SYN_COOKIES=y
45−CONFIG_INET_AH=m
46−CONFIG_INET_ESP=m
47−CONFIG_INET_IPCOMP=m
48−# CONFIG_INET_LRO is not set
49−CONFIG_INET6_AH=m
50−CONFIG_INET6_ESP=m
51−CONFIG_INET6_IPCOMP=m
52−CONFIG_IPV6_TUNNEL=m
53−CONFIG_BRIDGE=m
54−CONFIG_VLAN_8021Q=m
55−CONFIG_ATALK=m
56−CONFIG_DEV_APPLETALK=m
57−CONFIG_IPDDP=m
58−CONFIG_IPDDP_ENCAP=y
59−CONFIG_NET_SCHED=y
60−CONFIG_NET_SCH_CBQ=m
61−CONFIG_NET_SCH_HTB=m
62−CONFIG_NET_SCH_HFSC=m
63−CONFIG_NET_SCH_PRIO=m
64−CONFIG_NET_SCH_RED=m
65−CONFIG_NET_SCH_SFQ=m
66−CONFIG_NET_SCH_TEQL=m
67−CONFIG_NET_SCH_TBF=m
68−CONFIG_NET_SCH_GRED=m
69−CONFIG_NET_SCH_DSMARK=m
70−CONFIG_NET_SCH_NETEM=m
71−CONFIG_NET_SCH_INGRESS=m
72−CONFIG_NET_CLS_BASIC=m
73−CONFIG_NET_CLS_TCINDEX=m
74−CONFIG_NET_CLS_ROUTE4=m
75−CONFIG_NET_CLS_FW=m
76−CONFIG_NET_CLS_U32=m
77−CONFIG_NET_CLS_RSVP=m
78−CONFIG_NET_CLS_RSVP6=m
79−CONFIG_NET_CLS_ACT=y
80−CONFIG_NET_ACT_POLICE=y
81−CONFIG_NET_CLS_IND=y
82−# CONFIG_WIRELESS is not set
83−CONFIG_DEVTMPFS=y
84−CONFIG_BLK_DEV_LOOP=y
85−CONFIG_BLK_DEV_CRYPTOLOOP=m
86−CONFIG_IDE=y
87−# CONFIG_IDE_PROC_FS is not set
88−# CONFIG_IDEPCI_PCIBUS_ORDER is not set
89−CONFIG_BLK_DEV_GENERIC=y
90−CONFIG_BLK_DEV_PIIX=y
91−CONFIG_SCSI=y
92−CONFIG_BLK_DEV_SD=y
93−CONFIG_CHR_DEV_SG=y
94−# CONFIG_SCSI_LOWLEVEL is not set
95−CONFIG_NETDEVICES=y
96−# CONFIG_NET_VENDOR_3COM is not set
97−# CONFIG_NET_VENDOR_ADAPTEC is not set
98−# CONFIG_NET_VENDOR_ALTEON is not set
99−CONFIG_PCNET32=y
100−# CONFIG_NET_VENDOR_ATHEROS is not set
101−# CONFIG_NET_VENDOR_BROADCOM is not set
102−# CONFIG_NET_VENDOR_BROCADE is not set
103−# CONFIG_NET_VENDOR_CHELSIO is not set
104−# CONFIG_NET_VENDOR_CISCO is not set
105−# CONFIG_NET_VENDOR_DEC is not set
106−# CONFIG_NET_VENDOR_DLINK is not set
107−# CONFIG_NET_VENDOR_EMULEX is not set
108−# CONFIG_NET_VENDOR_EXAR is not set
109−# CONFIG_NET_VENDOR_HP is not set
110−# CONFIG_NET_VENDOR_INTEL is not set
111−# CONFIG_NET_VENDOR_MARVELL is not set
112−# CONFIG_NET_VENDOR_MELLANOX is not set
113−# CONFIG_NET_VENDOR_MICREL is not set
114−# CONFIG_NET_VENDOR_MYRI is not set
115−# CONFIG_NET_VENDOR_NATSEMI is not set
116−# CONFIG_NET_VENDOR_NVIDIA is not set
117−# CONFIG_NET_VENDOR_OKI is not set
118−# CONFIG_NET_PACKET_ENGINE is not set
119−# CONFIG_NET_VENDOR_QLOGIC is not set
120−# CONFIG_NET_VENDOR_REALTEK is not set
121−# CONFIG_NET_VENDOR_RDC is not set
122−# CONFIG_NET_VENDOR_SEEQ is not set
123−# CONFIG_NET_VENDOR_SILAN is not set
124−# CONFIG_NET_VENDOR_SIS is not set
125−# CONFIG_NET_VENDOR_SMSC is not set
126−# CONFIG_NET_VENDOR_STMICRO is not set
127−# CONFIG_NET_VENDOR_SUN is not set
128−# CONFIG_NET_VENDOR_TEHUTI is not set
129−# CONFIG_NET_VENDOR_TI is not set
130−# CONFIG_NET_VENDOR_TOSHIBA is not set
131−# CONFIG_NET_VENDOR_VIA is not set
132−# CONFIG_WLAN is not set
133−# CONFIG_VT is not set
134−CONFIG_LEGACY_PTY_COUNT=16
135−CONFIG_SERIAL_8250=y
136−CONFIG_SERIAL_8250_CONSOLE=y
137−CONFIG_HW_RANDOM=y
138−# CONFIG_HWMON is not set
139−CONFIG_VIDEO_OUTPUT_CONTROL=m
140−CONFIG_FB=y
141−CONFIG_FIRMWARE_EDID=y
142−CONFIG_FB_MATROX=y
143−CONFIG_FB_MATROX_G=y
144−CONFIG_USB=y
145−CONFIG_USB_EHCI_HCD=y
146−# CONFIG_USB_EHCI_TT_NEWSCHED is not set
147−CONFIG_USB_UHCI_HCD=y
148−CONFIG_USB_STORAGE=y
149−CONFIG_NEW_LEDS=y
150−CONFIG_LEDS_CLASS=y
151−CONFIG_LEDS_TRIGGERS=y
152−CONFIG_LEDS_TRIGGER_TIMER=y
153−CONFIG_LEDS_TRIGGER_IDE_DISK=y
154−CONFIG_LEDS_TRIGGER_HEARTBEAT=y
155−CONFIG_LEDS_TRIGGER_BACKLIGHT=y
156−CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
157−CONFIG_RTC_CLASS=y
158−CONFIG_RTC_DRV_CMOS=y
159−CONFIG_EXT2_FS=y
160−CONFIG_EXT3_FS=y
161−# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
162−CONFIG_XFS_FS=y
163−CONFIG_XFS_QUOTA=y
164−CONFIG_XFS_POSIX_ACL=y
165−CONFIG_QUOTA=y
166−CONFIG_QFMT_V2=y
167−CONFIG_MSDOS_FS=m
168−CONFIG_VFAT_FS=m
169−CONFIG_PROC_KCORE=y
170−CONFIG_TMPFS=y
171−CONFIG_NFS_FS=y
172−CONFIG_ROOT_NFS=y
173−CONFIG_CIFS=m
174−CONFIG_CIFS_WEAK_PW_HASH=y
175−CONFIG_CIFS_XATTR=y
176−CONFIG_CIFS_POSIX=y
177−CONFIG_NLS_CODEPAGE_437=m
178−CONFIG_NLS_ISO8859_1=m
179−# CONFIG_FTRACE is not set
180−CONFIG_CRYPTO_NULL=m
181−CONFIG_CRYPTO_PCBC=m
182−CONFIG_CRYPTO_HMAC=y
183−CONFIG_CRYPTO_MICHAEL_MIC=m
184−CONFIG_CRYPTO_SHA512=m
185−CONFIG_CRYPTO_TGR192=m
186−CONFIG_CRYPTO_WP512=m
187−CONFIG_CRYPTO_ANUBIS=m
188−CONFIG_CRYPTO_BLOWFISH=m
189−CONFIG_CRYPTO_CAST5=m
190−CONFIG_CRYPTO_CAST6=m
191−CONFIG_CRYPTO_KHAZAD=m
192−CONFIG_CRYPTO_SERPENT=m
193−CONFIG_CRYPTO_TEA=m
194−CONFIG_CRYPTO_TWOFISH=m
195−# CONFIG_CRYPTO_ANSI_CPRNG is not set
196−# CONFIG_CRYPTO_HW is not set
arch/mips/configs/maltasmvp_defconfig+1−2
@@ -4,10 +4,9 @@ CONFIG_CPU_MIPS32_R2=y · 3 unmodified lines
44 CONFIG_PAGE_SIZE_16KB=y
55 CONFIG_MIPS_MT_SMP=y
66 CONFIG_SCHED_SMT=y
7−CONFIG_MIPS_CMP=y
7+CONFIG_MIPS_CPS=y
88 CONFIG_NR_CPUS=8
99 CONFIG_HZ_100=y
10−CONFIG_LOCALVERSION="cmp"
1110 CONFIG_SYSVIPC=y
1211 CONFIG_POSIX_MQUEUE=y
1312 CONFIG_AUDIT=y
arch/mips/configs/maltasmvp_eva_defconfig+1−2
@@ -5,10 +5,9 @@ CONFIG_CPU_MIPS32_3_5_FEATURES=y · 4 unmodified lines
55 CONFIG_PAGE_SIZE_16KB=y
66 CONFIG_MIPS_MT_SMP=y
77 CONFIG_SCHED_SMT=y
8−CONFIG_MIPS_CMP=y
8+CONFIG_MIPS_CPS=y
99 CONFIG_NR_CPUS=8
1010 CONFIG_HZ_100=y
11−CONFIG_LOCALVERSION="cmp"
1211 CONFIG_SYSVIPC=y
1312 CONFIG_POSIX_MQUEUE=y
1413 CONFIG_AUDIT=y
arch/mips/configs/mips_paravirt_defconfig+103−0
@@ -0,0 +1,103 @@
1+CONFIG_MIPS_PARAVIRT=y
2+CONFIG_CPU_MIPS64_R2=y
3+CONFIG_64BIT=y
4+CONFIG_TRANSPARENT_HUGEPAGE=y
5+CONFIG_SMP=y
6+CONFIG_HZ_1000=y
7+CONFIG_PREEMPT=y
8+CONFIG_SYSVIPC=y
9+CONFIG_BSD_PROCESS_ACCT=y
10+CONFIG_BSD_PROCESS_ACCT_V3=y
11+CONFIG_IKCONFIG=y
12+CONFIG_IKCONFIG_PROC=y
13+CONFIG_LOG_BUF_SHIFT=14
14+CONFIG_RELAY=y
15+CONFIG_BLK_DEV_INITRD=y
16+CONFIG_EXPERT=y
17+CONFIG_SLAB=y
18+CONFIG_MODULES=y
19+CONFIG_MODULE_UNLOAD=y
20+# CONFIG_BLK_DEV_BSG is not set
21+CONFIG_PCI=y
22+CONFIG_MIPS32_COMPAT=y
23+CONFIG_MIPS32_O32=y
24+CONFIG_MIPS32_N32=y
25+CONFIG_NET=y
26+CONFIG_PACKET=y
27+CONFIG_UNIX=y
28+CONFIG_INET=y
29+CONFIG_IP_MULTICAST=y
30+CONFIG_IP_ADVANCED_ROUTER=y
31+CONFIG_IP_MULTIPLE_TABLES=y
32+CONFIG_IP_ROUTE_MULTIPATH=y
33+CONFIG_IP_ROUTE_VERBOSE=y
34+CONFIG_IP_PNP=y
35+CONFIG_IP_PNP_DHCP=y
36+CONFIG_IP_PNP_BOOTP=y
37+CONFIG_IP_PNP_RARP=y
38+CONFIG_IP_MROUTE=y
39+CONFIG_IP_PIMSM_V1=y
40+CONFIG_IP_PIMSM_V2=y
41+CONFIG_SYN_COOKIES=y
42+# CONFIG_INET_LRO is not set
43+CONFIG_IPV6=y
44+# CONFIG_WIRELESS is not set
45+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
46+# CONFIG_FW_LOADER is not set
47+CONFIG_BLK_DEV_LOOP=y
48+CONFIG_VIRTIO_BLK=y
49+CONFIG_SCSI=y
50+CONFIG_BLK_DEV_SD=y
51+CONFIG_NETDEVICES=y
52+CONFIG_VIRTIO_NET=y
53+# CONFIG_NET_VENDOR_BROADCOM is not set
54+# CONFIG_NET_VENDOR_INTEL is not set
55+# CONFIG_NET_VENDOR_MARVELL is not set
56+# CONFIG_NET_VENDOR_MICREL is not set
57+# CONFIG_NET_VENDOR_NATSEMI is not set
58+# CONFIG_NET_VENDOR_SMSC is not set
59+# CONFIG_NET_VENDOR_STMICRO is not set
60+# CONFIG_NET_VENDOR_WIZNET is not set
61+CONFIG_PHYLIB=y
62+CONFIG_MARVELL_PHY=y
63+CONFIG_BROADCOM_PHY=y
64+CONFIG_BCM87XX_PHY=y
65+# CONFIG_WLAN is not set
66+# CONFIG_INPUT is not set
67+# CONFIG_SERIO is not set
68+# CONFIG_VT is not set
69+CONFIG_VIRTIO_CONSOLE=y
70+# CONFIG_HW_RANDOM is not set
71+# CONFIG_HWMON is not set
72+# CONFIG_USB_SUPPORT is not set
73+CONFIG_VIRTIO_PCI=y
74+CONFIG_VIRTIO_BALLOON=y
75+CONFIG_VIRTIO_MMIO=y
76+# CONFIG_IOMMU_SUPPORT is not set
77+CONFIG_EXT4_FS=y
78+CONFIG_EXT4_FS_POSIX_ACL=y
79+CONFIG_EXT4_FS_SECURITY=y
80+CONFIG_MSDOS_FS=y
81+CONFIG_VFAT_FS=y
82+CONFIG_PROC_KCORE=y
83+CONFIG_TMPFS=y
84+CONFIG_HUGETLBFS=y
85+# CONFIG_MISC_FILESYSTEMS is not set
86+CONFIG_NFS_FS=y
87+CONFIG_NFS_V4=y
88+CONFIG_NFS_V4_1=y
89+CONFIG_ROOT_NFS=y
90+CONFIG_NLS_CODEPAGE_437=y
91+CONFIG_NLS_ASCII=y
92+CONFIG_NLS_ISO8859_1=y
93+CONFIG_NLS_UTF8=y
94+CONFIG_DEBUG_INFO=y
95+CONFIG_DEBUG_FS=y
96+CONFIG_MAGIC_SYSRQ=y
97+# CONFIG_SCHED_DEBUG is not set
98+# CONFIG_FTRACE is not set
99+CONFIG_CRYPTO_CBC=y
100+CONFIG_CRYPTO_HMAC=y
101+CONFIG_CRYPTO_MD5=y
102+CONFIG_CRYPTO_DES=y
103+# CONFIG_CRYPTO_ANSI_CPRNG is not set
arch/mips/configs/rt305x_defconfig+1−1
@@ -81,7 +81,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" · 80 unmodified lines
8181 # CONFIG_FIRMWARE_IN_KERNEL is not set
8282 CONFIG_MTD=y
8383 CONFIG_MTD_CMDLINE_PARTS=y
84−CONFIG_MTD_CHAR=y
8584 CONFIG_MTD_BLOCK=y
8685 CONFIG_MTD_CFI=y
8786 CONFIG_MTD_CFI_AMDSTD=y
@@ -89,6 +88,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y · 1 unmodified line
8988 CONFIG_MTD_PHYSMAP=y
9089 CONFIG_MTD_PHYSMAP_OF=y
9190 CONFIG_MTD_M25P80=y
91+CONFIG_MTD_SPI_NOR=y
9292 CONFIG_EEPROM_93CX6=m
9393 CONFIG_SCSI=y
9494 CONFIG_BLK_DEV_SD=y
arch/mips/dec/setup.c+5−0
@@ -23,6 +23,7 @@ · 22 unmodified lines
2323 #include <asm/bootinfo.h>
2424 #include <asm/cpu.h>
2525 #include <asm/cpu-features.h>
26+#include <asm/cpu-type.h>
2627 #include <asm/irq.h>
2728 #include <asm/irq_cpu.h>
2829 #include <asm/mipsregs.h>
@@ -748,6 +749,10 @@ void __init arch_init_irq(void) · 719 unmodified lines
748749 cpu_fpu_mask = 0;
749750 dec_interrupt[DEC_IRQ_FPU] = -1;
750751 }
752+ /* Free the halt interrupt unused on R4k systems. */
753+ if (current_cpu_type() == CPU_R4000SC ||
754+ current_cpu_type() == CPU_R4400SC)
755+ dec_interrupt[DEC_IRQ_HALT] = -1;
751756
752757 /* Register board interrupts: FPU and cascade. */
753758 if (dec_interrupt[DEC_IRQ_FPU] >= 0)
arch/mips/include/asm/asmmacro.h+34−28
@@ -17,26 +17,8 @@ · 16 unmodified lines
1717 #ifdef CONFIG_64BIT
1818 #include <asm/asmmacro-64.h>
1919 #endif
20−#ifdef CONFIG_MIPS_MT_SMTC
21−#include <asm/mipsmtregs.h>
22−#endif
23−
24−#ifdef CONFIG_MIPS_MT_SMTC
25− .macro local_irq_enable reg=t0
26− mfc0 \reg, CP0_TCSTATUS
27− ori \reg, \reg, TCSTATUS_IXMT
28− xori \reg, \reg, TCSTATUS_IXMT
29− mtc0 \reg, CP0_TCSTATUS
30− _ehb
31− .endm
3220
33− .macro local_irq_disable reg=t0
34− mfc0 \reg, CP0_TCSTATUS
35− ori \reg, \reg, TCSTATUS_IXMT
36− mtc0 \reg, CP0_TCSTATUS
37− _ehb
38− .endm
39−#elif defined(CONFIG_CPU_MIPSR2)
21+#ifdef CONFIG_CPU_MIPSR2
4022 .macro local_irq_enable reg=t0
4123 ei
4224 irq_enable_hazard
@@ -71,7 +53,7 @@ · 28 unmodified lines
7153 sw \reg, TI_PRE_COUNT($28)
7254 #endif
7355 .endm
74−#endif /* CONFIG_MIPS_MT_SMTC */
56+#endif /* CONFIG_CPU_MIPSR2 */
7557
7658 .macro fpu_save_16even thread tmp=t0
7759 cfc1 \tmp, fcr31
@@ -267,13 +249,35 @@ · 189 unmodified lines
267249 .set pop
268250 .endm
269251 #else
252+
253+#ifdef CONFIG_CPU_MICROMIPS
254+#define CFC_MSA_INSN 0x587e0056
255+#define CTC_MSA_INSN 0x583e0816
256+#define LDD_MSA_INSN 0x58000837
257+#define STD_MSA_INSN 0x5800083f
258+#define COPY_UW_MSA_INSN 0x58f00056
259+#define COPY_UD_MSA_INSN 0x58f80056
260+#define INSERT_W_MSA_INSN 0x59300816
261+#define INSERT_D_MSA_INSN 0x59380816
262+#else
263+#define CFC_MSA_INSN 0x787e0059
264+#define CTC_MSA_INSN 0x783e0819
265+#define LDD_MSA_INSN 0x78000823
266+#define STD_MSA_INSN 0x78000827
267+#define COPY_UW_MSA_INSN 0x78f00059
268+#define COPY_UD_MSA_INSN 0x78f80059
269+#define INSERT_W_MSA_INSN 0x79300819
270+#define INSERT_D_MSA_INSN 0x79380819
271+#endif
272+
270273 /*
271274 * Temporary until all toolchains in use include MSA support.
272275 */
273276 .macro cfcmsa rd, cs
274277 .set push
275278 .set noat
276− .word 0x787e0059 | (\cs << 11)
279+ .insn
280+ .word CFC_MSA_INSN | (\cs << 11)
277281 move \rd, $1
278282 .set pop
279283 .endm
@@ -282,7 +286,7 @@ · 2 unmodified lines
282286 .set push
283287 .set noat
284288 move $1, \rs
285− .word 0x783e0819 | (\cd << 6)
289+ .word CTC_MSA_INSN | (\cd << 6)
286290 .set pop
287291 .endm
288292
@@ -290,7 +294,7 @@ · 1 unmodified line
290294 .set push
291295 .set noat
292296 add $1, \base, \off
293− .word 0x78000823 | (\wd << 6)
297+ .word LDD_MSA_INSN | (\wd << 6)
294298 .set pop
295299 .endm
296300
@@ -298,14 +302,15 @@ · 1 unmodified line
298302 .set push
299303 .set noat
300304 add $1, \base, \off
301− .word 0x78000827 | (\wd << 6)
305+ .word STD_MSA_INSN | (\wd << 6)
302306 .set pop
303307 .endm
304308
305309 .macro copy_u_w rd, ws, n
306310 .set push
307311 .set noat
308− .word 0x78f00059 | (\n << 16) | (\ws << 11)
312+ .insn
313+ .word COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)
309314 /* move triggers an assembler bug... */
310315 or \rd, $1, zero
311316 .set pop
@@ -314,7 +319,8 @@ · 2 unmodified lines
314319 .macro copy_u_d rd, ws, n
315320 .set push
316321 .set noat
317− .word 0x78f80059 | (\n << 16) | (\ws << 11)
322+ .insn
323+ .word COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)
318324 /* move triggers an assembler bug... */
319325 or \rd, $1, zero
320326 .set pop
@@ -325,7 +331,7 @@ · 4 unmodified lines
325331 .set noat
326332 /* move triggers an assembler bug... */
327333 or $1, \rs, zero
328− .word 0x79300819 | (\n << 16) | (\wd << 6)
334+ .word INSERT_W_MSA_INSN | (\n << 16) | (\wd << 6)
329335 .set pop
330336 .endm
331337
@@ -334,7 +340,7 @@ · 2 unmodified lines
334340 .set noat
335341 /* move triggers an assembler bug... */
336342 or $1, \rs, zero
337− .word 0x79380819 | (\n << 16) | (\wd << 6)
343+ .word INSERT_D_MSA_INSN | (\n << 16) | (\wd << 6)
338344 .set pop
339345 .endm
340346 #endif
arch/mips/include/asm/branch.h+30−0
@@ -8,6 +8,8 @@ · 7 unmodified lines
88 #ifndef _ASM_BRANCH_H
99 #define _ASM_BRANCH_H
1010
11+#include <asm/cpu-features.h>
12+#include <asm/mipsregs.h>
1113 #include <asm/ptrace.h>
1214 #include <asm/inst.h>
1315
@@ -18,12 +20,40 @@ extern int __compute_return_epc_for_insn(struct pt_regs *regs, · 4 unmodified lines
1820 extern int __microMIPS_compute_return_epc(struct pt_regs *regs);
1921 extern int __MIPS16e_compute_return_epc(struct pt_regs *regs);
2022
23+/*
24+ * microMIPS bitfields
25+ */
26+#define MM_POOL32A_MINOR_MASK 0x3f
27+#define MM_POOL32A_MINOR_SHIFT 0x6
28+#define MM_MIPS32_COND_FC 0x30
29+
30+extern int __mm_isBranchInstr(struct pt_regs *regs,
31+ struct mm_decoded_insn dec_insn, unsigned long *contpc);
32+
33+static inline int mm_isBranchInstr(struct pt_regs *regs,
34+ struct mm_decoded_insn dec_insn, unsigned long *contpc)
35+{
36+ if (!cpu_has_mmips)
37+ return 0;
38+
39+ return __mm_isBranchInstr(regs, dec_insn, contpc);
40+}
2141
2242 static inline int delay_slot(struct pt_regs *regs)
2343 {
2444 return regs->cp0_cause & CAUSEF_BD;
2545 }
2646
47+static inline void clear_delay_slot(struct pt_regs *regs)
48+{
49+ regs->cp0_cause &= ~CAUSEF_BD;
50+}
51+
52+static inline void set_delay_slot(struct pt_regs *regs)
53+{
54+ regs->cp0_cause |= CAUSEF_BD;
55+}
56+
2757 static inline unsigned long exception_epc(struct pt_regs *regs)
2858 {
2959 if (likely(!delay_slot(regs)))
arch/mips/include/asm/cacheflush.h+6−0
@@ -113,6 +113,12 @@ unsigned long run_uncached(void *func); · 112 unmodified lines
113113
114114 extern void *kmap_coherent(struct page *page, unsigned long addr);
115115 extern void kunmap_coherent(void);
116+extern void *kmap_noncoherent(struct page *page, unsigned long addr);
117+
118+static inline void kunmap_noncoherent(void)
119+{
120+ kunmap_coherent();
121+}
116122
117123 #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
118124 static inline void flush_kernel_dcache_page(struct page *page)
arch/mips/include/asm/cmp.h+0−1
@@ -10,7 +10,6 @@ extern void cmp_smp_setup(void); · 9 unmodified lines
1010 extern void cmp_smp_finish(void);
1111 extern void cmp_boot_secondary(int cpu, struct task_struct *t);
1212 extern void cmp_init_secondary(void);
13−extern void cmp_cpus_done(void);
1413 extern void cmp_prepare_cpus(unsigned int max_cpus);
1514
1615 /* This is platform specific */
arch/mips/include/asm/cpu-features.h+19−1
@@ -110,9 +110,15 @@ · 109 unmodified lines
110110 #ifndef cpu_has_smartmips
111111 #define cpu_has_smartmips (cpu_data[0].ases & MIPS_ASE_SMARTMIPS)
112112 #endif
113+
113114 #ifndef cpu_has_rixi
114−#define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI)
115+# ifdef CONFIG_64BIT
116+# define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI)
117+# else /* CONFIG_32BIT */
118+# define cpu_has_rixi ((cpu_data[0].options & MIPS_CPU_RIXI) && !cpu_has_64bits)
119+# endif
115120 #endif
121+
116122 #ifndef cpu_has_mmips
117123 # ifdef CONFIG_SYS_SUPPORTS_MICROMIPS
118124 # define cpu_has_mmips (cpu_data[0].options & MIPS_CPU_MICROMIPS)
@@ -120,6 +126,7 @@ · 1 unmodified line
120126 # define cpu_has_mmips 0
121127 # endif
122128 #endif
129+
123130 #ifndef cpu_has_vtag_icache
124131 #define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG)
125132 #endif
@@ -183,6 +190,17 @@ · 57 unmodified lines
183190 /*
184191 * Shortcuts ...
185192 */
193+#define cpu_has_mips_2_3_4_5 (cpu_has_mips_2 | cpu_has_mips_3_4_5)
194+#define cpu_has_mips_3_4_5 (cpu_has_mips_3 | cpu_has_mips_4_5)
195+#define cpu_has_mips_4_5 (cpu_has_mips_4 | cpu_has_mips_5)
196+
197+#define cpu_has_mips_2_3_4_5_r (cpu_has_mips_2 | cpu_has_mips_3_4_5_r)
198+#define cpu_has_mips_3_4_5_r (cpu_has_mips_3 | cpu_has_mips_4_5_r)
199+#define cpu_has_mips_4_5_r (cpu_has_mips_4 | cpu_has_mips_5_r)
200+#define cpu_has_mips_5_r (cpu_has_mips_5 | cpu_has_mips_r)
201+
202+#define cpu_has_mips_4_5_r2 (cpu_has_mips_4_5 | cpu_has_mips_r2)
203+
186204 #define cpu_has_mips32 (cpu_has_mips32r1 | cpu_has_mips32r2)
187205 #define cpu_has_mips64 (cpu_has_mips64r1 | cpu_has_mips64r2)
188206 #define cpu_has_mips_r1 (cpu_has_mips32r1 | cpu_has_mips64r1)
arch/mips/include/asm/cpu-info.h+4−9
@@ -65,17 +65,12 @@ struct cpuinfo_mips { · 64 unmodified lines
6565 #ifdef CONFIG_64BIT
6666 int vmbits; /* Virtual memory size in bits */
6767 #endif
68−#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
68+#ifdef CONFIG_MIPS_MT_SMP
6969 /*
70− * In the MIPS MT "SMTC" model, each TC is considered
71− * to be a "CPU" for the purposes of scheduling, but
72− * exception resources, ASID spaces, etc, are common
73− * to all TCs within the same VPE.
70+ * There is not necessarily a 1:1 mapping of VPE num to CPU number
71+ * in particular on multi-core systems.
7472 */
7573 int vpe_id; /* Virtual Processor number */
76−#endif
77−#ifdef CONFIG_MIPS_MT_SMTC
78− int tc_id; /* Thread Context number */
7974 #endif
8075 void *data; /* Additional data */
8176 unsigned int watch_reg_count; /* Number that exist */
@@ -117,7 +112,7 @@ struct proc_cpuinfo_notifier_args { · 35 unmodified lines
117112 unsigned long n;
118113 };
119114
120−#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
115+#ifdef CONFIG_MIPS_MT_SMP
121116 # define cpu_vpe_id(cpuinfo) ((cpuinfo)->vpe_id)
122117 #else
123118 # define cpu_vpe_id(cpuinfo) 0
arch/mips/include/asm/cpu-type.h+1−3
@@ -155,9 +155,6 @@ static inline int __pure __get_cpu_type(const int cpu_type) · 154 unmodified lines
155155 case CPU_RM7000:
156156 case CPU_SR71000:
157157 #endif
158−#ifdef CONFIG_SYS_HAS_CPU_RM9000
159− case CPU_RM9000:
160−#endif
161158 #ifdef CONFIG_SYS_HAS_CPU_SB1
162159 case CPU_SB1:
163160 case CPU_SB1A:
@@ -166,6 +163,7 @@ static inline int __pure __get_cpu_type(const int cpu_type) · 2 unmodified lines
166163 case CPU_CAVIUM_OCTEON:
167164 case CPU_CAVIUM_OCTEON_PLUS:
168165 case CPU_CAVIUM_OCTEON2:
166+ case CPU_CAVIUM_OCTEON3:
169167 #endif
170168
171169 #if defined(CONFIG_SYS_HAS_CPU_BMIPS32_3300) || \
arch/mips/include/asm/cpu.h+2−1
@@ -201,6 +201,7 @@ · 200 unmodified lines
201201 #define PRID_IMP_NETLOGIC_XLP3XX 0x1100
202202 #define PRID_IMP_NETLOGIC_XLP2XX 0x1200
203203 #define PRID_IMP_NETLOGIC_XLP9XX 0x1500
204+#define PRID_IMP_NETLOGIC_XLP5XX 0x1300
204205
205206 /*
206207 * Particular Revision values for bits 7:0 of the PRId register.
@@ -281,7 +282,7 @@ enum cpu_type_enum { · 74 unmodified lines
281282 CPU_R4700, CPU_R5000, CPU_R5500, CPU_NEVADA, CPU_R5432, CPU_R10000,
282283 CPU_R12000, CPU_R14000, CPU_VR41XX, CPU_VR4111, CPU_VR4121, CPU_VR4122,
283284 CPU_VR4131, CPU_VR4133, CPU_VR4181, CPU_VR4181A, CPU_RM7000,
284− CPU_SR71000, CPU_RM9000, CPU_TX49XX,
285+ CPU_SR71000, CPU_TX49XX,
285286
286287 /*
287288 * R8000 class processors
arch/mips/include/asm/dec/kn05.h+12−3
@@ -48,13 +48,21 @@ · 47 unmodified lines
4848 #define KN4K_RES_14 (14*IOASIC_SLOT_SIZE) /* unused? */
4949 #define KN4K_RES_15 (15*IOASIC_SLOT_SIZE) /* unused? */
5050
51+/*
52+ * MB ASIC interrupt bits.
53+ */
54+#define KN4K_MB_INR_MB 4 /* ??? */
55+#define KN4K_MB_INR_MT 3 /* memory, I/O bus read/write errors */
56+#define KN4K_MB_INR_RES_2 2 /* unused */
57+#define KN4K_MB_INR_RTC 1 /* RTC */
58+#define KN4K_MB_INR_TC 0 /* I/O ASIC cascade */
59+
5160 /*
5261 * Bits for the MB interrupt register.
5362 * The register appears read-only.
5463 */
55−#define KN4K_MB_INT_TC (1<<0) /* TURBOchannel? */
56−#define KN4K_MB_INT_RTC (1<<1) /* RTC? */
57−#define KN4K_MB_INT_MT (1<<3) /* I/O ASIC cascade */
64+#define KN4K_MB_INT_IRQ (0x1f<<0) /* CPU Int[4:0] status. */
65+#define KN4K_MB_INT_IRQ_N(n) (1<<(n)) /* Individual status bits. */
5866
5967 /*
6068 * Bits for the MB control & status register.
@@ -70,6 +78,7 @@ · 9 unmodified lines
7078 #define KN4K_MB_CSR_NC (1<<14) /* ??? */
7179 #define KN4K_MB_CSR_EE (1<<15) /* (bus) Exception Enable? */
7280 #define KN4K_MB_CSR_MSK (0x1f<<16) /* CPU Int[4:0] mask */
81+#define KN4K_MB_CSR_MSK_N(n) (1<<((n)+16)) /* Individual mask bits. */
7382 #define KN4K_MB_CSR_FW (1<<21) /* ??? */
7483 #define KN4K_MB_CSR_W (1<<31) /* ??? */
7584
arch/mips/include/asm/fixmap.h+0−4
@@ -48,11 +48,7 @@ · 47 unmodified lines
4848 enum fixed_addresses {
4949 #define FIX_N_COLOURS 8
5050 FIX_CMAP_BEGIN,
51−#ifdef CONFIG_MIPS_MT_SMTC
52− FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS * 2),
53−#else
5451 FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * 2),
55−#endif
5652 #ifdef CONFIG_HIGHMEM
5753 /* reserved pte's for temporary kernel mappings */
5854 FIX_KMAP_BEGIN = FIX_CMAP_END + 1,
arch/mips/include/asm/fpu.h+4−3
@@ -17,6 +17,7 @@ · 16 unmodified lines
1717 #include <asm/mipsregs.h>
1818 #include <asm/cpu.h>
1919 #include <asm/cpu-features.h>
20+#include <asm/fpu_emulator.h>
2021 #include <asm/hazards.h>
2122 #include <asm/processor.h>
2223 #include <asm/current.h>
@@ -28,7 +29,6 @@ · 5 unmodified lines
2829 struct sigcontext;
2930 struct sigcontext32;
3031
31−extern void fpu_emulator_init_fpu(void);
3232 extern void _init_fpu(void);
3333 extern void _save_fp(struct task_struct *);
3434 extern void _restore_fp(struct task_struct *);
@@ -156,15 +156,16 @@ static inline int init_fpu(void) · 121 unmodified lines
156156 int ret = 0;
157157
158158 preempt_disable();
159+
159160 if (cpu_has_fpu) {
160161 ret = __own_fpu();
161162 if (!ret)
162163 _init_fpu();
163− } else {
164+ } else
164165 fpu_emulator_init_fpu();
165− }
166166
167167 preempt_enable();
168+
168169 return ret;
169170 }
170171
arch/mips/include/asm/fpu_emulator.h+21−0
@@ -23,9 +23,12 @@ · 22 unmodified lines
2323 #ifndef _ASM_FPU_EMULATOR_H
2424 #define _ASM_FPU_EMULATOR_H
2525
26+#include <linux/sched.h>
2627 #include <asm/break.h>
28+#include <asm/thread_info.h>
2729 #include <asm/inst.h>
2830 #include <asm/local.h>
31+#include <asm/processor.h>
2932
3033 #ifdef CONFIG_DEBUG_FS
3134
@@ -36,6 +39,11 @@ struct mips_fpu_emulator_stats { · 4 unmodified lines
3639 local_t cp1ops;
3740 local_t cp1xops;
3841 local_t errors;
42+ local_t ieee754_inexact;
43+ local_t ieee754_underflow;
44+ local_t ieee754_overflow;
45+ local_t ieee754_zerodiv;
46+ local_t ieee754_invalidop;
3947 };
4048
4149 DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
@@ -71,4 +79,17 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, · 29 unmodified lines
7179 */
7280 #define BREAK_MATH (0x0000000d | (BRK_MEMU << 16))
7381
82+#define SIGNALLING_NAN 0x7ff800007ff80000LL
83+
84+static inline void fpu_emulator_init_fpu(void)
85+{
86+ struct task_struct *t = current;
87+ int i;
88+
89+ t->thread.fpu.fcr31 = 0;
90+
91+ for (i = 0; i < 32; i++)
92+ set_fpr64(&t->thread.fpu.fpr[i], 0, SIGNALLING_NAN);
93+}
94+
7495 #endif /* _ASM_FPU_EMULATOR_H */
arch/mips/include/asm/gic.h+1−0
@@ -380,6 +380,7 @@ extern unsigned int gic_compare_int (void); · 379 unmodified lines
380380 extern cycle_t gic_read_count(void);
381381 extern cycle_t gic_read_compare(void);
382382 extern void gic_write_compare(cycle_t cnt);
383+extern void gic_write_cpu_compare(cycle_t cnt, int cpu);
383384 extern void gic_send_ipi(unsigned int intr);
384385 extern unsigned int plat_ipi_call_int_xlate(unsigned int);
385386 extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
arch/mips/include/asm/gio_device.h+2−2
@@ -50,7 +50,7 @@ static inline void gio_device_free(struct gio_device *dev) · 49 unmodified lines
5050 extern int gio_register_driver(struct gio_driver *);
5151 extern void gio_unregister_driver(struct gio_driver *);
5252
53−#define gio_get_drvdata(_dev) drv_get_drvdata(&(_dev)->dev)
54−#define gio_set_drvdata(_dev, data) drv_set_drvdata(&(_dev)->dev, (data))
53+#define gio_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev)
54+#define gio_set_drvdata(_dev, data) dev_set_drvdata(&(_dev)->dev, (data))
5555
5656 extern void gio_set_master(struct gio_device *);
arch/mips/include/asm/idle.h+14−0
@@ -1,6 +1,7 @@
11 #ifndef __ASM_IDLE_H
22 #define __ASM_IDLE_H
33
4+#include <linux/cpuidle.h>
45 #include <linux/linkage.h>
56
67 extern void (*cpu_wait)(void);
@@ -20,4 +21,17 @@ static inline int address_is_in_r4k_wait_irqoff(unsigned long addr) · 13 unmodified lines
2021 addr < (unsigned long)__pastwait;
2122 }
2223
24+extern int mips_cpuidle_wait_enter(struct cpuidle_device *dev,
25+ struct cpuidle_driver *drv, int index);
26+
27+#define MIPS_CPUIDLE_WAIT_STATE {\
28+ .enter = mips_cpuidle_wait_enter,\
29+ .exit_latency = 1,\
30+ .target_residency = 1,\
31+ .power_usage = UINT_MAX,\
32+ .flags = CPUIDLE_FLAG_TIME_VALID,\
33+ .name = "wait",\
34+ .desc = "MIPS wait",\
35+}
36+
2337 #endif /* __ASM_IDLE_H */
arch/mips/include/asm/irq.h+0−96
@@ -26,104 +26,8 @@ static inline int irq_canonicalize(int irq) · 25 unmodified lines
2626 #define irq_canonicalize(irq) (irq) /* Sane hardware, sane code ... */
2727 #endif
2828
29−#ifdef CONFIG_MIPS_MT_SMTC
30−
31−struct irqaction;
32−
33−extern unsigned long irq_hwmask[];
34−extern int setup_irq_smtc(unsigned int irq, struct irqaction * new,
35− unsigned long hwmask);
36−
37−static inline void smtc_im_ack_irq(unsigned int irq)
38−{
39− if (irq_hwmask[irq] & ST0_IM)
40− set_c0_status(irq_hwmask[irq] & ST0_IM);
41−}
42−
43−#else
44−
45−static inline void smtc_im_ack_irq(unsigned int irq)
46−{
47−}
48−
49−#endif /* CONFIG_MIPS_MT_SMTC */
50−
51−#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
52−#include <linux/cpumask.h>
53−
54−extern int plat_set_irq_affinity(struct irq_data *d,
55− const struct cpumask *affinity, bool force);
56−extern void smtc_forward_irq(struct irq_data *d);
57−
58−/*
59− * IRQ affinity hook invoked at the beginning of interrupt dispatch
60− * if option is enabled.
61− *
62− * Up through Linux 2.6.22 (at least) cpumask operations are very
63− * inefficient on MIPS. Initial prototypes of SMTC IRQ affinity
64− * used a "fast path" per-IRQ-descriptor cache of affinity information
65− * to reduce latency. As there is a project afoot to optimize the
66− * cpumask implementations, this version is optimistically assuming
67− * that cpumask.h macro overhead is reasonable during interrupt dispatch.
68− */
69−static inline int handle_on_other_cpu(unsigned int irq)
70−{
71− struct irq_data *d = irq_get_irq_data(irq);
72−
73− if (cpumask_test_cpu(smp_processor_id(), d->affinity))
74− return 0;
75− smtc_forward_irq(d);
76− return 1;
77−}
78−
79−#else /* Not doing SMTC affinity */
80−
81−static inline int handle_on_other_cpu(unsigned int irq) { return 0; }
82−
83−#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
84−
85−#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
86−
87−static inline void smtc_im_backstop(unsigned int irq)
88−{
89− if (irq_hwmask[irq] & 0x0000ff00)
90− write_c0_tccontext(read_c0_tccontext() &
91− ~(irq_hwmask[irq] & 0x0000ff00));
92−}
93−
94−/*
95− * Clear interrupt mask handling "backstop" if irq_hwmask
96− * entry so indicates. This implies that the ack() or end()
97− * functions will take over re-enabling the low-level mask.
98− * Otherwise it will be done on return from exception.
99− */
100−static inline int smtc_handle_on_other_cpu(unsigned int irq)
101−{
102− int ret = handle_on_other_cpu(irq);
103−
104− if (!ret)
105− smtc_im_backstop(irq);
106− return ret;
107−}
108−
109−#else
110−
111−static inline void smtc_im_backstop(unsigned int irq) { }
112−static inline int smtc_handle_on_other_cpu(unsigned int irq)
113−{
114− return handle_on_other_cpu(irq);
115−}
116−
117−#endif
118−
11929 extern void do_IRQ(unsigned int irq);
12030
121−#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
122−
123−extern void do_IRQ_no_affinity(unsigned int irq);
124−
125−#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
126−
12731 extern void arch_init_irq(void);
12832 extern void spurious_interrupt(void);
12933
arch/mips/include/asm/irqflags.h+3−29
@@ -17,7 +17,7 @@ · 16 unmodified lines
1717 #include <linux/stringify.h>
1818 #include <asm/hazards.h>
1919
20−#if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC)
20+#ifdef CONFIG_CPU_MIPSR2
2121
2222 static inline void arch_local_irq_disable(void)
2323 {
@@ -118,30 +118,15 @@ void arch_local_irq_disable(void); · 94 unmodified lines
118118 unsigned long arch_local_irq_save(void);
119119 void arch_local_irq_restore(unsigned long flags);
120120 void __arch_local_irq_restore(unsigned long flags);
121−#endif /* if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) */
122−
123−
124−extern void smtc_ipi_replay(void);
121+#endif /* CONFIG_CPU_MIPSR2 */
125122
126123 static inline void arch_local_irq_enable(void)
127124 {
128−#ifdef CONFIG_MIPS_MT_SMTC
129− /*
130− * SMTC kernel needs to do a software replay of queued
131− * IPIs, at the cost of call overhead on each local_irq_enable()
132− */
133− smtc_ipi_replay();
134−#endif
135125 __asm__ __volatile__(
136126 " .set push \n"
137127 " .set reorder \n"
138128 " .set noat \n"
139−#ifdef CONFIG_MIPS_MT_SMTC
140− " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n"
141− " ori $1, 0x400 \n"
142− " xori $1, 0x400 \n"
143− " mtc0 $1, $2, 1 \n"
144−#elif defined(CONFIG_CPU_MIPSR2)
129+#if defined(CONFIG_CPU_MIPSR2)
145130 " ei \n"
146131 #else
147132 " mfc0 $1,$12 \n"
@@ -163,11 +148,7 @@ static inline unsigned long arch_local_save_flags(void) · 15 unmodified lines
163148 asm __volatile__(
164149 " .set push \n"
165150 " .set reorder \n"
166−#ifdef CONFIG_MIPS_MT_SMTC
167− " mfc0 %[flags], $2, 1 \n"
168−#else
169151 " mfc0 %[flags], $12 \n"
170−#endif
171152 " .set pop \n"
172153 : [flags] "=r" (flags));
173154
@@ -177,14 +158,7 @@ static inline unsigned long arch_local_save_flags(void) · 3 unmodified lines
177158
178159 static inline int arch_irqs_disabled_flags(unsigned long flags)
179160 {
180−#ifdef CONFIG_MIPS_MT_SMTC
181− /*
182− * SMTC model uses TCStatus.IXMT to disable interrupts for a thread/CPU
183− */
184− return flags & 0x400;
185−#else
186161 return !(flags & 1);
187−#endif
188162 }
189163
190164 #endif /* #ifndef __ASSEMBLY__ */
arch/mips/include/asm/kvm_para.h+109−0
@@ -0,0 +1,109 @@
1+#ifndef _ASM_MIPS_KVM_PARA_H
2+#define _ASM_MIPS_KVM_PARA_H
3+
4+#include <uapi/asm/kvm_para.h>
5+
6+#define KVM_HYPERCALL ".word 0x42000028"
7+
8+/*
9+ * Hypercalls for KVM.
10+ *
11+ * Hypercall number is passed in v0.
12+ * Return value will be placed in v0.
13+ * Up to 3 arguments are passed in a0, a1, and a2.
14+ */
15+static inline unsigned long kvm_hypercall0(unsigned long num)
16+{
17+ register unsigned long n asm("v0");
18+ register unsigned long r asm("v0");
19+
20+ n = num;
21+ __asm__ __volatile__(
22+ KVM_HYPERCALL
23+ : "=r" (r) : "r" (n) : "memory"
24+ );
25+
26+ return r;
27+}
28+
29+static inline unsigned long kvm_hypercall1(unsigned long num,
30+ unsigned long arg0)
31+{
32+ register unsigned long n asm("v0");
33+ register unsigned long r asm("v0");
34+ register unsigned long a0 asm("a0");
35+
36+ n = num;
37+ a0 = arg0;
38+ __asm__ __volatile__(
39+ KVM_HYPERCALL
40+ : "=r" (r) : "r" (n), "r" (a0) : "memory"
41+ );
42+
43+ return r;
44+}
45+
46+static inline unsigned long kvm_hypercall2(unsigned long num,
47+ unsigned long arg0, unsigned long arg1)
48+{
49+ register unsigned long n asm("v0");
50+ register unsigned long r asm("v0");
51+ register unsigned long a0 asm("a0");
52+ register unsigned long a1 asm("a1");
53+
54+ n = num;
55+ a0 = arg0;
56+ a1 = arg1;
57+ __asm__ __volatile__(
58+ KVM_HYPERCALL
59+ : "=r" (r) : "r" (n), "r" (a0), "r" (a1) : "memory"
60+ );
61+
62+ return r;
63+}
64+
65+static inline unsigned long kvm_hypercall3(unsigned long num,
66+ unsigned long arg0, unsigned long arg1, unsigned long arg2)
67+{
68+ register unsigned long n asm("v0");
69+ register unsigned long r asm("v0");
70+ register unsigned long a0 asm("a0");
71+ register unsigned long a1 asm("a1");
72+ register unsigned long a2 asm("a2");
73+
74+ n = num;
75+ a0 = arg0;
76+ a1 = arg1;
77+ a2 = arg2;
78+ __asm__ __volatile__(
79+ KVM_HYPERCALL
80+ : "=r" (r) : "r" (n), "r" (a0), "r" (a1), "r" (a2) : "memory"
81+ );
82+
83+ return r;
84+}
85+
86+static inline bool kvm_check_and_clear_guest_paused(void)
87+{
88+ return false;
89+}
90+
91+static inline unsigned int kvm_arch_para_features(void)
92+{
93+ return 0;
94+}
95+
96+#ifdef CONFIG_MIPS_PARAVIRT
97+static inline bool kvm_para_available(void)
98+{
99+ return true;
100+}
101+#else
102+static inline bool kvm_para_available(void)
103+{
104+ return false;
105+}
106+#endif
107+
108+
109+#endif /* _ASM_MIPS_KVM_PARA_H */
arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h+0−1
@@ -22,7 +22,6 @@ · 21 unmodified lines
2222 #define cpu_has_3k_cache 0
2323 #define cpu_has_4k_cache 0
2424 #define cpu_has_tx39_cache 0
25−#define cpu_has_fpu 0
2625 #define cpu_has_counter 1
2726 #define cpu_has_watch 1
2827 #define cpu_has_divec 1
arch/mips/include/asm/mach-cavium-octeon/irq.h+2−0
@@ -35,6 +35,8 @@ enum octeon_irq { · 34 unmodified lines
3535 OCTEON_IRQ_PCI_MSI2,
3636 OCTEON_IRQ_PCI_MSI3,
3737
38+ OCTEON_IRQ_TWSI,
39+ OCTEON_IRQ_TWSI2,
3840 OCTEON_IRQ_RML,
3941 OCTEON_IRQ_TIMER0,
4042 OCTEON_IRQ_TIMER1,
arch/mips/include/asm/mach-ip22/cpu-feature-overrides.h+4−0
@@ -39,6 +39,10 @@ · 38 unmodified lines
3939 #define cpu_has_nofpuex 0
4040 #define cpu_has_64bits 1
4141
42+#define cpu_has_mips_2 1
43+#define cpu_has_mips_3 1
44+#define cpu_has_mips_5 0
45+
4246 #define cpu_has_mips32r1 0
4347 #define cpu_has_mips32r2 0
4448 #define cpu_has_mips64r1 0
arch/mips/include/asm/mach-malta/kernel-entry-init.h+0−30
@@ -80,36 +80,6 @@ · 79 unmodified lines
8080 .endm
8181
8282 .macro kernel_entry_setup
83−#ifdef CONFIG_MIPS_MT_SMTC
84− mfc0 t0, CP0_CONFIG
85− bgez t0, 9f
86− mfc0 t0, CP0_CONFIG, 1
87− bgez t0, 9f
88− mfc0 t0, CP0_CONFIG, 2
89− bgez t0, 9f
90− mfc0 t0, CP0_CONFIG, 3
91− and t0, 1<<2
92− bnez t0, 0f
93−9:
94− /* Assume we came from YAMON... */
95− PTR_LA v0, 0x9fc00534 /* YAMON print */
96− lw v0, (v0)
97− move a0, zero
98− PTR_LA a1, nonmt_processor
99− jal v0
100−
101− PTR_LA v0, 0x9fc00520 /* YAMON exit */
102− lw v0, (v0)
103− li a0, 1
104− jal v0
105−
106−1: b 1b
107−
108− __INITDATA
109−nonmt_processor:
110− .asciz "SMTC kernel requires the MT ASE to run\n"
111− __FINIT
112−#endif
11383
11484 #ifdef CONFIG_EVA
11585 sync
arch/mips/include/asm/mach-malta/malta-pm.h+37−0
@@ -0,0 +1,37 @@
1+/*
2+ * Copyright (C) 2014 Imagination Technologies
3+ * Author: Paul Burton <paul.burton@imgtec.com>
4+ *
5+ * This program is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License as published by the
7+ * Free Software Foundation; either version 2 of the License, or (at your
8+ * option) any later version.
9+ */
10+
11+#ifndef __ASM_MIPS_MACH_MALTA_PM_H__
12+#define __ASM_MIPS_MACH_MALTA_PM_H__
13+
14+#include <asm/mips-boards/piix4.h>
15+
16+#ifdef CONFIG_MIPS_MALTA_PM
17+
18+/**
19+ * mips_pm_suspend - enter a suspend state
20+ * @state: the state to enter, one of PIIX4_FUNC3IO_PMCNTRL_SUS_TYP_*
21+ *
22+ * Enters a suspend state via the Malta's PIIX4. If the state to be entered
23+ * is one which loses context (eg. SOFF) then this function will never
24+ * return.
25+ */
26+extern int mips_pm_suspend(unsigned state);
27+
28+#else /* !CONFIG_MIPS_MALTA_PM */
29+
30+static inline int mips_pm_suspend(unsigned state)
31+{
32+ return -EINVAL;
33+}
34+
35+#endif /* !CONFIG_MIPS_MALTA_PM */
36+
37+#endif /* __ASM_MIPS_MACH_MALTA_PM_H__ */
arch/mips/include/asm/mach-netlogic/topology.h+2−0
@@ -10,10 +10,12 @@ · 9 unmodified lines
1010
1111 #include <asm/mach-netlogic/multi-node.h>
1212
13+#ifdef CONFIG_SMP
1314 #define topology_physical_package_id(cpu) cpu_to_node(cpu)
1415 #define topology_core_id(cpu) (cpu_logical_map(cpu) / NLM_THREADS_PER_CORE)
1516 #define topology_thread_cpumask(cpu) (&cpu_sibling_map[cpu])
1617 #define topology_core_cpumask(cpu) cpumask_of_node(cpu_to_node(cpu))
18+#endif
1719
1820 #include <asm-generic/topology.h>
1921
arch/mips/include/asm/mach-paravirt/cpu-feature-overrides.h+36−0
@@ -0,0 +1,36 @@
1+/*
2+ * This file is subject to the terms and conditions of the GNU General Public
3+ * License. See the file "COPYING" in the main directory of this archive
4+ * for more details.
5+ *
6+ * Copyright (C) 2013 Cavium, Inc.
7+ */
8+#ifndef __ASM_MACH_PARAVIRT_CPU_FEATURE_OVERRIDES_H
9+#define __ASM_MACH_PARAVIRT_CPU_FEATURE_OVERRIDES_H
10+
11+#define cpu_has_4kex 1
12+#define cpu_has_3k_cache 0
13+#define cpu_has_tx39_cache 0
14+#define cpu_has_counter 1
15+#define cpu_has_llsc 1
16+/*
17+ * We Disable LL/SC on non SMP systems as it is faster to disable
18+ * interrupts for atomic access than a LL/SC.
19+ */
20+#ifdef CONFIG_SMP
21+# define kernel_uses_llsc 1
22+#else
23+# define kernel_uses_llsc 0
24+#endif
25+
26+#ifdef CONFIG_CPU_CAVIUM_OCTEON
27+#define cpu_dcache_line_size() 128
28+#define cpu_icache_line_size() 128
29+#define cpu_has_octeon_cache 1
30+#define cpu_has_4k_cache 0
31+#else
32+#define cpu_has_octeon_cache 0
33+#define cpu_has_4k_cache 1
34+#endif
35+
36+#endif /* __ASM_MACH_PARAVIRT_CPU_FEATURE_OVERRIDES_H */
arch/mips/include/asm/mach-paravirt/irq.h+19−0
@@ -0,0 +1,19 @@
1+/*
2+ * This file is subject to the terms and conditions of the GNU General Public
3+ * License. See the file "COPYING" in the main directory of this archive
4+ * for more details.
5+ *
6+ * Copyright (C) 2013 Cavium, Inc.
7+ */
8+#ifndef __ASM_MACH_PARAVIRT_IRQ_H__
9+#define __ASM_MACH_PARAVIRT_IRQ_H__
10+
11+#define NR_IRQS 64
12+#define MIPS_CPU_IRQ_BASE 1
13+
14+#define MIPS_IRQ_PCIA (MIPS_CPU_IRQ_BASE + 8)
15+
16+#define MIPS_IRQ_MBOX0 (MIPS_CPU_IRQ_BASE + 32)
17+#define MIPS_IRQ_MBOX1 (MIPS_CPU_IRQ_BASE + 33)
18+
19+#endif /* __ASM_MACH_PARAVIRT_IRQ_H__ */
arch/mips/include/asm/mach-paravirt/kernel-entry-init.h+50−0
@@ -0,0 +1,50 @@
1+/*
2+ * This file is subject to the terms and conditions of the GNU General Public
3+ * License. See the file "COPYING" in the main directory of this archive
4+ * for more details.
5+ *
6+ * Copyright (C) 2013 Cavium, Inc
7+ */
8+#ifndef __ASM_MACH_PARAVIRT_KERNEL_ENTRY_H
9+#define __ASM_MACH_PARAVIRT_KERNEL_ENTRY_H
10+
11+#define CP0_EBASE $15, 1
12+
13+ .macro kernel_entry_setup
14+ mfc0 t0, CP0_EBASE
15+ andi t0, t0, 0x3ff # CPUNum
16+ beqz t0, 1f
17+ # CPUs other than zero goto smp_bootstrap
18+ j smp_bootstrap
19+
20+1:
21+ .endm
22+
23+/*
24+ * Do SMP slave processor setup necessary before we can safely execute
25+ * C code.
26+ */
27+ .macro smp_slave_setup
28+ mfc0 t0, CP0_EBASE
29+ andi t0, t0, 0x3ff # CPUNum
30+ slti t1, t0, NR_CPUS
31+ bnez t1, 1f
32+2:
33+ di
34+ wait
35+ b 2b # Unknown CPU, loop forever.
36+1:
37+ PTR_LA t1, paravirt_smp_sp
38+ PTR_SLL t0, PTR_SCALESHIFT
39+ PTR_ADDU t1, t1, t0
40+3:
41+ PTR_L sp, 0(t1)
42+ beqz sp, 3b # Spin until told to proceed.
43+
44+ PTR_LA t1, paravirt_smp_gp
45+ PTR_ADDU t1, t1, t0
46+ sync
47+ PTR_L gp, 0(t1)
48+ .endm
49+
50+#endif /* __ASM_MACH_PARAVIRT_KERNEL_ENTRY_H */
arch/mips/include/asm/mach-paravirt/war.h+25−0
@@ -0,0 +1,25 @@
1+/*
2+ * This file is subject to the terms and conditions of the GNU General Public
3+ * License. See the file "COPYING" in the main directory of this archive
4+ * for more details.
5+ *
6+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
7+ * Copyright (C) 2013 Cavium Networks <support@caviumnetworks.com>
8+ */
9+#ifndef __ASM_MIPS_MACH_PARAVIRT_WAR_H
10+#define __ASM_MIPS_MACH_PARAVIRT_WAR_H
11+
12+#define R4600_V1_INDEX_ICACHEOP_WAR 0
13+#define R4600_V1_HIT_CACHEOP_WAR 0
14+#define R4600_V2_HIT_CACHEOP_WAR 0
15+#define R5432_CP0_INTERRUPT_WAR 0
16+#define BCM1250_M3_WAR 0
17+#define SIBYTE_1956_WAR 0
18+#define MIPS4K_ICACHE_REFILL_WAR 0
19+#define MIPS_CACHE_SYNC_WAR 0
20+#define TX49XX_ICACHE_INDEX_INV_WAR 0
21+#define ICACHE_REFILLS_WORKAROUND_WAR 0
22+#define R10000_LLSC_WAR 0
23+#define MIPS34K_MISSED_ITLB_WAR 0
24+
25+#endif /* __ASM_MIPS_MACH_PARAVIRT_WAR_H */
arch/mips/include/asm/mach-pmcs-msp71xx/msp_usb.h+0−4
@@ -25,11 +25,7 @@ · 24 unmodified lines
2525 #ifndef MSP_USB_H_
2626 #define MSP_USB_H_
2727
28−#ifdef CONFIG_MSP_HAS_DUAL_USB
29−#define NUM_USB_DEVS 2
30−#else
3128 #define NUM_USB_DEVS 1
32−#endif
3329
3430 /* Register spaces for USB host 0 */
3531 #define MSP_USB0_MAB_START (MSP_USB0_BASE + 0x0)
arch/mips/include/asm/mach-ralink/war.h+0−1
@@ -17,7 +17,6 @@ · 16 unmodified lines
1717 #define MIPS4K_ICACHE_REFILL_WAR 0
1818 #define MIPS_CACHE_SYNC_WAR 0
1919 #define TX49XX_ICACHE_INDEX_INV_WAR 0
20−#define RM9000_CDEX_SMP_WAR 0
2120 #define ICACHE_REFILLS_WORKAROUND_WAR 0
2221 #define R10000_LLSC_WAR 0
2322 #define MIPS34K_MISSED_ITLB_WAR 0
arch/mips/include/asm/mach-sead3/kernel-entry-init.h+0−31
@@ -10,37 +10,6 @@ · 9 unmodified lines
1010 #define __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H
1111
1212 .macro kernel_entry_setup
13−#ifdef CONFIG_MIPS_MT_SMTC
14− mfc0 t0, CP0_CONFIG
15− bgez t0, 9f
16− mfc0 t0, CP0_CONFIG, 1
17− bgez t0, 9f
18− mfc0 t0, CP0_CONFIG, 2
19− bgez t0, 9f
20− mfc0 t0, CP0_CONFIG, 3
21− and t0, 1<<2
22− bnez t0, 0f
23−9 :
24− /* Assume we came from YAMON... */
25− PTR_LA v0, 0x9fc00534 /* YAMON print */
26− lw v0, (v0)
27− move a0, zero
28− PTR_LA a1, nonmt_processor
29− jal v0
30−
31− PTR_LA v0, 0x9fc00520 /* YAMON exit */
32− lw v0, (v0)
33− li a0, 1
34− jal v0
35−
36−1 : b 1b
37−
38− __INITDATA
39−nonmt_processor :
40− .asciz "SMTC kernel requires the MT ASE to run\n"
41− __FINIT
42−0 :
43−#endif
4413 .endm
4514
4615 /*
arch/mips/include/asm/mips-boards/piix4.h+12−0
@@ -55,4 +55,16 @@ · 54 unmodified lines
5555 #define PIIX4_FUNC3_PMREGMISC 0x80
5656 #define PIIX4_FUNC3_PMREGMISC_EN (1 << 0)
5757
58+/* Power Management IO Space */
59+#define PIIX4_FUNC3IO_PMSTS 0x00
60+#define PIIX4_FUNC3IO_PMSTS_PWRBTN_STS (1 << 8)
61+#define PIIX4_FUNC3IO_PMCNTRL 0x04
62+#define PIIX4_FUNC3IO_PMCNTRL_SUS_EN (1 << 13)
63+#define PIIX4_FUNC3IO_PMCNTRL_SUS_TYP (0x7 << 10)
64+#define PIIX4_FUNC3IO_PMCNTRL_SUS_TYP_SOFF (0x0 << 10)
65+#define PIIX4_FUNC3IO_PMCNTRL_SUS_TYP_STR (0x1 << 10)
66+
67+/* Data for magic special PCI cycle */
68+#define PIIX4_SUSPEND_MAGIC 0x00120002
69+
5870 #endif /* __ASM_MIPS_BOARDS_PIIX4_H */
arch/mips/include/asm/mips-cpc.h+33−1
@@ -72,7 +72,12 @@ static inline bool mips_cpc_present(void) · 71 unmodified lines
7272 #define MIPS_CPC_COCB_OFS 0x4000
7373
7474 /* Macros to ease the creation of register access functions */
75−#define BUILD_CPC_R_(name, off) \
75+#define BUILD_CPC_R_(name, off) \
76+static inline u32 *addr_cpc_##name(void) \
77+{ \
78+ return (u32 *)(mips_cpc_base + (off)); \
79+} \
80+ \
7681 static inline u32 read_cpc_##name(void) \
7782 { \
7883 return __raw_readl(mips_cpc_base + (off)); \
@@ -147,4 +152,31 @@ BUILD_CPC_Cx_RW(other, 0x10) · 68 unmodified lines
147152 #define CPC_Cx_OTHER_CORENUM_SHF 16
148153 #define CPC_Cx_OTHER_CORENUM_MSK (_ULCAST_(0xff) << 16)
149154
155+#ifdef CONFIG_MIPS_CPC
156+
157+/**
158+ * mips_cpc_lock_other - lock access to another core
159+ * core: the other core to be accessed
160+ *
161+ * Call before operating upon a core via the 'other' register region in
162+ * order to prevent the region being moved during access. Must be followed
163+ * by a call to mips_cpc_unlock_other.
164+ */
165+extern void mips_cpc_lock_other(unsigned int core);
166+
167+/**
168+ * mips_cpc_unlock_other - unlock access to another core
169+ *
170+ * Call after operating upon another core via the 'other' register region.
171+ * Must be called after mips_cpc_lock_other.
172+ */
173+extern void mips_cpc_unlock_other(void);
174+
175+#else /* !CONFIG_MIPS_CPC */
176+
177+static inline void mips_cpc_lock_other(unsigned int core) { }
178+static inline void mips_cpc_unlock_other(void) { }
179+
180+#endif /* !CONFIG_MIPS_CPC */
181+
150182 #endif /* __MIPS_ASM_MIPS_CPC_H__ */
arch/mips/include/asm/mips_mt.h+2−3
@@ -1,7 +1,6 @@
11 /*
2− * Definitions and decalrations for MIPS MT support
3− * that are common between SMTC, VSMP, and/or AP/SP
4− * kernel models.
2+ * Definitions and decalrations for MIPS MT support that are common between
3+ * the VSMP, and AP/SP kernel models.
54 */
65 #ifndef __ASM_MIPS_MT_H
76 #define __ASM_MIPS_MT_H
arch/mips/include/asm/mipsmtregs.h+2−0
@@ -36,6 +36,8 @@ · 35 unmodified lines
3636
3737 #define read_c0_tcbind() __read_32bit_c0_register($2, 2)
3838
39+#define write_c0_tchalt(val) __write_32bit_c0_register($2, 4, val)
40+
3941 #define read_c0_tccontext() __read_32bit_c0_register($2, 5)
4042 #define write_c0_tccontext(val) __write_32bit_c0_register($2, 5, val)
4143
arch/mips/include/asm/mipsregs.h+18−133
@@ -709,11 +709,18 @@ · 708 unmodified lines
709709 #ifndef __ASSEMBLY__
710710
711711 /*
712− * Macros for handling the ISA mode bit for microMIPS.
712+ * Macros for handling the ISA mode bit for MIPS16 and microMIPS.
713713 */
714+#if defined(CONFIG_SYS_SUPPORTS_MIPS16) || \
715+ defined(CONFIG_SYS_SUPPORTS_MICROMIPS)
714716 #define get_isa16_mode(x) ((x) & 0x1)
715717 #define msk_isa16_mode(x) ((x) & ~0x1)
716718 #define set_isa16_mode(x) do { (x) |= 0x1; } while(0)
719+#else
720+#define get_isa16_mode(x) 0
721+#define msk_isa16_mode(x) (x)
722+#define set_isa16_mode(x) do { } while(0)
723+#endif
717724
718725 /*
719726 * microMIPS instructions can be 16-bit or 32-bit in length. This
@@ -1007,19 +1014,8 @@ do { \ · 287 unmodified lines
10071014 #define write_c0_compare3(val) __write_32bit_c0_register($11, 7, val)
10081015
10091016 #define read_c0_status() __read_32bit_c0_register($12, 0)
1010−#ifdef CONFIG_MIPS_MT_SMTC
1011−#define write_c0_status(val) \
1012−do { \
1013− __write_32bit_c0_register($12, 0, val); \
1014− __ehb(); \
1015−} while (0)
1016−#else
1017−/*
1018− * Legacy non-SMTC code, which may be hazardous
1019− * but which might not support EHB
1020− */
1017+
10211018 #define write_c0_status(val) __write_32bit_c0_register($12, 0, val)
1022−#endif /* CONFIG_MIPS_MT_SMTC */
10231019
10241020 #define read_c0_cause() __read_32bit_c0_register($13, 0)
10251021 #define write_c0_cause(val) __write_32bit_c0_register($13, 0, val)
@@ -1743,11 +1739,6 @@ static inline void tlb_write_random(void) · 717 unmodified lines
17431739 /*
17441740 * Manipulate bits in a c0 register.
17451741 */
1746−#ifndef CONFIG_MIPS_MT_SMTC
1747−/*
1748− * SMTC Linux requires shutting-down microthread scheduling
1749− * during CP0 register read-modify-write sequences.
1750− */
17511742 #define __BUILD_SET_C0(name) \
17521743 static inline unsigned int \
17531744 set_c0_##name(unsigned int set) \
@@ -1786,121 +1777,6 @@ change_c0_##name(unsigned int change, unsigned int val) \ · 32 unmodified lines
17861777 return res; \
17871778 }
17881779
1789−#else /* SMTC versions that manage MT scheduling */
1790−
1791−#include <linux/irqflags.h>
1792−
1793−/*
1794− * This is a duplicate of dmt() in mipsmtregs.h to avoid problems with
1795− * header file recursion.
1796− */
1797−static inline unsigned int __dmt(void)
1798−{
1799− int res;
1800−
1801− __asm__ __volatile__(
1802− " .set push \n"
1803− " .set mips32r2 \n"
1804− " .set noat \n"
1805− " .word 0x41610BC1 # dmt $1 \n"
1806− " ehb \n"
1807− " move %0, $1 \n"
1808− " .set pop \n"
1809− : "=r" (res));
1810−
1811− instruction_hazard();
1812−
1813− return res;
1814−}
1815−
1816−#define __VPECONTROL_TE_SHIFT 15
1817−#define __VPECONTROL_TE (1UL << __VPECONTROL_TE_SHIFT)
1818−
1819−#define __EMT_ENABLE __VPECONTROL_TE
1820−
1821−static inline void __emt(unsigned int previous)
1822−{
1823− if ((previous & __EMT_ENABLE))
1824− __asm__ __volatile__(
1825− " .set mips32r2 \n"
1826− " .word 0x41600be1 # emt \n"
1827− " ehb \n"
1828− " .set mips0 \n");
1829−}
1830−
1831−static inline void __ehb(void)
1832−{
1833− __asm__ __volatile__(
1834− " .set mips32r2 \n"
1835− " ehb \n" " .set mips0 \n");
1836−}
1837−
1838−/*
1839− * Note that local_irq_save/restore affect TC-specific IXMT state,
1840− * not Status.IE as in non-SMTC kernel.
1841− */
1842−
1843−#define __BUILD_SET_C0(name) \
1844−static inline unsigned int \
1845−set_c0_##name(unsigned int set) \
1846−{ \
1847− unsigned int res; \
1848− unsigned int new; \
1849− unsigned int omt; \
1850− unsigned long flags; \
1851− \
1852− local_irq_save(flags); \
1853− omt = __dmt(); \
1854− res = read_c0_##name(); \
1855− new = res | set; \
1856− write_c0_##name(new); \
1857− __emt(omt); \
1858− local_irq_restore(flags); \
1859− \
1860− return res; \
1861−} \
1862− \
1863−static inline unsigned int \
1864−clear_c0_##name(unsigned int clear) \
1865−{ \
1866− unsigned int res; \
1867− unsigned int new; \
1868− unsigned int omt; \
1869− unsigned long flags; \
1870− \
1871− local_irq_save(flags); \
1872− omt = __dmt(); \
1873− res = read_c0_##name(); \
1874− new = res & ~clear; \
1875− write_c0_##name(new); \
1876− __emt(omt); \
1877− local_irq_restore(flags); \
1878− \
1879− return res; \
1880−} \
1881− \
1882−static inline unsigned int \
1883−change_c0_##name(unsigned int change, unsigned int newbits) \
1884−{ \
1885− unsigned int res; \
1886− unsigned int new; \
1887− unsigned int omt; \
1888− unsigned long flags; \
1889− \
1890− local_irq_save(flags); \
1891− \
1892− omt = __dmt(); \
1893− res = read_c0_##name(); \
1894− new = res & ~change; \
1895− new |= (newbits & change); \
1896− write_c0_##name(new); \
1897− __emt(omt); \
1898− local_irq_restore(flags); \
1899− \
1900− return res; \
1901−}
1902−#endif
1903−
19041780 __BUILD_SET_C0(status)
19051781 __BUILD_SET_C0(cause)
19061782 __BUILD_SET_C0(config)
@@ -1916,6 +1792,15 @@ __BUILD_SET_C0(brcm_cmt_ctrl) · 9 unmodified lines
19161792 __BUILD_SET_C0(brcm_config)
19171793 __BUILD_SET_C0(brcm_mode)
19181794
1795+/*
1796+ * Return low 10 bits of ebase.
1797+ * Note that under KVM (MIPSVZ) this returns vcpu id.
1798+ */
1799+static inline unsigned int get_ebase_cpunum(void)
1800+{
1801+ return read_c0_ebase() & 0x3ff;
1802+}
1803+
19191804 #endif /* !__ASSEMBLY__ */
19201805
19211806 #endif /* _ASM_MIPSREGS_H */
arch/mips/include/asm/mmu_context.h+11−111
@@ -18,10 +18,6 @@ · 17 unmodified lines
1818 #include <asm/cacheflush.h>
1919 #include <asm/hazards.h>
2020 #include <asm/tlbflush.h>
21−#ifdef CONFIG_MIPS_MT_SMTC
22−#include <asm/mipsmtregs.h>
23−#include <asm/smtc.h>
24−#endif /* SMTC */
2521 #include <asm-generic/mm_hooks.h>
2622
2723 #define TLBMISS_HANDLER_SETUP_PGD(pgd) \
@@ -31,11 +27,15 @@ do { \ · 3 unmodified lines
3127 } while (0)
3228
3329 #ifdef CONFIG_MIPS_PGD_C0_CONTEXT
30+
31+#define TLBMISS_HANDLER_RESTORE() \
32+ write_c0_xcontext((unsigned long) smp_processor_id() << \
33+ SMP_CPUID_REGSHIFT)
34+
3435 #define TLBMISS_HANDLER_SETUP() \
3536 do { \
3637 TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir); \
37− write_c0_xcontext((unsigned long) smp_processor_id() << \
38− SMP_CPUID_REGSHIFT); \
38+ TLBMISS_HANDLER_RESTORE(); \
3939 } while (0)
4040
4141 #else /* !CONFIG_MIPS_PGD_C0_CONTEXT: using pgd_current*/
@@ -47,9 +47,12 @@ do { \ · 5 unmodified lines
4747 */
4848 extern unsigned long pgd_current[];
4949
50−#define TLBMISS_HANDLER_SETUP() \
50+#define TLBMISS_HANDLER_RESTORE() \
5151 write_c0_context((unsigned long) smp_processor_id() << \
52− SMP_CPUID_REGSHIFT); \
52+ SMP_CPUID_REGSHIFT)
53+
54+#define TLBMISS_HANDLER_SETUP() \
55+ TLBMISS_HANDLER_RESTORE(); \
5356 back_to_back_c0_hazard(); \
5457 TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
5558 #endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/
@@ -63,13 +66,6 @@ extern unsigned long pgd_current[]; · 7 unmodified lines
6366 #define ASID_INC 0x10
6467 #define ASID_MASK 0xff0
6568
66−#elif defined(CONFIG_MIPS_MT_SMTC)
67−
68−#define ASID_INC 0x1
69−extern unsigned long smtc_asid_mask;
70−#define ASID_MASK (smtc_asid_mask)
71−#define HW_ASID_MASK 0xff
72−/* End SMTC/34K debug hack */
7369 #else /* FIXME: not correct for R6000 */
7470
7571 #define ASID_INC 0x1
@@ -92,7 +88,6 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) · 16 unmodified lines
9288 #define ASID_VERSION_MASK ((unsigned long)~(ASID_MASK|(ASID_MASK-1)))
9389 #define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1)
9490
95−#ifndef CONFIG_MIPS_MT_SMTC
9691 /* Normal, classic MIPS get_new_mmu_context */
9792 static inline void
9893 get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
@@ -115,12 +110,6 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) · 16 unmodified lines
115110 cpu_context(cpu, mm) = asid_cache(cpu) = asid;
116111 }
117112
118−#else /* CONFIG_MIPS_MT_SMTC */
119−
120−#define get_new_mmu_context(mm, cpu) smtc_get_new_mmu_context((mm), (cpu))
121−
122−#endif /* CONFIG_MIPS_MT_SMTC */
123−
124113 /*
125114 * Initialize the context related info for a new mm_struct
126115 * instance.
@@ -141,46 +130,12 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, · 14 unmodified lines
141130 {
142131 unsigned int cpu = smp_processor_id();
143132 unsigned long flags;
144−#ifdef CONFIG_MIPS_MT_SMTC
145− unsigned long oldasid;
146− unsigned long mtflags;
147− int mytlb = (smtc_status & SMTC_TLB_SHARED) ? 0 : cpu_data[cpu].vpe_id;
148133 local_irq_save(flags);
149− mtflags = dvpe();
150−#else /* Not SMTC */
151− local_irq_save(flags);
152−#endif /* CONFIG_MIPS_MT_SMTC */
153134
154135 /* Check if our ASID is of an older version and thus invalid */
155136 if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & ASID_VERSION_MASK)
156137 get_new_mmu_context(next, cpu);
157−#ifdef CONFIG_MIPS_MT_SMTC
158− /*
159− * If the EntryHi ASID being replaced happens to be
160− * the value flagged at ASID recycling time as having
161− * an extended life, clear the bit showing it being
162− * in use by this "CPU", and if that's the last bit,
163− * free up the ASID value for use and flush any old
164− * instances of it from the TLB.
165− */
166− oldasid = (read_c0_entryhi() & ASID_MASK);
167− if(smtc_live_asid[mytlb][oldasid]) {
168− smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu);
169− if(smtc_live_asid[mytlb][oldasid] == 0)
170− smtc_flush_tlb_asid(oldasid);
171− }
172− /*
173− * Tread softly on EntryHi, and so long as we support
174− * having ASID_MASK smaller than the hardware maximum,
175− * make sure no "soft" bits become "hard"...
176− */
177− write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) |
178− cpu_asid(cpu, next));
179− ehb(); /* Make sure it propagates to TCStatus */
180− evpe(mtflags);
181−#else
182138 write_c0_entryhi(cpu_asid(cpu, next));
183−#endif /* CONFIG_MIPS_MT_SMTC */
184139 TLBMISS_HANDLER_SETUP_PGD(next->pgd);
185140
186141 /*
@@ -213,34 +168,12 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next) · 26 unmodified lines
213168 unsigned long flags;
214169 unsigned int cpu = smp_processor_id();
215170
216−#ifdef CONFIG_MIPS_MT_SMTC
217− unsigned long oldasid;
218− unsigned long mtflags;
219− int mytlb = (smtc_status & SMTC_TLB_SHARED) ? 0 : cpu_data[cpu].vpe_id;
220−#endif /* CONFIG_MIPS_MT_SMTC */
221−
222171 local_irq_save(flags);
223172
224173 /* Unconditionally get a new ASID. */
225174 get_new_mmu_context(next, cpu);
226175
227−#ifdef CONFIG_MIPS_MT_SMTC
228− /* See comments for similar code above */
229− mtflags = dvpe();
230− oldasid = read_c0_entryhi() & ASID_MASK;
231− if(smtc_live_asid[mytlb][oldasid]) {
232− smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu);
233− if(smtc_live_asid[mytlb][oldasid] == 0)
234− smtc_flush_tlb_asid(oldasid);
235− }
236− /* See comments for similar code above */
237− write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) |
238− cpu_asid(cpu, next));
239− ehb(); /* Make sure it propagates to TCStatus */
240− evpe(mtflags);
241−#else
242176 write_c0_entryhi(cpu_asid(cpu, next));
243−#endif /* CONFIG_MIPS_MT_SMTC */
244177 TLBMISS_HANDLER_SETUP_PGD(next->pgd);
245178
246179 /* mark mmu ownership change */
@@ -258,48 +191,15 @@ static inline void · 11 unmodified lines
258191 drop_mmu_context(struct mm_struct *mm, unsigned cpu)
259192 {
260193 unsigned long flags;
261−#ifdef CONFIG_MIPS_MT_SMTC
262− unsigned long oldasid;
263− /* Can't use spinlock because called from TLB flush within DVPE */
264− unsigned int prevvpe;
265− int mytlb = (smtc_status & SMTC_TLB_SHARED) ? 0 : cpu_data[cpu].vpe_id;
266−#endif /* CONFIG_MIPS_MT_SMTC */
267194
268195 local_irq_save(flags);
269196
270197 if (cpumask_test_cpu(cpu, mm_cpumask(mm))) {
271198 get_new_mmu_context(mm, cpu);
272−#ifdef CONFIG_MIPS_MT_SMTC
273− /* See comments for similar code above */
274− prevvpe = dvpe();
275− oldasid = (read_c0_entryhi() & ASID_MASK);
276− if (smtc_live_asid[mytlb][oldasid]) {
277− smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu);
278− if(smtc_live_asid[mytlb][oldasid] == 0)
279− smtc_flush_tlb_asid(oldasid);
280− }
281− /* See comments for similar code above */
282− write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK)
283− | cpu_asid(cpu, mm));
284− ehb(); /* Make sure it propagates to TCStatus */
285− evpe(prevvpe);
286−#else /* not CONFIG_MIPS_MT_SMTC */
287199 write_c0_entryhi(cpu_asid(cpu, mm));
288−#endif /* CONFIG_MIPS_MT_SMTC */
289200 } else {
290201 /* will get a new context next time */
291−#ifndef CONFIG_MIPS_MT_SMTC
292202 cpu_context(cpu, mm) = 0;
293−#else /* SMTC */
294− int i;
295−
296− /* SMTC shares the TLB (and ASIDs) across VPEs */
297− for_each_online_cpu(i) {
298− if((smtc_status & SMTC_TLB_SHARED)
299− || (cpu_data[i].vpe_id == cpu_data[cpu].vpe_id))
300− cpu_context(i, mm) = 0;
301− }
302−#endif /* CONFIG_MIPS_MT_SMTC */
303203 }
304204 local_irq_restore(flags);
305205 }
arch/mips/include/asm/module.h+1−7
@@ -144,13 +144,7 @@ search_module_dbetables(unsigned long addr) · 143 unmodified lines
144144 #define MODULE_KERNEL_TYPE "64BIT "
145145 #endif
146146
147−#ifdef CONFIG_MIPS_MT_SMTC
148−#define MODULE_KERNEL_SMTC "MT_SMTC "
149−#else
150−#define MODULE_KERNEL_SMTC ""
151−#endif
152−
153147 #define MODULE_ARCH_VERMAGIC \
154− MODULE_PROC_FAMILY MODULE_KERNEL_TYPE MODULE_KERNEL_SMTC
148+ MODULE_PROC_FAMILY MODULE_KERNEL_TYPE
155149
156150 #endif /* _ASM_MODULE_H */
arch/mips/include/asm/msa.h+12−3
@@ -84,7 +84,7 @@ static inline void write_msa_##name(unsigned int val) \ · 83 unmodified lines
8484 __asm__ __volatile__( \
8585 " .set push\n" \
8686 " .set msa\n" \
87− " cfcmsa $" #cs ", %0\n" \
87+ " ctcmsa $" #cs ", %0\n" \
8888 " .set pop\n" \
8989 : : "r"(val)); \
9090 }
@@ -96,6 +96,13 @@ static inline void write_msa_##name(unsigned int val) \ · 5 unmodified lines
9696 * allow compilation with toolchains that do not support MSA. Once all
9797 * toolchains in use support MSA these can be removed.
9898 */
99+#ifdef CONFIG_CPU_MICROMIPS
100+#define CFC_MSA_INSN 0x587e0056
101+#define CTC_MSA_INSN 0x583e0816
102+#else
103+#define CFC_MSA_INSN 0x787e0059
104+#define CTC_MSA_INSN 0x783e0819
105+#endif
99106
100107 #define __BUILD_MSA_CTL_REG(name, cs) \
101108 static inline unsigned int read_msa_##name(void) \
@@ -104,7 +111,8 @@ static inline unsigned int read_msa_##name(void) \ · 2 unmodified lines
104111 __asm__ __volatile__( \
105112 " .set push\n" \
106113 " .set noat\n" \
107− " .word 0x787e0059 | (" #cs " << 11)\n" \
114+ " .insn\n" \
115+ " .word #CFC_MSA_INSN | (" #cs " << 11)\n" \
108116 " move %0, $1\n" \
109117 " .set pop\n" \
110118 : "=r"(reg)); \
@@ -117,7 +125,8 @@ static inline void write_msa_##name(unsigned int val) \ · 6 unmodified lines
117125 " .set push\n" \
118126 " .set noat\n" \
119127 " move $1, %0\n" \
120− " .word 0x783e0819 | (" #cs " << 6)\n" \
128+ " .insn\n" \
129+ " .word #CTC_MSA_INSN | (" #cs " << 6)\n" \
121130 " .set pop\n" \
122131 : : "r"(val)); \
123132 }
arch/mips/include/asm/netlogic/mips-extns.h+3−2
@@ -146,9 +146,10 @@ static inline int hard_smp_processor_id(void) · 145 unmodified lines
146146
147147 static inline int nlm_nodeid(void)
148148 {
149− uint32_t prid = read_c0_prid();
149+ uint32_t prid = read_c0_prid() & PRID_IMP_MASK;
150150
151− if ((prid & 0xff00) == PRID_IMP_NETLOGIC_XLP9XX)
151+ if ((prid == PRID_IMP_NETLOGIC_XLP9XX) ||
152+ (prid == PRID_IMP_NETLOGIC_XLP5XX))
152153 return (__read_32bit_c0_register($15, 1) >> 7) & 0x7;
153154 else
154155 return (__read_32bit_c0_register($15, 1) >> 5) & 0x3;
arch/mips/include/asm/netlogic/xlp-hal/iomap.h+11−7
@@ -74,6 +74,8 @@ · 73 unmodified lines
7474 #define XLP_IO_USB_OHCI2_OFFSET(node) XLP_HDR_OFFSET(node, 0, 2, 4)
7575 #define XLP_IO_USB_OHCI3_OFFSET(node) XLP_HDR_OFFSET(node, 0, 2, 5)
7676
77+#define XLP_IO_SATA_OFFSET(node) XLP_HDR_OFFSET(node, 0, 3, 2)
78+
7779 /* XLP2xx has an updated USB block */
7880 #define XLP2XX_IO_USB_OFFSET(node, i) XLP_HDR_OFFSET(node, 0, 4, i)
7981 #define XLP2XX_IO_USB_XHCI0_OFFSET(node) XLP_HDR_OFFSET(node, 0, 4, 1)
@@ -103,13 +105,11 @@ · 23 unmodified lines
103105 #define XLP_IO_SYS_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 5)
104106 #define XLP_IO_JTAG_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 6)
105107
108+/* Flash */
106109 #define XLP_IO_NOR_OFFSET(node) XLP_HDR_OFFSET(node, 0, 7, 0)
107110 #define XLP_IO_NAND_OFFSET(node) XLP_HDR_OFFSET(node, 0, 7, 1)
108111 #define XLP_IO_SPI_OFFSET(node) XLP_HDR_OFFSET(node, 0, 7, 2)
109−/* SD flash */
110−#define XLP_IO_SD_OFFSET(node) XLP_HDR_OFFSET(node, 0, 7, 3)
111−#define XLP_IO_MMC_OFFSET(node, slot) \
112− ((XLP_IO_SD_OFFSET(node))+(slot*0x100)+XLP_IO_PCI_HDRSZ)
112+#define XLP_IO_MMC_OFFSET(node) XLP_HDR_OFFSET(node, 0, 7, 3)
113113
114114 /* Things have changed drastically in XLP 9XX */
115115 #define XLP9XX_HDR_OFFSET(n, d, f) \
@@ -120,6 +120,8 @@ · 4 unmodified lines
120120 #define XLP9XX_IO_UART_OFFSET(node) XLP9XX_HDR_OFFSET(node, 2, 2)
121121 #define XLP9XX_IO_SYS_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 0)
122122 #define XLP9XX_IO_FUSE_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 1)
123+#define XLP9XX_IO_CLOCK_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 2)
124+#define XLP9XX_IO_POWER_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 3)
123125 #define XLP9XX_IO_JTAG_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 4)
124126
125127 #define XLP9XX_IO_PCIE_OFFSET(node, i) XLP9XX_HDR_OFFSET(node, 1, i)
@@ -135,11 +137,11 @@ · 9 unmodified lines
135137 /* XLP9XX on-chip SATA controller */
136138 #define XLP9XX_IO_SATA_OFFSET(node) XLP9XX_HDR_OFFSET(node, 3, 2)
137139
140+/* Flash */
138141 #define XLP9XX_IO_NOR_OFFSET(node) XLP9XX_HDR_OFFSET(node, 7, 0)
139142 #define XLP9XX_IO_NAND_OFFSET(node) XLP9XX_HDR_OFFSET(node, 7, 1)
140143 #define XLP9XX_IO_SPI_OFFSET(node) XLP9XX_HDR_OFFSET(node, 7, 2)
141−/* SD flash */
142−#define XLP9XX_IO_MMCSD_OFFSET(node) XLP9XX_HDR_OFFSET(node, 7, 3)
144+#define XLP9XX_IO_MMC_OFFSET(node) XLP9XX_HDR_OFFSET(node, 7, 3)
143145
144146 /* PCI config header register id's */
145147 #define XLP_PCI_CFGREG0 0x00
@@ -186,8 +188,10 @@ · 40 unmodified lines
186188 #define PCI_DEVICE_ID_NLM_NOR 0x1015
187189 #define PCI_DEVICE_ID_NLM_NAND 0x1016
188190 #define PCI_DEVICE_ID_NLM_MMC 0x1018
189−#define PCI_DEVICE_ID_NLM_XHCI 0x101d
191+#define PCI_DEVICE_ID_NLM_SATA 0x101A
192+#define PCI_DEVICE_ID_NLM_XHCI 0x101D
190193
194+#define PCI_DEVICE_ID_XLP9XX_MMC 0x9018
191195 #define PCI_DEVICE_ID_XLP9XX_SATA 0x901A
192196 #define PCI_DEVICE_ID_XLP9XX_XHCI 0x901D
193197
arch/mips/include/asm/netlogic/xlp-hal/pcibus.h+14−0
@@ -69,6 +69,20 @@ · 68 unmodified lines
6969 #define PCIE_9XX_BYTE_SWAP_IO_BASE 0x25e
7070 #define PCIE_9XX_BYTE_SWAP_IO_LIM 0x25f
7171
72+#define PCIE_9XX_BRIDGE_MSIX_ADDR_BASE 0x264
73+#define PCIE_9XX_BRIDGE_MSIX_ADDR_LIMIT 0x265
74+#define PCIE_9XX_MSI_STATUS 0x283
75+#define PCIE_9XX_MSI_EN 0x284
76+/* 128 MSIX vectors available in 9xx */
77+#define PCIE_9XX_MSIX_STATUS0 0x286
78+#define PCIE_9XX_MSIX_STATUSX(n) (n + 0x286)
79+#define PCIE_9XX_MSIX_VEC 0x296
80+#define PCIE_9XX_MSIX_VECX(n) (n + 0x296)
81+#define PCIE_9XX_INT_STATUS0 0x397
82+#define PCIE_9XX_INT_STATUS1 0x398
83+#define PCIE_9XX_INT_EN0 0x399
84+#define PCIE_9XX_INT_EN1 0x39a
85+
7286 /* other */
7387 #define PCIE_NLINKS 4
7488
arch/mips/include/asm/netlogic/xlp-hal/pic.h+4−0
@@ -199,6 +199,10 @@ · 198 unmodified lines
199199 #define PIC_IRT_PCIE_LINK_3_INDEX 81
200200 #define PIC_IRT_PCIE_LINK_INDEX(num) ((num) + PIC_IRT_PCIE_LINK_0_INDEX)
201201
202+#define PIC_9XX_IRT_PCIE_LINK_0_INDEX 191
203+#define PIC_9XX_IRT_PCIE_LINK_INDEX(num) \
204+ ((num) + PIC_9XX_IRT_PCIE_LINK_0_INDEX)
205+
202206 #define PIC_CLOCK_TIMER 7
203207
204208 #if !defined(LOCORE) && !defined(__ASSEMBLY__)
arch/mips/include/asm/netlogic/xlp-hal/sys.h+35−0
@@ -118,6 +118,10 @@ · 117 unmodified lines
118118 #define SYS_SCRTCH3 0x4c
119119
120120 /* PLL registers XLP2XX */
121+#define SYS_CPU_PLL_CTRL0(core) (0x1c0 + (core * 4))
122+#define SYS_CPU_PLL_CTRL1(core) (0x1c1 + (core * 4))
123+#define SYS_CPU_PLL_CTRL2(core) (0x1c2 + (core * 4))
124+#define SYS_CPU_PLL_CTRL3(core) (0x1c3 + (core * 4))
121125 #define SYS_PLL_CTRL0 0x240
122126 #define SYS_PLL_CTRL1 0x241
123127 #define SYS_PLL_CTRL2 0x242
@@ -147,6 +151,32 @@ · 23 unmodified lines
147151 #define SYS_SYS_PLL_MEM_REQ 0x2a3
148152 #define SYS_PLL_MEM_STAT 0x2a4
149153
154+/* PLL registers XLP9XX */
155+#define SYS_9XX_CPU_PLL_CTRL0(core) (0xc0 + (core * 4))
156+#define SYS_9XX_CPU_PLL_CTRL1(core) (0xc1 + (core * 4))
157+#define SYS_9XX_CPU_PLL_CTRL2(core) (0xc2 + (core * 4))
158+#define SYS_9XX_CPU_PLL_CTRL3(core) (0xc3 + (core * 4))
159+#define SYS_9XX_DMC_PLL_CTRL0 0x140
160+#define SYS_9XX_DMC_PLL_CTRL1 0x141
161+#define SYS_9XX_DMC_PLL_CTRL2 0x142
162+#define SYS_9XX_DMC_PLL_CTRL3 0x143
163+#define SYS_9XX_PLL_CTRL0 0x144
164+#define SYS_9XX_PLL_CTRL1 0x145
165+#define SYS_9XX_PLL_CTRL2 0x146
166+#define SYS_9XX_PLL_CTRL3 0x147
167+
168+#define SYS_9XX_PLL_CTRL0_DEVX(x) (0x148 + (x) * 4)
169+#define SYS_9XX_PLL_CTRL1_DEVX(x) (0x149 + (x) * 4)
170+#define SYS_9XX_PLL_CTRL2_DEVX(x) (0x14a + (x) * 4)
171+#define SYS_9XX_PLL_CTRL3_DEVX(x) (0x14b + (x) * 4)
172+
173+#define SYS_9XX_CPU_PLL_CHG_CTRL 0x188
174+#define SYS_9XX_PLL_CHG_CTRL 0x189
175+#define SYS_9XX_CLK_DEV_DIS 0x18a
176+#define SYS_9XX_CLK_DEV_SEL 0x18b
177+#define SYS_9XX_CLK_DEV_DIV 0x18d
178+#define SYS_9XX_CLK_DEV_CHG 0x18f
179+
150180 /* Registers changed on 9XX */
151181 #define SYS_9XX_POWER_ON_RESET_CFG 0x00
152182 #define SYS_9XX_CHIP_RESET 0x01
@@ -170,6 +200,11 @@ · 17 unmodified lines
170200 #define nlm_get_fuse_regbase(node) \
171201 (nlm_get_fuse_pcibase(node) + XLP_IO_PCI_HDRSZ)
172202
203+#define nlm_get_clock_pcibase(node) \
204+ nlm_pcicfg_base(XLP9XX_IO_CLOCK_OFFSET(node))
205+#define nlm_get_clock_regbase(node) \
206+ (nlm_get_clock_pcibase(node) + XLP_IO_PCI_HDRSZ)
207+
173208 unsigned int nlm_get_pic_frequency(int node);
174209 #endif
175210 #endif
arch/mips/include/asm/netlogic/xlp-hal/xlp.h+13−6
@@ -58,6 +58,10 @@ · 57 unmodified lines
5858 #define PIC_I2C_1_IRQ 31
5959 #define PIC_I2C_2_IRQ 32
6060 #define PIC_I2C_3_IRQ 33
61+#define PIC_SPI_IRQ 34
62+#define PIC_NAND_IRQ 37
63+#define PIC_SATA_IRQ 38
64+#define PIC_GPIO_IRQ 39
6165
6266 #define PIC_PCIE_LINK_MSI_IRQ_BASE 44 /* 44 - 47 MSI IRQ */
6367 #define PIC_PCIE_LINK_MSI_IRQ(i) (44 + (i))
@@ -66,8 +70,9 @@ · 2 unmodified lines
6670 #define PIC_PCIE_MSIX_IRQ_BASE 48 /* 48 - 51 MSI-X IRQ */
6771 #define PIC_PCIE_MSIX_IRQ(i) (48 + (i))
6872
69−#define NLM_MSIX_VEC_BASE 96 /* 96 - 127 - MSIX mapped */
70−#define NLM_MSI_VEC_BASE 128 /* 128 -255 - MSI mapped */
73+/* XLP9xx and XLP8xx has 128 and 32 MSIX vectors respectively */
74+#define NLM_MSIX_VEC_BASE 96 /* 96 - 223 - MSIX mapped */
75+#define NLM_MSI_VEC_BASE 224 /* 224 -351 - MSI mapped */
7176
7277 #define NLM_PIC_INDIRECT_VEC_BASE 512
7378 #define NLM_GPIO_VEC_BASE 768
@@ -95,17 +100,19 @@ void *xlp_dt_init(void *fdtp); · 21 unmodified lines
95100
96101 static inline int cpu_is_xlpii(void)
97102 {
98− int chip = read_c0_prid() & 0xff00;
103+ int chip = read_c0_prid() & PRID_IMP_MASK;
99104
100105 return chip == PRID_IMP_NETLOGIC_XLP2XX ||
101− chip == PRID_IMP_NETLOGIC_XLP9XX;
106+ chip == PRID_IMP_NETLOGIC_XLP9XX ||
107+ chip == PRID_IMP_NETLOGIC_XLP5XX;
102108 }
103109
104110 static inline int cpu_is_xlp9xx(void)
105111 {
106− int chip = read_c0_prid() & 0xff00;
112+ int chip = read_c0_prid() & PRID_IMP_MASK;
107113
108− return chip == PRID_IMP_NETLOGIC_XLP9XX;
114+ return chip == PRID_IMP_NETLOGIC_XLP9XX ||
115+ chip == PRID_IMP_NETLOGIC_XLP5XX;
109116 }
110117 #endif /* !__ASSEMBLY__ */
111118 #endif /* _ASM_NLM_XLP_H */
arch/mips/include/asm/nile4.h+1−1
@@ -1,7 +1,7 @@
11 /*
22 * asm-mips/nile4.h -- NEC Vrc-5074 Nile 4 definitions
33 *
4− * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
4+ * Copyright (C) 2000 Geert Uytterhoeven <geert@linux-m68k.org>
55 * Sony Software Development Center Europe (SDCE), Brussels
66 *
77 * This file is based on the following documentation:
arch/mips/include/asm/octeon/octeon.h+0−1
@@ -211,7 +211,6 @@ union octeon_cvmemctl { · 210 unmodified lines
211211
212212 extern void octeon_write_lcd(const char *s);
213213 extern void octeon_check_cpu_bist(void);
214−extern int octeon_get_boot_debug_flag(void);
215214 extern int octeon_get_boot_uart(void);
216215
217216 struct uart_port;
arch/mips/include/asm/pgtable.h+2−0
@@ -32,6 +32,8 @@ struct vm_area_struct; · 31 unmodified lines
3232 _page_cachable_default)
3333 #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
3434 _PAGE_GLOBAL | _page_cachable_default)
35+#define PAGE_KERNEL_NC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
36+ _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT)
3537 #define PAGE_USERIO __pgprot(_PAGE_PRESENT | (cpu_has_rixi ? 0 : _PAGE_READ) | _PAGE_WRITE | \
3638 _page_cachable_default)
3739 #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
arch/mips/include/asm/pm-cps.h+51−0
@@ -0,0 +1,51 @@
1+/*
2+ * Copyright (C) 2014 Imagination Technologies
3+ * Author: Paul Burton <paul.burton@imgtec.com>
4+ *
5+ * This program is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License as published by the
7+ * Free Software Foundation; either version 2 of the License, or (at your
8+ * option) any later version.
9+ */
10+
11+#ifndef __MIPS_ASM_PM_CPS_H__
12+#define __MIPS_ASM_PM_CPS_H__
13+
14+/*
15+ * The CM & CPC can only handle coherence & power control on a per-core basis,
16+ * thus in an MT system the VPEs within each core are coupled and can only
17+ * enter or exit states requiring CM or CPC assistance in unison.
18+ */
19+#ifdef CONFIG_MIPS_MT
20+# define coupled_coherence cpu_has_mipsmt
21+#else
22+# define coupled_coherence 0
23+#endif
24+
25+/* Enumeration of possible PM states */
26+enum cps_pm_state {
27+ CPS_PM_NC_WAIT, /* MIPS wait instruction, non-coherent */
28+ CPS_PM_CLOCK_GATED, /* Core clock gated */
29+ CPS_PM_POWER_GATED, /* Core power gated */
30+ CPS_PM_STATE_COUNT,
31+};
32+
33+/**
34+ * cps_pm_support_state - determine whether the system supports a PM state
35+ * @state: the state to test for support
36+ *
37+ * Returns true if the system supports the given state, otherwise false.
38+ */
39+extern bool cps_pm_support_state(enum cps_pm_state state);
40+
41+/**
42+ * cps_pm_enter_state - enter a PM state
43+ * @state: the state to enter
44+ *
45+ * Enter the given PM state. If coupled_coherence is non-zero then it is
46+ * expected that this function be called at approximately the same time on
47+ * each coupled CPU. Returns 0 on successful entry & exit, otherwise -errno.
48+ */
49+extern int cps_pm_enter_state(enum cps_pm_state state);
50+
51+#endif /* __MIPS_ASM_PM_CPS_H__ */
arch/mips/include/asm/pm.h+159−0
@@ -0,0 +1,159 @@
1+/*
2+ * Copyright (C) 2014 Imagination Technologies Ltd
3+ *
4+ * This program is free software; you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License as published by the
6+ * Free Software Foundation; either version 2 of the License, or (at your
7+ * option) any later version.
8+ *
9+ * PM helper macros for CPU power off (e.g. Suspend-to-RAM).
10+ */
11+
12+#ifndef __ASM_PM_H
13+#define __ASM_PM_H
14+
15+#ifdef __ASSEMBLY__
16+
17+#include <asm/asm-offsets.h>
18+#include <asm/asm.h>
19+#include <asm/mipsregs.h>
20+#include <asm/regdef.h>
21+
22+/* Save CPU state to stack for suspend to RAM */
23+.macro SUSPEND_SAVE_REGS
24+ subu sp, PT_SIZE
25+ /* Call preserved GPRs */
26+ LONG_S $16, PT_R16(sp)
27+ LONG_S $17, PT_R17(sp)
28+ LONG_S $18, PT_R18(sp)
29+ LONG_S $19, PT_R19(sp)
30+ LONG_S $20, PT_R20(sp)
31+ LONG_S $21, PT_R21(sp)
32+ LONG_S $22, PT_R22(sp)
33+ LONG_S $23, PT_R23(sp)
34+ LONG_S $28, PT_R28(sp)
35+ LONG_S $30, PT_R30(sp)
36+ LONG_S $31, PT_R31(sp)
37+ /* A couple of CP0 registers with space in pt_regs */
38+ mfc0 k0, CP0_STATUS
39+ LONG_S k0, PT_STATUS(sp)
40+.endm
41+
42+/* Restore CPU state from stack after resume from RAM */
43+.macro RESUME_RESTORE_REGS_RETURN
44+ .set push
45+ .set noreorder
46+ /* A couple of CP0 registers with space in pt_regs */
47+ LONG_L k0, PT_STATUS(sp)
48+ mtc0 k0, CP0_STATUS
49+ /* Call preserved GPRs */
50+ LONG_L $16, PT_R16(sp)
51+ LONG_L $17, PT_R17(sp)
52+ LONG_L $18, PT_R18(sp)
53+ LONG_L $19, PT_R19(sp)
54+ LONG_L $20, PT_R20(sp)
55+ LONG_L $21, PT_R21(sp)
56+ LONG_L $22, PT_R22(sp)
57+ LONG_L $23, PT_R23(sp)
58+ LONG_L $28, PT_R28(sp)
59+ LONG_L $30, PT_R30(sp)
60+ LONG_L $31, PT_R31(sp)
61+ /* Pop and return */
62+ jr ra
63+ addiu sp, PT_SIZE
64+ .set pop
65+.endm
66+
67+/* Get address of static suspend state into t1 */
68+.macro LA_STATIC_SUSPEND
69+ la t1, mips_static_suspend_state
70+.endm
71+
72+/* Save important CPU state for early restoration to global data */
73+.macro SUSPEND_SAVE_STATIC
74+#ifdef CONFIG_EVA
75+ /*
76+ * Segment configuration is saved in global data where it can be easily
77+ * reloaded without depending on the segment configuration.
78+ */
79+ mfc0 k0, CP0_PAGEMASK, 2 /* SegCtl0 */
80+ LONG_S k0, SSS_SEGCTL0(t1)
81+ mfc0 k0, CP0_PAGEMASK, 3 /* SegCtl1 */
82+ LONG_S k0, SSS_SEGCTL1(t1)
83+ mfc0 k0, CP0_PAGEMASK, 4 /* SegCtl2 */
84+ LONG_S k0, SSS_SEGCTL2(t1)
85+#endif
86+ /* save stack pointer (pointing to GPRs) */
87+ LONG_S sp, SSS_SP(t1)
88+.endm
89+
90+/* Restore important CPU state early from global data */
91+.macro RESUME_RESTORE_STATIC
92+#ifdef CONFIG_EVA
93+ /*
94+ * Segment configuration must be restored prior to any access to
95+ * allocated memory, as it may reside outside of the legacy kernel
96+ * segments.
97+ */
98+ LONG_L k0, SSS_SEGCTL0(t1)
99+ mtc0 k0, CP0_PAGEMASK, 2 /* SegCtl0 */
100+ LONG_L k0, SSS_SEGCTL1(t1)
101+ mtc0 k0, CP0_PAGEMASK, 3 /* SegCtl1 */
102+ LONG_L k0, SSS_SEGCTL2(t1)
103+ mtc0 k0, CP0_PAGEMASK, 4 /* SegCtl2 */
104+ tlbw_use_hazard
105+#endif
106+ /* restore stack pointer (pointing to GPRs) */
107+ LONG_L sp, SSS_SP(t1)
108+.endm
109+
110+/* flush caches to make sure context has reached memory */
111+.macro SUSPEND_CACHE_FLUSH
112+ .extern __wback_cache_all
113+ .set push
114+ .set noreorder
115+ la t1, __wback_cache_all
116+ LONG_L t0, 0(t1)
117+ jalr t0
118+ nop
119+ .set pop
120+ .endm
121+
122+/* Save suspend state and flush data caches to RAM */
123+.macro SUSPEND_SAVE
124+ SUSPEND_SAVE_REGS
125+ LA_STATIC_SUSPEND
126+ SUSPEND_SAVE_STATIC
127+ SUSPEND_CACHE_FLUSH
128+.endm
129+
130+/* Restore saved state after resume from RAM and return */
131+.macro RESUME_RESTORE_RETURN
132+ LA_STATIC_SUSPEND
133+ RESUME_RESTORE_STATIC
134+ RESUME_RESTORE_REGS_RETURN
135+.endm
136+
137+#else /* __ASSEMBLY__ */
138+
139+/**
140+ * struct mips_static_suspend_state - Core saved CPU state across S2R.
141+ * @segctl: CP0 Segment control registers.
142+ * @sp: Stack frame where GP register context is saved.
143+ *
144+ * This structure contains minimal CPU state that must be saved in static kernel
145+ * data in order to be able to restore the rest of the state. This includes
146+ * segmentation configuration in the case of EVA being enabled, as they must be
147+ * restored prior to any kmalloc'd memory being referenced (even the stack
148+ * pointer).
149+ */
150+struct mips_static_suspend_state {
151+#ifdef CONFIG_EVA
152+ unsigned long segctl[3];
153+#endif
154+ unsigned long sp;
155+};
156+
157+#endif /* !__ASSEMBLY__ */
158+
159+#endif /* __ASM_PM_HELPERS_H */
arch/mips/include/asm/ptrace.h+0−3
@@ -39,9 +39,6 @@ struct pt_regs { · 38 unmodified lines
3939 unsigned long cp0_badvaddr;
4040 unsigned long cp0_cause;
4141 unsigned long cp0_epc;
42−#ifdef CONFIG_MIPS_MT_SMTC
43− unsigned long cp0_tcstatus;
44−#endif /* CONFIG_MIPS_MT_SMTC */
4542 #ifdef CONFIG_CPU_CAVIUM_OCTEON
4643 unsigned long long mpl[3]; /* MTM{0,1,2} */
4744 unsigned long long mtp[3]; /* MTP{0,1,2} */
arch/mips/include/asm/r4kcache.h+4−3
@@ -43,11 +43,10 @@ · 42 unmodified lines
4343 : "i" (op), "R" (*(unsigned char *)(addr)))
4444
4545 #ifdef CONFIG_MIPS_MT
46+
4647 /*
47− * Temporary hacks for SMTC debug. Optionally force single-threaded
48− * execution during I-cache flushes.
48+ * Optionally force single-threaded execution during I-cache flushes.
4949 */
50−
5150 #define PROTECT_CACHE_FLUSHES 1
5251
5352 #ifdef PROTECT_CACHE_FLUSHES
@@ -524,6 +523,8 @@ __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32, · 470 unmodified lines
524523 __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64, )
525524 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64, )
526525 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64, )
526+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 128, )
527+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 128, )
527528 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128, )
528529
529530 __BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16, )
arch/mips/include/asm/sgi/ip22.h+2−0
@@ -69,6 +69,8 @@ · 68 unmodified lines
6969 #define SGI_EISA_IRQ SGINT_LOCAL2 + 3 /* EISA interrupts */
7070 #define SGI_KEYBD_IRQ SGINT_LOCAL2 + 4 /* keyboard */
7171 #define SGI_SERIAL_IRQ SGINT_LOCAL2 + 5 /* onboard serial */
72+#define SGI_GIOEXP0_IRQ (SGINT_LOCAL2 + 6) /* Indy GIO EXP0 */
73+#define SGI_GIOEXP1_IRQ (SGINT_LOCAL2 + 7) /* Indy GIO EXP1 */
7274
7375 #define ip22_is_fullhouse() (sgioc->sysid & SGIOC_SYSID_FULLHOUSE)
7476
arch/mips/include/asm/smp-cps.h+15−4
@@ -13,17 +13,28 @@ · 12 unmodified lines
1313
1414 #ifndef __ASSEMBLY__
1515
16−struct boot_config {
17− unsigned int core;
18− unsigned int vpe;
16+struct vpe_boot_config {
1917 unsigned long pc;
2018 unsigned long sp;
2119 unsigned long gp;
2220 };
2321
24−extern struct boot_config mips_cps_bootcfg;
22+struct core_boot_config {
23+ atomic_t vpe_mask;
24+ struct vpe_boot_config *vpe_config;
25+};
26+
27+extern struct core_boot_config *mips_cps_core_bootcfg;
2528
2629 extern void mips_cps_core_entry(void);
30+extern void mips_cps_core_init(void);
31+
32+extern struct vpe_boot_config *mips_cps_boot_vpes(void);
33+
34+extern bool mips_cps_smp_in_use(void);
35+
36+extern void mips_cps_pm_save(void);
37+extern void mips_cps_pm_restore(void);
2738
2839 #else /* __ASSEMBLY__ */
2940
arch/mips/include/asm/smp-ops.h+0−1
@@ -26,7 +26,6 @@ struct plat_smp_ops { · 25 unmodified lines
2626 void (*send_ipi_mask)(const struct cpumask *mask, unsigned int action);
2727 void (*init_secondary)(void);
2828 void (*smp_finish)(void);
29− void (*cpus_done)(void);
3029 void (*boot_secondary)(int cpu, struct task_struct *idle);
3130 void (*smp_setup)(void);
3231 void (*prepare_cpus)(unsigned int max_cpus);
arch/mips/include/asm/smp.h+3−0
@@ -46,6 +46,9 @@ extern int __cpu_logical_map[NR_CPUS]; · 45 unmodified lines
4646
4747 extern volatile cpumask_t cpu_callin_map;
4848
49+/* Mask of CPUs which are currently definitely operating coherently */
50+extern cpumask_t cpu_coherent_mask;
51+
4952 extern void asmlinkage smp_bootstrap(void);
5053
5154 /*
arch/mips/include/asm/smtc.h+0−78
@@ -1,78 +0,0 @@
1−#ifndef _ASM_SMTC_MT_H
2−#define _ASM_SMTC_MT_H
3−
4−/*
5− * Definitions for SMTC multitasking on MIPS MT cores
6− */
7−
8−#include <asm/mips_mt.h>
9−#include <asm/smtc_ipi.h>
10−
11−/*
12− * System-wide SMTC status information
13− */
14−
15−extern unsigned int smtc_status;
16−
17−#define SMTC_TLB_SHARED 0x00000001
18−#define SMTC_MTC_ACTIVE 0x00000002
19−
20−/*
21− * TLB/ASID Management information
22− */
23−
24−#define MAX_SMTC_TLBS 2
25−#define MAX_SMTC_ASIDS 256
26−#if NR_CPUS <= 8
27−typedef char asiduse;
28−#else
29−#if NR_CPUS <= 16
30−typedef short asiduse;
31−#else
32−typedef long asiduse;
33−#endif
34−#endif
35−
36−/*
37− * VPE Management information
38− */
39−
40−#define MAX_SMTC_VPES MAX_SMTC_TLBS /* FIXME: May not always be true. */
41−
42−extern asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS];
43−
44−struct mm_struct;
45−struct task_struct;
46−
47−void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu);
48−void self_ipi(struct smtc_ipi *);
49−void smtc_flush_tlb_asid(unsigned long asid);
50−extern int smtc_build_cpu_map(int startslot);
51−extern void smtc_prepare_cpus(int cpus);
52−extern void smtc_smp_finish(void);
53−extern void smtc_boot_secondary(int cpu, struct task_struct *t);
54−extern void smtc_cpus_done(void);
55−extern void smtc_init_secondary(void);
56−
57−
58−/*
59− * Sharing the TLB between multiple VPEs means that the
60− * "random" index selection function is not allowed to
61− * select the current value of the Index register. To
62− * avoid additional TLB pressure, the Index registers
63− * are "parked" with an non-Valid value.
64− */
65−
66−#define PARKED_INDEX ((unsigned int)0x80000000)
67−
68−/*
69− * Define low-level interrupt mask for IPIs, if necessary.
70− * By default, use SW interrupt 1, which requires no external
71− * hardware support, but which works only for single-core
72− * MIPS MT systems.
73− */
74−#ifndef MIPS_CPU_IPI_IRQ
75−#define MIPS_CPU_IPI_IRQ 1
76−#endif
77−
78−#endif /* _ASM_SMTC_MT_H */
arch/mips/include/asm/smtc_ipi.h+0−129
@@ -1,129 +0,0 @@
1−/*
2− * Definitions used in MIPS MT SMTC "Interprocessor Interrupt" code.
3− */
4−#ifndef __ASM_SMTC_IPI_H
5−#define __ASM_SMTC_IPI_H
6−
7−#include <linux/spinlock.h>
8−
9−//#define SMTC_IPI_DEBUG
10−
11−#ifdef SMTC_IPI_DEBUG
12−#include <asm/mipsregs.h>
13−#include <asm/mipsmtregs.h>
14−#endif /* SMTC_IPI_DEBUG */
15−
16−/*
17− * An IPI "message"
18− */
19−
20−struct smtc_ipi {
21− struct smtc_ipi *flink;
22− int type;
23− void *arg;
24− int dest;
25−#ifdef SMTC_IPI_DEBUG
26− int sender;
27− long stamp;
28−#endif /* SMTC_IPI_DEBUG */
29−};
30−
31−/*
32− * Defined IPI Types
33− */
34−
35−#define LINUX_SMP_IPI 1
36−#define SMTC_CLOCK_TICK 2
37−#define IRQ_AFFINITY_IPI 3
38−
39−/*
40− * A queue of IPI messages
41− */
42−
43−struct smtc_ipi_q {
44− struct smtc_ipi *head;
45− spinlock_t lock;
46− struct smtc_ipi *tail;
47− int depth;
48− int resched_flag; /* reschedule already queued */
49−};
50−
51−static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
52−{
53− unsigned long flags;
54−
55− spin_lock_irqsave(&q->lock, flags);
56− if (q->head == NULL)
57− q->head = q->tail = p;
58− else
59− q->tail->flink = p;
60− p->flink = NULL;
61− q->tail = p;
62− q->depth++;
63−#ifdef SMTC_IPI_DEBUG
64− p->sender = read_c0_tcbind();
65− p->stamp = read_c0_count();
66−#endif /* SMTC_IPI_DEBUG */
67− spin_unlock_irqrestore(&q->lock, flags);
68−}
69−
70−static inline struct smtc_ipi *__smtc_ipi_dq(struct smtc_ipi_q *q)
71−{
72− struct smtc_ipi *p;
73−
74− if (q->head == NULL)
75− p = NULL;
76− else {
77− p = q->head;
78− q->head = q->head->flink;
79− q->depth--;
80− /* Arguably unnecessary, but leaves queue cleaner */
81− if (q->head == NULL)
82− q->tail = NULL;
83− }
84−
85− return p;
86−}
87−
88−static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q)
89−{
90− unsigned long flags;
91− struct smtc_ipi *p;
92−
93− spin_lock_irqsave(&q->lock, flags);
94− p = __smtc_ipi_dq(q);
95− spin_unlock_irqrestore(&q->lock, flags);
96−
97− return p;
98−}
99−
100−static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p)
101−{
102− unsigned long flags;
103−
104− spin_lock_irqsave(&q->lock, flags);
105− if (q->head == NULL) {
106− q->head = q->tail = p;
107− p->flink = NULL;
108− } else {
109− p->flink = q->head;
110− q->head = p;
111− }
112− q->depth++;
113− spin_unlock_irqrestore(&q->lock, flags);
114−}
115−
116−static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q)
117−{
118− unsigned long flags;
119− int retval;
120−
121− spin_lock_irqsave(&q->lock, flags);
122− retval = q->depth;
123− spin_unlock_irqrestore(&q->lock, flags);
124− return retval;
125−}
126−
127−extern void smtc_send_ipi(int cpu, int type, unsigned int action);
128−
129−#endif /* __ASM_SMTC_IPI_H */
arch/mips/include/asm/smtc_proc.h+0−23
@@ -1,23 +0,0 @@
1−/*
2− * Definitions for SMTC /proc entries
3− * Copyright(C) 2005 MIPS Technologies Inc.
4− */
5−#ifndef __ASM_SMTC_PROC_H
6−#define __ASM_SMTC_PROC_H
7−
8−/*
9− * per-"CPU" statistics
10− */
11−
12−struct smtc_cpu_proc {
13− unsigned long timerints;
14− unsigned long selfipis;
15−};
16−
17−extern struct smtc_cpu_proc smtc_cpu_stats[NR_CPUS];
18−
19−/* Count of number of recoveries of "stolen" FPU access rights on 34K */
20−
21−extern atomic_t smtc_fpu_recoveries;
22−
23−#endif /* __ASM_SMTC_PROC_H */
arch/mips/include/asm/stackframe.h+1−195
@@ -19,22 +19,12 @@ · 18 unmodified lines
1919 #include <asm/asm-offsets.h>
2020 #include <asm/thread_info.h>
2121
22−/*
23− * For SMTC kernel, global IE should be left set, and interrupts
24− * controlled exclusively via IXMT.
25− */
26−#ifdef CONFIG_MIPS_MT_SMTC
27−#define STATMASK 0x1e
28−#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
22+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
2923 #define STATMASK 0x3f
3024 #else
3125 #define STATMASK 0x1f
3226 #endif
3327
34−#ifdef CONFIG_MIPS_MT_SMTC
35−#include <asm/mipsmtregs.h>
36−#endif /* CONFIG_MIPS_MT_SMTC */
37−
3828 .macro SAVE_AT
3929 .set push
4030 .set noat
@@ -186,16 +176,6 @@ · 145 unmodified lines
186176 mfc0 v1, CP0_STATUS
187177 LONG_S $2, PT_R2(sp)
188178 LONG_S v1, PT_STATUS(sp)
189−#ifdef CONFIG_MIPS_MT_SMTC
190− /*
191− * Ideally, these instructions would be shuffled in
192− * to cover the pipeline delay.
193− */
194− .set mips32
195− mfc0 k0, CP0_TCSTATUS
196− .set mips0
197− LONG_S k0, PT_TCSTATUS(sp)
198−#endif /* CONFIG_MIPS_MT_SMTC */
199179 LONG_S $4, PT_R4(sp)
200180 mfc0 v1, CP0_CAUSE
201181 LONG_S $5, PT_R5(sp)
@@ -321,36 +301,6 @@ · 119 unmodified lines
321301 .set push
322302 .set reorder
323303 .set noat
324−#ifdef CONFIG_MIPS_MT_SMTC
325− .set mips32r2
326− /*
327− * We need to make sure the read-modify-write
328− * of Status below isn't perturbed by an interrupt
329− * or cross-TC access, so we need to do at least a DMT,
330− * protected by an interrupt-inhibit. But setting IXMT
331− * also creates a few-cycle window where an IPI could
332− * be queued and not be detected before potentially
333− * returning to a WAIT or user-mode loop. It must be
334− * replayed.
335− *
336− * We're in the middle of a context switch, and
337− * we can't dispatch it directly without trashing
338− * some registers, so we'll try to detect this unlikely
339− * case and program a software interrupt in the VPE,
340− * as would be done for a cross-VPE IPI. To accommodate
341− * the handling of that case, we're doing a DVPE instead
342− * of just a DMT here to protect against other threads.
343− * This is a lot of cruft to cover a tiny window.
344− * If you can find a better design, implement it!
345− *
346− */
347− mfc0 v0, CP0_TCSTATUS
348− ori v0, TCSTATUS_IXMT
349− mtc0 v0, CP0_TCSTATUS
350− _ehb
351− DVPE 5 # dvpe a1
352− jal mips_ihb
353−#endif /* CONFIG_MIPS_MT_SMTC */
354304 mfc0 a0, CP0_STATUS
355305 ori a0, STATMASK
356306 xori a0, STATMASK
@@ -362,59 +312,6 @@ · 5 unmodified lines
362312 and v0, v1
363313 or v0, a0
364314 mtc0 v0, CP0_STATUS
365−#ifdef CONFIG_MIPS_MT_SMTC
366−/*
367− * Only after EXL/ERL have been restored to status can we
368− * restore TCStatus.IXMT.
369− */
370− LONG_L v1, PT_TCSTATUS(sp)
371− _ehb
372− mfc0 a0, CP0_TCSTATUS
373− andi v1, TCSTATUS_IXMT
374− bnez v1, 0f
375−
376−/*
377− * We'd like to detect any IPIs queued in the tiny window
378− * above and request an software interrupt to service them
379− * when we ERET.
380− *
381− * Computing the offset into the IPIQ array of the executing
382− * TC's IPI queue in-line would be tedious. We use part of
383− * the TCContext register to hold 16 bits of offset that we
384− * can add in-line to find the queue head.
385− */
386− mfc0 v0, CP0_TCCONTEXT
387− la a2, IPIQ
388− srl v0, v0, 16
389− addu a2, a2, v0
390− LONG_L v0, 0(a2)
391− beqz v0, 0f
392−/*
393− * If we have a queue, provoke dispatch within the VPE by setting C_SW1
394− */
395− mfc0 v0, CP0_CAUSE
396− ori v0, v0, C_SW1
397− mtc0 v0, CP0_CAUSE
398−0:
399− /*
400− * This test should really never branch but
401− * let's be prudent here. Having atomized
402− * the shared register modifications, we can
403− * now EVPE, and must do so before interrupts
404− * are potentially re-enabled.
405− */
406− andi a1, a1, MVPCONTROL_EVP
407− beqz a1, 1f
408− evpe
409−1:
410− /* We know that TCStatua.IXMT should be set from above */
411− xori a0, a0, TCSTATUS_IXMT
412− or a0, a0, v1
413− mtc0 a0, CP0_TCSTATUS
414− _ehb
415−
416− .set mips0
417−#endif /* CONFIG_MIPS_MT_SMTC */
418315 LONG_L v1, PT_EPC(sp)
419316 MTC0 v1, CP0_EPC
420317 LONG_L $31, PT_R31(sp)
@@ -467,33 +364,11 @@ · 46 unmodified lines
467364 * Set cp0 enable bit as sign that we're running on the kernel stack
468365 */
469366 .macro CLI
470−#if !defined(CONFIG_MIPS_MT_SMTC)
471367 mfc0 t0, CP0_STATUS
472368 li t1, ST0_CU0 | STATMASK
473369 or t0, t1
474370 xori t0, STATMASK
475371 mtc0 t0, CP0_STATUS
476−#else /* CONFIG_MIPS_MT_SMTC */
477− /*
478− * For SMTC, we need to set privilege
479− * and disable interrupts only for the
480− * current TC, using the TCStatus register.
481− */
482− mfc0 t0, CP0_TCSTATUS
483− /* Fortunately CU 0 is in the same place in both registers */
484− /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */
485− li t1, ST0_CU0 | 0x08001c00
486− or t0, t1
487− /* Clear TKSU, leave IXMT */
488− xori t0, 0x00001800
489− mtc0 t0, CP0_TCSTATUS
490− _ehb
491− /* We need to leave the global IE bit set, but clear EXL...*/
492− mfc0 t0, CP0_STATUS
493− ori t0, ST0_EXL | ST0_ERL
494− xori t0, ST0_EXL | ST0_ERL
495− mtc0 t0, CP0_STATUS
496−#endif /* CONFIG_MIPS_MT_SMTC */
497372 irq_disable_hazard
498373 .endm
499374
@@ -502,35 +377,11 @@ · 2 unmodified lines
502377 * Set cp0 enable bit as sign that we're running on the kernel stack
503378 */
504379 .macro STI
505−#if !defined(CONFIG_MIPS_MT_SMTC)
506380 mfc0 t0, CP0_STATUS
507381 li t1, ST0_CU0 | STATMASK
508382 or t0, t1
509383 xori t0, STATMASK & ~1
510384 mtc0 t0, CP0_STATUS
511−#else /* CONFIG_MIPS_MT_SMTC */
512− /*
513− * For SMTC, we need to set privilege
514− * and enable interrupts only for the
515− * current TC, using the TCStatus register.
516− */
517− _ehb
518− mfc0 t0, CP0_TCSTATUS
519− /* Fortunately CU 0 is in the same place in both registers */
520− /* Set TCU0, TKSU (for later inversion) and IXMT */
521− li t1, ST0_CU0 | 0x08001c00
522− or t0, t1
523− /* Clear TKSU *and* IXMT */
524− xori t0, 0x00001c00
525− mtc0 t0, CP0_TCSTATUS
526− _ehb
527− /* We need to leave the global IE bit set, but clear EXL...*/
528− mfc0 t0, CP0_STATUS
529− ori t0, ST0_EXL
530− xori t0, ST0_EXL
531− mtc0 t0, CP0_STATUS
532− /* irq_enable_hazard below should expand to EHB for 24K/34K cpus */
533−#endif /* CONFIG_MIPS_MT_SMTC */
534385 irq_enable_hazard
535386 .endm
536387
@@ -540,32 +391,6 @@ · 3 unmodified lines
540391 * Set cp0 enable bit as sign that we're running on the kernel stack
541392 */
542393 .macro KMODE
543−#ifdef CONFIG_MIPS_MT_SMTC
544− /*
545− * This gets baroque in SMTC. We want to
546− * protect the non-atomic clearing of EXL
547− * with DMT/EMT, but we don't want to take
548− * an interrupt while DMT is still in effect.
549− */
550−
551− /* KMODE gets invoked from both reorder and noreorder code */
552− .set push
553− .set mips32r2
554− .set noreorder
555− mfc0 v0, CP0_TCSTATUS
556− andi v1, v0, TCSTATUS_IXMT
557− ori v0, TCSTATUS_IXMT
558− mtc0 v0, CP0_TCSTATUS
559− _ehb
560− DMT 2 # dmt v0
561− /*
562− * We don't know a priori if ra is "live"
563− */
564− move t0, ra
565− jal mips_ihb
566− nop /* delay slot */
567− move ra, t0
568−#endif /* CONFIG_MIPS_MT_SMTC */
569394 mfc0 t0, CP0_STATUS
570395 li t1, ST0_CU0 | (STATMASK & ~1)
571396 #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
@@ -576,25 +401,6 @@ · 4 unmodified lines
576401 or t0, t1
577402 xori t0, STATMASK & ~1
578403 mtc0 t0, CP0_STATUS
579−#ifdef CONFIG_MIPS_MT_SMTC
580− _ehb
581− andi v0, v0, VPECONTROL_TE
582− beqz v0, 2f
583− nop /* delay slot */
584− emt
585−2:
586− mfc0 v0, CP0_TCSTATUS
587− /* Clear IXMT, then OR in previous value */
588− ori v0, TCSTATUS_IXMT
589− xori v0, TCSTATUS_IXMT
590− or v0, v1, v0
591− mtc0 v0, CP0_TCSTATUS
592− /*
593− * irq_disable_hazard below should expand to EHB
594− * on 24K/34K CPUS
595− */
596− .set pop
597−#endif /* CONFIG_MIPS_MT_SMTC */
598404 irq_disable_hazard
599405 .endm
600406
arch/mips/include/asm/thread_info.h+1−10
@@ -159,11 +159,7 @@ static inline struct thread_info *current_thread_info(void) · 158 unmodified lines
159159 * We stash processor id into a COP0 register to retrieve it fast
160160 * at kernel exception entry.
161161 */
162−#if defined(CONFIG_MIPS_MT_SMTC)
163−#define SMP_CPUID_REG 2, 2 /* TCBIND */
164−#define ASM_SMP_CPUID_REG $2, 2
165−#define SMP_CPUID_PTRSHIFT 19
166−#elif defined(CONFIG_MIPS_PGD_C0_CONTEXT)
162+#if defined(CONFIG_MIPS_PGD_C0_CONTEXT)
167163 #define SMP_CPUID_REG 20, 0 /* XCONTEXT */
168164 #define ASM_SMP_CPUID_REG $20
169165 #define SMP_CPUID_PTRSHIFT 48
@@ -179,13 +175,8 @@ static inline struct thread_info *current_thread_info(void) · 9 unmodified lines
179175 #define SMP_CPUID_REGSHIFT (SMP_CPUID_PTRSHIFT + 2)
180176 #endif
181177
182−#ifdef CONFIG_MIPS_MT_SMTC
183−#define ASM_CPUID_MFC0 mfc0
184−#define UASM_i_CPUID_MFC0 uasm_i_mfc0
185−#else
186178 #define ASM_CPUID_MFC0 MFC0
187179 #define UASM_i_CPUID_MFC0 UASM_i_MFC0
188−#endif
189180
190181 #endif /* __KERNEL__ */
191182 #endif /* _ASM_THREAD_INFO_H */
arch/mips/include/asm/time.h+1−4
@@ -52,14 +52,11 @@ extern int (*perf_irq)(void); · 51 unmodified lines
5252 */
5353 extern unsigned int __weak get_c0_compare_int(void);
5454 extern int r4k_clockevent_init(void);
55−extern int smtc_clockevent_init(void);
5655 extern int gic_clockevent_init(void);
5756
5857 static inline int mips_clockevent_init(void)
5958 {
60−#ifdef CONFIG_MIPS_MT_SMTC
61− return smtc_clockevent_init();
62−#elif defined(CONFIG_CEVT_GIC)
59+#if defined(CONFIG_CEVT_GIC)
6360 return (gic_clockevent_init() | r4k_clockevent_init());
6461 #elif defined(CONFIG_CEVT_R4K)
6562 return r4k_clockevent_init();
arch/mips/include/asm/timex.h+47−18
@@ -4,12 +4,16 @@ · 3 unmodified lines
44 * for more details.
55 *
66 * Copyright (C) 1998, 1999, 2003 by Ralf Baechle
7+ * Copyright (C) 2014 by Maciej W. Rozycki
78 */
89 #ifndef _ASM_TIMEX_H
910 #define _ASM_TIMEX_H
1011
1112 #ifdef __KERNEL__
1213
14+#include <linux/compiler.h>
15+
16+#include <asm/cpu.h>
1317 #include <asm/cpu-features.h>
1418 #include <asm/mipsregs.h>
1519 #include <asm/cpu-type.h>
@@ -45,29 +49,54 @@ typedef unsigned int cycles_t; · 29 unmodified lines
4549 * However for now the implementaton of this function doesn't get these
4650 * fine details right.
4751 */
48−static inline cycles_t get_cycles(void)
52+static inline int can_use_mips_counter(unsigned int prid)
4953 {
50− switch (boot_cpu_type()) {
51− case CPU_R4400PC:
52− case CPU_R4400SC:
53− case CPU_R4400MC:
54− if ((read_c0_prid() & 0xff) >= 0x0050)
55− return read_c0_count();
56− break;
54+ int comp = (prid & PRID_COMP_MASK) != PRID_COMP_LEGACY;
5755
58− case CPU_R4000PC:
59− case CPU_R4000SC:
60− case CPU_R4000MC:
61− break;
56+ if (__builtin_constant_p(cpu_has_counter) && !cpu_has_counter)
57+ return 0;
58+ else if (__builtin_constant_p(cpu_has_mips_r) && cpu_has_mips_r)
59+ return 1;
60+ else if (likely(!__builtin_constant_p(cpu_has_mips_r) && comp))
61+ return 1;
62+ /* Make sure we don't peek at cpu_data[0].options in the fast path! */
63+ if (!__builtin_constant_p(cpu_has_counter))
64+ asm volatile("" : "=m" (cpu_data[0].options));
65+ if (likely(cpu_has_counter &&
66+ prid >= (PRID_IMP_R4000 | PRID_REV_ENCODE_44(5, 0))))
67+ return 1;
68+ else
69+ return 0;
70+}
6271
63− default:
64− if (cpu_has_counter)
65− return read_c0_count();
66− break;
67− }
72+static inline cycles_t get_cycles(void)
73+{
74+ if (can_use_mips_counter(read_c0_prid()))
75+ return read_c0_count();
76+ else
77+ return 0; /* no usable counter */
78+}
79+
80+/*
81+ * Like get_cycles - but where c0_count is not available we desperately
82+ * use c0_random in an attempt to get at least a little bit of entropy.
83+ *
84+ * R6000 and R6000A neither have a count register nor a random register.
85+ * That leaves no entropy source in the CPU itself.
86+ */
87+static inline unsigned long random_get_entropy(void)
88+{
89+ unsigned int prid = read_c0_prid();
90+ unsigned int imp = prid & PRID_IMP_MASK;
6891
69− return 0; /* no usable counter */
92+ if (can_use_mips_counter(prid))
93+ return read_c0_count();
94+ else if (likely(imp != PRID_IMP_R6000 && imp != PRID_IMP_R6000A))
95+ return read_c0_random();
96+ else
97+ return 0; /* no usable register */
7098 }
99+#define random_get_entropy random_get_entropy
71100
72101 #endif /* __KERNEL__ */
73102
arch/mips/include/asm/uasm.h+23−0
@@ -55,6 +55,9 @@ void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c) · 54 unmodified lines
5555 #define Ip_u2u1u3(op) \
5656 void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
5757
58+#define Ip_u3u2u1(op) \
59+void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
60+
5861 #define Ip_u3u1u2(op) \
5962 void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
6063
@@ -74,6 +77,9 @@ void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c, \ · 13 unmodified lines
7477 #define Ip_u1u2(op) \
7578 void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b)
7679
80+#define Ip_u2u1(op) \
81+void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b)
82+
7783 #define Ip_u1s2(op) \
7884 void ISAOPC(op)(u32 **buf, unsigned int a, signed int b)
7985
@@ -99,6 +105,7 @@ Ip_u2u1s3(_daddiu); · 19 unmodified lines
99105 Ip_u3u1u2(_daddu);
100106 Ip_u2u1msbu3(_dins);
101107 Ip_u2u1msbu3(_dinsm);
108+Ip_u1u2(_divu);
102109 Ip_u1u2u3(_dmfc0);
103110 Ip_u1u2u3(_dmtc0);
104111 Ip_u2u1u3(_drotr);
@@ -114,16 +121,22 @@ Ip_u2u1msbu3(_ext); · 9 unmodified lines
114121 Ip_u2u1msbu3(_ins);
115122 Ip_u1(_j);
116123 Ip_u1(_jal);
124+Ip_u2u1(_jalr);
117125 Ip_u1(_jr);
126+Ip_u2s3u1(_lb);
118127 Ip_u2s3u1(_ld);
119128 Ip_u3u1u2(_ldx);
129+Ip_u2s3u1(_lh);
120130 Ip_u2s3u1(_ll);
121131 Ip_u2s3u1(_lld);
122132 Ip_u1s2(_lui);
123133 Ip_u2s3u1(_lw);
124134 Ip_u3u1u2(_lwx);
125135 Ip_u1u2u3(_mfc0);
136+Ip_u1(_mfhi);
137+Ip_u1(_mflo);
126138 Ip_u1u2u3(_mtc0);
139+Ip_u3u1u2(_mul);
127140 Ip_u3u1u2(_or);
128141 Ip_u2u1u3(_ori);
129142 Ip_u2s3u1(_pref);
@@ -133,17 +146,25 @@ Ip_u2s3u1(_sc); · 3 unmodified lines
133146 Ip_u2s3u1(_scd);
134147 Ip_u2s3u1(_sd);
135148 Ip_u2u1u3(_sll);
149+Ip_u3u2u1(_sllv);
150+Ip_u2u1s3(_sltiu);
151+Ip_u3u1u2(_sltu);
136152 Ip_u2u1u3(_sra);
137153 Ip_u2u1u3(_srl);
154+Ip_u3u2u1(_srlv);
138155 Ip_u3u1u2(_subu);
139156 Ip_u2s3u1(_sw);
157+Ip_u1(_sync);
140158 Ip_u1(_syscall);
141159 Ip_0(_tlbp);
142160 Ip_0(_tlbr);
143161 Ip_0(_tlbwi);
144162 Ip_0(_tlbwr);
163+Ip_u1(_wait);
164+Ip_u2u1(_wsbh);
145165 Ip_u3u1u2(_xor);
146166 Ip_u2u1u3(_xori);
167+Ip_u2u1(_yield);
147168
148169
149170 /* Handle labels. */
@@ -264,6 +285,8 @@ void uasm_il_bbit0(u32 **p, struct uasm_reloc **r, unsigned int reg, · 114 unmodified lines
264285 unsigned int bit, int lid);
265286 void uasm_il_bbit1(u32 **p, struct uasm_reloc **r, unsigned int reg,
266287 unsigned int bit, int lid);
288+void uasm_il_beq(u32 **p, struct uasm_reloc **r, unsigned int r1,
289+ unsigned int r2, int lid);
267290 void uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
268291 void uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
269292 void uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
arch/mips/include/uapi/asm/Kbuild+1−0
@@ -4,6 +4,7 @@ include include/uapi/asm-generic/Kbuild.asm · 3 unmodified lines
44 generic-y += auxvec.h
55 generic-y += ipcbuf.h
66
7+header-y += bitfield.h
78 header-y += bitsperlong.h
89 header-y += break.h
910 header-y += byteorder.h
arch/mips/include/uapi/asm/bitfield.h+29−0
@@ -0,0 +1,29 @@
1+/*
2+ * This file is subject to the terms and conditions of the GNU General Public
3+ * License. See the file "COPYING" in the main directory of this archive
4+ * for more details.
5+ *
6+ * Copyright (C) 2014 by Ralf Baechle <ralf@linux-mips.org>
7+ */
8+#ifndef __UAPI_ASM_BITFIELD_H
9+#define __UAPI_ASM_BITFIELD_H
10+
11+/*
12+ * * Damn ... bitfields depend from byteorder :-(
13+ * */
14+#ifdef __MIPSEB__
15+#define __BITFIELD_FIELD(field, more) \
16+ field; \
17+ more
18+
19+#elif defined(__MIPSEL__)
20+
21+#define __BITFIELD_FIELD(field, more) \
22+ more \
23+ field;
24+
25+#else /* !defined (__MIPSEB__) && !defined (__MIPSEL__) */
26+#error "MIPS but neither __MIPSEL__ nor __MIPSEB__?"
27+#endif
28+
29+#endif /* __UAPI_ASM_BITFIELD_H */
arch/mips/include/uapi/asm/inst.h+35−29
@@ -13,6 +13,8 @@ · 12 unmodified lines
1313 #ifndef _UAPI_ASM_INST_H
1414 #define _UAPI_ASM_INST_H
1515
16+#include <asm/bitfield.h>
17+
1618 /*
1719 * Major opcodes; before MIPS IV cop1x was called cop3.
1820 */
@@ -74,16 +76,17 @@ enum spec2_op { · 55 unmodified lines
7476 enum spec3_op {
7577 ext_op, dextm_op, dextu_op, dext_op,
7678 ins_op, dinsm_op, dinsu_op, dins_op,
77− lx_op = 0x0a, lwle_op = 0x19,
78− lwre_op = 0x1a, cachee_op = 0x1b,
79− sbe_op = 0x1c, she_op = 0x1d,
80− sce_op = 0x1e, swe_op = 0x1f,
81− bshfl_op = 0x20, swle_op = 0x21,
82− swre_op = 0x22, prefe_op = 0x23,
83− dbshfl_op = 0x24, lbue_op = 0x28,
84− lhue_op = 0x29, lbe_op = 0x2c,
85− lhe_op = 0x2d, lle_op = 0x2e,
86− lwe_op = 0x2f, rdhwr_op = 0x3b
79+ yield_op = 0x09, lx_op = 0x0a,
80+ lwle_op = 0x19, lwre_op = 0x1a,
81+ cachee_op = 0x1b, sbe_op = 0x1c,
82+ she_op = 0x1d, sce_op = 0x1e,
83+ swe_op = 0x1f, bshfl_op = 0x20,
84+ swle_op = 0x21, swre_op = 0x22,
85+ prefe_op = 0x23, dbshfl_op = 0x24,
86+ lbue_op = 0x28, lhue_op = 0x29,
87+ lbe_op = 0x2c, lhe_op = 0x2d,
88+ lle_op = 0x2e, lwe_op = 0x2f,
89+ rdhwr_op = 0x3b
8790 };
8891
8992 /*
@@ -125,7 +128,8 @@ enum bcop_op { · 35 unmodified lines
125128 enum cop0_coi_func {
126129 tlbr_op = 0x01, tlbwi_op = 0x02,
127130 tlbwr_op = 0x06, tlbp_op = 0x08,
128− rfe_op = 0x10, eret_op = 0x18
131+ rfe_op = 0x10, eret_op = 0x18,
132+ wait_op = 0x20,
129133 };
130134
131135 /*
@@ -201,6 +205,16 @@ enum lx_func { · 69 unmodified lines
201205 lbx_op = 0x16,
202206 };
203207
208+/*
209+ * BSHFL opcodes
210+ */
211+enum bshfl_func {
212+ wsbh_op = 0x2,
213+ dshd_op = 0x5,
214+ seb_op = 0x10,
215+ seh_op = 0x18,
216+};
217+
204218 /*
205219 * (microMIPS) Major opcodes.
206220 */
@@ -244,17 +258,22 @@ enum mm_32i_minor_op { · 37 unmodified lines
244258 enum mm_32a_minor_op {
245259 mm_sll32_op = 0x000,
246260 mm_ins_op = 0x00c,
261+ mm_sllv32_op = 0x010,
247262 mm_ext_op = 0x02c,
248263 mm_pool32axf_op = 0x03c,
249264 mm_srl32_op = 0x040,
250265 mm_sra_op = 0x080,
266+ mm_srlv32_op = 0x090,
251267 mm_rotr_op = 0x0c0,
252268 mm_lwxs_op = 0x118,
253269 mm_addu32_op = 0x150,
254270 mm_subu32_op = 0x1d0,
271+ mm_wsbh_op = 0x1ec,
272+ mm_mul_op = 0x210,
255273 mm_and_op = 0x250,
256274 mm_or32_op = 0x290,
257275 mm_xor32_op = 0x310,
276+ mm_sltu_op = 0x390,
258277 };
259278
260279 /*
@@ -294,15 +313,20 @@ enum mm_32axf_minor_op { · 33 unmodified lines
294313 mm_mfc0_op = 0x003,
295314 mm_mtc0_op = 0x00b,
296315 mm_tlbp_op = 0x00d,
316+ mm_mfhi32_op = 0x035,
297317 mm_jalr_op = 0x03c,
298318 mm_tlbr_op = 0x04d,
319+ mm_mflo32_op = 0x075,
299320 mm_jalrhb_op = 0x07c,
300321 mm_tlbwi_op = 0x08d,
301322 mm_tlbwr_op = 0x0cd,
302323 mm_jalrs_op = 0x13c,
303324 mm_jalrshb_op = 0x17c,
325+ mm_sync_op = 0x1ad,
304326 mm_syscall_op = 0x22d,
327+ mm_wait_op = 0x24d,
305328 mm_eret_op = 0x3cd,
329+ mm_divu_op = 0x5dc,
306330 };
307331
308332 /*
@@ -480,24 +504,6 @@ enum MIPS6e_i8_func { · 171 unmodified lines
480504 */
481505 #define MM_NOP16 0x0c00
482506
483−/*
484− * Damn ... bitfields depend from byteorder :-(
485− */
486−#ifdef __MIPSEB__
487−#define __BITFIELD_FIELD(field, more) \
488− field; \
489− more
490−
491−#elif defined(__MIPSEL__)
492−
493−#define __BITFIELD_FIELD(field, more) \
494− more \
495− field;
496−
497−#else /* !defined (__MIPSEB__) && !defined (__MIPSEL__) */
498−#error "MIPS but neither __MIPSEL__ nor __MIPSEB__?"
499−#endif
500−
501507 struct j_format {
502508 __BITFIELD_FIELD(unsigned int opcode : 6, /* Jump format */
503509 __BITFIELD_FIELD(unsigned int target : 26,
arch/mips/include/uapi/asm/kvm_para.h+5−1
@@ -1 +1,5 @@
1−#include <asm-generic/kvm_para.h>
1+#ifndef _UAPI_ASM_MIPS_KVM_PARA_H
2+#define _UAPI_ASM_MIPS_KVM_PARA_H
3+
4+
5+#endif /* _UAPI_ASM_MIPS_KVM_PARA_H */
arch/mips/include/uapi/asm/types.h+4−1
@@ -14,9 +14,12 @@ · 13 unmodified lines
1414 /*
1515 * We don't use int-l64.h for the kernel anymore but still use it for
1616 * userspace to avoid code changes.
17+ *
18+ * However, some user programs (e.g. perf) may not want this. They can
19+ * flag __SANE_USERSPACE_TYPES__ to get int-ll64.h here.
1720 */
1821 #ifndef __KERNEL__
19−# if _MIPS_SZLONG == 64
22+# if _MIPS_SZLONG == 64 && !defined(__SANE_USERSPACE_TYPES__)
2023 # include <asm-generic/int-l64.h>
2124 # else
2225 # include <asm-generic/int-ll64.h>
arch/mips/kernel/Makefile+4−3
@@ -17,7 +17,6 @@ endif · 16 unmodified lines
1717
1818 obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o
1919 obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o
20−obj-$(CONFIG_MIPS_MT_SMTC) += cevt-smtc.o
2120 obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o
2221 obj-$(CONFIG_CEVT_GIC) += cevt-gic.o
2322 obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o
@@ -42,7 +41,7 @@ obj-$(CONFIG_CPU_R4K_FPU) += r4k_fpu.o r4k_switch.o · 18 unmodified lines
4241 obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o
4342 obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o
4443 obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o
45−obj-$(CONFIG_CPU_CAVIUM_OCTEON) += octeon_switch.o
44+obj-$(CONFIG_CPU_CAVIUM_OCTEON) += r4k_fpu.o octeon_switch.o
4645
4746 obj-$(CONFIG_SMP) += smp.o
4847 obj-$(CONFIG_SMP_UP) += smp-up.o
@@ -50,7 +49,6 @@ obj-$(CONFIG_CPU_BMIPS) += smp-bmips.o bmips_vec.o · 1 unmodified line
5049
5150 obj-$(CONFIG_MIPS_MT) += mips-mt.o
5251 obj-$(CONFIG_MIPS_MT_FPAFF) += mips-mt-fpaff.o
53−obj-$(CONFIG_MIPS_MT_SMTC) += smtc.o smtc-asm.o smtc-proc.o
5452 obj-$(CONFIG_MIPS_MT_SMP) += smp-mt.o
5553 obj-$(CONFIG_MIPS_CMP) += smp-cmp.o
5654 obj-$(CONFIG_MIPS_CPS) += smp-cps.o cps-vec.o
@@ -107,6 +105,9 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o · 50 unmodified lines
107105 obj-$(CONFIG_MIPS_CM) += mips-cm.o
108106 obj-$(CONFIG_MIPS_CPC) += mips-cpc.o
109107
108+obj-$(CONFIG_CPU_PM) += pm.o
109+obj-$(CONFIG_MIPS_CPS_PM) += pm-cps.o
110+
110111 #
111112 # DSP ASE supported for MIPS32 or MIPS64 Release 2 cores only. It is not
112113 # safe to unconditionnaly use the assembler -mdsp / -mdspr2 switches
arch/mips/kernel/asm-offsets.c+24−8
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414 #include <linux/mm.h>
1515 #include <linux/kbuild.h>
1616 #include <linux/suspend.h>
17+#include <asm/pm.h>
1718 #include <asm/ptrace.h>
1819 #include <asm/processor.h>
1920 #include <asm/smp-cps.h>
@@ -64,9 +65,6 @@ void output_ptreg_defines(void) · 44 unmodified lines
6465 OFFSET(PT_BVADDR, pt_regs, cp0_badvaddr);
6566 OFFSET(PT_STATUS, pt_regs, cp0_status);
6667 OFFSET(PT_CAUSE, pt_regs, cp0_cause);
67−#ifdef CONFIG_MIPS_MT_SMTC
68− OFFSET(PT_TCSTATUS, pt_regs, cp0_tcstatus);
69−#endif /* CONFIG_MIPS_MT_SMTC */
7068 #ifdef CONFIG_CPU_CAVIUM_OCTEON
7169 OFFSET(PT_MPL, pt_regs, mpl);
7270 OFFSET(PT_MTP, pt_regs, mtp);
@@ -404,6 +402,20 @@ void output_pbe_defines(void) · 331 unmodified lines
404402 }
405403 #endif
406404
405+#ifdef CONFIG_CPU_PM
406+void output_pm_defines(void)
407+{
408+ COMMENT(" PM offsets. ");
409+#ifdef CONFIG_EVA
410+ OFFSET(SSS_SEGCTL0, mips_static_suspend_state, segctl[0]);
411+ OFFSET(SSS_SEGCTL1, mips_static_suspend_state, segctl[1]);
412+ OFFSET(SSS_SEGCTL2, mips_static_suspend_state, segctl[2]);
413+#endif
414+ OFFSET(SSS_SP, mips_static_suspend_state, sp);
415+ BLANK();
416+}
417+#endif
418+
407419 void output_kvm_defines(void)
408420 {
409421 COMMENT(" KVM/MIPS Specfic offsets. ");
@@ -472,10 +484,14 @@ void output_kvm_defines(void) · 62 unmodified lines
472484 void output_cps_defines(void)
473485 {
474486 COMMENT(" MIPS CPS offsets. ");
475− OFFSET(BOOTCFG_CORE, boot_config, core);
476− OFFSET(BOOTCFG_VPE, boot_config, vpe);
477− OFFSET(BOOTCFG_PC, boot_config, pc);
478− OFFSET(BOOTCFG_SP, boot_config, sp);
479− OFFSET(BOOTCFG_GP, boot_config, gp);
487+
488+ OFFSET(COREBOOTCFG_VPEMASK, core_boot_config, vpe_mask);
489+ OFFSET(COREBOOTCFG_VPECONFIG, core_boot_config, vpe_config);
490+ DEFINE(COREBOOTCFG_SIZE, sizeof(struct core_boot_config));
491+
492+ OFFSET(VPEBOOTCFG_PC, vpe_boot_config, pc);
493+ OFFSET(VPEBOOTCFG_SP, vpe_boot_config, sp);
494+ OFFSET(VPEBOOTCFG_GP, vpe_boot_config, gp);
495+ DEFINE(VPEBOOTCFG_SIZE, sizeof(struct vpe_boot_config));
480496 }
481497 #endif
arch/mips/kernel/branch.c+201−1
@@ -48,6 +48,202 @@ int __isa_exception_epc(struct pt_regs *regs) · 47 unmodified lines
4848 return epc;
4949 }
5050
51+/* (microMIPS) Convert 16-bit register encoding to 32-bit register encoding. */
52+static const unsigned int reg16to32map[8] = {16, 17, 2, 3, 4, 5, 6, 7};
53+
54+int __mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
55+ unsigned long *contpc)
56+{
57+ union mips_instruction insn = (union mips_instruction)dec_insn.insn;
58+ int bc_false = 0;
59+ unsigned int fcr31;
60+ unsigned int bit;
61+
62+ if (!cpu_has_mmips)
63+ return 0;
64+
65+ switch (insn.mm_i_format.opcode) {
66+ case mm_pool32a_op:
67+ if ((insn.mm_i_format.simmediate & MM_POOL32A_MINOR_MASK) ==
68+ mm_pool32axf_op) {
69+ switch (insn.mm_i_format.simmediate >>
70+ MM_POOL32A_MINOR_SHIFT) {
71+ case mm_jalr_op:
72+ case mm_jalrhb_op:
73+ case mm_jalrs_op:
74+ case mm_jalrshb_op:
75+ if (insn.mm_i_format.rt != 0) /* Not mm_jr */
76+ regs->regs[insn.mm_i_format.rt] =
77+ regs->cp0_epc +
78+ dec_insn.pc_inc +
79+ dec_insn.next_pc_inc;
80+ *contpc = regs->regs[insn.mm_i_format.rs];
81+ return 1;
82+ }
83+ }
84+ break;
85+ case mm_pool32i_op:
86+ switch (insn.mm_i_format.rt) {
87+ case mm_bltzals_op:
88+ case mm_bltzal_op:
89+ regs->regs[31] = regs->cp0_epc +
90+ dec_insn.pc_inc +
91+ dec_insn.next_pc_inc;
92+ /* Fall through */
93+ case mm_bltz_op:
94+ if ((long)regs->regs[insn.mm_i_format.rs] < 0)
95+ *contpc = regs->cp0_epc +
96+ dec_insn.pc_inc +
97+ (insn.mm_i_format.simmediate << 1);
98+ else
99+ *contpc = regs->cp0_epc +
100+ dec_insn.pc_inc +
101+ dec_insn.next_pc_inc;
102+ return 1;
103+ case mm_bgezals_op:
104+ case mm_bgezal_op:
105+ regs->regs[31] = regs->cp0_epc +
106+ dec_insn.pc_inc +
107+ dec_insn.next_pc_inc;
108+ /* Fall through */
109+ case mm_bgez_op:
110+ if ((long)regs->regs[insn.mm_i_format.rs] >= 0)
111+ *contpc = regs->cp0_epc +
112+ dec_insn.pc_inc +
113+ (insn.mm_i_format.simmediate << 1);
114+ else
115+ *contpc = regs->cp0_epc +
116+ dec_insn.pc_inc +
117+ dec_insn.next_pc_inc;
118+ return 1;
119+ case mm_blez_op:
120+ if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
121+ *contpc = regs->cp0_epc +
122+ dec_insn.pc_inc +
123+ (insn.mm_i_format.simmediate << 1);
124+ else
125+ *contpc = regs->cp0_epc +
126+ dec_insn.pc_inc +
127+ dec_insn.next_pc_inc;
128+ return 1;
129+ case mm_bgtz_op:
130+ if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
131+ *contpc = regs->cp0_epc +
132+ dec_insn.pc_inc +
133+ (insn.mm_i_format.simmediate << 1);
134+ else
135+ *contpc = regs->cp0_epc +
136+ dec_insn.pc_inc +
137+ dec_insn.next_pc_inc;
138+ return 1;
139+ case mm_bc2f_op:
140+ case mm_bc1f_op:
141+ bc_false = 1;
142+ /* Fall through */
143+ case mm_bc2t_op:
144+ case mm_bc1t_op:
145+ preempt_disable();
146+ if (is_fpu_owner())
147+ asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
148+ else
149+ fcr31 = current->thread.fpu.fcr31;
150+ preempt_enable();
151+
152+ if (bc_false)
153+ fcr31 = ~fcr31;
154+
155+ bit = (insn.mm_i_format.rs >> 2);
156+ bit += (bit != 0);
157+ bit += 23;
158+ if (fcr31 & (1 << bit))
159+ *contpc = regs->cp0_epc +
160+ dec_insn.pc_inc +
161+ (insn.mm_i_format.simmediate << 1);
162+ else
163+ *contpc = regs->cp0_epc +
164+ dec_insn.pc_inc + dec_insn.next_pc_inc;
165+ return 1;
166+ }
167+ break;
168+ case mm_pool16c_op:
169+ switch (insn.mm_i_format.rt) {
170+ case mm_jalr16_op:
171+ case mm_jalrs16_op:
172+ regs->regs[31] = regs->cp0_epc +
173+ dec_insn.pc_inc + dec_insn.next_pc_inc;
174+ /* Fall through */
175+ case mm_jr16_op:
176+ *contpc = regs->regs[insn.mm_i_format.rs];
177+ return 1;
178+ }
179+ break;
180+ case mm_beqz16_op:
181+ if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] == 0)
182+ *contpc = regs->cp0_epc +
183+ dec_insn.pc_inc +
184+ (insn.mm_b1_format.simmediate << 1);
185+ else
186+ *contpc = regs->cp0_epc +
187+ dec_insn.pc_inc + dec_insn.next_pc_inc;
188+ return 1;
189+ case mm_bnez16_op:
190+ if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] != 0)
191+ *contpc = regs->cp0_epc +
192+ dec_insn.pc_inc +
193+ (insn.mm_b1_format.simmediate << 1);
194+ else
195+ *contpc = regs->cp0_epc +
196+ dec_insn.pc_inc + dec_insn.next_pc_inc;
197+ return 1;
198+ case mm_b16_op:
199+ *contpc = regs->cp0_epc + dec_insn.pc_inc +
200+ (insn.mm_b0_format.simmediate << 1);
201+ return 1;
202+ case mm_beq32_op:
203+ if (regs->regs[insn.mm_i_format.rs] ==
204+ regs->regs[insn.mm_i_format.rt])
205+ *contpc = regs->cp0_epc +
206+ dec_insn.pc_inc +
207+ (insn.mm_i_format.simmediate << 1);
208+ else
209+ *contpc = regs->cp0_epc +
210+ dec_insn.pc_inc +
211+ dec_insn.next_pc_inc;
212+ return 1;
213+ case mm_bne32_op:
214+ if (regs->regs[insn.mm_i_format.rs] !=
215+ regs->regs[insn.mm_i_format.rt])
216+ *contpc = regs->cp0_epc +
217+ dec_insn.pc_inc +
218+ (insn.mm_i_format.simmediate << 1);
219+ else
220+ *contpc = regs->cp0_epc +
221+ dec_insn.pc_inc + dec_insn.next_pc_inc;
222+ return 1;
223+ case mm_jalx32_op:
224+ regs->regs[31] = regs->cp0_epc +
225+ dec_insn.pc_inc + dec_insn.next_pc_inc;
226+ *contpc = regs->cp0_epc + dec_insn.pc_inc;
227+ *contpc >>= 28;
228+ *contpc <<= 28;
229+ *contpc |= (insn.j_format.target << 2);
230+ return 1;
231+ case mm_jals32_op:
232+ case mm_jal32_op:
233+ regs->regs[31] = regs->cp0_epc +
234+ dec_insn.pc_inc + dec_insn.next_pc_inc;
235+ /* Fall through */
236+ case mm_j32_op:
237+ *contpc = regs->cp0_epc + dec_insn.pc_inc;
238+ *contpc >>= 27;
239+ *contpc <<= 27;
240+ *contpc |= (insn.j_format.target << 1);
241+ set_isa16_mode(*contpc);
242+ return 1;
243+ }
244+ return 0;
245+}
246+
51247 /*
52248 * Compute return address and emulate branch in microMIPS mode after an
53249 * exception only. It does not handle compact branches/jumps and cannot
@@ -366,7 +562,11 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, · 312 unmodified lines
366562 case cop1_op:
367563 preempt_disable();
368564 if (is_fpu_owner())
369− asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
565+ asm volatile(
566+ ".set push\n"
567+ "\t.set mips1\n"
568+ "\tcfc1\t%0,$31\n"
569+ "\t.set pop" : "=r" (fcr31));
370570 else
371571 fcr31 = current->thread.fpu.fcr31;
372572 preempt_enable();
arch/mips/kernel/cevt-gic.c+3−2
@@ -26,7 +26,7 @@ static int gic_next_event(unsigned long delta, struct clock_event_device *evt) · 25 unmodified lines
2626
2727 cnt = gic_read_count();
2828 cnt += (u64)delta;
29− gic_write_compare(cnt);
29+ gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask));
3030 res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0;
3131 return res;
3232 }
@@ -73,7 +73,8 @@ int gic_clockevent_init(void) · 40 unmodified lines
7373 cd = &per_cpu(gic_clockevent_device, cpu);
7474
7575 cd->name = "MIPS GIC";
76− cd->features = CLOCK_EVT_FEAT_ONESHOT;
76+ cd->features = CLOCK_EVT_FEAT_ONESHOT |
77+ CLOCK_EVT_FEAT_C3STOP;
7778
7879 clockevent_set_clock(cd, gic_frequency);
7980
arch/mips/kernel/cevt-r4k.c+3−21
@@ -12,17 +12,10 @@ · 11 unmodified lines
1212 #include <linux/smp.h>
1313 #include <linux/irq.h>
1414
15−#include <asm/smtc_ipi.h>
1615 #include <asm/time.h>
1716 #include <asm/cevt-r4k.h>
1817 #include <asm/gic.h>
1918
20−/*
21− * The SMTC Kernel for the 34K, 1004K, et. al. replaces several
22− * of these routines with SMTC-specific variants.
23− */
24−
25−#ifndef CONFIG_MIPS_MT_SMTC
2619 static int mips_next_event(unsigned long delta,
2720 struct clock_event_device *evt)
2821 {
@@ -36,8 +29,6 @@ static int mips_next_event(unsigned long delta, · 7 unmodified lines
3629 return res;
3730 }
3831
39−#endif /* CONFIG_MIPS_MT_SMTC */
40−
4132 void mips_set_clock_mode(enum clock_event_mode mode,
4233 struct clock_event_device *evt)
4334 {
@@ -47,7 +38,6 @@ void mips_set_clock_mode(enum clock_event_mode mode, · 3 unmodified lines
4738 DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device);
4839 int cp0_timer_irq_installed;
4940
50−#ifndef CONFIG_MIPS_MT_SMTC
5141 irqreturn_t c0_compare_interrupt(int irq, void *dev_id)
5242 {
5343 const int r2 = cpu_has_mips_r2;
@@ -72,9 +62,6 @@ irqreturn_t c0_compare_interrupt(int irq, void *dev_id) · 18 unmodified lines
7262 /* Clear Count/Compare Interrupt */
7363 write_c0_compare(read_c0_compare());
7464 cd = &per_cpu(mips_clockevent_device, cpu);
75−#ifdef CONFIG_CEVT_GIC
76− if (!gic_present)
77−#endif
7865 cd->event_handler(cd);
7966 }
8067
@@ -82,8 +69,6 @@ out: · 1 unmodified line
8269 return IRQ_HANDLED;
8370 }
8471
85−#endif /* Not CONFIG_MIPS_MT_SMTC */
86−
8772 struct irqaction c0_compare_irqaction = {
8873 .handler = c0_compare_interrupt,
8974 .flags = IRQF_PERCPU | IRQF_TIMER,
@@ -170,7 +155,6 @@ int c0_compare_int_usable(void) · 80 unmodified lines
170155 return 1;
171156 }
172157
173−#ifndef CONFIG_MIPS_MT_SMTC
174158 int r4k_clockevent_init(void)
175159 {
176160 unsigned int cpu = smp_processor_id();
@@ -195,7 +179,9 @@ int r4k_clockevent_init(void) · 18 unmodified lines
195179 cd = &per_cpu(mips_clockevent_device, cpu);
196180
197181 cd->name = "MIPS";
198− cd->features = CLOCK_EVT_FEAT_ONESHOT;
182+ cd->features = CLOCK_EVT_FEAT_ONESHOT |
183+ CLOCK_EVT_FEAT_C3STOP |
184+ CLOCK_EVT_FEAT_PERCPU;
199185
200186 clockevent_set_clock(cd, mips_hpt_frequency);
201187
@@ -210,9 +196,6 @@ int r4k_clockevent_init(void) · 8 unmodified lines
210196 cd->set_mode = mips_set_clock_mode;
211197 cd->event_handler = mips_event_handler;
212198
213−#ifdef CONFIG_CEVT_GIC
214− if (!gic_present)
215−#endif
216199 clockevents_register_device(cd);
217200
218201 if (cp0_timer_irq_installed)
@@ -225,4 +208,3 @@ int r4k_clockevent_init(void) · 6 unmodified lines
225208 return 0;
226209 }
227210
228−#endif /* Not CONFIG_MIPS_MT_SMTC */
arch/mips/kernel/cevt-smtc.c+0−324
@@ -1,324 +0,0 @@
1−/*
2− * This file is subject to the terms and conditions of the GNU General Public
3− * License. See the file "COPYING" in the main directory of this archive
4− * for more details.
5− *
6− * Copyright (C) 2007 MIPS Technologies, Inc.
7− * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org>
8− * Copyright (C) 2008 Kevin D. Kissell, Paralogos sarl
9− */
10−#include <linux/clockchips.h>
11−#include <linux/interrupt.h>
12−#include <linux/percpu.h>
13−#include <linux/smp.h>
14−#include <linux/irq.h>
15−
16−#include <asm/smtc_ipi.h>
17−#include <asm/time.h>
18−#include <asm/cevt-r4k.h>
19−
20−/*
21− * Variant clock event timer support for SMTC on MIPS 34K, 1004K
22− * or other MIPS MT cores.
23− *
24− * Notes on SMTC Support:
25− *
26− * SMTC has multiple microthread TCs pretending to be Linux CPUs.
27− * But there's only one Count/Compare pair per VPE, and Compare
28− * interrupts are taken opportunisitically by available TCs
29− * bound to the VPE with the Count register. The new timer
30− * framework provides for global broadcasts, but we really
31− * want VPE-level multicasts for best behavior. So instead
32− * of invoking the high-level clock-event broadcast code,
33− * this version of SMTC support uses the historical SMTC
34− * multicast mechanisms "under the hood", appearing to the
35− * generic clock layer as if the interrupts are per-CPU.
36− *
37− * The approach taken here is to maintain a set of NR_CPUS
38− * virtual timers, and track which "CPU" needs to be alerted
39− * at each event.
40− *
41− * It's unlikely that we'll see a MIPS MT core with more than
42− * 2 VPEs, but we *know* that we won't need to handle more
43− * VPEs than we have "CPUs". So NCPUs arrays of NCPUs elements
44− * is always going to be overkill, but always going to be enough.
45− */
46−
47−unsigned long smtc_nexttime[NR_CPUS][NR_CPUS];
48−static int smtc_nextinvpe[NR_CPUS];
49−
50−/*
51− * Timestamps stored are absolute values to be programmed
52− * into Count register. Valid timestamps will never be zero.
53− * If a Zero Count value is actually calculated, it is converted
54− * to be a 1, which will introduce 1 or two CPU cycles of error
55− * roughly once every four billion events, which at 1000 HZ means
56− * about once every 50 days. If that's actually a problem, one
57− * could alternate squashing 0 to 1 and to -1.
58− */
59−
60−#define MAKEVALID(x) (((x) == 0L) ? 1L : (x))
61−#define ISVALID(x) ((x) != 0L)
62−
63−/*
64− * Time comparison is subtle, as it's really truncated
65− * modular arithmetic.
66− */
67−
68−#define IS_SOONER(a, b, reference) \
69− (((a) - (unsigned long)(reference)) < ((b) - (unsigned long)(reference)))
70−
71−/*
72− * CATCHUP_INCREMENT, used when the function falls behind the counter.
73− * Could be an increasing function instead of a constant;
74− */
75−
76−#define CATCHUP_INCREMENT 64
77−
78−static int mips_next_event(unsigned long delta,
79− struct clock_event_device *evt)
80−{
81− unsigned long flags;
82− unsigned int mtflags;
83− unsigned long timestamp, reference, previous;
84− unsigned long nextcomp = 0L;
85− int vpe = current_cpu_data.vpe_id;
86− int cpu = smp_processor_id();
87− local_irq_save(flags);
88− mtflags = dmt();
89−
90− /*
91− * Maintain the per-TC virtual timer
92− * and program the per-VPE shared Count register
93− * as appropriate here...
94− */
95− reference = (unsigned long)read_c0_count();
96− timestamp = MAKEVALID(reference + delta);
97− /*
98− * To really model the clock, we have to catch the case
99− * where the current next-in-VPE timestamp is the old
100− * timestamp for the calling CPE, but the new value is
101− * in fact later. In that case, we have to do a full
102− * scan and discover the new next-in-VPE CPU id and
103− * timestamp.
104− */
105− previous = smtc_nexttime[vpe][cpu];
106− if (cpu == smtc_nextinvpe[vpe] && ISVALID(previous)
107− && IS_SOONER(previous, timestamp, reference)) {
108− int i;
109− int soonest = cpu;
110−
111− /*
112− * Update timestamp array here, so that new
113− * value gets considered along with those of
114− * other virtual CPUs on the VPE.
115− */
116− smtc_nexttime[vpe][cpu] = timestamp;
117− for_each_online_cpu(i) {
118− if (ISVALID(smtc_nexttime[vpe][i])
119− && IS_SOONER(smtc_nexttime[vpe][i],
120− smtc_nexttime[vpe][soonest], reference)) {
121− soonest = i;
122− }
123− }
124− smtc_nextinvpe[vpe] = soonest;
125− nextcomp = smtc_nexttime[vpe][soonest];
126− /*
127− * Otherwise, we don't have to process the whole array rank,
128− * we just have to see if the event horizon has gotten closer.
129− */
130− } else {
131− if (!ISVALID(smtc_nexttime[vpe][smtc_nextinvpe[vpe]]) ||
132− IS_SOONER(timestamp,
133− smtc_nexttime[vpe][smtc_nextinvpe[vpe]], reference)) {
134− smtc_nextinvpe[vpe] = cpu;
135− nextcomp = timestamp;
136− }
137− /*
138− * Since next-in-VPE may me the same as the executing
139− * virtual CPU, we update the array *after* checking
140− * its value.
141− */
142− smtc_nexttime[vpe][cpu] = timestamp;
143− }
144−
145− /*
146− * It may be that, in fact, we don't need to update Compare,
147− * but if we do, we want to make sure we didn't fall into
148− * a crack just behind Count.
149− */
150− if (ISVALID(nextcomp)) {
151− write_c0_compare(nextcomp);
152− ehb();
153− /*
154− * We never return an error, we just make sure
155− * that we trigger the handlers as quickly as
156− * we can if we fell behind.
157− */
158− while ((nextcomp - (unsigned long)read_c0_count())
159− > (unsigned long)LONG_MAX) {
160− nextcomp += CATCHUP_INCREMENT;
161− write_c0_compare(nextcomp);
162− ehb();
163− }
164− }
165− emt(mtflags);
166− local_irq_restore(flags);
167− return 0;
168−}
169−
170−
171−void smtc_distribute_timer(int vpe)
172−{
173− unsigned long flags;
174− unsigned int mtflags;
175− int cpu;
176− struct clock_event_device *cd;
177− unsigned long nextstamp;
178− unsigned long reference;
179−
180−
181−repeat:
182− nextstamp = 0L;
183− for_each_online_cpu(cpu) {
184− /*
185− * Find virtual CPUs within the current VPE who have
186− * unserviced timer requests whose time is now past.
187− */
188− local_irq_save(flags);
189− mtflags = dmt();
190− if (cpu_data[cpu].vpe_id == vpe &&
191− ISVALID(smtc_nexttime[vpe][cpu])) {
192− reference = (unsigned long)read_c0_count();
193− if ((smtc_nexttime[vpe][cpu] - reference)
194− > (unsigned long)LONG_MAX) {
195− smtc_nexttime[vpe][cpu] = 0L;
196− emt(mtflags);
197− local_irq_restore(flags);
198− /*
199− * We don't send IPIs to ourself.
200− */
201− if (cpu != smp_processor_id()) {
202− smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0);
203− } else {
204− cd = &per_cpu(mips_clockevent_device, cpu);
205− cd->event_handler(cd);
206− }
207− } else {
208− /* Local to VPE but Valid Time not yet reached. */
209− if (!ISVALID(nextstamp) ||
210− IS_SOONER(smtc_nexttime[vpe][cpu], nextstamp,
211− reference)) {
212− smtc_nextinvpe[vpe] = cpu;
213− nextstamp = smtc_nexttime[vpe][cpu];
214− }
215− emt(mtflags);
216− local_irq_restore(flags);
217− }
218− } else {
219− emt(mtflags);
220− local_irq_restore(flags);
221−
222− }
223− }
224− /* Reprogram for interrupt at next soonest timestamp for VPE */
225− if (ISVALID(nextstamp)) {
226− write_c0_compare(nextstamp);
227− ehb();
228− if ((nextstamp - (unsigned long)read_c0_count())
229− > (unsigned long)LONG_MAX)
230− goto repeat;
231− }
232−}
233−
234−
235−irqreturn_t c0_compare_interrupt(int irq, void *dev_id)
236−{
237− int cpu = smp_processor_id();
238−
239− /* If we're running SMTC, we've got MIPS MT and therefore MIPS32R2 */
240− handle_perf_irq(1);
241−
242− if (read_c0_cause() & (1 << 30)) {
243− /* Clear Count/Compare Interrupt */
244− write_c0_compare(read_c0_compare());
245− smtc_distribute_timer(cpu_data[cpu].vpe_id);
246− }
247− return IRQ_HANDLED;
248−}
249−
250−
251−int smtc_clockevent_init(void)
252−{
253− uint64_t mips_freq = mips_hpt_frequency;
254− unsigned int cpu = smp_processor_id();
255− struct clock_event_device *cd;
256− unsigned int irq;
257− int i;
258− int j;
259−
260− if (!cpu_has_counter || !mips_hpt_frequency)
261− return -ENXIO;
262− if (cpu == 0) {
263− for (i = 0; i < num_possible_cpus(); i++) {
264− smtc_nextinvpe[i] = 0;
265− for (j = 0; j < num_possible_cpus(); j++)
266− smtc_nexttime[i][j] = 0L;
267− }
268− /*
269− * SMTC also can't have the usablility test
270− * run by secondary TCs once Compare is in use.
271− */
272− if (!c0_compare_int_usable())
273− return -ENXIO;
274− }
275−
276− /*
277− * With vectored interrupts things are getting platform specific.
278− * get_c0_compare_int is a hook to allow a platform to return the
279− * interrupt number of it's liking.
280− */
281− irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
282− if (get_c0_compare_int)
283− irq = get_c0_compare_int();
284−
285− cd = &per_cpu(mips_clockevent_device, cpu);
286−
287− cd->name = "MIPS";
288− cd->features = CLOCK_EVT_FEAT_ONESHOT;
289−
290− /* Calculate the min / max delta */
291− cd->mult = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
292− cd->shift = 32;
293− cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
294− cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
295−
296− cd->rating = 300;
297− cd->irq = irq;
298− cd->cpumask = cpumask_of(cpu);
299− cd->set_next_event = mips_next_event;
300− cd->set_mode = mips_set_clock_mode;
301− cd->event_handler = mips_event_handler;
302−
303− clockevents_register_device(cd);
304−
305− /*
306− * On SMTC we only want to do the data structure
307− * initialization and IRQ setup once.
308− */
309− if (cpu)
310− return 0;
311− /*
312− * And we need the hwmask associated with the c0_compare
313− * vector to be initialized.
314− */
315− irq_hwmask[irq] = (0x100 << cp0_compare_irq);
316− if (cp0_timer_irq_installed)
317− return 0;
318−
319− cp0_timer_irq_installed = 1;
320−
321− setup_irq(irq, &c0_compare_irqaction);
322−
323− return 0;
324−}
arch/mips/kernel/cps-vec.S+312−16
@@ -14,19 +14,43 @@ · 13 unmodified lines
1414 #include <asm/asmmacro.h>
1515 #include <asm/cacheops.h>
1616 #include <asm/mipsregs.h>
17+#include <asm/mipsmtregs.h>
18+#include <asm/pm.h>
1719
18−#define GCR_CL_COHERENCE_OFS 0x2008
20+#define GCR_CL_COHERENCE_OFS 0x2008
21+#define GCR_CL_ID_OFS 0x2028
22+
23+.extern mips_cm_base
24+
25+.set noreorder
26+
27+ /*
28+ * Set dest to non-zero if the core supports the MT ASE, else zero. If
29+ * MT is not supported then branch to nomt.
30+ */
31+ .macro has_mt dest, nomt
32+ mfc0 \dest, CP0_CONFIG
33+ bgez \dest, \nomt
34+ mfc0 \dest, CP0_CONFIG, 1
35+ bgez \dest, \nomt
36+ mfc0 \dest, CP0_CONFIG, 2
37+ bgez \dest, \nomt
38+ mfc0 \dest, CP0_CONFIG, 3
39+ andi \dest, \dest, MIPS_CONF3_MT
40+ beqz \dest, \nomt
41+ .endm
1942
2043 .section .text.cps-vec
2144 .balign 0x1000
22−.set noreorder
2345
2446 LEAF(mips_cps_core_entry)
2547 /*
26− * These first 8 bytes will be patched by cps_smp_setup to load the
27− * base address of the CM GCRs into register v1.
48+ * These first 12 bytes will be patched by cps_smp_setup to load the
49+ * base address of the CM GCRs into register v1 and the CCA to use into
50+ * register s0.
2851 */
2952 .quad 0
53+ .word 0
3054
3155 /* Check whether we're here due to an NMI */
3256 mfc0 k0, CP0_STATUS
@@ -117,10 +141,11 @@ icache_done: · 84 unmodified lines
117141 add a0, a0, t0
118142 dcache_done:
119143
120− /* Set Kseg0 cacheable, coherent, write-back, write-allocate */
144+ /* Set Kseg0 CCA to that in s0 */
121145 mfc0 t0, CP0_CONFIG
122146 ori t0, 0x7
123− xori t0, 0x2
147+ xori t0, 0x7
148+ or t0, t0, s0
124149 mtc0 t0, CP0_CONFIG
125150 ehb
126151
@@ -134,21 +159,24 @@ dcache_done: · 7 unmodified lines
134159 jr t0
135160 nop
136161
137−1: /* We're up, cached & coherent */
162+ /*
163+ * We're up, cached & coherent. Perform any further required core-level
164+ * initialisation.
165+ */
166+1: jal mips_cps_core_init
167+ nop
138168
139169 /*
140− * TODO: We should check the VPE number we intended to boot here, and
141− * if non-zero we should start that VPE and stop this one. For
142− * the moment this doesn't matter since CPUs are brought up
143− * sequentially and in order, but once hotplug is implemented
144− * this will need revisiting.
170+ * Boot any other VPEs within this core that should be online, and
171+ * deactivate this VPE if it should be offline.
145172 */
173+ jal mips_cps_boot_vpes
174+ nop
146175
147176 /* Off we go! */
148− la t0, mips_cps_bootcfg
149− lw t1, BOOTCFG_PC(t0)
150− lw gp, BOOTCFG_GP(t0)
151− lw sp, BOOTCFG_SP(t0)
177+ lw t1, VPEBOOTCFG_PC(v0)
178+ lw gp, VPEBOOTCFG_GP(v0)
179+ lw sp, VPEBOOTCFG_SP(v0)
152180 jr t1
153181 nop
154182 END(mips_cps_core_entry)
@@ -189,3 +217,271 @@ LEAF(excep_ejtag) · 34 unmodified lines
189217 jr k0
190218 nop
191219 END(excep_ejtag)
220+
221+LEAF(mips_cps_core_init)
222+#ifdef CONFIG_MIPS_MT
223+ /* Check that the core implements the MT ASE */
224+ has_mt t0, 3f
225+ nop
226+
227+ .set push
228+ .set mt
229+
230+ /* Only allow 1 TC per VPE to execute... */
231+ dmt
232+
233+ /* ...and for the moment only 1 VPE */
234+ dvpe
235+ la t1, 1f
236+ jr.hb t1
237+ nop
238+
239+ /* Enter VPE configuration state */
240+1: mfc0 t0, CP0_MVPCONTROL
241+ ori t0, t0, MVPCONTROL_VPC
242+ mtc0 t0, CP0_MVPCONTROL
243+
244+ /* Retrieve the number of VPEs within the core */
245+ mfc0 t0, CP0_MVPCONF0
246+ srl t0, t0, MVPCONF0_PVPE_SHIFT
247+ andi t0, t0, (MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT)
248+ addi t7, t0, 1
249+
250+ /* If there's only 1, we're done */
251+ beqz t0, 2f
252+ nop
253+
254+ /* Loop through each VPE within this core */
255+ li t5, 1
256+
257+1: /* Operate on the appropriate TC */
258+ mtc0 t5, CP0_VPECONTROL
259+ ehb
260+
261+ /* Bind TC to VPE (1:1 TC:VPE mapping) */
262+ mttc0 t5, CP0_TCBIND
263+
264+ /* Set exclusive TC, non-active, master */
265+ li t0, VPECONF0_MVP
266+ sll t1, t5, VPECONF0_XTC_SHIFT
267+ or t0, t0, t1
268+ mttc0 t0, CP0_VPECONF0
269+
270+ /* Set TC non-active, non-allocatable */
271+ mttc0 zero, CP0_TCSTATUS
272+
273+ /* Set TC halted */
274+ li t0, TCHALT_H
275+ mttc0 t0, CP0_TCHALT
276+
277+ /* Next VPE */
278+ addi t5, t5, 1
279+ slt t0, t5, t7
280+ bnez t0, 1b
281+ nop
282+
283+ /* Leave VPE configuration state */
284+2: mfc0 t0, CP0_MVPCONTROL
285+ xori t0, t0, MVPCONTROL_VPC
286+ mtc0 t0, CP0_MVPCONTROL
287+
288+3: .set pop
289+#endif
290+ jr ra
291+ nop
292+ END(mips_cps_core_init)
293+
294+LEAF(mips_cps_boot_vpes)
295+ /* Retrieve CM base address */
296+ la t0, mips_cm_base
297+ lw t0, 0(t0)
298+
299+ /* Calculate a pointer to this cores struct core_boot_config */
300+ lw t0, GCR_CL_ID_OFS(t0)
301+ li t1, COREBOOTCFG_SIZE
302+ mul t0, t0, t1
303+ la t1, mips_cps_core_bootcfg
304+ lw t1, 0(t1)
305+ addu t0, t0, t1
306+
307+ /* Calculate this VPEs ID. If the core doesn't support MT use 0 */
308+ has_mt t6, 1f
309+ li t9, 0
310+
311+ /* Find the number of VPEs present in the core */
312+ mfc0 t1, CP0_MVPCONF0
313+ srl t1, t1, MVPCONF0_PVPE_SHIFT
314+ andi t1, t1, MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT
315+ addi t1, t1, 1
316+
317+ /* Calculate a mask for the VPE ID from EBase.CPUNum */
318+ clz t1, t1
319+ li t2, 31
320+ subu t1, t2, t1
321+ li t2, 1
322+ sll t1, t2, t1
323+ addiu t1, t1, -1
324+
325+ /* Retrieve the VPE ID from EBase.CPUNum */
326+ mfc0 t9, $15, 1
327+ and t9, t9, t1
328+
329+1: /* Calculate a pointer to this VPEs struct vpe_boot_config */
330+ li t1, VPEBOOTCFG_SIZE
331+ mul v0, t9, t1
332+ lw t7, COREBOOTCFG_VPECONFIG(t0)
333+ addu v0, v0, t7
334+
335+#ifdef CONFIG_MIPS_MT
336+
337+ /* If the core doesn't support MT then return */
338+ bnez t6, 1f
339+ nop
340+ jr ra
341+ nop
342+
343+ .set push
344+ .set mt
345+
346+1: /* Enter VPE configuration state */
347+ dvpe
348+ la t1, 1f
349+ jr.hb t1
350+ nop
351+1: mfc0 t1, CP0_MVPCONTROL
352+ ori t1, t1, MVPCONTROL_VPC
353+ mtc0 t1, CP0_MVPCONTROL
354+ ehb
355+
356+ /* Loop through each VPE */
357+ lw t6, COREBOOTCFG_VPEMASK(t0)
358+ move t8, t6
359+ li t5, 0
360+
361+ /* Check whether the VPE should be running. If not, skip it */
362+1: andi t0, t6, 1
363+ beqz t0, 2f
364+ nop
365+
366+ /* Operate on the appropriate TC */
367+ mfc0 t0, CP0_VPECONTROL
368+ ori t0, t0, VPECONTROL_TARGTC
369+ xori t0, t0, VPECONTROL_TARGTC
370+ or t0, t0, t5
371+ mtc0 t0, CP0_VPECONTROL
372+ ehb
373+
374+ /* Skip the VPE if its TC is not halted */
375+ mftc0 t0, CP0_TCHALT
376+ beqz t0, 2f
377+ nop
378+
379+ /* Calculate a pointer to the VPEs struct vpe_boot_config */
380+ li t0, VPEBOOTCFG_SIZE
381+ mul t0, t0, t5
382+ addu t0, t0, t7
383+
384+ /* Set the TC restart PC */
385+ lw t1, VPEBOOTCFG_PC(t0)
386+ mttc0 t1, CP0_TCRESTART
387+
388+ /* Set the TC stack pointer */
389+ lw t1, VPEBOOTCFG_SP(t0)
390+ mttgpr t1, sp
391+
392+ /* Set the TC global pointer */
393+ lw t1, VPEBOOTCFG_GP(t0)
394+ mttgpr t1, gp
395+
396+ /* Copy config from this VPE */
397+ mfc0 t0, CP0_CONFIG
398+ mttc0 t0, CP0_CONFIG
399+
400+ /* Ensure no software interrupts are pending */
401+ mttc0 zero, CP0_CAUSE
402+ mttc0 zero, CP0_STATUS
403+
404+ /* Set TC active, not interrupt exempt */
405+ mftc0 t0, CP0_TCSTATUS
406+ li t1, ~TCSTATUS_IXMT
407+ and t0, t0, t1
408+ ori t0, t0, TCSTATUS_A
409+ mttc0 t0, CP0_TCSTATUS
410+
411+ /* Clear the TC halt bit */
412+ mttc0 zero, CP0_TCHALT
413+
414+ /* Set VPE active */
415+ mftc0 t0, CP0_VPECONF0
416+ ori t0, t0, VPECONF0_VPA
417+ mttc0 t0, CP0_VPECONF0
418+
419+ /* Next VPE */
420+2: srl t6, t6, 1
421+ addi t5, t5, 1
422+ bnez t6, 1b
423+ nop
424+
425+ /* Leave VPE configuration state */
426+ mfc0 t1, CP0_MVPCONTROL
427+ xori t1, t1, MVPCONTROL_VPC
428+ mtc0 t1, CP0_MVPCONTROL
429+ ehb
430+ evpe
431+
432+ /* Check whether this VPE is meant to be running */
433+ li t0, 1
434+ sll t0, t0, t9
435+ and t0, t0, t8
436+ bnez t0, 2f
437+ nop
438+
439+ /* This VPE should be offline, halt the TC */
440+ li t0, TCHALT_H
441+ mtc0 t0, CP0_TCHALT
442+ la t0, 1f
443+1: jr.hb t0
444+ nop
445+
446+2: .set pop
447+
448+#endif /* CONFIG_MIPS_MT */
449+
450+ /* Return */
451+ jr ra
452+ nop
453+ END(mips_cps_boot_vpes)
454+
455+#if defined(CONFIG_MIPS_CPS_PM) && defined(CONFIG_CPU_PM)
456+
457+ /* Calculate a pointer to this CPUs struct mips_static_suspend_state */
458+ .macro psstate dest
459+ .set push
460+ .set noat
461+ lw $1, TI_CPU(gp)
462+ sll $1, $1, LONGLOG
463+ la \dest, __per_cpu_offset
464+ addu $1, $1, \dest
465+ lw $1, 0($1)
466+ la \dest, cps_cpu_state
467+ addu \dest, \dest, $1
468+ .set pop
469+ .endm
470+
471+LEAF(mips_cps_pm_save)
472+ /* Save CPU state */
473+ SUSPEND_SAVE_REGS
474+ psstate t1
475+ SUSPEND_SAVE_STATIC
476+ jr v0
477+ nop
478+ END(mips_cps_pm_save)
479+
480+LEAF(mips_cps_pm_restore)
481+ /* Restore CPU state */
482+ psstate t1
483+ RESUME_RESTORE_STATIC
484+ RESUME_RESTORE_REGS_RETURN
485+ END(mips_cps_pm_restore)
486+
487+#endif /* CONFIG_MIPS_CPS_PM && CONFIG_CPU_PM */
arch/mips/kernel/cpu-probe.c+4−17
@@ -62,7 +62,7 @@ static inline void check_errata(void) · 61 unmodified lines
6262 case CPU_34K:
6363 /*
6464 * Erratum "RPS May Cause Incorrect Instruction Execution"
65− * This code only handles VPE0, any SMP/SMTC/RTOS code
65+ * This code only handles VPE0, any SMP/RTOS code
6666 * making use of VPE1 will be responsable for that VPE.
6767 */
6868 if ((c->processor_id & PRID_REV_MASK) <= PRID_REV_34K_V1_0_2)
@@ -423,7 +423,7 @@ static void decode_configs(struct cpuinfo_mips *c) · 354 unmodified lines
423423
424424 #ifndef CONFIG_MIPS_CPS
425425 if (cpu_has_mips_r2) {
426− c->core = read_c0_ebase() & 0x3ff;
426+ c->core = get_ebase_cpunum();
427427 if (cpu_has_mipsmt)
428428 c->core >>= fls(core_nvpes()) - 1;
429429 }
@@ -684,21 +684,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) · 254 unmodified lines
684684 */
685685 c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48;
686686 break;
687− case PRID_IMP_RM9000:
688− c->cputype = CPU_RM9000;
689− __cpu_name[cpu] = "RM9000";
690− set_isa(c, MIPS_CPU_ISA_IV);
691− c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
692− MIPS_CPU_LLSC;
693− /*
694− * Bit 29 in the info register of the RM9000
695− * indicates if the TLB has 48 or 64 entries.
696− *
697− * 29 1 => 64 entry JTLB
698− * 0 => 48 entry JTLB
699− */
700− c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48;
701− break;
702687 case PRID_IMP_R8000:
703688 c->cputype = CPU_R8000;
704689 __cpu_name[cpu] = "RM8000";
@@ -1041,6 +1026,7 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu) · 336 unmodified lines
10411026 decode_configs(c);
10421027 /* JZRISC does not implement the CP0 counter. */
10431028 c->options &= ~MIPS_CPU_COUNTER;
1029+ BUG_ON(!__builtin_constant_p(cpu_has_counter) || cpu_has_counter);
10441030 switch (c->processor_id & PRID_IMP_MASK) {
10451031 case PRID_IMP_JZRISC:
10461032 c->cputype = CPU_JZRISC;
@@ -1074,6 +1060,7 @@ static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu) · 27 unmodified lines
10741060 switch (c->processor_id & PRID_IMP_MASK) {
10751061 case PRID_IMP_NETLOGIC_XLP2XX:
10761062 case PRID_IMP_NETLOGIC_XLP9XX:
1063+ case PRID_IMP_NETLOGIC_XLP5XX:
10771064 c->cputype = CPU_XLP;
10781065 __cpu_name[cpu] = "Broadcom XLPII";
10791066 break;
arch/mips/kernel/entry.S+0−38
@@ -16,9 +16,6 @@ · 15 unmodified lines
1616 #include <asm/isadep.h>
1717 #include <asm/thread_info.h>
1818 #include <asm/war.h>
19−#ifdef CONFIG_MIPS_MT_SMTC
20−#include <asm/mipsmtregs.h>
21−#endif
2219
2320 #ifndef CONFIG_PREEMPT
2421 #define resume_kernel restore_all
@@ -89,41 +86,6 @@ FEXPORT(syscall_exit) · 64 unmodified lines
8986 bnez t0, syscall_exit_work
9087
9188 restore_all: # restore full frame
92−#ifdef CONFIG_MIPS_MT_SMTC
93−#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
94−/* Re-arm any temporarily masked interrupts not explicitly "acked" */
95− mfc0 v0, CP0_TCSTATUS
96− ori v1, v0, TCSTATUS_IXMT
97− mtc0 v1, CP0_TCSTATUS
98− andi v0, TCSTATUS_IXMT
99− _ehb
100− mfc0 t0, CP0_TCCONTEXT
101− DMT 9 # dmt t1
102− jal mips_ihb
103− mfc0 t2, CP0_STATUS
104− andi t3, t0, 0xff00
105− or t2, t2, t3
106− mtc0 t2, CP0_STATUS
107− _ehb
108− andi t1, t1, VPECONTROL_TE
109− beqz t1, 1f
110− EMT
111−1:
112− mfc0 v1, CP0_TCSTATUS
113− /* We set IXMT above, XOR should clear it here */
114− xori v1, v1, TCSTATUS_IXMT
115− or v1, v0, v1
116− mtc0 v1, CP0_TCSTATUS
117− _ehb
118− xor t0, t0, t3
119− mtc0 t0, CP0_TCCONTEXT
120−#endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */
121−/* Detect and execute deferred IPI "interrupts" */
122− LONG_L s0, TI_REGS($28)
123− LONG_S sp, TI_REGS($28)
124− jal deferred_smtc_ipi
125− LONG_S s0, TI_REGS($28)
126−#endif /* CONFIG_MIPS_MT_SMTC */
12789 .set noat
12890 RESTORE_TEMP
12991 RESTORE_AT
arch/mips/kernel/genex.S+0−54
@@ -21,20 +21,6 @@ · 20 unmodified lines
2121 #include <asm/war.h>
2222 #include <asm/thread_info.h>
2323
24−#ifdef CONFIG_MIPS_MT_SMTC
25−#define PANIC_PIC(msg) \
26− .set push; \
27− .set nomicromips; \
28− .set reorder; \
29− PTR_LA a0,8f; \
30− .set noat; \
31− PTR_LA AT, panic; \
32− jr AT; \
33−9: b 9b; \
34− .set pop; \
35− TEXT(msg)
36−#endif
37−
3824 __INIT
3925
4026 /*
@@ -251,15 +237,6 @@ NESTED(except_vec_vi, 0, sp) · 210 unmodified lines
251237 SAVE_AT
252238 .set push
253239 .set noreorder
254−#ifdef CONFIG_MIPS_MT_SMTC
255− /*
256− * To keep from blindly blocking *all* interrupts
257− * during service by SMTC kernel, we also want to
258− * pass the IM value to be cleared.
259− */
260−FEXPORT(except_vec_vi_mori)
261− ori a0, $0, 0
262−#endif /* CONFIG_MIPS_MT_SMTC */
263240 PTR_LA v1, except_vec_vi_handler
264241 FEXPORT(except_vec_vi_lui)
265242 lui v0, 0 /* Patched */
@@ -277,37 +254,10 @@ EXPORT(except_vec_vi_end) · 11 unmodified lines
277254 NESTED(except_vec_vi_handler, 0, sp)
278255 SAVE_TEMP
279256 SAVE_STATIC
280−#ifdef CONFIG_MIPS_MT_SMTC
281− /*
282− * SMTC has an interesting problem that interrupts are level-triggered,
283− * and the CLI macro will clear EXL, potentially causing a duplicate
284− * interrupt service invocation. So we need to clear the associated
285− * IM bit of Status prior to doing CLI, and restore it after the
286− * service routine has been invoked - we must assume that the
287− * service routine will have cleared the state, and any active
288− * level represents a new or otherwised unserviced event...
289− */
290− mfc0 t1, CP0_STATUS
291− and t0, a0, t1
292−#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
293− mfc0 t2, CP0_TCCONTEXT
294− or t2, t0, t2
295− mtc0 t2, CP0_TCCONTEXT
296−#endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */
297− xor t1, t1, t0
298− mtc0 t1, CP0_STATUS
299− _ehb
300−#endif /* CONFIG_MIPS_MT_SMTC */
301257 CLI
302258 #ifdef CONFIG_TRACE_IRQFLAGS
303259 move s0, v0
304−#ifdef CONFIG_MIPS_MT_SMTC
305− move s1, a0
306−#endif
307260 TRACE_IRQS_OFF
308−#ifdef CONFIG_MIPS_MT_SMTC
309− move a0, s1
310−#endif
311261 move v0, s0
312262 #endif
313263
@@ -496,9 +446,6 @@ NESTED(nmi_handler, PT_SIZE, sp) · 182 unmodified lines
496446
497447 .align 5
498448 LEAF(handle_ri_rdhwr_vivt)
499−#ifdef CONFIG_MIPS_MT_SMTC
500− PANIC_PIC("handle_ri_rdhwr_vivt called")
501−#else
502449 .set push
503450 .set noat
504451 .set noreorder
@@ -517,7 +464,6 @@ NESTED(nmi_handler, PT_SIZE, sp) · 12 unmodified lines
517464 .set pop
518465 bltz k1, handle_ri /* slow path */
519466 /* fall thru */
520−#endif
521467 END(handle_ri_rdhwr_vivt)
522468
523469 LEAF(handle_ri_rdhwr)
arch/mips/kernel/head.S+0−56
@@ -35,33 +35,12 @@ · 34 unmodified lines
3535 */
3636 .macro setup_c0_status set clr
3737 .set push
38−#ifdef CONFIG_MIPS_MT_SMTC
39− /*
40− * For SMTC, we need to set privilege and disable interrupts only for
41− * the current TC, using the TCStatus register.
42− */
43− mfc0 t0, CP0_TCSTATUS
44− /* Fortunately CU 0 is in the same place in both registers */
45− /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */
46− li t1, ST0_CU0 | 0x08001c00
47− or t0, t1
48− /* Clear TKSU, leave IXMT */
49− xori t0, 0x00001800
50− mtc0 t0, CP0_TCSTATUS
51− _ehb
52− /* We need to leave the global IE bit set, but clear EXL...*/
53− mfc0 t0, CP0_STATUS
54− or t0, ST0_CU0 | ST0_EXL | ST0_ERL | \set | \clr
55− xor t0, ST0_EXL | ST0_ERL | \clr
56− mtc0 t0, CP0_STATUS
57−#else
5838 mfc0 t0, CP0_STATUS
5939 or t0, ST0_CU0|\set|0x1f|\clr
6040 xor t0, 0x1f|\clr
6141 mtc0 t0, CP0_STATUS
6242 .set noreorder
6343 sll zero,3 # ehb
64−#endif
6544 .set pop
6645 .endm
6746
@@ -115,24 +94,6 @@ NESTED(kernel_entry, 16, sp) # kernel entry point · 47 unmodified lines
11594 jr t0
11695 0:
11796
118−#ifdef CONFIG_MIPS_MT_SMTC
119− /*
120− * In SMTC kernel, "CLI" is thread-specific, in TCStatus.
121− * We still need to enable interrupts globally in Status,
122− * and clear EXL/ERL.
123− *
124− * TCContext is used to track interrupt levels under
125− * service in SMTC kernel. Clear for boot TC before
126− * allowing any interrupts.
127− */
128− mtc0 zero, CP0_TCCONTEXT
129−
130− mfc0 t0, CP0_STATUS
131− ori t0, t0, 0xff1f
132− xori t0, t0, 0x001e
133− mtc0 t0, CP0_STATUS
134−#endif /* CONFIG_MIPS_MT_SMTC */
135−
13697 PTR_LA t0, __bss_start # clear .bss
13798 LONG_S zero, (t0)
13899 PTR_LA t1, __bss_stop - LONGSIZE
@@ -164,25 +125,8 @@ NESTED(kernel_entry, 16, sp) # kernel entry point · 25 unmodified lines
164125 * function after setting up the stack and gp registers.
165126 */
166127 NESTED(smp_bootstrap, 16, sp)
167−#ifdef CONFIG_MIPS_MT_SMTC
168− /*
169− * Read-modify-writes of Status must be atomic, and this
170− * is one case where CLI is invoked without EXL being
171− * necessarily set. The CLI and setup_c0_status will
172− * in fact be redundant for all but the first TC of
173− * each VPE being booted.
174− */
175− DMT 10 # dmt t2 /* t0, t1 are used by CLI and setup_c0_status() */
176− jal mips_ihb
177−#endif /* CONFIG_MIPS_MT_SMTC */
178128 smp_slave_setup
179129 setup_c0_status_sec
180−#ifdef CONFIG_MIPS_MT_SMTC
181− andi t2, t2, VPECONTROL_TE
182− beqz t2, 2f
183− EMT # emt
184−2:
185−#endif /* CONFIG_MIPS_MT_SMTC */
186130 j start_secondary
187131 END(smp_bootstrap)
188132 #endif /* CONFIG_SMP */
arch/mips/kernel/i8259.c+0−4
@@ -42,9 +42,6 @@ static struct irq_chip i8259A_chip = { · 41 unmodified lines
4242 .irq_disable = disable_8259A_irq,
4343 .irq_unmask = enable_8259A_irq,
4444 .irq_mask_ack = mask_and_ack_8259A,
45−#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
46− .irq_set_affinity = plat_set_irq_affinity,
47−#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
4845 };
4946
5047 /*
@@ -180,7 +177,6 @@ handle_real_irq: · 129 unmodified lines
180177 outb(cached_master_mask, PIC_MASTER_IMR);
181178 outb(0x60+irq, PIC_MASTER_CMD); /* 'Specific EOI to master */
182179 }
183− smtc_im_ack_irq(irq);
184180 raw_spin_unlock_irqrestore(&i8259A_lock, flags);
185181 return;
186182
arch/mips/kernel/idle.c+11−14
@@ -224,29 +224,26 @@ void __init check_wait(void) · 223 unmodified lines
224224 cpu_wait = r4k_wait;
225225 */
226226 break;
227− case CPU_RM9000:
228− if ((c->processor_id & 0x00ff) >= 0x40)
229− cpu_wait = r4k_wait;
230− break;
231227 default:
232228 break;
233229 }
234230 }
235231
236−static void smtc_idle_hook(void)
237−{
238−#ifdef CONFIG_MIPS_MT_SMTC
239− void smtc_idle_loop_hook(void);
240−
241− smtc_idle_loop_hook();
242−#endif
243−}
244−
245232 void arch_cpu_idle(void)
246233 {
247− smtc_idle_hook();
248234 if (cpu_wait)
249235 cpu_wait();
250236 else
251237 local_irq_enable();
252238 }
239+
240+#ifdef CONFIG_CPU_IDLE
241+
242+int mips_cpuidle_wait_enter(struct cpuidle_device *dev,
243+ struct cpuidle_driver *drv, int index)
244+{
245+ arch_cpu_idle();
246+ return index;
247+}
248+
249+#endif
arch/mips/kernel/irq-gic.c+15−0
@@ -54,6 +54,21 @@ void gic_write_compare(cycle_t cnt) · 53 unmodified lines
5454 (int)(cnt & 0xffffffff));
5555 }
5656
57+void gic_write_cpu_compare(cycle_t cnt, int cpu)
58+{
59+ unsigned long flags;
60+
61+ local_irq_save(flags);
62+
63+ GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu);
64+ GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI),
65+ (int)(cnt >> 32));
66+ GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO),
67+ (int)(cnt & 0xffffffff));
68+
69+ local_irq_restore(flags);
70+}
71+
5772 cycle_t gic_read_compare(void)
5873 {
5974 unsigned int hi, lo;
arch/mips/kernel/irq-msc01.c+0−5
@@ -53,13 +53,9 @@ static inline void unmask_msc_irq(struct irq_data *d) · 52 unmodified lines
5353 */
5454 static void level_mask_and_ack_msc_irq(struct irq_data *d)
5555 {
56− unsigned int irq = d->irq;
57−
5856 mask_msc_irq(d);
5957 if (!cpu_has_veic)
6058 MSCIC_WRITE(MSC01_IC_EOI, 0);
61− /* This actually needs to be a call into platform code */
62− smtc_im_ack_irq(irq);
6359 }
6460
6561 /*
@@ -78,7 +74,6 @@ static void edge_mask_and_ack_msc_irq(struct irq_data *d) · 12 unmodified lines
7874 MSCIC_WRITE(MSC01_IC_SUP+irq*8, r | ~MSC01_IC_SUP_EDGE_BIT);
7975 MSCIC_WRITE(MSC01_IC_SUP+irq*8, r);
8076 }
81− smtc_im_ack_irq(irq);
8277 }
8378
8479 /*
arch/mips/kernel/irq.c+0−17
@@ -73,7 +73,6 @@ void free_irqno(unsigned int irq) · 72 unmodified lines
7373 */
7474 void ack_bad_irq(unsigned int irq)
7575 {
76− smtc_im_ack_irq(irq);
7776 printk("unexpected IRQ # %d\n", irq);
7877 }
7978
@@ -142,23 +141,7 @@ void __irq_entry do_IRQ(unsigned int irq) · 62 unmodified lines
142141 {
143142 irq_enter();
144143 check_stack_overflow();
145− if (!smtc_handle_on_other_cpu(irq))
146− generic_handle_irq(irq);
147− irq_exit();
148−}
149−
150−#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
151−/*
152− * To avoid inefficient and in some cases pathological re-checking of
153− * IRQ affinity, we have this variant that skips the affinity check.
154− */
155−
156−void __irq_entry do_IRQ_no_affinity(unsigned int irq)
157−{
158− irq_enter();
159− smtc_im_backstop(irq);
160144 generic_handle_irq(irq);
161145 irq_exit();
162146 }
163147
164−#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
arch/mips/kernel/mips-cpc.c+28−0
@@ -9,12 +9,18 @@ · 8 unmodified lines
99 */
1010
1111 #include <linux/errno.h>
12+#include <linux/percpu.h>
13+#include <linux/spinlock.h>
1214
1315 #include <asm/mips-cm.h>
1416 #include <asm/mips-cpc.h>
1517
1618 void __iomem *mips_cpc_base;
1719
20+static DEFINE_PER_CPU_ALIGNED(spinlock_t, cpc_core_lock);
21+
22+static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags);
23+
1824 phys_t __weak mips_cpc_phys_base(void)
1925 {
2026 u32 cpc_base;
@@ -39,6 +45,10 @@ phys_t __weak mips_cpc_phys_base(void) · 18 unmodified lines
3945 int mips_cpc_probe(void)
4046 {
4147 phys_t addr;
48+ unsigned cpu;
49+
50+ for_each_possible_cpu(cpu)
51+ spin_lock_init(&per_cpu(cpc_core_lock, cpu));
4252
4353 addr = mips_cpc_phys_base();
4454 if (!addr)
@@ -50,3 +60,21 @@ int mips_cpc_probe(void) · 5 unmodified lines
5060
5161 return 0;
5262 }
63+
64+void mips_cpc_lock_other(unsigned int core)
65+{
66+ unsigned curr_core;
67+ preempt_disable();
68+ curr_core = current_cpu_data.core;
69+ spin_lock_irqsave(&per_cpu(cpc_core_lock, curr_core),
70+ per_cpu(cpc_core_lock_flags, curr_core));
71+ write_cpc_cl_other(core << CPC_Cx_OTHER_CORENUM_SHF);
72+}
73+
74+void mips_cpc_unlock_other(void)
75+{
76+ unsigned curr_core = current_cpu_data.core;
77+ spin_unlock_irqrestore(&per_cpu(cpc_core_lock, curr_core),
78+ per_cpu(cpc_core_lock_flags, curr_core));
79+ preempt_enable();
80+}
arch/mips/kernel/mips-mt-fpaff.c+1−1
@@ -1,5 +1,5 @@
11 /*
2− * General MIPS MT support routines, usable in AP/SP, SMVP, or SMTC kernels
2+ * General MIPS MT support routines, usable in AP/SP and SMVP.
33 * Copyright (C) 2005 Mips Technologies, Inc
44 */
55 #include <linux/cpu.h>
arch/mips/kernel/mips-mt.c+1−17
@@ -1,5 +1,5 @@
11 /*
2− * General MIPS MT support routines, usable in AP/SP, SMVP, or SMTC kernels
2+ * General MIPS MT support routines, usable in AP/SP and SMVP.
33 * Copyright (C) 2005 Mips Technologies, Inc
44 */
55
@@ -57,9 +57,6 @@ void mips_mt_regdump(unsigned long mvpctl) · 51 unmodified lines
5757 int tc;
5858 unsigned long haltval;
5959 unsigned long tcstatval;
60−#ifdef CONFIG_MIPS_MT_SMTC
61− void smtc_soft_dump(void);
62−#endif /* CONFIG_MIPT_MT_SMTC */
6360
6461 local_irq_save(flags);
6562 vpflags = dvpe();
@@ -116,9 +113,6 @@ void mips_mt_regdump(unsigned long mvpctl) · 50 unmodified lines
116113 if (!haltval)
117114 write_tc_c0_tchalt(0);
118115 }
119−#ifdef CONFIG_MIPS_MT_SMTC
120− smtc_soft_dump();
121−#endif /* CONFIG_MIPT_MT_SMTC */
122116 printk("===========================\n");
123117 evpe(vpflags);
124118 local_irq_restore(flags);
@@ -295,21 +289,11 @@ void mips_mt_set_cpuoptions(void) · 170 unmodified lines
295289
296290 void mt_cflush_lockdown(void)
297291 {
298−#ifdef CONFIG_MIPS_MT_SMTC
299− void smtc_cflush_lockdown(void);
300−
301− smtc_cflush_lockdown();
302−#endif /* CONFIG_MIPS_MT_SMTC */
303292 /* FILL IN VSMP and AP/SP VERSIONS HERE */
304293 }
305294
306295 void mt_cflush_release(void)
307296 {
308−#ifdef CONFIG_MIPS_MT_SMTC
309− void smtc_cflush_release(void);
310−
311− smtc_cflush_release();
312−#endif /* CONFIG_MIPS_MT_SMTC */
313297 /* FILL IN VSMP and AP/SP VERSIONS HERE */
314298 }
315299
arch/mips/kernel/octeon_switch.S+61−23
@@ -10,24 +10,12 @@ · 9 unmodified lines
1010 * Copyright (C) 2000 MIPS Technologies, Inc.
1111 * written by Carsten Langgaard, carstenl@mips.com
1212 */
13−#include <asm/asm.h>
14−#include <asm/cachectl.h>
15−#include <asm/fpregdef.h>
16−#include <asm/mipsregs.h>
17−#include <asm/asm-offsets.h>
18−#include <asm/pgtable-bits.h>
19−#include <asm/regdef.h>
20−#include <asm/stackframe.h>
21−#include <asm/thread_info.h>
22−
23−#include <asm/asmmacro.h>
24−
25−/*
26− * Offset to the current process status flags, the first 32 bytes of the
27− * stack are not used.
28− */
29−#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS)
3013
14+#define USE_ALTERNATE_RESUME_IMPL 1
15+ .set push
16+ .set arch=mips64r2
17+#include "r4k_switch.S"
18+ .set pop
3119 /*
3220 * task_struct *resume(task_struct *prev, task_struct *next,
3321 * struct thread_info *next_ti, int usedfpu)
@@ -40,6 +28,61 @@ · 6 unmodified lines
4028 cpu_save_nonscratch a0
4129 LONG_S ra, THREAD_REG31(a0)
4230
31+ /*
32+ * check if we need to save FPU registers
33+ */
34+ PTR_L t3, TASK_THREAD_INFO(a0)
35+ LONG_L t0, TI_FLAGS(t3)
36+ li t1, _TIF_USEDFPU
37+ and t2, t0, t1
38+ beqz t2, 1f
39+ nor t1, zero, t1
40+
41+ and t0, t0, t1
42+ LONG_S t0, TI_FLAGS(t3)
43+
44+ /*
45+ * clear saved user stack CU1 bit
46+ */
47+ LONG_L t0, ST_OFF(t3)
48+ li t1, ~ST0_CU1
49+ and t0, t0, t1
50+ LONG_S t0, ST_OFF(t3)
51+
52+ .set push
53+ .set arch=mips64r2
54+ fpu_save_double a0 t0 t1 # c0_status passed in t0
55+ # clobbers t1
56+ .set pop
57+1:
58+
59+ /* check if we need to save COP2 registers */
60+ PTR_L t2, TASK_THREAD_INFO(a0)
61+ LONG_L t0, ST_OFF(t2)
62+ bbit0 t0, 30, 1f
63+
64+ /* Disable COP2 in the stored process state */
65+ li t1, ST0_CU2
66+ xor t0, t1
67+ LONG_S t0, ST_OFF(t2)
68+
69+ /* Enable COP2 so we can save it */
70+ mfc0 t0, CP0_STATUS
71+ or t0, t1
72+ mtc0 t0, CP0_STATUS
73+
74+ /* Save COP2 */
75+ daddu a0, THREAD_CP2
76+ jal octeon_cop2_save
77+ dsubu a0, THREAD_CP2
78+
79+ /* Disable COP2 now that we are done */
80+ mfc0 t0, CP0_STATUS
81+ li t1, ST0_CU2
82+ xor t0, t1
83+ mtc0 t0, CP0_STATUS
84+
85+1:
4386 #if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
4487 /* Check if we need to store CVMSEG state */
4588 mfc0 t0, $11,7 /* CvmMemCtl */
@@ -85,12 +128,7 @@ · 39 unmodified lines
85128 move $28, a2
86129 cpu_restore_nonscratch a1
87130
88−#if (_THREAD_SIZE - 32) < 0x8000
89− PTR_ADDIU t0, $28, _THREAD_SIZE - 32
90−#else
91− PTR_LI t0, _THREAD_SIZE - 32
92− PTR_ADDU t0, $28
93−#endif
131+ PTR_ADDU t0, $28, _THREAD_SIZE - 32
94132 set_saved_sp t0, t1, t2
95133
96134 mfc0 t1, CP0_STATUS /* Do we really need this? */
arch/mips/kernel/pm-cps.c+716−0
@@ -0,0 +1,716 @@
1+/*
2+ * Copyright (C) 2014 Imagination Technologies
3+ * Author: Paul Burton <paul.burton@imgtec.com>
4+ *
5+ * This program is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License as published by the
7+ * Free Software Foundation; either version 2 of the License, or (at your
8+ * option) any later version.
9+ */
10+
11+#include <linux/init.h>
12+#include <linux/percpu.h>
13+#include <linux/slab.h>
14+
15+#include <asm/asm-offsets.h>
16+#include <asm/cacheflush.h>
17+#include <asm/cacheops.h>
18+#include <asm/idle.h>
19+#include <asm/mips-cm.h>
20+#include <asm/mips-cpc.h>
21+#include <asm/mipsmtregs.h>
22+#include <asm/pm.h>
23+#include <asm/pm-cps.h>
24+#include <asm/smp-cps.h>
25+#include <asm/uasm.h>
26+
27+/*
28+ * cps_nc_entry_fn - type of a generated non-coherent state entry function
29+ * @online: the count of online coupled VPEs
30+ * @nc_ready_count: pointer to a non-coherent mapping of the core ready_count
31+ *
32+ * The code entering & exiting non-coherent states is generated at runtime
33+ * using uasm, in order to ensure that the compiler cannot insert a stray
34+ * memory access at an unfortunate time and to allow the generation of optimal
35+ * core-specific code particularly for cache routines. If coupled_coherence
36+ * is non-zero and this is the entry function for the CPS_PM_NC_WAIT state,
37+ * returns the number of VPEs that were in the wait state at the point this
38+ * VPE left it. Returns garbage if coupled_coherence is zero or this is not
39+ * the entry function for CPS_PM_NC_WAIT.
40+ */
41+typedef unsigned (*cps_nc_entry_fn)(unsigned online, u32 *nc_ready_count);
42+
43+/*
44+ * The entry point of the generated non-coherent idle state entry/exit
45+ * functions. Actually per-core rather than per-CPU.
46+ */
47+static DEFINE_PER_CPU_READ_MOSTLY(cps_nc_entry_fn[CPS_PM_STATE_COUNT],
48+ nc_asm_enter);
49+
50+/* Bitmap indicating which states are supported by the system */
51+DECLARE_BITMAP(state_support, CPS_PM_STATE_COUNT);
52+
53+/*
54+ * Indicates the number of coupled VPEs ready to operate in a non-coherent
55+ * state. Actually per-core rather than per-CPU.
56+ */
57+static DEFINE_PER_CPU_ALIGNED(u32*, ready_count);
58+static DEFINE_PER_CPU_ALIGNED(void*, ready_count_alloc);
59+
60+/* Indicates online CPUs coupled with the current CPU */
61+static DEFINE_PER_CPU_ALIGNED(cpumask_t, online_coupled);
62+
63+/*
64+ * Used to synchronize entry to deep idle states. Actually per-core rather
65+ * than per-CPU.
66+ */
67+static DEFINE_PER_CPU_ALIGNED(atomic_t, pm_barrier);
68+
69+/* Saved CPU state across the CPS_PM_POWER_GATED state */
70+DEFINE_PER_CPU_ALIGNED(struct mips_static_suspend_state, cps_cpu_state);
71+
72+/* A somewhat arbitrary number of labels & relocs for uasm */
73+static struct uasm_label labels[32] __initdata;
74+static struct uasm_reloc relocs[32] __initdata;
75+
76+/* CPU dependant sync types */
77+static unsigned stype_intervention;
78+static unsigned stype_memory;
79+static unsigned stype_ordering;
80+
81+enum mips_reg {
82+ zero, at, v0, v1, a0, a1, a2, a3,
83+ t0, t1, t2, t3, t4, t5, t6, t7,
84+ s0, s1, s2, s3, s4, s5, s6, s7,
85+ t8, t9, k0, k1, gp, sp, fp, ra,
86+};
87+
88+bool cps_pm_support_state(enum cps_pm_state state)
89+{
90+ return test_bit(state, state_support);
91+}
92+
93+static void coupled_barrier(atomic_t *a, unsigned online)
94+{
95+ /*
96+ * This function is effectively the same as
97+ * cpuidle_coupled_parallel_barrier, which can't be used here since
98+ * there's no cpuidle device.
99+ */
100+
101+ if (!coupled_coherence)
102+ return;
103+
104+ smp_mb__before_atomic_inc();
105+ atomic_inc(a);
106+
107+ while (atomic_read(a) < online)
108+ cpu_relax();
109+
110+ if (atomic_inc_return(a) == online * 2) {
111+ atomic_set(a, 0);
112+ return;
113+ }
114+
115+ while (atomic_read(a) > online)
116+ cpu_relax();
117+}
118+
119+int cps_pm_enter_state(enum cps_pm_state state)
120+{
121+ unsigned cpu = smp_processor_id();
122+ unsigned core = current_cpu_data.core;
123+ unsigned online, left;
124+ cpumask_t *coupled_mask = this_cpu_ptr(&online_coupled);
125+ u32 *core_ready_count, *nc_core_ready_count;
126+ void *nc_addr;
127+ cps_nc_entry_fn entry;
128+ struct core_boot_config *core_cfg;
129+ struct vpe_boot_config *vpe_cfg;
130+
131+ /* Check that there is an entry function for this state */
132+ entry = per_cpu(nc_asm_enter, core)[state];
133+ if (!entry)
134+ return -EINVAL;
135+
136+ /* Calculate which coupled CPUs (VPEs) are online */
137+#ifdef CONFIG_MIPS_MT
138+ if (cpu_online(cpu)) {
139+ cpumask_and(coupled_mask, cpu_online_mask,
140+ &cpu_sibling_map[cpu]);
141+ online = cpumask_weight(coupled_mask);
142+ cpumask_clear_cpu(cpu, coupled_mask);
143+ } else
144+#endif
145+ {
146+ cpumask_clear(coupled_mask);
147+ online = 1;
148+ }
149+
150+ /* Setup the VPE to run mips_cps_pm_restore when started again */
151+ if (config_enabled(CONFIG_CPU_PM) && state == CPS_PM_POWER_GATED) {
152+ core_cfg = &mips_cps_core_bootcfg[core];
153+ vpe_cfg = &core_cfg->vpe_config[current_cpu_data.vpe_id];
154+ vpe_cfg->pc = (unsigned long)mips_cps_pm_restore;
155+ vpe_cfg->gp = (unsigned long)current_thread_info();
156+ vpe_cfg->sp = 0;
157+ }
158+
159+ /* Indicate that this CPU might not be coherent */
160+ cpumask_clear_cpu(cpu, &cpu_coherent_mask);
161+ smp_mb__after_clear_bit();
162+
163+ /* Create a non-coherent mapping of the core ready_count */
164+ core_ready_count = per_cpu(ready_count, core);
165+ nc_addr = kmap_noncoherent(virt_to_page(core_ready_count),
166+ (unsigned long)core_ready_count);
167+ nc_addr += ((unsigned long)core_ready_count & ~PAGE_MASK);
168+ nc_core_ready_count = nc_addr;
169+
170+ /* Ensure ready_count is zero-initialised before the assembly runs */
171+ ACCESS_ONCE(*nc_core_ready_count) = 0;
172+ coupled_barrier(&per_cpu(pm_barrier, core), online);
173+
174+ /* Run the generated entry code */
175+ left = entry(online, nc_core_ready_count);
176+
177+ /* Remove the non-coherent mapping of ready_count */
178+ kunmap_noncoherent();
179+
180+ /* Indicate that this CPU is definitely coherent */
181+ cpumask_set_cpu(cpu, &cpu_coherent_mask);
182+
183+ /*
184+ * If this VPE is the first to leave the non-coherent wait state then
185+ * it needs to wake up any coupled VPEs still running their wait
186+ * instruction so that they return to cpuidle, which can then complete
187+ * coordination between the coupled VPEs & provide the governor with
188+ * a chance to reflect on the length of time the VPEs were in the
189+ * idle state.
190+ */
191+ if (coupled_coherence && (state == CPS_PM_NC_WAIT) && (left == online))
192+ arch_send_call_function_ipi_mask(coupled_mask);
193+
194+ return 0;
195+}
196+
197+static void __init cps_gen_cache_routine(u32 **pp, struct uasm_label **pl,
198+ struct uasm_reloc **pr,
199+ const struct cache_desc *cache,
200+ unsigned op, int lbl)
201+{
202+ unsigned cache_size = cache->ways << cache->waybit;
203+ unsigned i;
204+ const unsigned unroll_lines = 32;
205+
206+ /* If the cache isn't present this function has it easy */
207+ if (cache->flags & MIPS_CACHE_NOT_PRESENT)
208+ return;
209+
210+ /* Load base address */
211+ UASM_i_LA(pp, t0, (long)CKSEG0);
212+
213+ /* Calculate end address */
214+ if (cache_size < 0x8000)
215+ uasm_i_addiu(pp, t1, t0, cache_size);
216+ else
217+ UASM_i_LA(pp, t1, (long)(CKSEG0 + cache_size));
218+
219+ /* Start of cache op loop */
220+ uasm_build_label(pl, *pp, lbl);
221+
222+ /* Generate the cache ops */
223+ for (i = 0; i < unroll_lines; i++)
224+ uasm_i_cache(pp, op, i * cache->linesz, t0);
225+
226+ /* Update the base address */
227+ uasm_i_addiu(pp, t0, t0, unroll_lines * cache->linesz);
228+
229+ /* Loop if we haven't reached the end address yet */
230+ uasm_il_bne(pp, pr, t0, t1, lbl);
231+ uasm_i_nop(pp);
232+}
233+
234+static int __init cps_gen_flush_fsb(u32 **pp, struct uasm_label **pl,
235+ struct uasm_reloc **pr,
236+ const struct cpuinfo_mips *cpu_info,
237+ int lbl)
238+{
239+ unsigned i, fsb_size = 8;
240+ unsigned num_loads = (fsb_size * 3) / 2;
241+ unsigned line_stride = 2;
242+ unsigned line_size = cpu_info->dcache.linesz;
243+ unsigned perf_counter, perf_event;
244+ unsigned revision = cpu_info->processor_id & PRID_REV_MASK;
245+
246+ /*
247+ * Determine whether this CPU requires an FSB flush, and if so which
248+ * performance counter/event reflect stalls due to a full FSB.
249+ */
250+ switch (__get_cpu_type(cpu_info->cputype)) {
251+ case CPU_INTERAPTIV:
252+ perf_counter = 1;
253+ perf_event = 51;
254+ break;
255+
256+ case CPU_PROAPTIV:
257+ /* Newer proAptiv cores don't require this workaround */
258+ if (revision >= PRID_REV_ENCODE_332(1, 1, 0))
259+ return 0;
260+
261+ /* On older ones it's unavailable */
262+ return -1;
263+
264+ /* CPUs which do not require the workaround */
265+ case CPU_P5600:
266+ return 0;
267+
268+ default:
269+ WARN_ONCE(1, "pm-cps: FSB flush unsupported for this CPU\n");
270+ return -1;
271+ }
272+
273+ /*
274+ * Ensure that the fill/store buffer (FSB) is not holding the results
275+ * of a prefetch, since if it is then the CPC sequencer may become
276+ * stuck in the D3 (ClrBus) state whilst entering a low power state.
277+ */
278+
279+ /* Preserve perf counter setup */
280+ uasm_i_mfc0(pp, t2, 25, (perf_counter * 2) + 0); /* PerfCtlN */
281+ uasm_i_mfc0(pp, t3, 25, (perf_counter * 2) + 1); /* PerfCntN */
282+
283+ /* Setup perf counter to count FSB full pipeline stalls */
284+ uasm_i_addiu(pp, t0, zero, (perf_event << 5) | 0xf);
285+ uasm_i_mtc0(pp, t0, 25, (perf_counter * 2) + 0); /* PerfCtlN */
286+ uasm_i_ehb(pp);
287+ uasm_i_mtc0(pp, zero, 25, (perf_counter * 2) + 1); /* PerfCntN */
288+ uasm_i_ehb(pp);
289+
290+ /* Base address for loads */
291+ UASM_i_LA(pp, t0, (long)CKSEG0);
292+
293+ /* Start of clear loop */
294+ uasm_build_label(pl, *pp, lbl);
295+
296+ /* Perform some loads to fill the FSB */
297+ for (i = 0; i < num_loads; i++)
298+ uasm_i_lw(pp, zero, i * line_size * line_stride, t0);
299+
300+ /*
301+ * Invalidate the new D-cache entries so that the cache will need
302+ * refilling (via the FSB) if the loop is executed again.
303+ */
304+ for (i = 0; i < num_loads; i++) {
305+ uasm_i_cache(pp, Hit_Invalidate_D,
306+ i * line_size * line_stride, t0);
307+ uasm_i_cache(pp, Hit_Writeback_Inv_SD,
308+ i * line_size * line_stride, t0);
309+ }
310+
311+ /* Completion barrier */
312+ uasm_i_sync(pp, stype_memory);
313+ uasm_i_ehb(pp);
314+
315+ /* Check whether the pipeline stalled due to the FSB being full */
316+ uasm_i_mfc0(pp, t1, 25, (perf_counter * 2) + 1); /* PerfCntN */
317+
318+ /* Loop if it didn't */
319+ uasm_il_beqz(pp, pr, t1, lbl);
320+ uasm_i_nop(pp);
321+
322+ /* Restore perf counter 1. The count may well now be wrong... */
323+ uasm_i_mtc0(pp, t2, 25, (perf_counter * 2) + 0); /* PerfCtlN */
324+ uasm_i_ehb(pp);
325+ uasm_i_mtc0(pp, t3, 25, (perf_counter * 2) + 1); /* PerfCntN */
326+ uasm_i_ehb(pp);
327+
328+ return 0;
329+}
330+
331+static void __init cps_gen_set_top_bit(u32 **pp, struct uasm_label **pl,
332+ struct uasm_reloc **pr,
333+ unsigned r_addr, int lbl)
334+{
335+ uasm_i_lui(pp, t0, uasm_rel_hi(0x80000000));
336+ uasm_build_label(pl, *pp, lbl);
337+ uasm_i_ll(pp, t1, 0, r_addr);
338+ uasm_i_or(pp, t1, t1, t0);
339+ uasm_i_sc(pp, t1, 0, r_addr);
340+ uasm_il_beqz(pp, pr, t1, lbl);
341+ uasm_i_nop(pp);
342+}
343+
344+static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
345+{
346+ struct uasm_label *l = labels;
347+ struct uasm_reloc *r = relocs;
348+ u32 *buf, *p;
349+ const unsigned r_online = a0;
350+ const unsigned r_nc_count = a1;
351+ const unsigned r_pcohctl = t7;
352+ const unsigned max_instrs = 256;
353+ unsigned cpc_cmd;
354+ int err;
355+ enum {
356+ lbl_incready = 1,
357+ lbl_poll_cont,
358+ lbl_secondary_hang,
359+ lbl_disable_coherence,
360+ lbl_flush_fsb,
361+ lbl_invicache,
362+ lbl_flushdcache,
363+ lbl_hang,
364+ lbl_set_cont,
365+ lbl_secondary_cont,
366+ lbl_decready,
367+ };
368+
369+ /* Allocate a buffer to hold the generated code */
370+ p = buf = kcalloc(max_instrs, sizeof(u32), GFP_KERNEL);
371+ if (!buf)
372+ return NULL;
373+
374+ /* Clear labels & relocs ready for (re)use */
375+ memset(labels, 0, sizeof(labels));
376+ memset(relocs, 0, sizeof(relocs));
377+
378+ if (config_enabled(CONFIG_CPU_PM) && state == CPS_PM_POWER_GATED) {
379+ /*
380+ * Save CPU state. Note the non-standard calling convention
381+ * with the return address placed in v0 to avoid clobbering
382+ * the ra register before it is saved.
383+ */
384+ UASM_i_LA(&p, t0, (long)mips_cps_pm_save);
385+ uasm_i_jalr(&p, v0, t0);
386+ uasm_i_nop(&p);
387+ }
388+
389+ /*
390+ * Load addresses of required CM & CPC registers. This is done early
391+ * because they're needed in both the enable & disable coherence steps
392+ * but in the coupled case the enable step will only run on one VPE.
393+ */
394+ UASM_i_LA(&p, r_pcohctl, (long)addr_gcr_cl_coherence());
395+
396+ if (coupled_coherence) {
397+ /* Increment ready_count */
398+ uasm_i_sync(&p, stype_ordering);
399+ uasm_build_label(&l, p, lbl_incready);
400+ uasm_i_ll(&p, t1, 0, r_nc_count);
401+ uasm_i_addiu(&p, t2, t1, 1);
402+ uasm_i_sc(&p, t2, 0, r_nc_count);
403+ uasm_il_beqz(&p, &r, t2, lbl_incready);
404+ uasm_i_addiu(&p, t1, t1, 1);
405+
406+ /* Ordering barrier */
407+ uasm_i_sync(&p, stype_ordering);
408+
409+ /*
410+ * If this is the last VPE to become ready for non-coherence
411+ * then it should branch below.
412+ */
413+ uasm_il_beq(&p, &r, t1, r_online, lbl_disable_coherence);
414+ uasm_i_nop(&p);
415+
416+ if (state < CPS_PM_POWER_GATED) {
417+ /*
418+ * Otherwise this is not the last VPE to become ready
419+ * for non-coherence. It needs to wait until coherence
420+ * has been disabled before proceeding, which it will do
421+ * by polling for the top bit of ready_count being set.
422+ */
423+ uasm_i_addiu(&p, t1, zero, -1);
424+ uasm_build_label(&l, p, lbl_poll_cont);
425+ uasm_i_lw(&p, t0, 0, r_nc_count);
426+ uasm_il_bltz(&p, &r, t0, lbl_secondary_cont);
427+ uasm_i_ehb(&p);
428+ uasm_i_yield(&p, zero, t1);
429+ uasm_il_b(&p, &r, lbl_poll_cont);
430+ uasm_i_nop(&p);
431+ } else {
432+ /*
433+ * The core will lose power & this VPE will not continue
434+ * so it can simply halt here.
435+ */
436+ uasm_i_addiu(&p, t0, zero, TCHALT_H);
437+ uasm_i_mtc0(&p, t0, 2, 4);
438+ uasm_build_label(&l, p, lbl_secondary_hang);
439+ uasm_il_b(&p, &r, lbl_secondary_hang);
440+ uasm_i_nop(&p);
441+ }
442+ }
443+
444+ /*
445+ * This is the point of no return - this VPE will now proceed to
446+ * disable coherence. At this point we *must* be sure that no other
447+ * VPE within the core will interfere with the L1 dcache.
448+ */
449+ uasm_build_label(&l, p, lbl_disable_coherence);
450+
451+ /* Invalidate the L1 icache */
452+ cps_gen_cache_routine(&p, &l, &r, &cpu_data[cpu].icache,
453+ Index_Invalidate_I, lbl_invicache);
454+
455+ /* Writeback & invalidate the L1 dcache */
456+ cps_gen_cache_routine(&p, &l, &r, &cpu_data[cpu].dcache,
457+ Index_Writeback_Inv_D, lbl_flushdcache);
458+
459+ /* Completion barrier */
460+ uasm_i_sync(&p, stype_memory);
461+ uasm_i_ehb(&p);
462+
463+ /*
464+ * Disable all but self interventions. The load from COHCTL is defined
465+ * by the interAptiv & proAptiv SUMs as ensuring that the operation
466+ * resulting from the preceeding store is complete.
467+ */
468+ uasm_i_addiu(&p, t0, zero, 1 << cpu_data[cpu].core);
469+ uasm_i_sw(&p, t0, 0, r_pcohctl);
470+ uasm_i_lw(&p, t0, 0, r_pcohctl);
471+
472+ /* Sync to ensure previous interventions are complete */
473+ uasm_i_sync(&p, stype_intervention);
474+ uasm_i_ehb(&p);
475+
476+ /* Disable coherence */
477+ uasm_i_sw(&p, zero, 0, r_pcohctl);
478+ uasm_i_lw(&p, t0, 0, r_pcohctl);
479+
480+ if (state >= CPS_PM_CLOCK_GATED) {
481+ err = cps_gen_flush_fsb(&p, &l, &r, &cpu_data[cpu],
482+ lbl_flush_fsb);
483+ if (err)
484+ goto out_err;
485+
486+ /* Determine the CPC command to issue */
487+ switch (state) {
488+ case CPS_PM_CLOCK_GATED:
489+ cpc_cmd = CPC_Cx_CMD_CLOCKOFF;
490+ break;
491+ case CPS_PM_POWER_GATED:
492+ cpc_cmd = CPC_Cx_CMD_PWRDOWN;
493+ break;
494+ default:
495+ BUG();
496+ goto out_err;
497+ }
498+
499+ /* Issue the CPC command */
500+ UASM_i_LA(&p, t0, (long)addr_cpc_cl_cmd());
501+ uasm_i_addiu(&p, t1, zero, cpc_cmd);
502+ uasm_i_sw(&p, t1, 0, t0);
503+
504+ if (state == CPS_PM_POWER_GATED) {
505+ /* If anything goes wrong just hang */
506+ uasm_build_label(&l, p, lbl_hang);
507+ uasm_il_b(&p, &r, lbl_hang);
508+ uasm_i_nop(&p);
509+
510+ /*
511+ * There's no point generating more code, the core is
512+ * powered down & if powered back up will run from the
513+ * reset vector not from here.
514+ */
515+ goto gen_done;
516+ }
517+
518+ /* Completion barrier */
519+ uasm_i_sync(&p, stype_memory);
520+ uasm_i_ehb(&p);
521+ }
522+
523+ if (state == CPS_PM_NC_WAIT) {
524+ /*
525+ * At this point it is safe for all VPEs to proceed with
526+ * execution. This VPE will set the top bit of ready_count
527+ * to indicate to the other VPEs that they may continue.
528+ */
529+ if (coupled_coherence)
530+ cps_gen_set_top_bit(&p, &l, &r, r_nc_count,
531+ lbl_set_cont);
532+
533+ /*
534+ * VPEs which did not disable coherence will continue
535+ * executing, after coherence has been disabled, from this
536+ * point.
537+ */
538+ uasm_build_label(&l, p, lbl_secondary_cont);
539+
540+ /* Now perform our wait */
541+ uasm_i_wait(&p, 0);
542+ }
543+
544+ /*
545+ * Re-enable coherence. Note that for CPS_PM_NC_WAIT all coupled VPEs
546+ * will run this. The first will actually re-enable coherence & the
547+ * rest will just be performing a rather unusual nop.
548+ */
549+ uasm_i_addiu(&p, t0, zero, CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK);
550+ uasm_i_sw(&p, t0, 0, r_pcohctl);
551+ uasm_i_lw(&p, t0, 0, r_pcohctl);
552+
553+ /* Completion barrier */
554+ uasm_i_sync(&p, stype_memory);
555+ uasm_i_ehb(&p);
556+
557+ if (coupled_coherence && (state == CPS_PM_NC_WAIT)) {
558+ /* Decrement ready_count */
559+ uasm_build_label(&l, p, lbl_decready);
560+ uasm_i_sync(&p, stype_ordering);
561+ uasm_i_ll(&p, t1, 0, r_nc_count);
562+ uasm_i_addiu(&p, t2, t1, -1);
563+ uasm_i_sc(&p, t2, 0, r_nc_count);
564+ uasm_il_beqz(&p, &r, t2, lbl_decready);
565+ uasm_i_andi(&p, v0, t1, (1 << fls(smp_num_siblings)) - 1);
566+
567+ /* Ordering barrier */
568+ uasm_i_sync(&p, stype_ordering);
569+ }
570+
571+ if (coupled_coherence && (state == CPS_PM_CLOCK_GATED)) {
572+ /*
573+ * At this point it is safe for all VPEs to proceed with
574+ * execution. This VPE will set the top bit of ready_count
575+ * to indicate to the other VPEs that they may continue.
576+ */
577+ cps_gen_set_top_bit(&p, &l, &r, r_nc_count, lbl_set_cont);
578+
579+ /*
580+ * This core will be reliant upon another core sending a
581+ * power-up command to the CPC in order to resume operation.
582+ * Thus an arbitrary VPE can't trigger the core leaving the
583+ * idle state and the one that disables coherence might as well
584+ * be the one to re-enable it. The rest will continue from here
585+ * after that has been done.
586+ */
587+ uasm_build_label(&l, p, lbl_secondary_cont);
588+
589+ /* Ordering barrier */
590+ uasm_i_sync(&p, stype_ordering);
591+ }
592+
593+ /* The core is coherent, time to return to C code */
594+ uasm_i_jr(&p, ra);
595+ uasm_i_nop(&p);
596+
597+gen_done:
598+ /* Ensure the code didn't exceed the resources allocated for it */
599+ BUG_ON((p - buf) > max_instrs);
600+ BUG_ON((l - labels) > ARRAY_SIZE(labels));
601+ BUG_ON((r - relocs) > ARRAY_SIZE(relocs));
602+
603+ /* Patch branch offsets */
604+ uasm_resolve_relocs(relocs, labels);
605+
606+ /* Flush the icache */
607+ local_flush_icache_range((unsigned long)buf, (unsigned long)p);
608+
609+ return buf;
610+out_err:
611+ kfree(buf);
612+ return NULL;
613+}
614+
615+static int __init cps_gen_core_entries(unsigned cpu)
616+{
617+ enum cps_pm_state state;
618+ unsigned core = cpu_data[cpu].core;
619+ unsigned dlinesz = cpu_data[cpu].dcache.linesz;
620+ void *entry_fn, *core_rc;
621+
622+ for (state = CPS_PM_NC_WAIT; state < CPS_PM_STATE_COUNT; state++) {
623+ if (per_cpu(nc_asm_enter, core)[state])
624+ continue;
625+ if (!test_bit(state, state_support))
626+ continue;
627+
628+ entry_fn = cps_gen_entry_code(cpu, state);
629+ if (!entry_fn) {
630+ pr_err("Failed to generate core %u state %u entry\n",
631+ core, state);
632+ clear_bit(state, state_support);
633+ }
634+
635+ per_cpu(nc_asm_enter, core)[state] = entry_fn;
636+ }
637+
638+ if (!per_cpu(ready_count, core)) {
639+ core_rc = kmalloc(dlinesz * 2, GFP_KERNEL);
640+ if (!core_rc) {
641+ pr_err("Failed allocate core %u ready_count\n", core);
642+ return -ENOMEM;
643+ }
644+ per_cpu(ready_count_alloc, core) = core_rc;
645+
646+ /* Ensure ready_count is aligned to a cacheline boundary */
647+ core_rc += dlinesz - 1;
648+ core_rc = (void *)((unsigned long)core_rc & ~(dlinesz - 1));
649+ per_cpu(ready_count, core) = core_rc;
650+ }
651+
652+ return 0;
653+}
654+
655+static int __init cps_pm_init(void)
656+{
657+ unsigned cpu;
658+ int err;
659+
660+ /* Detect appropriate sync types for the system */
661+ switch (current_cpu_data.cputype) {
662+ case CPU_INTERAPTIV:
663+ case CPU_PROAPTIV:
664+ case CPU_M5150:
665+ case CPU_P5600:
666+ stype_intervention = 0x2;
667+ stype_memory = 0x3;
668+ stype_ordering = 0x10;
669+ break;
670+
671+ default:
672+ pr_warn("Power management is using heavyweight sync 0\n");
673+ }
674+
675+ /* A CM is required for all non-coherent states */
676+ if (!mips_cm_present()) {
677+ pr_warn("pm-cps: no CM, non-coherent states unavailable\n");
678+ goto out;
679+ }
680+
681+ /*
682+ * If interrupts were enabled whilst running a wait instruction on a
683+ * non-coherent core then the VPE may end up processing interrupts
684+ * whilst non-coherent. That would be bad.
685+ */
686+ if (cpu_wait == r4k_wait_irqoff)
687+ set_bit(CPS_PM_NC_WAIT, state_support);
688+ else
689+ pr_warn("pm-cps: non-coherent wait unavailable\n");
690+
691+ /* Detect whether a CPC is present */
692+ if (mips_cpc_present()) {
693+ /* Detect whether clock gating is implemented */
694+ if (read_cpc_cl_stat_conf() & CPC_Cx_STAT_CONF_CLKGAT_IMPL_MSK)
695+ set_bit(CPS_PM_CLOCK_GATED, state_support);
696+ else
697+ pr_warn("pm-cps: CPC does not support clock gating\n");
698+
699+ /* Power gating is available with CPS SMP & any CPC */
700+ if (mips_cps_smp_in_use())
701+ set_bit(CPS_PM_POWER_GATED, state_support);
702+ else
703+ pr_warn("pm-cps: CPS SMP not in use, power gating unavailable\n");
704+ } else {
705+ pr_warn("pm-cps: no CPC, clock & power gating unavailable\n");
706+ }
707+
708+ for_each_present_cpu(cpu) {
709+ err = cps_gen_core_entries(cpu);
710+ if (err)
711+ return err;
712+ }
713+out:
714+ return 0;
715+}
716+arch_initcall(cps_pm_init);
arch/mips/kernel/pm.c+99−0
@@ -0,0 +1,99 @@
1+/*
2+ * Copyright (C) 2014 Imagination Technologies Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License as published by the
6+ * Free Software Foundation; either version 2 of the License, or (at your
7+ * option) any later version.
8+ *
9+ * CPU PM notifiers for saving/restoring general CPU state.
10+ */
11+
12+#include <linux/cpu_pm.h>
13+#include <linux/init.h>
14+
15+#include <asm/dsp.h>
16+#include <asm/fpu.h>
17+#include <asm/mmu_context.h>
18+#include <asm/pm.h>
19+#include <asm/watch.h>
20+
21+/* Used by PM helper macros in asm/pm.h */
22+struct mips_static_suspend_state mips_static_suspend_state;
23+
24+/**
25+ * mips_cpu_save() - Save general CPU state.
26+ * Ensures that general CPU context is saved, notably FPU and DSP.
27+ */
28+static int mips_cpu_save(void)
29+{
30+ /* Save FPU state */
31+ lose_fpu(1);
32+
33+ /* Save DSP state */
34+ save_dsp(current);
35+
36+ return 0;
37+}
38+
39+/**
40+ * mips_cpu_restore() - Restore general CPU state.
41+ * Restores important CPU context.
42+ */
43+static void mips_cpu_restore(void)
44+{
45+ unsigned int cpu = smp_processor_id();
46+
47+ /* Restore ASID */
48+ if (current->mm)
49+ write_c0_entryhi(cpu_asid(cpu, current->mm));
50+
51+ /* Restore DSP state */
52+ restore_dsp(current);
53+
54+ /* Restore UserLocal */
55+ if (cpu_has_userlocal)
56+ write_c0_userlocal(current_thread_info()->tp_value);
57+
58+ /* Restore watch registers */
59+ __restore_watch();
60+}
61+
62+/**
63+ * mips_pm_notifier() - Notifier for preserving general CPU context.
64+ * @self: Notifier block.
65+ * @cmd: CPU PM event.
66+ * @v: Private data (unused).
67+ *
68+ * This is called when a CPU power management event occurs, and is used to
69+ * ensure that important CPU context is preserved across a CPU power down.
70+ */
71+static int mips_pm_notifier(struct notifier_block *self, unsigned long cmd,
72+ void *v)
73+{
74+ int ret;
75+
76+ switch (cmd) {
77+ case CPU_PM_ENTER:
78+ ret = mips_cpu_save();
79+ if (ret)
80+ return NOTIFY_STOP;
81+ break;
82+ case CPU_PM_ENTER_FAILED:
83+ case CPU_PM_EXIT:
84+ mips_cpu_restore();
85+ break;
86+ }
87+
88+ return NOTIFY_OK;
89+}
90+
91+static struct notifier_block mips_pm_notifier_block = {
92+ .notifier_call = mips_pm_notifier,
93+};
94+
95+static int __init mips_pm_init(void)
96+{
97+ return cpu_pm_register_notifier(&mips_pm_notifier_block);
98+}
99+arch_initcall(mips_pm_init);
arch/mips/kernel/process.c+0−7
@@ -140,13 +140,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, · 139 unmodified lines
140140 */
141141 childregs->cp0_status &= ~(ST0_CU2|ST0_CU1);
142142
143−#ifdef CONFIG_MIPS_MT_SMTC
144− /*
145− * SMTC restores TCStatus after Status, and the CU bits
146− * are aliased there.
147− */
148− childregs->cp0_tcstatus &= ~(ST0_CU2|ST0_CU1);
149−#endif
150143 clear_tsk_thread_flag(p, TIF_USEDFPU);
151144
152145 #ifdef CONFIG_MIPS_MT_FPAFF
arch/mips/kernel/r4k_switch.S+3−33
@@ -28,6 +28,7 @@ · 27 unmodified lines
2828 */
2929 #define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS)
3030
31+#ifndef USE_ALTERNATE_RESUME_IMPL
3132 /*
3233 * task_struct *resume(task_struct *prev, task_struct *next,
3334 * struct thread_info *next_ti, s32 fp_save)
@@ -87,18 +88,6 @@ · 53 unmodified lines
8788
8889 PTR_ADDU t0, $28, _THREAD_SIZE - 32
8990 set_saved_sp t0, t1, t2
90−#ifdef CONFIG_MIPS_MT_SMTC
91− /* Read-modify-writes of Status must be atomic on a VPE */
92− mfc0 t2, CP0_TCSTATUS
93− ori t1, t2, TCSTATUS_IXMT
94− mtc0 t1, CP0_TCSTATUS
95− andi t2, t2, TCSTATUS_IXMT
96− _ehb
97− DMT 8 # dmt t0
98− move t1,ra
99− jal mips_ihb
100− move ra,t1
101−#endif /* CONFIG_MIPS_MT_SMTC */
10291 mfc0 t1, CP0_STATUS /* Do we really need this? */
10392 li a3, 0xff01
10493 and t1, a3
@@ -107,22 +96,12 @@ · 2 unmodified lines
10796 and a2, a3
10897 or a2, t1
10998 mtc0 a2, CP0_STATUS
110−#ifdef CONFIG_MIPS_MT_SMTC
111− _ehb
112− andi t0, t0, VPECONTROL_TE
113− beqz t0, 1f
114− emt
115−1:
116− mfc0 t1, CP0_TCSTATUS
117− xori t1, t1, TCSTATUS_IXMT
118− or t1, t1, t2
119− mtc0 t1, CP0_TCSTATUS
120− _ehb
121−#endif /* CONFIG_MIPS_MT_SMTC */
12299 move v0, a0
123100 jr ra
124101 END(resume)
125102
103+#endif /* USE_ALTERNATE_RESUME_IMPL */
104+
126105 /*
127106 * Save a thread's fp context.
128107 */
@@ -176,19 +155,10 @@ LEAF(_restore_msa) · 47 unmodified lines
176155 #define FPU_DEFAULT 0x00000000
177156
178157 LEAF(_init_fpu)
179−#ifdef CONFIG_MIPS_MT_SMTC
180− /* Rather than manipulate per-VPE Status, set per-TC bit in TCStatus */
181− mfc0 t0, CP0_TCSTATUS
182− /* Bit position is the same for Status, TCStatus */
183− li t1, ST0_CU1
184− or t0, t1
185− mtc0 t0, CP0_TCSTATUS
186−#else /* Normal MIPS CU1 enable */
187158 mfc0 t0, CP0_STATUS
188159 li t1, ST0_CU1
189160 or t0, t1
190161 mtc0 t0, CP0_STATUS
191−#endif /* CONFIG_MIPS_MT_SMTC */
192162 enable_fpu_hazard
193163
194164 li t1, FPU_DEFAULT
arch/mips/kernel/rtlx-mt.c+0−1
@@ -36,7 +36,6 @@ static irqreturn_t rtlx_interrupt(int irq, void *dev_id) · 35 unmodified lines
3636 unsigned long flags;
3737 int i;
3838
39− /* Ought not to be strictly necessary for SMTC builds */
4039 local_irq_save(flags);
4140 vpeflags = dvpe();
4241 set_c0_status(0x100 << MIPS_CPU_RTLX_IRQ);
arch/mips/kernel/smp-bmips.c+0−9
@@ -280,13 +280,6 @@ static void bmips_smp_finish(void) · 279 unmodified lines
280280 irq_enable_hazard();
281281 }
282282
283−/*
284− * Runs on CPU0 after all CPUs have been booted
285− */
286−static void bmips_cpus_done(void)
287−{
288−}
289−
290283 /*
291284 * BMIPS5000 raceless IPIs
292285 *
@@ -434,7 +427,6 @@ struct plat_smp_ops bmips43xx_smp_ops = { · 141 unmodified lines
434427 .boot_secondary = bmips_boot_secondary,
435428 .smp_finish = bmips_smp_finish,
436429 .init_secondary = bmips_init_secondary,
437− .cpus_done = bmips_cpus_done,
438430 .send_ipi_single = bmips43xx_send_ipi_single,
439431 .send_ipi_mask = bmips43xx_send_ipi_mask,
440432 #ifdef CONFIG_HOTPLUG_CPU
@@ -449,7 +441,6 @@ struct plat_smp_ops bmips5000_smp_ops = { · 8 unmodified lines
449441 .boot_secondary = bmips_boot_secondary,
450442 .smp_finish = bmips_smp_finish,
451443 .init_secondary = bmips_init_secondary,
452− .cpus_done = bmips_cpus_done,
453444 .send_ipi_single = bmips5000_send_ipi_single,
454445 .send_ipi_mask = bmips5000_send_ipi_mask,
455446 #ifdef CONFIG_HOTPLUG_CPU
arch/mips/kernel/smp-cmp.c+1−14
@@ -49,14 +49,11 @@ static void cmp_init_secondary(void) · 48 unmodified lines
4949
5050 /* Enable per-cpu interrupts: platform specific */
5151
52−#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
52+#ifdef CONFIG_MIPS_MT_SMP
5353 if (cpu_has_mipsmt)
5454 c->vpe_id = (read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) &
5555 TCBIND_CURVPE;
5656 #endif
57−#ifdef CONFIG_MIPS_MT_SMTC
58− c->tc_id = (read_c0_tcbind() & TCBIND_CURTC) >> TCBIND_CURTC_SHIFT;
59−#endif
6057 }
6158
6259 static void cmp_smp_finish(void)
@@ -75,11 +72,6 @@ static void cmp_smp_finish(void) · 12 unmodified lines
7572 local_irq_enable();
7673 }
7774
78−static void cmp_cpus_done(void)
79−{
80− pr_debug("SMPCMP: CPU%d: %s\n", smp_processor_id(), __func__);
81−}
82−
8375 /*
8476 * Setup the PC, SP, and GP of a secondary processor and start it running
8577 * smp_bootstrap is the place to resume from
@@ -135,10 +127,6 @@ void __init cmp_smp_setup(void) · 49 unmodified lines
135127 unsigned int mvpconf0 = read_c0_mvpconf0();
136128
137129 nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
138−#elif defined(CONFIG_MIPS_MT_SMTC)
139− unsigned int mvpconf0 = read_c0_mvpconf0();
140−
141− nvpe = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
142130 #endif
143131 smp_num_siblings = nvpe;
144132 }
@@ -165,7 +153,6 @@ struct plat_smp_ops cmp_smp_ops = { · 20 unmodified lines
165153 .send_ipi_mask = gic_send_ipi_mask,
166154 .init_secondary = cmp_init_secondary,
167155 .smp_finish = cmp_smp_finish,
168− .cpus_done = cmp_cpus_done,
169156 .boot_secondary = cmp_boot_secondary,
170157 .smp_setup = cmp_smp_setup,
171158 .prepare_cpus = cmp_prepare_cpus,
arch/mips/kernel/smp-cps.c+281−150
@@ -20,104 +20,43 @@ · 19 unmodified lines
2020 #include <asm/mips-cpc.h>
2121 #include <asm/mips_mt.h>
2222 #include <asm/mipsregs.h>
23+#include <asm/pm-cps.h>
2324 #include <asm/smp-cps.h>
2425 #include <asm/time.h>
2526 #include <asm/uasm.h>
2627
2728 static DECLARE_BITMAP(core_power, NR_CPUS);
2829
29−struct boot_config mips_cps_bootcfg;
30+struct core_boot_config *mips_cps_core_bootcfg;
3031
31−static void init_core(void)
32+static unsigned core_vpe_count(unsigned core)
3233 {
33− unsigned int nvpes, t;
34− u32 mvpconf0, vpeconf0, vpecontrol, tcstatus, tcbind, status;
34+ unsigned cfg;
3535
36− if (!cpu_has_mipsmt)
37− return;
38−
39− /* Enter VPE configuration state */
40− dvpe();
41− set_c0_mvpcontrol(MVPCONTROL_VPC);
42−
43− /* Retrieve the count of VPEs in this core */
44− mvpconf0 = read_c0_mvpconf0();
45− nvpes = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
46− smp_num_siblings = nvpes;
47−
48− for (t = 1; t < nvpes; t++) {
49− /* Use a 1:1 mapping of TC index to VPE index */
50− settc(t);
51−
52− /* Bind 1 TC to this VPE */
53− tcbind = read_tc_c0_tcbind();
54− tcbind &= ~TCBIND_CURVPE;
55− tcbind |= t << TCBIND_CURVPE_SHIFT;
56− write_tc_c0_tcbind(tcbind);
57−
58− /* Set exclusive TC, non-active, master */
59− vpeconf0 = read_vpe_c0_vpeconf0();
60− vpeconf0 &= ~(VPECONF0_XTC | VPECONF0_VPA);
61− vpeconf0 |= t << VPECONF0_XTC_SHIFT;
62− vpeconf0 |= VPECONF0_MVP;
63− write_vpe_c0_vpeconf0(vpeconf0);
64−
65− /* Declare TC non-active, non-allocatable & interrupt exempt */
66− tcstatus = read_tc_c0_tcstatus();
67− tcstatus &= ~(TCSTATUS_A | TCSTATUS_DA);
68− tcstatus |= TCSTATUS_IXMT;
69− write_tc_c0_tcstatus(tcstatus);
70−
71− /* Halt the TC */
72− write_tc_c0_tchalt(TCHALT_H);
73−
74− /* Allow only 1 TC to execute */
75− vpecontrol = read_vpe_c0_vpecontrol();
76− vpecontrol &= ~VPECONTROL_TE;
77− write_vpe_c0_vpecontrol(vpecontrol);
78−
79− /* Copy (most of) Status from VPE 0 */
80− status = read_c0_status();
81− status &= ~(ST0_IM | ST0_IE | ST0_KSU);
82− status |= ST0_CU0;
83− write_vpe_c0_status(status);
84−
85− /* Copy Config from VPE 0 */
86− write_vpe_c0_config(read_c0_config());
87− write_vpe_c0_config7(read_c0_config7());
88−
89− /* Ensure no software interrupts are pending */
90− write_vpe_c0_cause(0);
91−
92− /* Sync Count */
93− write_vpe_c0_count(read_c0_count());
94− }
36+ if (!config_enabled(CONFIG_MIPS_MT_SMP) || !cpu_has_mipsmt)
37+ return 1;
9538
96− /* Leave VPE configuration state */
97− clear_c0_mvpcontrol(MVPCONTROL_VPC);
39+ write_gcr_cl_other(core << CM_GCR_Cx_OTHER_CORENUM_SHF);
40+ cfg = read_gcr_co_config() & CM_GCR_Cx_CONFIG_PVPE_MSK;
41+ return (cfg >> CM_GCR_Cx_CONFIG_PVPE_SHF) + 1;
9842 }
9943
10044 static void __init cps_smp_setup(void)
10145 {
10246 unsigned int ncores, nvpes, core_vpes;
10347 int c, v;
104− u32 core_cfg, *entry_code;
10548
10649 /* Detect & record VPE topology */
10750 ncores = mips_cm_numcores();
10851 pr_info("VPE topology ");
10952 for (c = nvpes = 0; c < ncores; c++) {
110− if (cpu_has_mipsmt && config_enabled(CONFIG_MIPS_MT_SMP)) {
111− write_gcr_cl_other(c << CM_GCR_Cx_OTHER_CORENUM_SHF);
112− core_cfg = read_gcr_co_config();
113− core_vpes = ((core_cfg & CM_GCR_Cx_CONFIG_PVPE_MSK) >>
114− CM_GCR_Cx_CONFIG_PVPE_SHF) + 1;
115− } else {
116− core_vpes = 1;
117− }
118−
53+ core_vpes = core_vpe_count(c);
11954 pr_cont("%c%u", c ? ',' : '{', core_vpes);
12055
56+ /* Use the number of VPEs in core 0 for smp_num_siblings */
57+ if (!c)
58+ smp_num_siblings = core_vpes;
59+
12160 for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) {
12261 cpu_data[nvpes + v].core = c;
12362 #ifdef CONFIG_MIPS_MT_SMP
@@ -137,19 +76,14 @@ static void __init cps_smp_setup(void) · 13 unmodified lines
13776 __cpu_logical_map[v] = v;
13877 }
13978
79+ /* Set a coherent default CCA (CWB) */
80+ change_c0_config(CONF_CM_CMASK, 0x5);
81+
14082 /* Core 0 is powered up (we're running on it) */
14183 bitmap_set(core_power, 0, 1);
14284
143− /* Disable MT - we only want to run 1 TC per VPE */
144− if (cpu_has_mipsmt)
145− dmt();
146−
14785 /* Initialise core 0 */
148− init_core();
149−
150− /* Patch the start of mips_cps_core_entry to provide the CM base */
151− entry_code = (u32 *)&mips_cps_core_entry;
152− UASM_i_LA(&entry_code, 3, (long)mips_cm_base);
86+ mips_cps_core_init();
15387
15488 /* Make core 0 coherent with everything */
15589 write_gcr_cl_coherence(0xff);
@@ -157,15 +91,99 @@ static void __init cps_smp_setup(void) · 1 unmodified line
15791
15892 static void __init cps_prepare_cpus(unsigned int max_cpus)
15993 {
94+ unsigned ncores, core_vpes, c, cca;
95+ bool cca_unsuitable;
96+ u32 *entry_code;
97+
16098 mips_mt_set_cpuoptions();
99+
100+ /* Detect whether the CCA is unsuited to multi-core SMP */
101+ cca = read_c0_config() & CONF_CM_CMASK;
102+ switch (cca) {
103+ case 0x4: /* CWBE */
104+ case 0x5: /* CWB */
105+ /* The CCA is coherent, multi-core is fine */
106+ cca_unsuitable = false;
107+ break;
108+
109+ default:
110+ /* CCA is not coherent, multi-core is not usable */
111+ cca_unsuitable = true;
112+ }
113+
114+ /* Warn the user if the CCA prevents multi-core */
115+ ncores = mips_cm_numcores();
116+ if (cca_unsuitable && ncores > 1) {
117+ pr_warn("Using only one core due to unsuitable CCA 0x%x\n",
118+ cca);
119+
120+ for_each_present_cpu(c) {
121+ if (cpu_data[c].core)
122+ set_cpu_present(c, false);
123+ }
124+ }
125+
126+ /*
127+ * Patch the start of mips_cps_core_entry to provide:
128+ *
129+ * v0 = CM base address
130+ * s0 = kseg0 CCA
131+ */
132+ entry_code = (u32 *)&mips_cps_core_entry;
133+ UASM_i_LA(&entry_code, 3, (long)mips_cm_base);
134+ uasm_i_addiu(&entry_code, 16, 0, cca);
135+ dma_cache_wback_inv((unsigned long)&mips_cps_core_entry,
136+ (void *)entry_code - (void *)&mips_cps_core_entry);
137+
138+ /* Allocate core boot configuration structs */
139+ mips_cps_core_bootcfg = kcalloc(ncores, sizeof(*mips_cps_core_bootcfg),
140+ GFP_KERNEL);
141+ if (!mips_cps_core_bootcfg) {
142+ pr_err("Failed to allocate boot config for %u cores\n", ncores);
143+ goto err_out;
144+ }
145+
146+ /* Allocate VPE boot configuration structs */
147+ for (c = 0; c < ncores; c++) {
148+ core_vpes = core_vpe_count(c);
149+ mips_cps_core_bootcfg[c].vpe_config = kcalloc(core_vpes,
150+ sizeof(*mips_cps_core_bootcfg[c].vpe_config),
151+ GFP_KERNEL);
152+ if (!mips_cps_core_bootcfg[c].vpe_config) {
153+ pr_err("Failed to allocate %u VPE boot configs\n",
154+ core_vpes);
155+ goto err_out;
156+ }
157+ }
158+
159+ /* Mark this CPU as booted */
160+ atomic_set(&mips_cps_core_bootcfg[current_cpu_data.core].vpe_mask,
161+ 1 << cpu_vpe_id(&current_cpu_data));
162+
163+ return;
164+err_out:
165+ /* Clean up allocations */
166+ if (mips_cps_core_bootcfg) {
167+ for (c = 0; c < ncores; c++)
168+ kfree(mips_cps_core_bootcfg[c].vpe_config);
169+ kfree(mips_cps_core_bootcfg);
170+ mips_cps_core_bootcfg = NULL;
171+ }
172+
173+ /* Effectively disable SMP by declaring CPUs not present */
174+ for_each_possible_cpu(c) {
175+ if (c == 0)
176+ continue;
177+ set_cpu_present(c, false);
178+ }
161179 }
162180
163−static void boot_core(struct boot_config *cfg)
181+static void boot_core(unsigned core)
164182 {
165183 u32 access;
166184
167185 /* Select the appropriate core */
168− write_gcr_cl_other(cfg->core << CM_GCR_Cx_OTHER_CORENUM_SHF);
186+ write_gcr_cl_other(core << CM_GCR_Cx_OTHER_CORENUM_SHF);
169187
170188 /* Set its reset vector */
171189 write_gcr_co_reset_base(CKSEG1ADDR((unsigned long)mips_cps_core_entry));
@@ -175,104 +193,74 @@ static void boot_core(struct boot_config *cfg) · 3 unmodified lines
175193
176194 /* Ensure the core can access the GCRs */
177195 access = read_gcr_access();
178− access |= 1 << (CM_GCR_ACCESS_ACCESSEN_SHF + cfg->core);
196+ access |= 1 << (CM_GCR_ACCESS_ACCESSEN_SHF + core);
179197 write_gcr_access(access);
180198
181− /* Copy cfg */
182− mips_cps_bootcfg = *cfg;
183−
184199 if (mips_cpc_present()) {
185− /* Select the appropriate core */
186− write_cpc_cl_other(cfg->core << CPC_Cx_OTHER_CORENUM_SHF);
187−
188200 /* Reset the core */
201+ mips_cpc_lock_other(core);
189202 write_cpc_co_cmd(CPC_Cx_CMD_RESET);
203+ mips_cpc_unlock_other();
190204 } else {
191205 /* Take the core out of reset */
192206 write_gcr_co_reset_release(0);
193207 }
194208
195209 /* The core is now powered up */
196− bitmap_set(core_power, cfg->core, 1);
210+ bitmap_set(core_power, core, 1);
197211 }
198212
199−static void boot_vpe(void *info)
213+static void remote_vpe_boot(void *dummy)
200214 {
201− struct boot_config *cfg = info;
202− u32 tcstatus, vpeconf0;
203−
204− /* Enter VPE configuration state */
205− dvpe();
206− set_c0_mvpcontrol(MVPCONTROL_VPC);
207−
208− settc(cfg->vpe);
209−
210− /* Set the TC restart PC */
211− write_tc_c0_tcrestart((unsigned long)&smp_bootstrap);
212−
213− /* Activate the TC, allow interrupts */
214− tcstatus = read_tc_c0_tcstatus();
215− tcstatus &= ~TCSTATUS_IXMT;
216− tcstatus |= TCSTATUS_A;
217− write_tc_c0_tcstatus(tcstatus);
218−
219− /* Clear the TC halt bit */
220− write_tc_c0_tchalt(0);
221−
222− /* Activate the VPE */
223− vpeconf0 = read_vpe_c0_vpeconf0();
224− vpeconf0 |= VPECONF0_VPA;
225− write_vpe_c0_vpeconf0(vpeconf0);
226−
227− /* Set the stack & global pointer registers */
228− write_tc_gpr_sp(cfg->sp);
229− write_tc_gpr_gp(cfg->gp);
230−
231− /* Leave VPE configuration state */
232− clear_c0_mvpcontrol(MVPCONTROL_VPC);
233−
234− /* Enable other VPEs to execute */
235− evpe(EVPE_ENABLE);
215+ mips_cps_boot_vpes();
236216 }
237217
238218 static void cps_boot_secondary(int cpu, struct task_struct *idle)
239219 {
240− struct boot_config cfg;
220+ unsigned core = cpu_data[cpu].core;
221+ unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]);
222+ struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core];
223+ struct vpe_boot_config *vpe_cfg = &core_cfg->vpe_config[vpe_id];
241224 unsigned int remote;
242225 int err;
243226
244− cfg.core = cpu_data[cpu].core;
245− cfg.vpe = cpu_vpe_id(&cpu_data[cpu]);
246− cfg.pc = (unsigned long)&smp_bootstrap;
247− cfg.sp = __KSTK_TOS(idle);
248− cfg.gp = (unsigned long)task_thread_info(idle);
227+ vpe_cfg->pc = (unsigned long)&smp_bootstrap;
228+ vpe_cfg->sp = __KSTK_TOS(idle);
229+ vpe_cfg->gp = (unsigned long)task_thread_info(idle);
230+
231+ atomic_or(1 << cpu_vpe_id(&cpu_data[cpu]), &core_cfg->vpe_mask);
249232
250− if (!test_bit(cfg.core, core_power)) {
233+ preempt_disable();
234+
235+ if (!test_bit(core, core_power)) {
251236 /* Boot a VPE on a powered down core */
252− boot_core(&cfg);
253− return;
237+ boot_core(core);
238+ goto out;
254239 }
255240
256− if (cfg.core != current_cpu_data.core) {
241+ if (core != current_cpu_data.core) {
257242 /* Boot a VPE on another powered up core */
258243 for (remote = 0; remote < NR_CPUS; remote++) {
259− if (cpu_data[remote].core != cfg.core)
244+ if (cpu_data[remote].core != core)
260245 continue;
261246 if (cpu_online(remote))
262247 break;
263248 }
264249 BUG_ON(remote >= NR_CPUS);
265250
266− err = smp_call_function_single(remote, boot_vpe, &cfg, 1);
251+ err = smp_call_function_single(remote, remote_vpe_boot,
252+ NULL, 1);
267253 if (err)
268254 panic("Failed to call remote CPU\n");
269− return;
255+ goto out;
270256 }
271257
272258 BUG_ON(!cpu_has_mipsmt);
273259
274260 /* Boot a VPE on this core */
275− boot_vpe(&cfg);
261+ mips_cps_boot_vpes();
262+out:
263+ preempt_enable();
276264 }
277265
278266 static void cps_init_secondary(void)
@@ -281,10 +269,6 @@ static void cps_init_secondary(void) · 2 unmodified lines
281269 if (cpu_has_mipsmt)
282270 dmt();
283271
284− /* TODO: revisit this assumption once hotplug is implemented */
285− if (cpu_vpe_id(&current_cpu_data) == 0)
286− init_core();
287−
288272 change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 |
289273 STATUSF_IP6 | STATUSF_IP7);
290274 }
@@ -302,10 +286,148 @@ static void cps_smp_finish(void) · 11 unmodified lines
302286 local_irq_enable();
303287 }
304288
305−static void cps_cpus_done(void)
289+#ifdef CONFIG_HOTPLUG_CPU
290+
291+static int cps_cpu_disable(void)
292+{
293+ unsigned cpu = smp_processor_id();
294+ struct core_boot_config *core_cfg;
295+
296+ if (!cpu)
297+ return -EBUSY;
298+
299+ if (!cps_pm_support_state(CPS_PM_POWER_GATED))
300+ return -EINVAL;
301+
302+ core_cfg = &mips_cps_core_bootcfg[current_cpu_data.core];
303+ atomic_sub(1 << cpu_vpe_id(&current_cpu_data), &core_cfg->vpe_mask);
304+ smp_mb__after_atomic_dec();
305+ set_cpu_online(cpu, false);
306+ cpu_clear(cpu, cpu_callin_map);
307+
308+ return 0;
309+}
310+
311+static DECLARE_COMPLETION(cpu_death_chosen);
312+static unsigned cpu_death_sibling;
313+static enum {
314+ CPU_DEATH_HALT,
315+ CPU_DEATH_POWER,
316+} cpu_death;
317+
318+void play_dead(void)
319+{
320+ unsigned cpu, core;
321+
322+ local_irq_disable();
323+ idle_task_exit();
324+ cpu = smp_processor_id();
325+ cpu_death = CPU_DEATH_POWER;
326+
327+ if (cpu_has_mipsmt) {
328+ core = cpu_data[cpu].core;
329+
330+ /* Look for another online VPE within the core */
331+ for_each_online_cpu(cpu_death_sibling) {
332+ if (cpu_data[cpu_death_sibling].core != core)
333+ continue;
334+
335+ /*
336+ * There is an online VPE within the core. Just halt
337+ * this TC and leave the core alone.
338+ */
339+ cpu_death = CPU_DEATH_HALT;
340+ break;
341+ }
342+ }
343+
344+ /* This CPU has chosen its way out */
345+ complete(&cpu_death_chosen);
346+
347+ if (cpu_death == CPU_DEATH_HALT) {
348+ /* Halt this TC */
349+ write_c0_tchalt(TCHALT_H);
350+ instruction_hazard();
351+ } else {
352+ /* Power down the core */
353+ cps_pm_enter_state(CPS_PM_POWER_GATED);
354+ }
355+
356+ /* This should never be reached */
357+ panic("Failed to offline CPU %u", cpu);
358+}
359+
360+static void wait_for_sibling_halt(void *ptr_cpu)
306361 {
362+ unsigned cpu = (unsigned)ptr_cpu;
363+ unsigned vpe_id = cpu_data[cpu].vpe_id;
364+ unsigned halted;
365+ unsigned long flags;
366+
367+ do {
368+ local_irq_save(flags);
369+ settc(vpe_id);
370+ halted = read_tc_c0_tchalt();
371+ local_irq_restore(flags);
372+ } while (!(halted & TCHALT_H));
373+}
374+
375+static void cps_cpu_die(unsigned int cpu)
376+{
377+ unsigned core = cpu_data[cpu].core;
378+ unsigned stat;
379+ int err;
380+
381+ /* Wait for the cpu to choose its way out */
382+ if (!wait_for_completion_timeout(&cpu_death_chosen,
383+ msecs_to_jiffies(5000))) {
384+ pr_err("CPU%u: didn't offline\n", cpu);
385+ return;
386+ }
387+
388+ /*
389+ * Now wait for the CPU to actually offline. Without doing this that
390+ * offlining may race with one or more of:
391+ *
392+ * - Onlining the CPU again.
393+ * - Powering down the core if another VPE within it is offlined.
394+ * - A sibling VPE entering a non-coherent state.
395+ *
396+ * In the non-MT halt case (ie. infinite loop) the CPU is doing nothing
397+ * with which we could race, so do nothing.
398+ */
399+ if (cpu_death == CPU_DEATH_POWER) {
400+ /*
401+ * Wait for the core to enter a powered down or clock gated
402+ * state, the latter happening when a JTAG probe is connected
403+ * in which case the CPC will refuse to power down the core.
404+ */
405+ do {
406+ mips_cpc_lock_other(core);
407+ stat = read_cpc_co_stat_conf();
408+ stat &= CPC_Cx_STAT_CONF_SEQSTATE_MSK;
409+ mips_cpc_unlock_other();
410+ } while (stat != CPC_Cx_STAT_CONF_SEQSTATE_D0 &&
411+ stat != CPC_Cx_STAT_CONF_SEQSTATE_D2 &&
412+ stat != CPC_Cx_STAT_CONF_SEQSTATE_U2);
413+
414+ /* Indicate the core is powered off */
415+ bitmap_clear(core_power, core, 1);
416+ } else if (cpu_has_mipsmt) {
417+ /*
418+ * Have a CPU with access to the offlined CPUs registers wait
419+ * for its TC to halt.
420+ */
421+ err = smp_call_function_single(cpu_death_sibling,
422+ wait_for_sibling_halt,
423+ (void *)cpu, 1);
424+ if (err)
425+ panic("Failed to call remote sibling CPU\n");
426+ }
307427 }
308428
429+#endif /* CONFIG_HOTPLUG_CPU */
430+
309431 static struct plat_smp_ops cps_smp_ops = {
310432 .smp_setup = cps_smp_setup,
311433 .prepare_cpus = cps_prepare_cpus,
@@ -314,9 +436,18 @@ static struct plat_smp_ops cps_smp_ops = { · 2 unmodified lines
314436 .smp_finish = cps_smp_finish,
315437 .send_ipi_single = gic_send_ipi_single,
316438 .send_ipi_mask = gic_send_ipi_mask,
317− .cpus_done = cps_cpus_done,
439+#ifdef CONFIG_HOTPLUG_CPU
440+ .cpu_disable = cps_cpu_disable,
441+ .cpu_die = cps_cpu_die,
442+#endif
318443 };
319444
445+bool mips_cps_smp_in_use(void)
446+{
447+ extern struct plat_smp_ops *mp_ops;
448+ return mp_ops == &cps_smp_ops;
449+}
450+
320451 int register_cps_smp_ops(void)
321452 {
322453 if (!mips_cm_present()) {
arch/mips/kernel/smp-gic.c+11−0
@@ -15,12 +15,14 @@ · 14 unmodified lines
1515 #include <linux/printk.h>
1616
1717 #include <asm/gic.h>
18+#include <asm/mips-cpc.h>
1819 #include <asm/smp-ops.h>
1920
2021 void gic_send_ipi_single(int cpu, unsigned int action)
2122 {
2223 unsigned long flags;
2324 unsigned int intr;
25+ unsigned int core = cpu_data[cpu].core;
2426
2527 pr_debug("CPU%d: %s cpu %d action %u status %08x\n",
2628 smp_processor_id(), __func__, cpu, action, read_c0_status());
@@ -41,6 +43,15 @@ void gic_send_ipi_single(int cpu, unsigned int action) · 14 unmodified lines
4143 }
4244
4345 gic_send_ipi(intr);
46+
47+ if (mips_cpc_present() && (core != current_cpu_data.core)) {
48+ while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) {
49+ mips_cpc_lock_other(core);
50+ write_cpc_co_cmd(CPC_Cx_CMD_PWRUP);
51+ mips_cpc_unlock_other();
52+ }
53+ }
54+
4455 local_irq_restore(flags);
4556 }
4657
arch/mips/kernel/smp-mt.c+0−5
@@ -183,10 +183,6 @@ static void vsmp_smp_finish(void) · 182 unmodified lines
183183 local_irq_enable();
184184 }
185185
186−static void vsmp_cpus_done(void)
187−{
188−}
189−
190186 /*
191187 * Setup the PC, SP, and GP of a secondary processor and start it
192188 * running!
@@ -287,7 +283,6 @@ struct plat_smp_ops vsmp_smp_ops = { · 94 unmodified lines
287283 .send_ipi_mask = vsmp_send_ipi_mask,
288284 .init_secondary = vsmp_init_secondary,
289285 .smp_finish = vsmp_smp_finish,
290− .cpus_done = vsmp_cpus_done,
291286 .boot_secondary = vsmp_boot_secondary,
292287 .smp_setup = vsmp_smp_setup,
293288 .prepare_cpus = vsmp_prepare_cpus,
arch/mips/kernel/smp-up.c+0−6
@@ -36,11 +36,6 @@ static void up_smp_finish(void) · 35 unmodified lines
3636 {
3737 }
3838
39−/* Hook for after all CPUs are online */
40−static void up_cpus_done(void)
41−{
42−}
43−
4439 /*
4540 * Firmware CPU startup hook
4641 */
@@ -73,7 +68,6 @@ struct plat_smp_ops up_smp_ops = { · 26 unmodified lines
7368 .send_ipi_mask = up_send_ipi_mask,
7469 .init_secondary = up_init_secondary,
7570 .smp_finish = up_smp_finish,
76− .cpus_done = up_cpus_done,
7771 .boot_secondary = up_boot_secondary,
7872 .smp_setup = up_smp_setup,
7973 .prepare_cpus = up_prepare_cpus,
arch/mips/kernel/smp.c+47−14
@@ -43,10 +43,6 @@ · 42 unmodified lines
4343 #include <asm/time.h>
4444 #include <asm/setup.h>
4545
46−#ifdef CONFIG_MIPS_MT_SMTC
47−#include <asm/mipsmtregs.h>
48−#endif /* CONFIG_MIPS_MT_SMTC */
49−
5046 volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */
5147
5248 int __cpu_number_map[NR_CPUS]; /* Map physical to logical */
@@ -66,6 +62,8 @@ EXPORT_SYMBOL(cpu_sibling_map); · 13 unmodified lines
6662 /* representing cpus for which sibling maps can be computed */
6763 static cpumask_t cpu_sibling_setup_map;
6864
65+cpumask_t cpu_coherent_mask;
66+
6967 static inline void set_cpu_sibling_map(int cpu)
7068 {
7169 int i;
@@ -102,12 +100,6 @@ asmlinkage void start_secondary(void) · 30 unmodified lines
102100 {
103101 unsigned int cpu;
104102
105−#ifdef CONFIG_MIPS_MT_SMTC
106− /* Only do cpu_probe for first TC of CPU */
107− if ((read_c0_tcbind() & TCBIND_CURTC) != 0)
108− __cpu_name[smp_processor_id()] = __cpu_name[0];
109− else
110−#endif /* CONFIG_MIPS_MT_SMTC */
111103 cpu_probe();
112104 cpu_report();
113105 per_cpu_trap_init(false);
@@ -124,6 +116,7 @@ asmlinkage void start_secondary(void) · 10 unmodified lines
124116 cpu = smp_processor_id();
125117 cpu_data[cpu].udelay_val = loops_per_jiffy;
126118
119+ cpu_set(cpu, cpu_coherent_mask);
127120 notify_cpu_starting(cpu);
128121
129122 set_cpu_online(cpu, true);
@@ -173,7 +166,6 @@ void smp_send_stop(void) · 43 unmodified lines
173166
174167 void __init smp_cpus_done(unsigned int max_cpus)
175168 {
176− mp_ops->cpus_done();
177169 }
178170
179171 /* called from main before smp_init() */
@@ -186,6 +178,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) · 6 unmodified lines
186178 #ifndef CONFIG_HOTPLUG_CPU
187179 init_cpu_present(cpu_possible_mask);
188180 #endif
181+ cpumask_copy(&cpu_coherent_mask, cpu_possible_mask);
189182 }
190183
191184 /* preload SMP state for boot cpu */
@@ -238,13 +231,10 @@ static void flush_tlb_mm_ipi(void *mm) · 46 unmodified lines
238231 * o collapses to normal function call on UP kernels
239232 * o collapses to normal function call on systems with a single shared
240233 * primary cache.
241− * o CONFIG_MIPS_MT_SMTC currently implies there is only one physical core.
242234 */
243235 static inline void smp_on_other_tlbs(void (*func) (void *info), void *info)
244236 {
245−#ifndef CONFIG_MIPS_MT_SMTC
246237 smp_call_function(func, info, 1);
247−#endif
248238 }
249239
250240 static inline void smp_on_each_tlb(void (*func) (void *info), void *info)
@@ -404,3 +394,46 @@ void dump_send_ipi(void (*dump_ipi_callback)(void *)) · 153 unmodified lines
404394 }
405395 EXPORT_SYMBOL(dump_send_ipi);
406396 #endif
397+
398+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
399+
400+static DEFINE_PER_CPU(atomic_t, tick_broadcast_count);
401+static DEFINE_PER_CPU(struct call_single_data, tick_broadcast_csd);
402+
403+void tick_broadcast(const struct cpumask *mask)
404+{
405+ atomic_t *count;
406+ struct call_single_data *csd;
407+ int cpu;
408+
409+ for_each_cpu(cpu, mask) {
410+ count = &per_cpu(tick_broadcast_count, cpu);
411+ csd = &per_cpu(tick_broadcast_csd, cpu);
412+
413+ if (atomic_inc_return(count) == 1)
414+ smp_call_function_single_async(cpu, csd);
415+ }
416+}
417+
418+static void tick_broadcast_callee(void *info)
419+{
420+ int cpu = smp_processor_id();
421+ tick_receive_broadcast();
422+ atomic_set(&per_cpu(tick_broadcast_count, cpu), 0);
423+}
424+
425+static int __init tick_broadcast_init(void)
426+{
427+ struct call_single_data *csd;
428+ int cpu;
429+
430+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
431+ csd = &per_cpu(tick_broadcast_csd, cpu);
432+ csd->func = tick_broadcast_callee;
433+ }
434+
435+ return 0;
436+}
437+early_initcall(tick_broadcast_init);
438+
439+#endif /* CONFIG_GENERIC_CLOCKEVENTS_BROADCAST */
arch/mips/kernel/smtc-asm.S+0−133
@@ -1,133 +0,0 @@
1−/*
2− * Assembly Language Functions for MIPS MT SMTC support
3− */
4−
5−/*
6− * This file should be built into the kernel only if CONFIG_MIPS_MT_SMTC is set. */
7−
8−#include <asm/regdef.h>
9−#include <asm/asmmacro.h>
10−#include <asm/stackframe.h>
11−#include <asm/irqflags.h>
12−
13−/*
14− * "Software Interrupt" linkage.
15− *
16− * This is invoked when an "Interrupt" is sent from one TC to another,
17− * where the TC to be interrupted is halted, has it's Restart address
18− * and Status values saved by the "remote control" thread, then modified
19− * to cause execution to begin here, in kenel mode. This code then
20− * disguises the TC state as that of an exception and transfers
21− * control to the general exception or vectored interrupt handler.
22− */
23− .set noreorder
24−
25−/*
26−The __smtc_ipi_vector would use k0 and k1 as temporaries and
27−1) Set EXL (this is per-VPE, so this can't be done by proxy!)
28−2) Restore the K/CU and IXMT bits to the pre "exception" state
29− (EXL means no interrupts and access to the kernel map).
30−3) Set EPC to be the saved value of TCRestart.
31−4) Jump to the exception handler entry point passed by the sender.
32−
33−CAN WE PROVE THAT WE WON'T DO THIS IF INTS DISABLED??
34−*/
35−
36−/*
37− * Reviled and slandered vision: Set EXL and restore K/CU/IXMT
38− * state of pre-halt thread, then save everything and call
39− * thought some function pointer to imaginary_exception, which
40− * will parse a register value or memory message queue to
41− * deliver things like interprocessor interrupts. On return
42− * from that function, jump to the global ret_from_irq code
43− * to invoke the scheduler and return as appropriate.
44− */
45−
46−#define PT_PADSLOT4 (PT_R0-8)
47−#define PT_PADSLOT5 (PT_R0-4)
48−
49− .text
50− .align 5
51−FEXPORT(__smtc_ipi_vector)
52−#ifdef CONFIG_CPU_MICROMIPS
53− nop
54−#endif
55− .set noat
56− /* Disable thread scheduling to make Status update atomic */
57− DMT 27 # dmt k1
58− _ehb
59− /* Set EXL */
60− mfc0 k0,CP0_STATUS
61− ori k0,k0,ST0_EXL
62− mtc0 k0,CP0_STATUS
63− _ehb
64− /* Thread scheduling now inhibited by EXL. Restore TE state. */
65− andi k1,k1,VPECONTROL_TE
66− beqz k1,1f
67− emt
68−1:
69− /*
70− * The IPI sender has put some information on the anticipated
71− * kernel stack frame. If we were in user mode, this will be
72− * built above the saved kernel SP. If we were already in the
73− * kernel, it will be built above the current CPU SP.
74− *
75− * Were we in kernel mode, as indicated by CU0?
76− */
77− sll k1,k0,3
78− .set noreorder
79− bltz k1,2f
80− move k1,sp
81− .set reorder
82− /*
83− * If previously in user mode, set CU0 and use kernel stack.
84− */
85− li k1,ST0_CU0
86− or k1,k1,k0
87− mtc0 k1,CP0_STATUS
88− _ehb
89− get_saved_sp
90− /* Interrupting TC will have pre-set values in slots in the new frame */
91−2: subu k1,k1,PT_SIZE
92− /* Load TCStatus Value */
93− lw k0,PT_TCSTATUS(k1)
94− /* Write it to TCStatus to restore CU/KSU/IXMT state */
95− mtc0 k0,$2,1
96− _ehb
97− lw k0,PT_EPC(k1)
98− mtc0 k0,CP0_EPC
99− /* Save all will redundantly recompute the SP, but use it for now */
100− SAVE_ALL
101− CLI
102− TRACE_IRQS_OFF
103− /* Function to be invoked passed stack pad slot 5 */
104− lw t0,PT_PADSLOT5(sp)
105− /* Argument from sender passed in stack pad slot 4 */
106− lw a0,PT_PADSLOT4(sp)
107− LONG_L s0, TI_REGS($28)
108− LONG_S sp, TI_REGS($28)
109− PTR_LA ra, ret_from_irq
110− jr t0
111−
112−/*
113− * Called from idle loop to provoke processing of queued IPIs
114− * First IPI message in queue passed as argument.
115− */
116−
117−LEAF(self_ipi)
118− /* Before anything else, block interrupts */
119− mfc0 t0,CP0_TCSTATUS
120− ori t1,t0,TCSTATUS_IXMT
121− mtc0 t1,CP0_TCSTATUS
122− _ehb
123− /* We know we're in kernel mode, so prepare stack frame */
124− subu t1,sp,PT_SIZE
125− sw ra,PT_EPC(t1)
126− sw a0,PT_PADSLOT4(t1)
127− la t2,ipi_decode
128− sw t2,PT_PADSLOT5(t1)
129− /* Save pre-disable value of TCStatus */
130− sw t0,PT_TCSTATUS(t1)
131− j __smtc_ipi_vector
132− nop
133−END(self_ipi)
arch/mips/kernel/smtc-proc.c+0−102
@@ -1,102 +0,0 @@
1−/*
2− * /proc hooks for SMTC kernel
3− * Copyright (C) 2005 Mips Technologies, Inc
4− */
5−
6−#include <linux/kernel.h>
7−#include <linux/sched.h>
8−#include <linux/cpumask.h>
9−#include <linux/interrupt.h>
10−
11−#include <asm/cpu.h>
12−#include <asm/processor.h>
13−#include <linux/atomic.h>
14−#include <asm/hardirq.h>
15−#include <asm/mmu_context.h>
16−#include <asm/mipsregs.h>
17−#include <asm/cacheflush.h>
18−#include <linux/proc_fs.h>
19−#include <linux/seq_file.h>
20−
21−#include <asm/smtc_proc.h>
22−
23−/*
24− * /proc diagnostic and statistics hooks
25− */
26−
27−/*
28− * Statistics gathered
29− */
30−unsigned long selfipis[NR_CPUS];
31−
32−struct smtc_cpu_proc smtc_cpu_stats[NR_CPUS];
33−
34−atomic_t smtc_fpu_recoveries;
35−
36−static int smtc_proc_show(struct seq_file *m, void *v)
37−{
38− int i;
39− extern unsigned long ebase;
40−
41− seq_printf(m, "SMTC Status Word: 0x%08x\n", smtc_status);
42− seq_printf(m, "Config7: 0x%08x\n", read_c0_config7());
43− seq_printf(m, "EBASE: 0x%08lx\n", ebase);
44− seq_printf(m, "Counter Interrupts taken per CPU (TC)\n");
45− for (i=0; i < NR_CPUS; i++)
46− seq_printf(m, "%d: %ld\n", i, smtc_cpu_stats[i].timerints);
47− seq_printf(m, "Self-IPIs by CPU:\n");
48− for(i = 0; i < NR_CPUS; i++)
49− seq_printf(m, "%d: %ld\n", i, smtc_cpu_stats[i].selfipis);
50− seq_printf(m, "%d Recoveries of \"stolen\" FPU\n",
51− atomic_read(&smtc_fpu_recoveries));
52− return 0;
53−}
54−
55−static int smtc_proc_open(struct inode *inode, struct file *file)
56−{
57− return single_open(file, smtc_proc_show, NULL);
58−}
59−
60−static const struct file_operations smtc_proc_fops = {
61− .open = smtc_proc_open,
62− .read = seq_read,
63− .llseek = seq_lseek,
64− .release = single_release,
65−};
66−
67−void init_smtc_stats(void)
68−{
69− int i;
70−
71− for (i=0; i<NR_CPUS; i++) {
72− smtc_cpu_stats[i].timerints = 0;
73− smtc_cpu_stats[i].selfipis = 0;
74− }
75−
76− atomic_set(&smtc_fpu_recoveries, 0);
77−
78− proc_create("smtc", 0444, NULL, &smtc_proc_fops);
79−}
80−
81−static int proc_cpuinfo_chain_call(struct notifier_block *nfb,
82− unsigned long action_unused, void *data)
83−{
84− struct proc_cpuinfo_notifier_args *pcn = data;
85− struct seq_file *m = pcn->m;
86− unsigned long n = pcn->n;
87−
88− if (!cpu_has_mipsmt)
89− return NOTIFY_OK;
90−
91− seq_printf(m, "VPE\t\t\t: %d\n", cpu_data[n].vpe_id);
92− seq_printf(m, "TC\t\t\t: %d\n", cpu_data[n].tc_id);
93−
94− return NOTIFY_OK;
95−}
96−
97−static int __init proc_cpuinfo_notifier_init(void)
98−{
99− return proc_cpuinfo_notifier(proc_cpuinfo_chain_call, 0);
100−}
101−
102−subsys_initcall(proc_cpuinfo_notifier_init);
arch/mips/kernel/smtc.c+0−1528
@@ -1,1528 +0,0 @@
1−/*
2− * This program is free software; you can redistribute it and/or
3− * modify it under the terms of the GNU General Public License
4− * as published by the Free Software Foundation; either version 2
5− * of the License, or (at your option) any later version.
6− *
7− * This program is distributed in the hope that it will be useful,
8− * but WITHOUT ANY WARRANTY; without even the implied warranty of
9− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10− * GNU General Public License for more details.
11− *
12− * You should have received a copy of the GNU General Public License
13− * along with this program; if not, write to the Free Software
14− * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15− *
16− * Copyright (C) 2004 Mips Technologies, Inc
17− * Copyright (C) 2008 Kevin D. Kissell
18− */
19−
20−#include <linux/clockchips.h>
21−#include <linux/kernel.h>
22−#include <linux/sched.h>
23−#include <linux/smp.h>
24−#include <linux/cpumask.h>
25−#include <linux/interrupt.h>
26−#include <linux/kernel_stat.h>
27−#include <linux/module.h>
28−#include <linux/ftrace.h>
29−#include <linux/slab.h>
30−
31−#include <asm/cpu.h>
32−#include <asm/processor.h>
33−#include <linux/atomic.h>
34−#include <asm/hardirq.h>
35−#include <asm/hazards.h>
36−#include <asm/irq.h>
37−#include <asm/idle.h>
38−#include <asm/mmu_context.h>
39−#include <asm/mipsregs.h>
40−#include <asm/cacheflush.h>
41−#include <asm/time.h>
42−#include <asm/addrspace.h>
43−#include <asm/smtc.h>
44−#include <asm/smtc_proc.h>
45−#include <asm/setup.h>
46−
47−/*
48− * SMTC Kernel needs to manipulate low-level CPU interrupt mask
49− * in do_IRQ. These are passed in setup_irq_smtc() and stored
50− * in this table.
51− */
52−unsigned long irq_hwmask[NR_IRQS];
53−
54−#define LOCK_MT_PRA() \
55− local_irq_save(flags); \
56− mtflags = dmt()
57−
58−#define UNLOCK_MT_PRA() \
59− emt(mtflags); \
60− local_irq_restore(flags)
61−
62−#define LOCK_CORE_PRA() \
63− local_irq_save(flags); \
64− mtflags = dvpe()
65−
66−#define UNLOCK_CORE_PRA() \
67− evpe(mtflags); \
68− local_irq_restore(flags)
69−
70−/*
71− * Data structures purely associated with SMTC parallelism
72− */
73−
74−
75−/*
76− * Table for tracking ASIDs whose lifetime is prolonged.
77− */
78−
79−asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS];
80−
81−/*
82− * Number of InterProcessor Interrupt (IPI) message buffers to allocate
83− */
84−
85−#define IPIBUF_PER_CPU 4
86−
87−struct smtc_ipi_q IPIQ[NR_CPUS];
88−static struct smtc_ipi_q freeIPIq;
89−
90−
91−/*
92− * Number of FPU contexts for each VPE
93− */
94−
95−static int smtc_nconf1[MAX_SMTC_VPES];
96−
97−
98−/* Forward declarations */
99−
100−void ipi_decode(struct smtc_ipi *);
101−static void post_direct_ipi(int cpu, struct smtc_ipi *pipi);
102−static void setup_cross_vpe_interrupts(unsigned int nvpe);
103−void init_smtc_stats(void);
104−
105−/* Global SMTC Status */
106−
107−unsigned int smtc_status;
108−
109−/* Boot command line configuration overrides */
110−
111−static int vpe0limit;
112−static int ipibuffers;
113−static int nostlb;
114−static int asidmask;
115−unsigned long smtc_asid_mask = 0xff;
116−
117−static int __init vpe0tcs(char *str)
118−{
119− get_option(&str, &vpe0limit);
120−
121− return 1;
122−}
123−
124−static int __init ipibufs(char *str)
125−{
126− get_option(&str, &ipibuffers);
127− return 1;
128−}
129−
130−static int __init stlb_disable(char *s)
131−{
132− nostlb = 1;
133− return 1;
134−}
135−
136−static int __init asidmask_set(char *str)
137−{
138− get_option(&str, &asidmask);
139− switch (asidmask) {
140− case 0x1:
141− case 0x3:
142− case 0x7:
143− case 0xf:
144− case 0x1f:
145− case 0x3f:
146− case 0x7f:
147− case 0xff:
148− smtc_asid_mask = (unsigned long)asidmask;
149− break;
150− default:
151− printk("ILLEGAL ASID mask 0x%x from command line\n", asidmask);
152− }
153− return 1;
154−}
155−
156−__setup("vpe0tcs=", vpe0tcs);
157−__setup("ipibufs=", ipibufs);
158−__setup("nostlb", stlb_disable);
159−__setup("asidmask=", asidmask_set);
160−
161−#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
162−
163−static int hang_trig;
164−
165−static int __init hangtrig_enable(char *s)
166−{
167− hang_trig = 1;
168− return 1;
169−}
170−
171−
172−__setup("hangtrig", hangtrig_enable);
173−
174−#define DEFAULT_BLOCKED_IPI_LIMIT 32
175−
176−static int timerq_limit = DEFAULT_BLOCKED_IPI_LIMIT;
177−
178−static int __init tintq(char *str)
179−{
180− get_option(&str, &timerq_limit);
181− return 1;
182−}
183−
184−__setup("tintq=", tintq);
185−
186−static int imstuckcount[MAX_SMTC_VPES][8];
187−/* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */
188−static int vpemask[MAX_SMTC_VPES][8] = {
189− {0, 0, 1, 0, 0, 0, 0, 1},
190− {0, 0, 0, 0, 0, 0, 0, 1}
191−};
192−int tcnoprog[NR_CPUS];
193−static atomic_t idle_hook_initialized = ATOMIC_INIT(0);
194−static int clock_hang_reported[NR_CPUS];
195−
196−#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
197−
198−/*
199− * Configure shared TLB - VPC configuration bit must be set by caller
200− */
201−
202−static void smtc_configure_tlb(void)
203−{
204− int i, tlbsiz, vpes;
205− unsigned long mvpconf0;
206− unsigned long config1val;
207−
208− /* Set up ASID preservation table */
209− for (vpes=0; vpes<MAX_SMTC_TLBS; vpes++) {
210− for(i = 0; i < MAX_SMTC_ASIDS; i++) {
211− smtc_live_asid[vpes][i] = 0;
212− }
213− }
214− mvpconf0 = read_c0_mvpconf0();
215−
216− if ((vpes = ((mvpconf0 & MVPCONF0_PVPE)
217− >> MVPCONF0_PVPE_SHIFT) + 1) > 1) {
218− /* If we have multiple VPEs, try to share the TLB */
219− if ((mvpconf0 & MVPCONF0_TLBS) && !nostlb) {
220− /*
221− * If TLB sizing is programmable, shared TLB
222− * size is the total available complement.
223− * Otherwise, we have to take the sum of all
224− * static VPE TLB entries.
225− */
226− if ((tlbsiz = ((mvpconf0 & MVPCONF0_PTLBE)
227− >> MVPCONF0_PTLBE_SHIFT)) == 0) {
228− /*
229− * If there's more than one VPE, there had better
230− * be more than one TC, because we need one to bind
231− * to each VPE in turn to be able to read
232− * its configuration state!
233− */
234− settc(1);
235− /* Stop the TC from doing anything foolish */
236− write_tc_c0_tchalt(TCHALT_H);
237− mips_ihb();
238− /* No need to un-Halt - that happens later anyway */
239− for (i=0; i < vpes; i++) {
240− write_tc_c0_tcbind(i);
241− /*
242− * To be 100% sure we're really getting the right
243− * information, we exit the configuration state
244− * and do an IHB after each rebinding.
245− */
246− write_c0_mvpcontrol(
247− read_c0_mvpcontrol() & ~ MVPCONTROL_VPC );
248− mips_ihb();
249− /*
250− * Only count if the MMU Type indicated is TLB
251− */
252− if (((read_vpe_c0_config() & MIPS_CONF_MT) >> 7) == 1) {
253− config1val = read_vpe_c0_config1();
254− tlbsiz += ((config1val >> 25) & 0x3f) + 1;
255− }
256−
257− /* Put core back in configuration state */
258− write_c0_mvpcontrol(
259− read_c0_mvpcontrol() | MVPCONTROL_VPC );
260− mips_ihb();
261− }
262− }
263− write_c0_mvpcontrol(read_c0_mvpcontrol() | MVPCONTROL_STLB);
264− ehb();
265−
266− /*
267− * Setup kernel data structures to use software total,
268− * rather than read the per-VPE Config1 value. The values
269− * for "CPU 0" gets copied to all the other CPUs as part
270− * of their initialization in smtc_cpu_setup().
271− */
272−
273− /* MIPS32 limits TLB indices to 64 */
274− if (tlbsiz > 64)
275− tlbsiz = 64;
276− cpu_data[0].tlbsize = current_cpu_data.tlbsize = tlbsiz;
277− smtc_status |= SMTC_TLB_SHARED;
278− local_flush_tlb_all();
279−
280− printk("TLB of %d entry pairs shared by %d VPEs\n",
281− tlbsiz, vpes);
282− } else {
283− printk("WARNING: TLB Not Sharable on SMTC Boot!\n");
284− }
285− }
286−}
287−
288−
289−/*
290− * Incrementally build the CPU map out of constituent MIPS MT cores,
291− * using the specified available VPEs and TCs. Plaform code needs
292− * to ensure that each MIPS MT core invokes this routine on reset,
293− * one at a time(!).
294− *
295− * This version of the build_cpu_map and prepare_cpus routines assumes
296− * that *all* TCs of a MIPS MT core will be used for Linux, and that
297− * they will be spread across *all* available VPEs (to minimise the
298− * loss of efficiency due to exception service serialization).
299− * An improved version would pick up configuration information and
300− * possibly leave some TCs/VPEs as "slave" processors.
301− *
302− * Use c0_MVPConf0 to find out how many TCs are available, setting up
303− * cpu_possible_mask and the logical/physical mappings.
304− */
305−
306−int __init smtc_build_cpu_map(int start_cpu_slot)
307−{
308− int i, ntcs;
309−
310− /*
311− * The CPU map isn't actually used for anything at this point,
312− * so it's not clear what else we should do apart from set
313− * everything up so that "logical" = "physical".
314− */
315− ntcs = ((read_c0_mvpconf0() & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
316− for (i=start_cpu_slot; i<NR_CPUS && i<ntcs; i++) {
317− set_cpu_possible(i, true);
318− __cpu_number_map[i] = i;
319− __cpu_logical_map[i] = i;
320− }
321−#ifdef CONFIG_MIPS_MT_FPAFF
322− /* Initialize map of CPUs with FPUs */
323− cpus_clear(mt_fpu_cpumask);
324−#endif
325−
326− /* One of those TC's is the one booting, and not a secondary... */
327− printk("%i available secondary CPU TC(s)\n", i - 1);
328−
329− return i;
330−}
331−
332−/*
333− * Common setup before any secondaries are started
334− * Make sure all CPUs are in a sensible state before we boot any of the
335− * secondaries.
336− *
337− * For MIPS MT "SMTC" operation, we set up all TCs, spread as evenly
338− * as possible across the available VPEs.
339− */
340−
341−static void smtc_tc_setup(int vpe, int tc, int cpu)
342−{
343− static int cp1contexts[MAX_SMTC_VPES];
344−
345− /*
346− * Make a local copy of the available FPU contexts in order
347− * to keep track of TCs that can have one.
348− */
349− if (tc == 1)
350− {
351− /*
352− * FIXME: Multi-core SMTC hasn't been tested and the
353− * maximum number of VPEs may change.
354− */
355− cp1contexts[0] = smtc_nconf1[0] - 1;
356− cp1contexts[1] = smtc_nconf1[1];
357− }
358−
359− settc(tc);
360− write_tc_c0_tchalt(TCHALT_H);
361− mips_ihb();
362− write_tc_c0_tcstatus((read_tc_c0_tcstatus()
363− & ~(TCSTATUS_TKSU | TCSTATUS_DA | TCSTATUS_IXMT))
364− | TCSTATUS_A);
365− /*
366− * TCContext gets an offset from the base of the IPIQ array
367− * to be used in low-level code to detect the presence of
368− * an active IPI queue.
369− */
370− write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16);
371−
372− /* Bind TC to VPE. */
373− write_tc_c0_tcbind(vpe);
374−
375− /* In general, all TCs should have the same cpu_data indications. */
376− memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips));
377−
378− /* Check to see if there is a FPU context available for this TC. */
379− if (!cp1contexts[vpe])
380− cpu_data[cpu].options &= ~MIPS_CPU_FPU;
381− else
382− cp1contexts[vpe]--;
383−
384− /* Store the TC and VPE into the cpu_data structure. */
385− cpu_data[cpu].vpe_id = vpe;
386− cpu_data[cpu].tc_id = tc;
387−
388− /* FIXME: Multi-core SMTC hasn't been tested, but be prepared. */
389− cpu_data[cpu].core = (read_vpe_c0_ebase() >> 1) & 0xff;
390−}
391−
392−/*
393− * Tweak to get Count registers synced as closely as possible. The
394− * value seems good for 34K-class cores.
395− */
396−
397−#define CP0_SKEW 8
398−
399−void smtc_prepare_cpus(int cpus)
400−{
401− int i, vpe, tc, ntc, nvpe, tcpervpe[NR_CPUS], slop, cpu;
402− unsigned long flags;
403− unsigned long val;
404− int nipi;
405− struct smtc_ipi *pipi;
406−
407− /* disable interrupts so we can disable MT */
408− local_irq_save(flags);
409− /* disable MT so we can configure */
410− dvpe();
411− dmt();
412−
413− spin_lock_init(&freeIPIq.lock);
414−
415− /*
416− * We probably don't have as many VPEs as we do SMP "CPUs",
417− * but it's possible - and in any case we'll never use more!
418− */
419− for (i=0; i<NR_CPUS; i++) {
420− IPIQ[i].head = IPIQ[i].tail = NULL;
421− spin_lock_init(&IPIQ[i].lock);
422− IPIQ[i].depth = 0;
423− IPIQ[i].resched_flag = 0; /* No reschedules queued initially */
424− }
425−
426− /* cpu_data index starts at zero */
427− cpu = 0;
428− cpu_data[cpu].vpe_id = 0;
429− cpu_data[cpu].tc_id = 0;
430− cpu_data[cpu].core = (read_c0_ebase() >> 1) & 0xff;
431− cpu++;
432−
433− /* Report on boot-time options */
434− mips_mt_set_cpuoptions();
435− if (vpelimit > 0)
436− printk("Limit of %d VPEs set\n", vpelimit);
437− if (tclimit > 0)
438− printk("Limit of %d TCs set\n", tclimit);
439− if (nostlb) {
440− printk("Shared TLB Use Inhibited - UNSAFE for Multi-VPE Operation\n");
441− }
442− if (asidmask)
443− printk("ASID mask value override to 0x%x\n", asidmask);
444−
445− /* Temporary */
446−#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
447− if (hang_trig)
448− printk("Logic Analyser Trigger on suspected TC hang\n");
449−#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
450−
451− /* Put MVPE's into 'configuration state' */
452− write_c0_mvpcontrol( read_c0_mvpcontrol() | MVPCONTROL_VPC );
453−
454− val = read_c0_mvpconf0();
455− nvpe = ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
456− if (vpelimit > 0 && nvpe > vpelimit)
457− nvpe = vpelimit;
458− ntc = ((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
459− if (ntc > NR_CPUS)
460− ntc = NR_CPUS;
461− if (tclimit > 0 && ntc > tclimit)
462− ntc = tclimit;
463− slop = ntc % nvpe;
464− for (i = 0; i < nvpe; i++) {
465− tcpervpe[i] = ntc / nvpe;
466− if (slop) {
467− if((slop - i) > 0) tcpervpe[i]++;
468− }
469− }
470− /* Handle command line override for VPE0 */
471− if (vpe0limit > ntc) vpe0limit = ntc;
472− if (vpe0limit > 0) {
473− int slopslop;
474− if (vpe0limit < tcpervpe[0]) {
475− /* Reducing TC count - distribute to others */
476− slop = tcpervpe[0] - vpe0limit;
477− slopslop = slop % (nvpe - 1);
478− tcpervpe[0] = vpe0limit;
479− for (i = 1; i < nvpe; i++) {
480− tcpervpe[i] += slop / (nvpe - 1);
481− if(slopslop && ((slopslop - (i - 1) > 0)))
482− tcpervpe[i]++;
483− }
484− } else if (vpe0limit > tcpervpe[0]) {
485− /* Increasing TC count - steal from others */
486− slop = vpe0limit - tcpervpe[0];
487− slopslop = slop % (nvpe - 1);
488− tcpervpe[0] = vpe0limit;
489− for (i = 1; i < nvpe; i++) {
490− tcpervpe[i] -= slop / (nvpe - 1);
491− if(slopslop && ((slopslop - (i - 1) > 0)))
492− tcpervpe[i]--;
493− }
494− }
495− }
496−
497− /* Set up shared TLB */
498− smtc_configure_tlb();
499−
500− for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) {
501− /* Get number of CP1 contexts for each VPE. */
502− if (tc == 0)
503− {
504− /*
505− * Do not call settc() for TC0 or the FPU context
506− * value will be incorrect. Besides, we know that
507− * we are TC0 anyway.
508− */
509− smtc_nconf1[0] = ((read_vpe_c0_vpeconf1() &
510− VPECONF1_NCP1) >> VPECONF1_NCP1_SHIFT);
511− if (nvpe == 2)
512− {
513− settc(1);
514− smtc_nconf1[1] = ((read_vpe_c0_vpeconf1() &
515− VPECONF1_NCP1) >> VPECONF1_NCP1_SHIFT);
516− settc(0);
517− }
518− }
519− if (tcpervpe[vpe] == 0)
520− continue;
521− if (vpe != 0)
522− printk(", ");
523− printk("VPE %d: TC", vpe);
524− for (i = 0; i < tcpervpe[vpe]; i++) {
525− /*
526− * TC 0 is bound to VPE 0 at reset,
527− * and is presumably executing this
528− * code. Leave it alone!
529− */
530− if (tc != 0) {
531− smtc_tc_setup(vpe, tc, cpu);
532− if (vpe != 0) {
533− /*
534− * Set MVP bit (possibly again). Do it
535− * here to catch CPUs that have no TCs
536− * bound to the VPE at reset. In that
537− * case, a TC must be bound to the VPE
538− * before we can set VPEControl[MVP]
539− */
540− write_vpe_c0_vpeconf0(
541− read_vpe_c0_vpeconf0() |
542− VPECONF0_MVP);
543− }
544− cpu++;
545− }
546− printk(" %d", tc);
547− tc++;
548− }
549− if (vpe != 0) {
550− /*
551− * Allow this VPE to control others.
552− */
553− write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() |
554− VPECONF0_MVP);
555−
556− /*
557− * Clear any stale software interrupts from VPE's Cause
558− */
559− write_vpe_c0_cause(0);
560−
561− /*
562− * Clear ERL/EXL of VPEs other than 0
563− * and set restricted interrupt enable/mask.
564− */
565− write_vpe_c0_status((read_vpe_c0_status()
566− & ~(ST0_BEV | ST0_ERL | ST0_EXL | ST0_IM))
567− | (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP7
568− | ST0_IE));
569− /*
570− * set config to be the same as vpe0,
571− * particularly kseg0 coherency alg
572− */
573− write_vpe_c0_config(read_c0_config());
574− /* Clear any pending timer interrupt */
575− write_vpe_c0_compare(0);
576− /* Propagate Config7 */
577− write_vpe_c0_config7(read_c0_config7());
578− write_vpe_c0_count(read_c0_count() + CP0_SKEW);
579− ehb();
580− }
581− /* enable multi-threading within VPE */
582− write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() | VPECONTROL_TE);
583− /* enable the VPE */
584− write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
585− }
586−
587− /*
588− * Pull any physically present but unused TCs out of circulation.
589− */
590− while (tc < (((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1)) {
591− set_cpu_possible(tc, false);
592− set_cpu_present(tc, false);
593− tc++;
594− }
595−
596− /* release config state */
597− write_c0_mvpcontrol( read_c0_mvpcontrol() & ~ MVPCONTROL_VPC );
598−
599− printk("\n");
600−
601− /* Set up coprocessor affinity CPU mask(s) */
602−
603−#ifdef CONFIG_MIPS_MT_FPAFF
604− for (tc = 0; tc < ntc; tc++) {
605− if (cpu_data[tc].options & MIPS_CPU_FPU)
606− cpu_set(tc, mt_fpu_cpumask);
607− }
608−#endif
609−
610− /* set up ipi interrupts... */
611−
612− /* If we have multiple VPEs running, set up the cross-VPE interrupt */
613−
614− setup_cross_vpe_interrupts(nvpe);
615−
616− /* Set up queue of free IPI "messages". */
617− nipi = NR_CPUS * IPIBUF_PER_CPU;
618− if (ipibuffers > 0)
619− nipi = ipibuffers;
620−
621− pipi = kmalloc(nipi *sizeof(struct smtc_ipi), GFP_KERNEL);
622− if (pipi == NULL)
623− panic("kmalloc of IPI message buffers failed");
624− else
625− printk("IPI buffer pool of %d buffers\n", nipi);
626− for (i = 0; i < nipi; i++) {
627− smtc_ipi_nq(&freeIPIq, pipi);
628− pipi++;
629− }
630−
631− /* Arm multithreading and enable other VPEs - but all TCs are Halted */
632− emt(EMT_ENABLE);
633− evpe(EVPE_ENABLE);
634− local_irq_restore(flags);
635− /* Initialize SMTC /proc statistics/diagnostics */
636− init_smtc_stats();
637−}
638−
639−
640−/*
641− * Setup the PC, SP, and GP of a secondary processor and start it
642− * running!
643− * smp_bootstrap is the place to resume from
644− * __KSTK_TOS(idle) is apparently the stack pointer
645− * (unsigned long)idle->thread_info the gp
646− *
647− */
648−void smtc_boot_secondary(int cpu, struct task_struct *idle)
649−{
650− extern u32 kernelsp[NR_CPUS];
651− unsigned long flags;
652− int mtflags;
653−
654− LOCK_MT_PRA();
655− if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) {
656− dvpe();
657− }
658− settc(cpu_data[cpu].tc_id);
659−
660− /* pc */
661− write_tc_c0_tcrestart((unsigned long)&smp_bootstrap);
662−
663− /* stack pointer */
664− kernelsp[cpu] = __KSTK_TOS(idle);
665− write_tc_gpr_sp(__KSTK_TOS(idle));
666−
667− /* global pointer */
668− write_tc_gpr_gp((unsigned long)task_thread_info(idle));
669−
670− smtc_status |= SMTC_MTC_ACTIVE;
671− write_tc_c0_tchalt(0);
672− if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) {
673− evpe(EVPE_ENABLE);
674− }
675− UNLOCK_MT_PRA();
676−}
677−
678−void smtc_init_secondary(void)
679−{
680−}
681−
682−void smtc_smp_finish(void)
683−{
684− int cpu = smp_processor_id();
685−
686− /*
687− * Lowest-numbered CPU per VPE starts a clock tick.
688− * Like per_cpu_trap_init() hack, this assumes that
689− * SMTC init code assigns TCs consdecutively and
690− * in ascending order across available VPEs.
691− */
692− if (cpu > 0 && (cpu_data[cpu].vpe_id != cpu_data[cpu - 1].vpe_id))
693− write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ);
694−
695− local_irq_enable();
696−
697− printk("TC %d going on-line as CPU %d\n",
698− cpu_data[smp_processor_id()].tc_id, smp_processor_id());
699−}
700−
701−void smtc_cpus_done(void)
702−{
703−}
704−
705−/*
706− * Support for SMTC-optimized driver IRQ registration
707− */
708−
709−/*
710− * SMTC Kernel needs to manipulate low-level CPU interrupt mask
711− * in do_IRQ. These are passed in setup_irq_smtc() and stored
712− * in this table.
713− */
714−
715−int setup_irq_smtc(unsigned int irq, struct irqaction * new,
716− unsigned long hwmask)
717−{
718−#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
719− unsigned int vpe = current_cpu_data.vpe_id;
720−
721− vpemask[vpe][irq - MIPS_CPU_IRQ_BASE] = 1;
722−#endif
723− irq_hwmask[irq] = hwmask;
724−
725− return setup_irq(irq, new);
726−}
727−
728−#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
729−/*
730− * Support for IRQ affinity to TCs
731− */
732−
733−void smtc_set_irq_affinity(unsigned int irq, cpumask_t affinity)
734−{
735− /*
736− * If a "fast path" cache of quickly decodable affinity state
737− * is maintained, this is where it gets done, on a call up
738− * from the platform affinity code.
739− */
740−}
741−
742−void smtc_forward_irq(struct irq_data *d)
743−{
744− unsigned int irq = d->irq;
745− int target;
746−
747− /*
748− * OK wise guy, now figure out how to get the IRQ
749− * to be serviced on an authorized "CPU".
750− *
751− * Ideally, to handle the situation where an IRQ has multiple
752− * eligible CPUS, we would maintain state per IRQ that would
753− * allow a fair distribution of service requests. Since the
754− * expected use model is any-or-only-one, for simplicity
755− * and efficiency, we just pick the easiest one to find.
756− */
757−
758− target = cpumask_first(d->affinity);
759−
760− /*
761− * We depend on the platform code to have correctly processed
762− * IRQ affinity change requests to ensure that the IRQ affinity
763− * mask has been purged of bits corresponding to nonexistent and
764− * offline "CPUs", and to TCs bound to VPEs other than the VPE
765− * connected to the physical interrupt input for the interrupt
766− * in question. Otherwise we have a nasty problem with interrupt
767− * mask management. This is best handled in non-performance-critical
768− * platform IRQ affinity setting code, to minimize interrupt-time
769− * checks.
770− */
771−
772− /* If no one is eligible, service locally */
773− if (target >= NR_CPUS)
774− do_IRQ_no_affinity(irq);
775− else
776− smtc_send_ipi(target, IRQ_AFFINITY_IPI, irq);
777−}
778−
779−#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
780−
781−/*
782− * IPI model for SMTC is tricky, because interrupts aren't TC-specific.
783− * Within a VPE one TC can interrupt another by different approaches.
784− * The easiest to get right would probably be to make all TCs except
785− * the target IXMT and set a software interrupt, but an IXMT-based
786− * scheme requires that a handler must run before a new IPI could
787− * be sent, which would break the "broadcast" loops in MIPS MT.
788− * A more gonzo approach within a VPE is to halt the TC, extract
789− * its Restart, Status, and a couple of GPRs, and program the Restart
790− * address to emulate an interrupt.
791− *
792− * Within a VPE, one can be confident that the target TC isn't in
793− * a critical EXL state when halted, since the write to the Halt
794− * register could not have issued on the writing thread if the
795− * halting thread had EXL set. So k0 and k1 of the target TC
796− * can be used by the injection code. Across VPEs, one can't
797− * be certain that the target TC isn't in a critical exception
798− * state. So we try a two-step process of sending a software
799− * interrupt to the target VPE, which either handles the event
800− * itself (if it was the target) or injects the event within
801− * the VPE.
802− */
803−
804−static void smtc_ipi_qdump(void)
805−{
806− int i;
807− struct smtc_ipi *temp;
808−
809− for (i = 0; i < NR_CPUS ;i++) {
810− pr_info("IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n",
811− i, (unsigned)IPIQ[i].head, (unsigned)IPIQ[i].tail,
812− IPIQ[i].depth);
813− temp = IPIQ[i].head;
814−
815− while (temp != IPIQ[i].tail) {
816− pr_debug("%d %d %d: ", temp->type, temp->dest,
817− (int)temp->arg);
818−#ifdef SMTC_IPI_DEBUG
819− pr_debug("%u %lu\n", temp->sender, temp->stamp);
820−#else
821− pr_debug("\n");
822−#endif
823− temp = temp->flink;
824− }
825− }
826−}
827−
828−/*
829− * The standard atomic.h primitives don't quite do what we want
830− * here: We need an atomic add-and-return-previous-value (which
831− * could be done with atomic_add_return and a decrement) and an
832− * atomic set/zero-and-return-previous-value (which can't really
833− * be done with the atomic.h primitives). And since this is
834− * MIPS MT, we can assume that we have LL/SC.
835− */
836−static inline int atomic_postincrement(atomic_t *v)
837−{
838− unsigned long result;
839−
840− unsigned long temp;
841−
842− __asm__ __volatile__(
843− "1: ll %0, %2 \n"
844− " addu %1, %0, 1 \n"
845− " sc %1, %2 \n"
846− " beqz %1, 1b \n"
847− __WEAK_LLSC_MB
848− : "=&r" (result), "=&r" (temp), "=m" (v->counter)
849− : "m" (v->counter)
850− : "memory");
851−
852− return result;
853−}
854−
855−void smtc_send_ipi(int cpu, int type, unsigned int action)
856−{
857− int tcstatus;
858− struct smtc_ipi *pipi;
859− unsigned long flags;
860− int mtflags;
861− unsigned long tcrestart;
862− int set_resched_flag = (type == LINUX_SMP_IPI &&
863− action == SMP_RESCHEDULE_YOURSELF);
864−
865− if (cpu == smp_processor_id()) {
866− printk("Cannot Send IPI to self!\n");
867− return;
868− }
869− if (set_resched_flag && IPIQ[cpu].resched_flag != 0)
870− return; /* There is a reschedule queued already */
871−
872− /* Set up a descriptor, to be delivered either promptly or queued */
873− pipi = smtc_ipi_dq(&freeIPIq);
874− if (pipi == NULL) {
875− bust_spinlocks(1);
876− mips_mt_regdump(dvpe());
877− panic("IPI Msg. Buffers Depleted");
878− }
879− pipi->type = type;
880− pipi->arg = (void *)action;
881− pipi->dest = cpu;
882− if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) {
883− /* If not on same VPE, enqueue and send cross-VPE interrupt */
884− IPIQ[cpu].resched_flag |= set_resched_flag;
885− smtc_ipi_nq(&IPIQ[cpu], pipi);
886− LOCK_CORE_PRA();
887− settc(cpu_data[cpu].tc_id);
888− write_vpe_c0_cause(read_vpe_c0_cause() | C_SW1);
889− UNLOCK_CORE_PRA();
890− } else {
891− /*
892− * Not sufficient to do a LOCK_MT_PRA (dmt) here,
893− * since ASID shootdown on the other VPE may
894− * collide with this operation.
895− */
896− LOCK_CORE_PRA();
897− settc(cpu_data[cpu].tc_id);
898− /* Halt the targeted TC */
899− write_tc_c0_tchalt(TCHALT_H);
900− mips_ihb();
901−
902− /*
903− * Inspect TCStatus - if IXMT is set, we have to queue
904− * a message. Otherwise, we set up the "interrupt"
905− * of the other TC
906− */
907− tcstatus = read_tc_c0_tcstatus();
908−
909− if ((tcstatus & TCSTATUS_IXMT) != 0) {
910− /*
911− * If we're in the the irq-off version of the wait
912− * loop, we need to force exit from the wait and
913− * do a direct post of the IPI.
914− */
915− if (cpu_wait == r4k_wait_irqoff) {
916− tcrestart = read_tc_c0_tcrestart();
917− if (address_is_in_r4k_wait_irqoff(tcrestart)) {
918− write_tc_c0_tcrestart(__pastwait);
919− tcstatus &= ~TCSTATUS_IXMT;
920− write_tc_c0_tcstatus(tcstatus);
921− goto postdirect;
922− }
923− }
924− /*
925− * Otherwise we queue the message for the target TC
926− * to pick up when he does a local_irq_restore()
927− */
928− write_tc_c0_tchalt(0);
929− UNLOCK_CORE_PRA();
930− IPIQ[cpu].resched_flag |= set_resched_flag;
931− smtc_ipi_nq(&IPIQ[cpu], pipi);
932− } else {
933−postdirect:
934− post_direct_ipi(cpu, pipi);
935− write_tc_c0_tchalt(0);
936− UNLOCK_CORE_PRA();
937− }
938− }
939−}
940−
941−/*
942− * Send IPI message to Halted TC, TargTC/TargVPE already having been set
943− */
944−static void post_direct_ipi(int cpu, struct smtc_ipi *pipi)
945−{
946− struct pt_regs *kstack;
947− unsigned long tcstatus;
948− unsigned long tcrestart;
949− extern u32 kernelsp[NR_CPUS];
950− extern void __smtc_ipi_vector(void);
951−//printk("%s: on %d for %d\n", __func__, smp_processor_id(), cpu);
952−
953− /* Extract Status, EPC from halted TC */
954− tcstatus = read_tc_c0_tcstatus();
955− tcrestart = read_tc_c0_tcrestart();
956− /* If TCRestart indicates a WAIT instruction, advance the PC */
957− if ((tcrestart & 0x80000000)
958− && ((*(unsigned int *)tcrestart & 0xfe00003f) == 0x42000020)) {
959− tcrestart += 4;
960− }
961− /*
962− * Save on TC's future kernel stack
963− *
964− * CU bit of Status is indicator that TC was
965− * already running on a kernel stack...
966− */
967− if (tcstatus & ST0_CU0) {
968− /* Note that this "- 1" is pointer arithmetic */
969− kstack = ((struct pt_regs *)read_tc_gpr_sp()) - 1;
970− } else {
971− kstack = ((struct pt_regs *)kernelsp[cpu]) - 1;
972− }
973−
974− kstack->cp0_epc = (long)tcrestart;
975− /* Save TCStatus */
976− kstack->cp0_tcstatus = tcstatus;
977− /* Pass token of operation to be performed kernel stack pad area */
978− kstack->pad0[4] = (unsigned long)pipi;
979− /* Pass address of function to be called likewise */
980− kstack->pad0[5] = (unsigned long)&ipi_decode;
981− /* Set interrupt exempt and kernel mode */
982− tcstatus |= TCSTATUS_IXMT;
983− tcstatus &= ~TCSTATUS_TKSU;
984− write_tc_c0_tcstatus(tcstatus);
985− ehb();
986− /* Set TC Restart address to be SMTC IPI vector */
987− write_tc_c0_tcrestart(__smtc_ipi_vector);
988−}
989−
990−static void ipi_resched_interrupt(void)
991−{
992− scheduler_ipi();
993−}
994−
995−static void ipi_call_interrupt(void)
996−{
997− /* Invoke generic function invocation code in smp.c */
998− smp_call_function_interrupt();
999−}
1000−
1001−DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device);
1002−
1003−static void __irq_entry smtc_clock_tick_interrupt(void)
1004−{
1005− unsigned int cpu = smp_processor_id();
1006− struct clock_event_device *cd;
1007− int irq = MIPS_CPU_IRQ_BASE + 1;
1008−
1009− irq_enter();
1010− kstat_incr_irq_this_cpu(irq);
1011− cd = &per_cpu(mips_clockevent_device, cpu);
1012− cd->event_handler(cd);
1013− irq_exit();
1014−}
1015−
1016−void ipi_decode(struct smtc_ipi *pipi)
1017−{
1018− void *arg_copy = pipi->arg;
1019− int type_copy = pipi->type;
1020−
1021− smtc_ipi_nq(&freeIPIq, pipi);
1022−
1023− switch (type_copy) {
1024− case SMTC_CLOCK_TICK:
1025− smtc_clock_tick_interrupt();
1026− break;
1027−
1028− case LINUX_SMP_IPI:
1029− switch ((int)arg_copy) {
1030− case SMP_RESCHEDULE_YOURSELF:
1031− ipi_resched_interrupt();
1032− break;
1033− case SMP_CALL_FUNCTION:
1034− ipi_call_interrupt();
1035− break;
1036− default:
1037− printk("Impossible SMTC IPI Argument %p\n", arg_copy);
1038− break;
1039− }
1040− break;
1041−#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
1042− case IRQ_AFFINITY_IPI:
1043− /*
1044− * Accept a "forwarded" interrupt that was initially
1045− * taken by a TC who doesn't have affinity for the IRQ.
1046− */
1047− do_IRQ_no_affinity((int)arg_copy);
1048− break;
1049−#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
1050− default:
1051− printk("Impossible SMTC IPI Type 0x%x\n", type_copy);
1052− break;
1053− }
1054−}
1055−
1056−/*
1057− * Similar to smtc_ipi_replay(), but invoked from context restore,
1058− * so it reuses the current exception frame rather than set up a
1059− * new one with self_ipi.
1060− */
1061−
1062−void deferred_smtc_ipi(void)
1063−{
1064− int cpu = smp_processor_id();
1065−
1066− /*
1067− * Test is not atomic, but much faster than a dequeue,
1068− * and the vast majority of invocations will have a null queue.
1069− * If irq_disabled when this was called, then any IPIs queued
1070− * after we test last will be taken on the next irq_enable/restore.
1071− * If interrupts were enabled, then any IPIs added after the
1072− * last test will be taken directly.
1073− */
1074−
1075− while (IPIQ[cpu].head != NULL) {
1076− struct smtc_ipi_q *q = &IPIQ[cpu];
1077− struct smtc_ipi *pipi;
1078− unsigned long flags;
1079−
1080− /*
1081− * It may be possible we'll come in with interrupts
1082− * already enabled.
1083− */
1084− local_irq_save(flags);
1085− spin_lock(&q->lock);
1086− pipi = __smtc_ipi_dq(q);
1087− spin_unlock(&q->lock);
1088− if (pipi != NULL) {
1089− if (pipi->type == LINUX_SMP_IPI &&
1090− (int)pipi->arg == SMP_RESCHEDULE_YOURSELF)
1091− IPIQ[cpu].resched_flag = 0;
1092− ipi_decode(pipi);
1093− }
1094− /*
1095− * The use of the __raw_local restore isn't
1096− * as obviously necessary here as in smtc_ipi_replay(),
1097− * but it's more efficient, given that we're already
1098− * running down the IPI queue.
1099− */
1100− __arch_local_irq_restore(flags);
1101− }
1102−}
1103−
1104−/*
1105− * Cross-VPE interrupts in the SMTC prototype use "software interrupts"
1106− * set via cross-VPE MTTR manipulation of the Cause register. It would be
1107− * in some regards preferable to have external logic for "doorbell" hardware
1108− * interrupts.
1109− */
1110−
1111−static int cpu_ipi_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_IRQ;
1112−
1113−static irqreturn_t ipi_interrupt(int irq, void *dev_idm)
1114−{
1115− int my_vpe = cpu_data[smp_processor_id()].vpe_id;
1116− int my_tc = cpu_data[smp_processor_id()].tc_id;
1117− int cpu;
1118− struct smtc_ipi *pipi;
1119− unsigned long tcstatus;
1120− int sent;
1121− unsigned long flags;
1122− unsigned int mtflags;
1123− unsigned int vpflags;
1124−
1125− /*
1126− * So long as cross-VPE interrupts are done via
1127− * MFTR/MTTR read-modify-writes of Cause, we need
1128− * to stop other VPEs whenever the local VPE does
1129− * anything similar.
1130− */
1131− local_irq_save(flags);
1132− vpflags = dvpe();
1133− clear_c0_cause(0x100 << MIPS_CPU_IPI_IRQ);
1134− set_c0_status(0x100 << MIPS_CPU_IPI_IRQ);
1135− irq_enable_hazard();
1136− evpe(vpflags);
1137− local_irq_restore(flags);
1138−
1139− /*
1140− * Cross-VPE Interrupt handler: Try to directly deliver IPIs
1141− * queued for TCs on this VPE other than the current one.
1142− * Return-from-interrupt should cause us to drain the queue
1143− * for the current TC, so we ought not to have to do it explicitly here.
1144− */
1145−
1146− for_each_online_cpu(cpu) {
1147− if (cpu_data[cpu].vpe_id != my_vpe)
1148− continue;
1149−
1150− pipi = smtc_ipi_dq(&IPIQ[cpu]);
1151− if (pipi != NULL) {
1152− if (cpu_data[cpu].tc_id != my_tc) {
1153− sent = 0;
1154− LOCK_MT_PRA();
1155− settc(cpu_data[cpu].tc_id);
1156− write_tc_c0_tchalt(TCHALT_H);
1157− mips_ihb();
1158− tcstatus = read_tc_c0_tcstatus();
1159− if ((tcstatus & TCSTATUS_IXMT) == 0) {
1160− post_direct_ipi(cpu, pipi);
1161− sent = 1;
1162− }
1163− write_tc_c0_tchalt(0);
1164− UNLOCK_MT_PRA();
1165− if (!sent) {
1166− smtc_ipi_req(&IPIQ[cpu], pipi);
1167− }
1168− } else {
1169− /*
1170− * ipi_decode() should be called
1171− * with interrupts off
1172− */
1173− local_irq_save(flags);
1174− if (pipi->type == LINUX_SMP_IPI &&
1175− (int)pipi->arg == SMP_RESCHEDULE_YOURSELF)
1176− IPIQ[cpu].resched_flag = 0;
1177− ipi_decode(pipi);
1178− local_irq_restore(flags);
1179− }
1180− }
1181− }
1182−
1183− return IRQ_HANDLED;
1184−}
1185−
1186−static void ipi_irq_dispatch(void)
1187−{
1188− do_IRQ(cpu_ipi_irq);
1189−}
1190−
1191−static struct irqaction irq_ipi = {
1192− .handler = ipi_interrupt,
1193− .flags = IRQF_PERCPU,
1194− .name = "SMTC_IPI"
1195−};
1196−
1197−static void setup_cross_vpe_interrupts(unsigned int nvpe)
1198−{
1199− if (nvpe < 1)
1200− return;
1201−
1202− if (!cpu_has_vint)
1203− panic("SMTC Kernel requires Vectored Interrupt support");
1204−
1205− set_vi_handler(MIPS_CPU_IPI_IRQ, ipi_irq_dispatch);
1206−
1207− setup_irq_smtc(cpu_ipi_irq, &irq_ipi, (0x100 << MIPS_CPU_IPI_IRQ));
1208−
1209− irq_set_handler(cpu_ipi_irq, handle_percpu_irq);
1210−}
1211−
1212−/*
1213− * SMTC-specific hacks invoked from elsewhere in the kernel.
1214− */
1215−
1216− /*
1217− * smtc_ipi_replay is called from raw_local_irq_restore
1218− */
1219−
1220−void smtc_ipi_replay(void)
1221−{
1222− unsigned int cpu = smp_processor_id();
1223−
1224− /*
1225− * To the extent that we've ever turned interrupts off,
1226− * we may have accumulated deferred IPIs. This is subtle.
1227− * we should be OK: If we pick up something and dispatch
1228− * it here, that's great. If we see nothing, but concurrent
1229− * with this operation, another TC sends us an IPI, IXMT
1230− * is clear, and we'll handle it as a real pseudo-interrupt
1231− * and not a pseudo-pseudo interrupt. The important thing
1232− * is to do the last check for queued message *after* the
1233− * re-enabling of interrupts.
1234− */
1235− while (IPIQ[cpu].head != NULL) {
1236− struct smtc_ipi_q *q = &IPIQ[cpu];
1237− struct smtc_ipi *pipi;
1238− unsigned long flags;
1239−
1240− /*
1241− * It's just possible we'll come in with interrupts
1242− * already enabled.
1243− */
1244− local_irq_save(flags);
1245−
1246− spin_lock(&q->lock);
1247− pipi = __smtc_ipi_dq(q);
1248− spin_unlock(&q->lock);
1249− /*
1250− ** But use a raw restore here to avoid recursion.
1251− */
1252− __arch_local_irq_restore(flags);
1253−
1254− if (pipi) {
1255− self_ipi(pipi);
1256− smtc_cpu_stats[cpu].selfipis++;
1257− }
1258− }
1259−}
1260−
1261−EXPORT_SYMBOL(smtc_ipi_replay);
1262−
1263−void smtc_idle_loop_hook(void)
1264−{
1265−#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
1266− int im;
1267− int flags;
1268− int mtflags;
1269− int bit;
1270− int vpe;
1271− int tc;
1272− int hook_ntcs;
1273− /*
1274− * printk within DMT-protected regions can deadlock,
1275− * so buffer diagnostic messages for later output.
1276− */
1277− char *pdb_msg;
1278− char id_ho_db_msg[768]; /* worst-case use should be less than 700 */
1279−
1280− if (atomic_read(&idle_hook_initialized) == 0) { /* fast test */
1281− if (atomic_add_return(1, &idle_hook_initialized) == 1) {
1282− int mvpconf0;
1283− /* Tedious stuff to just do once */
1284− mvpconf0 = read_c0_mvpconf0();
1285− hook_ntcs = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
1286− if (hook_ntcs > NR_CPUS)
1287− hook_ntcs = NR_CPUS;
1288− for (tc = 0; tc < hook_ntcs; tc++) {
1289− tcnoprog[tc] = 0;
1290− clock_hang_reported[tc] = 0;
1291− }
1292− for (vpe = 0; vpe < 2; vpe++)
1293− for (im = 0; im < 8; im++)
1294− imstuckcount[vpe][im] = 0;
1295− printk("Idle loop test hook initialized for %d TCs\n", hook_ntcs);
1296− atomic_set(&idle_hook_initialized, 1000);
1297− } else {
1298− /* Someone else is initializing in parallel - let 'em finish */
1299− while (atomic_read(&idle_hook_initialized) < 1000)
1300− ;
1301− }
1302− }
1303−
1304− /* Have we stupidly left IXMT set somewhere? */
1305− if (read_c0_tcstatus() & 0x400) {
1306− write_c0_tcstatus(read_c0_tcstatus() & ~0x400);
1307− ehb();
1308− printk("Dangling IXMT in cpu_idle()\n");
1309− }
1310−
1311− /* Have we stupidly left an IM bit turned off? */
1312−#define IM_LIMIT 2000
1313− local_irq_save(flags);
1314− mtflags = dmt();
1315− pdb_msg = &id_ho_db_msg[0];
1316− im = read_c0_status();
1317− vpe = current_cpu_data.vpe_id;
1318− for (bit = 0; bit < 8; bit++) {
1319− /*
1320− * In current prototype, I/O interrupts
1321− * are masked for VPE > 0
1322− */
1323− if (vpemask[vpe][bit]) {
1324− if (!(im & (0x100 << bit)))
1325− imstuckcount[vpe][bit]++;
1326− else
1327− imstuckcount[vpe][bit] = 0;
1328− if (imstuckcount[vpe][bit] > IM_LIMIT) {
1329− set_c0_status(0x100 << bit);
1330− ehb();
1331− imstuckcount[vpe][bit] = 0;
1332− pdb_msg += sprintf(pdb_msg,
1333− "Dangling IM %d fixed for VPE %d\n", bit,
1334− vpe);
1335− }
1336− }
1337− }
1338−
1339− emt(mtflags);
1340− local_irq_restore(flags);
1341− if (pdb_msg != &id_ho_db_msg[0])
1342− printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg);
1343−#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
1344−
1345− smtc_ipi_replay();
1346−}
1347−
1348−void smtc_soft_dump(void)
1349−{
1350− int i;
1351−
1352− printk("Counter Interrupts taken per CPU (TC)\n");
1353− for (i=0; i < NR_CPUS; i++) {
1354− printk("%d: %ld\n", i, smtc_cpu_stats[i].timerints);
1355− }
1356− printk("Self-IPI invocations:\n");
1357− for (i=0; i < NR_CPUS; i++) {
1358− printk("%d: %ld\n", i, smtc_cpu_stats[i].selfipis);
1359− }
1360− smtc_ipi_qdump();
1361− printk("%d Recoveries of \"stolen\" FPU\n",
1362− atomic_read(&smtc_fpu_recoveries));
1363−}
1364−
1365−
1366−/*
1367− * TLB management routines special to SMTC
1368− */
1369−
1370−void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
1371−{
1372− unsigned long flags, mtflags, tcstat, prevhalt, asid;
1373− int tlb, i;
1374−
1375− /*
1376− * It would be nice to be able to use a spinlock here,
1377− * but this is invoked from within TLB flush routines
1378− * that protect themselves with DVPE, so if a lock is
1379− * held by another TC, it'll never be freed.
1380− *
1381− * DVPE/DMT must not be done with interrupts enabled,
1382− * so even so most callers will already have disabled
1383− * them, let's be really careful...
1384− */
1385−
1386− local_irq_save(flags);
1387− if (smtc_status & SMTC_TLB_SHARED) {
1388− mtflags = dvpe();
1389− tlb = 0;
1390− } else {
1391− mtflags = dmt();
1392− tlb = cpu_data[cpu].vpe_id;
1393− }
1394− asid = asid_cache(cpu);
1395−
1396− do {
1397− if (!((asid += ASID_INC) & ASID_MASK) ) {
1398− if (cpu_has_vtag_icache)
1399− flush_icache_all();
1400− /* Traverse all online CPUs (hack requires contiguous range) */
1401− for_each_online_cpu(i) {
1402− /*
1403− * We don't need to worry about our own CPU, nor those of
1404− * CPUs who don't share our TLB.
1405− */
1406− if ((i != smp_processor_id()) &&
1407− ((smtc_status & SMTC_TLB_SHARED) ||
1408− (cpu_data[i].vpe_id == cpu_data[cpu].vpe_id))) {
1409− settc(cpu_data[i].tc_id);
1410− prevhalt = read_tc_c0_tchalt() & TCHALT_H;
1411− if (!prevhalt) {
1412− write_tc_c0_tchalt(TCHALT_H);
1413− mips_ihb();
1414− }
1415− tcstat = read_tc_c0_tcstatus();
1416− smtc_live_asid[tlb][(tcstat & ASID_MASK)] |= (asiduse)(0x1 << i);
1417− if (!prevhalt)
1418− write_tc_c0_tchalt(0);
1419− }
1420− }
1421− if (!asid) /* fix version if needed */
1422− asid = ASID_FIRST_VERSION;
1423− local_flush_tlb_all(); /* start new asid cycle */
1424− }
1425− } while (smtc_live_asid[tlb][(asid & ASID_MASK)]);
1426−
1427− /*
1428− * SMTC shares the TLB within VPEs and possibly across all VPEs.
1429− */
1430− for_each_online_cpu(i) {
1431− if ((smtc_status & SMTC_TLB_SHARED) ||
1432− (cpu_data[i].vpe_id == cpu_data[cpu].vpe_id))
1433− cpu_context(i, mm) = asid_cache(i) = asid;
1434− }
1435−
1436− if (smtc_status & SMTC_TLB_SHARED)
1437− evpe(mtflags);
1438− else
1439− emt(mtflags);
1440− local_irq_restore(flags);
1441−}
1442−
1443−/*
1444− * Invoked from macros defined in mmu_context.h
1445− * which must already have disabled interrupts
1446− * and done a DVPE or DMT as appropriate.
1447− */
1448−
1449−void smtc_flush_tlb_asid(unsigned long asid)
1450−{
1451− int entry;
1452− unsigned long ehi;
1453−
1454− entry = read_c0_wired();
1455−
1456− /* Traverse all non-wired entries */
1457− while (entry < current_cpu_data.tlbsize) {
1458− write_c0_index(entry);
1459− ehb();
1460− tlb_read();
1461− ehb();
1462− ehi = read_c0_entryhi();
1463− if ((ehi & ASID_MASK) == asid) {
1464− /*
1465− * Invalidate only entries with specified ASID,
1466− * makiing sure all entries differ.
1467− */
1468− write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1)));
1469− write_c0_entrylo0(0);
1470− write_c0_entrylo1(0);
1471− mtc0_tlbw_hazard();
1472− tlb_write_indexed();
1473− }
1474− entry++;
1475− }
1476− write_c0_index(PARKED_INDEX);
1477− tlbw_use_hazard();
1478−}
1479−
1480−/*
1481− * Support for single-threading cache flush operations.
1482− */
1483−
1484−static int halt_state_save[NR_CPUS];
1485−
1486−/*
1487− * To really, really be sure that nothing is being done
1488− * by other TCs, halt them all. This code assumes that
1489− * a DVPE has already been done, so while their Halted
1490− * state is theoretically architecturally unstable, in
1491− * practice, it's not going to change while we're looking
1492− * at it.
1493− */
1494−
1495−void smtc_cflush_lockdown(void)
1496−{
1497− int cpu;
1498−
1499− for_each_online_cpu(cpu) {
1500− if (cpu != smp_processor_id()) {
1501− settc(cpu_data[cpu].tc_id);
1502− halt_state_save[cpu] = read_tc_c0_tchalt();
1503− write_tc_c0_tchalt(TCHALT_H);
1504− }
1505− }
1506− mips_ihb();
1507−}
1508−
1509−/* It would be cheating to change the cpu_online states during a flush! */
1510−
1511−void smtc_cflush_release(void)
1512−{
1513− int cpu;
1514−
1515− /*
1516− * Start with a hazard barrier to ensure
1517− * that all CACHE ops have played through.
1518− */
1519− mips_ihb();
1520−
1521− for_each_online_cpu(cpu) {
1522− if (cpu != smp_processor_id()) {
1523− settc(cpu_data[cpu].tc_id);
1524− write_tc_c0_tchalt(halt_state_save[cpu]);
1525− }
1526− }
1527− mips_ihb();
1528−}
arch/mips/kernel/sync-r4k.c+0−18
@@ -6,8 +6,6 @@ · 5 unmodified lines
66 * not have done anything significant (but they may have had interrupts
77 * enabled briefly - prom_smp_finish() should not be responsible for enabling
88 * interrupts...)
9− *
10− * FIXME: broken for SMTC
119 */
1210
1311 #include <linux/kernel.h>
@@ -33,14 +31,6 @@ void synchronise_count_master(int cpu) · 19 unmodified lines
3331 unsigned long flags;
3432 unsigned int initcount;
3533
36−#ifdef CONFIG_MIPS_MT_SMTC
37− /*
38− * SMTC needs to synchronise per VPE, not per CPU
39− * ignore for now
40− */
41− return;
42−#endif
43−
4434 printk(KERN_INFO "Synchronize counters for CPU %u: ", cpu);
4535
4636 local_irq_save(flags);
@@ -110,14 +100,6 @@ void synchronise_count_slave(int cpu) · 63 unmodified lines
110100 int i;
111101 unsigned int initcount;
112102
113−#ifdef CONFIG_MIPS_MT_SMTC
114− /*
115− * SMTC needs to synchronise per VPE, not per CPU
116− * ignore for now
117− */
118− return;
119−#endif
120−
121103 /*
122104 * Not every cpu is online at the time this gets called,
123105 * so we first wait for the master to say everyone is ready
arch/mips/kernel/time.c+0−1
@@ -26,7 +26,6 @@ · 25 unmodified lines
2626 #include <asm/cpu-features.h>
2727 #include <asm/cpu-type.h>
2828 #include <asm/div64.h>
29−#include <asm/smtc_ipi.h>
3029 #include <asm/time.h>
3130
3231 /*
arch/mips/kernel/traps.c+54−68
@@ -15,6 +15,7 @@ · 14 unmodified lines
1515 #include <linux/bug.h>
1616 #include <linux/compiler.h>
1717 #include <linux/context_tracking.h>
18+#include <linux/cpu_pm.h>
1819 #include <linux/kexec.h>
1920 #include <linux/init.h>
2021 #include <linux/kernel.h>
@@ -370,9 +371,6 @@ void __noreturn die(const char *str, struct pt_regs *regs) · 349 unmodified lines
370371 {
371372 static int die_counter;
372373 int sig = SIGSEGV;
373−#ifdef CONFIG_MIPS_MT_SMTC
374− unsigned long dvpret;
375−#endif /* CONFIG_MIPS_MT_SMTC */
376374
377375 oops_enter();
378376
@@ -382,13 +380,7 @@ void __noreturn die(const char *str, struct pt_regs *regs) · 3 unmodified lines
382380
383381 console_verbose();
384382 raw_spin_lock_irq(&die_lock);
385−#ifdef CONFIG_MIPS_MT_SMTC
386− dvpret = dvpe();
387−#endif /* CONFIG_MIPS_MT_SMTC */
388383 bust_spinlocks(1);
389−#ifdef CONFIG_MIPS_MT_SMTC
390− mips_mt_regdump(dvpret);
391−#endif /* CONFIG_MIPS_MT_SMTC */
392384
393385 printk("%s[#%d]:\n", str, ++die_counter);
394386 show_registers(regs);
@@ -712,10 +704,12 @@ int process_fpemu_return(int sig, void __user *fault_addr) · 317 unmodified lines
712704 si.si_addr = fault_addr;
713705 si.si_signo = sig;
714706 if (sig == SIGSEGV) {
707+ down_read(&current->mm->mmap_sem);
715708 if (find_vma(current->mm, (unsigned long)fault_addr))
716709 si.si_code = SEGV_ACCERR;
717710 else
718711 si.si_code = SEGV_MAPERR;
712+ up_read(&current->mm->mmap_sem);
719713 } else {
720714 si.si_code = BUS_ADRERR;
721715 }
@@ -1759,19 +1753,6 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) · 1037 unmodified lines
17591753 extern char rollback_except_vec_vi;
17601754 char *vec_start = using_rollback_handler() ?
17611755 &rollback_except_vec_vi : &except_vec_vi;
1762−#ifdef CONFIG_MIPS_MT_SMTC
1763− /*
1764− * We need to provide the SMTC vectored interrupt handler
1765− * not only with the address of the handler, but with the
1766− * Status.IM bit to be masked before going there.
1767− */
1768− extern char except_vec_vi_mori;
1769−#if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN)
1770− const int mori_offset = &except_vec_vi_mori - vec_start + 2;
1771−#else
1772− const int mori_offset = &except_vec_vi_mori - vec_start;
1773−#endif
1774−#endif /* CONFIG_MIPS_MT_SMTC */
17751756 #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN)
17761757 const int lui_offset = &except_vec_vi_lui - vec_start + 2;
17771758 const int ori_offset = &except_vec_vi_ori - vec_start + 2;
@@ -1795,12 +1776,6 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) · 17 unmodified lines
17951776 #else
17961777 handler_len);
17971778 #endif
1798−#ifdef CONFIG_MIPS_MT_SMTC
1799− BUG_ON(n > 7); /* Vector index %d exceeds SMTC maximum. */
1800−
1801− h = (u16 *)(b + mori_offset);
1802− *h = (0x100 << n);
1803−#endif /* CONFIG_MIPS_MT_SMTC */
18041779 h = (u16 *)(b + lui_offset);
18051780 *h = (handler >> 16) & 0xffff;
18061781 h = (u16 *)(b + ori_offset);
@@ -1865,32 +1840,16 @@ static int __init ulri_disable(char *s) · 58 unmodified lines
18651840 }
18661841 __setup("noulri", ulri_disable);
18671842
1868−void per_cpu_trap_init(bool is_boot_cpu)
1843+/* configure STATUS register */
1844+static void configure_status(void)
18691845 {
1870− unsigned int cpu = smp_processor_id();
1871− unsigned int status_set = ST0_CU0;
1872− unsigned int hwrena = cpu_hwrena_impl_bits;
1873−#ifdef CONFIG_MIPS_MT_SMTC
1874− int secondaryTC = 0;
1875− int bootTC = (cpu == 0);
1876−
1877− /*
1878− * Only do per_cpu_trap_init() for first TC of Each VPE.
1879− * Note that this hack assumes that the SMTC init code
1880− * assigns TCs consecutively and in ascending order.
1881− */
1882−
1883− if (((read_c0_tcbind() & TCBIND_CURTC) != 0) &&
1884− ((read_c0_tcbind() & TCBIND_CURVPE) == cpu_data[cpu - 1].vpe_id))
1885− secondaryTC = 1;
1886−#endif /* CONFIG_MIPS_MT_SMTC */
1887−
18881846 /*
18891847 * Disable coprocessors and select 32-bit or 64-bit addressing
18901848 * and the 16/32 or 32/32 FPR register model. Reset the BEV
18911849 * flag that some firmware may have left set and the TS bit (for
18921850 * IP27). Set XX for ISA IV code to work.
18931851 */
1852+ unsigned int status_set = ST0_CU0;
18941853 #ifdef CONFIG_64BIT
18951854 status_set |= ST0_FR|ST0_KX|ST0_SX|ST0_UX;
18961855 #endif
@@ -1901,6 +1860,12 @@ void per_cpu_trap_init(bool is_boot_cpu) · 4 unmodified lines
19011860
19021861 change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
19031862 status_set);
1863+}
1864+
1865+/* configure HWRENA register */
1866+static void configure_hwrena(void)
1867+{
1868+ unsigned int hwrena = cpu_hwrena_impl_bits;
19041869
19051870 if (cpu_has_mips_r2)
19061871 hwrena |= 0x0000000f;
@@ -1910,11 +1875,10 @@ void per_cpu_trap_init(bool is_boot_cpu) · 3 unmodified lines
19101875
19111876 if (hwrena)
19121877 write_c0_hwrena(hwrena);
1878+}
19131879
1914−#ifdef CONFIG_MIPS_MT_SMTC
1915− if (!secondaryTC) {
1916−#endif /* CONFIG_MIPS_MT_SMTC */
1917−
1880+static void configure_exception_vector(void)
1881+{
19181882 if (cpu_has_veic || cpu_has_vint) {
19191883 unsigned long sr = set_c0_status(ST0_BEV);
19201884 write_c0_ebase(ebase);
@@ -1930,6 +1894,16 @@ void per_cpu_trap_init(bool is_boot_cpu) · 9 unmodified lines
19301894 } else
19311895 set_c0_cause(CAUSEF_IV);
19321896 }
1897+}
1898+
1899+void per_cpu_trap_init(bool is_boot_cpu)
1900+{
1901+ unsigned int cpu = smp_processor_id();
1902+
1903+ configure_status();
1904+ configure_hwrena();
1905+
1906+ configure_exception_vector();
19331907
19341908 /*
19351909 * Before R2 both interrupt numbers were fixed to 7, so on R2 only:
@@ -1949,10 +1923,6 @@ void per_cpu_trap_init(bool is_boot_cpu) · 13 unmodified lines
19491923 cp0_perfcount_irq = -1;
19501924 }
19511925
1952−#ifdef CONFIG_MIPS_MT_SMTC
1953− }
1954−#endif /* CONFIG_MIPS_MT_SMTC */
1955−
19561926 if (!cpu_data[cpu].asid_cache)
19571927 cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
19581928
@@ -1961,23 +1931,10 @@ void per_cpu_trap_init(bool is_boot_cpu) · 2 unmodified lines
19611931 BUG_ON(current->mm);
19621932 enter_lazy_tlb(&init_mm, current);
19631933
1964−#ifdef CONFIG_MIPS_MT_SMTC
1965− if (bootTC) {
1966−#endif /* CONFIG_MIPS_MT_SMTC */
19671934 /* Boot CPU's cache setup in setup_arch(). */
19681935 if (!is_boot_cpu)
19691936 cpu_cache_init();
19701937 tlb_init();
1971−#ifdef CONFIG_MIPS_MT_SMTC
1972− } else if (!secondaryTC) {
1973− /*
1974− * First TC in non-boot VPE must do subset of tlb_init()
1975− * for MMU countrol registers.
1976− */
1977− write_c0_pagemask(PM_DEFAULT_MASK);
1978− write_c0_wired(0);
1979− }
1980−#endif /* CONFIG_MIPS_MT_SMTC */
19811938 TLBMISS_HANDLER_SETUP();
19821939 }
19831940
@@ -2185,3 +2142,32 @@ void __init trap_init(void) · 201 unmodified lines
21852142
21862143 cu2_notifier(default_cu2_call, 0x80000000); /* Run last */
21872144 }
2145+
2146+static int trap_pm_notifier(struct notifier_block *self, unsigned long cmd,
2147+ void *v)
2148+{
2149+ switch (cmd) {
2150+ case CPU_PM_ENTER_FAILED:
2151+ case CPU_PM_EXIT:
2152+ configure_status();
2153+ configure_hwrena();
2154+ configure_exception_vector();
2155+
2156+ /* Restore register with CPU number for TLB handlers */
2157+ TLBMISS_HANDLER_RESTORE();
2158+
2159+ break;
2160+ }
2161+
2162+ return NOTIFY_OK;
2163+}
2164+
2165+static struct notifier_block trap_pm_notifier_block = {
2166+ .notifier_call = trap_pm_notifier,
2167+};
2168+
2169+static int __init trap_pm_init(void)
2170+{
2171+ return cpu_pm_register_notifier(&trap_pm_notifier_block);
2172+}
2173+arch_initcall(trap_pm_init);
arch/mips/kernel/vpe-mt.c+7−9
@@ -127,9 +127,8 @@ int vpe_run(struct vpe *v) · 126 unmodified lines
127127 clear_c0_mvpcontrol(MVPCONTROL_VPC);
128128
129129 /*
130− * SMTC/SMVP kernels manage VPE enable independently,
131− * but uniprocessor kernels need to turn it on, even
132− * if that wasn't the pre-dvpe() state.
130+ * SMVP kernels manage VPE enable independently, but uniprocessor
131+ * kernels need to turn it on, even if that wasn't the pre-dvpe() state.
133132 */
134133 #ifdef CONFIG_SMP
135134 evpe(vpeflags);
@@ -454,12 +453,11 @@ int __init vpe_module_init(void) · 318 unmodified lines
454453
455454 settc(tc);
456455
457− /* Any TC that is bound to VPE0 gets left as is - in
458− * case we are running SMTC on VPE0. A TC that is bound
459− * to any other VPE gets bound to VPE0, ideally I'd like
460− * to make it homeless but it doesn't appear to let me
461− * bind a TC to a non-existent VPE. Which is perfectly
462− * reasonable.
456+ /*
457+ * A TC that is bound to any other VPE gets bound to
458+ * VPE0, ideally I'd like to make it homeless but it
459+ * doesn't appear to let me bind a TC to a non-existent
460+ * VPE. Which is perfectly reasonable.
463461 *
464462 * The (un)bound state is visible to an EJTAG probe so
465463 * may notify GDB...
arch/mips/lantiq/irq.c+2−2
@@ -61,7 +61,7 @@ · 60 unmodified lines
6161 /* we have a cascade of 8 irqs */
6262 #define MIPS_CPU_IRQ_CASCADE 8
6363
64−#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
64+#ifdef CONFIG_MIPS_MT_SMP
6565 int gic_present;
6666 #endif
6767
@@ -440,7 +440,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) · 372 unmodified lines
440440 arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ, &irq_call);
441441 #endif
442442
443−#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
443+#ifndef CONFIG_MIPS_MT_SMP
444444 set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
445445 IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
446446 #else
arch/mips/lib/delay.c+3−5
@@ -11,7 +11,9 @@ · 10 unmodified lines
1111 #include <linux/module.h>
1212 #include <linux/param.h>
1313 #include <linux/smp.h>
14+#include <linux/stringify.h>
1415
16+#include <asm/asm.h>
1517 #include <asm/compiler.h>
1618 #include <asm/war.h>
1719
@@ -27,11 +29,7 @@ void __delay(unsigned long loops) · 9 unmodified lines
2729 " .set noreorder \n"
2830 " .align 3 \n"
2931 "1: bnez %0, 1b \n"
30−#if BITS_PER_LONG == 32
31− " subu %0, %1 \n"
32−#else
33− " dsubu %0, %1 \n"
34−#endif
32+ " " __stringify(LONG_SUBU) " %0, %1 \n"
3533 " .set reorder \n"
3634 : "=r" (loops)
3735 : GCC_DADDI_IMM_ASM() (1), "0" (loops));
arch/mips/lib/mips-atomic.c+6−40
@@ -15,7 +15,7 @@ · 14 unmodified lines
1515 #include <linux/export.h>
1616 #include <linux/stringify.h>
1717
18−#if !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC)
18+#ifndef CONFIG_CPU_MIPSR2
1919
2020 /*
2121 * For cli() we have to insert nops to make sure that the new value
@@ -42,12 +42,7 @@ notrace void arch_local_irq_disable(void) · 20 unmodified lines
4242 __asm__ __volatile__(
4343 " .set push \n"
4444 " .set noat \n"
45−#ifdef CONFIG_MIPS_MT_SMTC
46− " mfc0 $1, $2, 1 \n"
47− " ori $1, 0x400 \n"
48− " .set noreorder \n"
49− " mtc0 $1, $2, 1 \n"
50−#elif defined(CONFIG_CPU_MIPSR2)
45+#if defined(CONFIG_CPU_MIPSR2)
5146 /* see irqflags.h for inline function */
5247 #else
5348 " mfc0 $1,$12 \n"
@@ -77,13 +72,7 @@ notrace unsigned long arch_local_irq_save(void) · 23 unmodified lines
7772 " .set push \n"
7873 " .set reorder \n"
7974 " .set noat \n"
80−#ifdef CONFIG_MIPS_MT_SMTC
81− " mfc0 %[flags], $2, 1 \n"
82− " ori $1, %[flags], 0x400 \n"
83− " .set noreorder \n"
84− " mtc0 $1, $2, 1 \n"
85− " andi %[flags], %[flags], 0x400 \n"
86−#elif defined(CONFIG_CPU_MIPSR2)
75+#if defined(CONFIG_CPU_MIPSR2)
8776 /* see irqflags.h for inline function */
8877 #else
8978 " mfc0 %[flags], $12 \n"
@@ -108,29 +97,13 @@ notrace void arch_local_irq_restore(unsigned long flags) · 18 unmodified lines
10897 {
10998 unsigned long __tmp1;
11099
111−#ifdef CONFIG_MIPS_MT_SMTC
112− /*
113− * SMTC kernel needs to do a software replay of queued
114− * IPIs, at the cost of branch and call overhead on each
115− * local_irq_restore()
116− */
117− if (unlikely(!(flags & 0x0400)))
118− smtc_ipi_replay();
119−#endif
120100 preempt_disable();
121101
122102 __asm__ __volatile__(
123103 " .set push \n"
124104 " .set noreorder \n"
125105 " .set noat \n"
126−#ifdef CONFIG_MIPS_MT_SMTC
127− " mfc0 $1, $2, 1 \n"
128− " andi %[flags], 0x400 \n"
129− " ori $1, 0x400 \n"
130− " xori $1, 0x400 \n"
131− " or %[flags], $1 \n"
132− " mtc0 %[flags], $2, 1 \n"
133−#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
106+#if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
134107 /* see irqflags.h for inline function */
135108 #elif defined(CONFIG_CPU_MIPSR2)
136109 /* see irqflags.h for inline function */
@@ -163,14 +136,7 @@ notrace void __arch_local_irq_restore(unsigned long flags) · 26 unmodified lines
163136 " .set push \n"
164137 " .set noreorder \n"
165138 " .set noat \n"
166−#ifdef CONFIG_MIPS_MT_SMTC
167− " mfc0 $1, $2, 1 \n"
168− " andi %[flags], 0x400 \n"
169− " ori $1, 0x400 \n"
170− " xori $1, 0x400 \n"
171− " or %[flags], $1 \n"
172− " mtc0 %[flags], $2, 1 \n"
173−#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
139+#if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
174140 /* see irqflags.h for inline function */
175141 #elif defined(CONFIG_CPU_MIPSR2)
176142 /* see irqflags.h for inline function */
@@ -192,4 +158,4 @@ notrace void __arch_local_irq_restore(unsigned long flags) · 15 unmodified lines
192158 }
193159 EXPORT_SYMBOL(__arch_local_irq_restore);
194160
195−#endif /* !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) */
161+#endif /* !CONFIG_CPU_MIPSR2 */
arch/mips/loongson/Kconfig+3−2
@@ -95,10 +95,11 @@ config CS5536 · 94 unmodified lines
9595
9696 config CS5536_MFGPT
9797 bool "CS5536 MFGPT Timer"
98− depends on CS5536
98+ depends on CS5536 && !HIGH_RES_TIMERS
9999 select MIPS_EXTERNAL_TIMER
100100 help
101− This option enables the mfgpt0 timer of AMD CS5536.
101+ This option enables the mfgpt0 timer of AMD CS5536. With this timer
102+ switched on you can not use high resolution timers.
102103
103104 If you want to enable the Loongson2 CPUFreq Driver, Please enable
104105 this option at first, otherwise, You will get wrong system time.
arch/mips/loongson/loongson-3/smp.c+0−8
@@ -279,13 +279,6 @@ static void loongson3_boot_secondary(int cpu, struct task_struct *idle) · 278 unmodified lines
279279 loongson3_ipi_write64(startargs[0], (void *)(ipi_mailbox_buf[cpu]+0x0));
280280 }
281281
282−/*
283− * Final cleanup after all secondaries booted
284− */
285−static void __init loongson3_cpus_done(void)
286−{
287−}
288−
289282 #ifdef CONFIG_HOTPLUG_CPU
290283
291284 static int loongson3_cpu_disable(void)
@@ -432,7 +425,6 @@ struct plat_smp_ops loongson3_smp_ops = { · 140 unmodified lines
432425 .send_ipi_mask = loongson3_send_ipi_mask,
433426 .init_secondary = loongson3_init_secondary,
434427 .smp_finish = loongson3_smp_finish,
435− .cpus_done = loongson3_cpus_done,
436428 .boot_secondary = loongson3_boot_secondary,
437429 .smp_setup = loongson3_smp_setup,
438430 .prepare_cpus = loongson3_prepare_cpus,
arch/mips/loongson1/Kconfig+1−0
@@ -14,6 +14,7 @@ config LOONGSON1_LS1B · 13 unmodified lines
1414 select SYS_SUPPORTS_32BIT_KERNEL
1515 select SYS_SUPPORTS_LITTLE_ENDIAN
1616 select SYS_SUPPORTS_HIGHMEM
17+ select SYS_SUPPORTS_MIPS16
1718 select SYS_HAS_EARLY_PRINTK
1819 select COMMON_CLK
1920
arch/mips/math-emu/Makefile+9−7
@@ -2,10 +2,12 @@ · 1 unmodified line
22 # Makefile for the Linux/MIPS kernel FPU emulation.
33 #
44
5−obj-y := cp1emu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
6− ieee754xcpt.o dp_frexp.o dp_modf.o dp_div.o dp_mul.o dp_sub.o \
7− dp_add.o dp_fsp.o dp_cmp.o dp_logb.o dp_scalb.o dp_simple.o \
8− dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \
9− sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \
10− sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \
11− dp_sqrt.o sp_sqrt.o kernel_linkage.o dsemul.o
5+obj-y += cp1emu.o ieee754dp.o ieee754sp.o ieee754.o dp_div.o dp_mul.o \
6+ dp_sub.o dp_add.o dp_fsp.o dp_cmp.o dp_simple.o dp_tint.o \
7+ dp_fint.o dp_tlong.o dp_flong.o sp_div.o sp_mul.o sp_sub.o \
8+ sp_add.o sp_fdp.o sp_cmp.o sp_simple.o sp_tint.o sp_fint.o \
9+ sp_tlong.o sp_flong.o dsemul.o
10+
11+lib-y += ieee754d.o dp_sqrt.o sp_sqrt.o
12+
13+obj-$(CONFIG_DEBUG_FS) += me-debugfs.o
arch/mips/math-emu/cp1emu.c+340−594
@@ -1,5 +1,5 @@
11 /*
2− * cp1emu.c: a MIPS coprocessor 1 (fpu) instruction emulator
2+ * cp1emu.c: a MIPS coprocessor 1 (FPU) instruction emulator
33 *
44 * MIPS floating point support
55 * Copyright (C) 1994-2000 Algorithmics Ltd.
@@ -18,61 +18,46 @@ · 12 unmodified lines
1818 *
1919 * You should have received a copy of the GNU General Public License along
2020 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
21+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2222 *
2323 * A complete emulator for MIPS coprocessor 1 instructions. This is
2424 * required for #float(switch) or #float(trap), where it catches all
2525 * COP1 instructions via the "CoProcessor Unusable" exception.
2626 *
2727 * More surprisingly it is also required for #float(ieee), to help out
28− * the hardware fpu at the boundaries of the IEEE-754 representation
28+ * the hardware FPU at the boundaries of the IEEE-754 representation
2929 * (denormalised values, infinities, underflow, etc). It is made
3030 * quite nasty because emulation of some non-COP1 instructions is
3131 * required, e.g. in branch delay slots.
3232 *
33− * Note if you know that you won't have an fpu, then you'll get much
33+ * Note if you know that you won't have an FPU, then you'll get much
3434 * better performance by compiling with -msoft-float!
3535 */
3636 #include <linux/sched.h>
37−#include <linux/module.h>
3837 #include <linux/debugfs.h>
38+#include <linux/kconfig.h>
39+#include <linux/percpu-defs.h>
3940 #include <linux/perf_event.h>
4041
42+#include <asm/branch.h>
4143 #include <asm/inst.h>
42−#include <asm/bootinfo.h>
43−#include <asm/processor.h>
4444 #include <asm/ptrace.h>
4545 #include <asm/signal.h>
46−#include <asm/mipsregs.h>
46+#include <asm/uaccess.h>
47+
48+#include <asm/processor.h>
4749 #include <asm/fpu_emulator.h>
4850 #include <asm/fpu.h>
49−#include <asm/uaccess.h>
50−#include <asm/branch.h>
5151
5252 #include "ieee754.h"
5353
54−/* Strap kernel emulator for full MIPS IV emulation */
55−
56−#ifdef __mips
57−#undef __mips
58−#endif
59−#define __mips 4
60−
6154 /* Function which emulates a floating point instruction. */
6255
6356 static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
6457 mips_instruction);
6558
66−#if __mips >= 4 && __mips != 32
6759 static int fpux_emu(struct pt_regs *,
6860 struct mips_fpu_struct *, mips_instruction, void *__user *);
69−#endif
70−
71−/* Further private data for which no space exists in mips_fpu_struct */
72−
73−#ifdef CONFIG_DEBUG_FS
74−DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
75−#endif
7661
7762 /* Control registers */
7863
@@ -82,27 +67,6 @@ DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats); · 3 unmodified lines
8267 /* Determine rounding mode from the RM bits of the FCSR */
8368 #define modeindex(v) ((v) & FPU_CSR_RM)
8469
85−/* microMIPS bitfields */
86−#define MM_POOL32A_MINOR_MASK 0x3f
87−#define MM_POOL32A_MINOR_SHIFT 0x6
88−#define MM_MIPS32_COND_FC 0x30
89−
90−/* Convert Mips rounding mode (0..3) to IEEE library modes. */
91−static const unsigned char ieee_rm[4] = {
92− [FPU_CSR_RN] = IEEE754_RN,
93− [FPU_CSR_RZ] = IEEE754_RZ,
94− [FPU_CSR_RU] = IEEE754_RU,
95− [FPU_CSR_RD] = IEEE754_RD,
96−};
97−/* Convert IEEE library modes to Mips rounding mode (0..3). */
98−static const unsigned char mips_rm[4] = {
99− [IEEE754_RN] = FPU_CSR_RN,
100− [IEEE754_RZ] = FPU_CSR_RZ,
101− [IEEE754_RD] = FPU_CSR_RD,
102− [IEEE754_RU] = FPU_CSR_RU,
103−};
104−
105−#if __mips >= 4
10670 /* convert condition code register number to csr bit */
10771 static const unsigned int fpucondbit[8] = {
10872 FPU_CSR_COND0,
@@ -114,10 +78,6 @@ static const unsigned int fpucondbit[8] = { · 5 unmodified lines
11478 FPU_CSR_COND6,
11579 FPU_CSR_COND7
11680 };
117−#endif
118−
119−/* (microMIPS) Convert 16-bit register encoding to 32-bit register encoding. */
120−static const unsigned int reg16to32map[8] = {16, 17, 2, 3, 4, 5, 6, 7};
12181
12282 /* (microMIPS) Convert certain microMIPS instructions to MIPS32 format. */
12383 static const int sd_format[] = {16, 17, 0, 0, 0, 0, 0, 0};
@@ -466,199 +426,6 @@ static int microMIPS32_to_MIPS32(union mips_instruction *insn_ptr) · 342 unmodified lines
466426 return 0;
467427 }
468428
469−int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
470− unsigned long *contpc)
471−{
472− union mips_instruction insn = (union mips_instruction)dec_insn.insn;
473− int bc_false = 0;
474− unsigned int fcr31;
475− unsigned int bit;
476−
477− if (!cpu_has_mmips)
478− return 0;
479−
480− switch (insn.mm_i_format.opcode) {
481− case mm_pool32a_op:
482− if ((insn.mm_i_format.simmediate & MM_POOL32A_MINOR_MASK) ==
483− mm_pool32axf_op) {
484− switch (insn.mm_i_format.simmediate >>
485− MM_POOL32A_MINOR_SHIFT) {
486− case mm_jalr_op:
487− case mm_jalrhb_op:
488− case mm_jalrs_op:
489− case mm_jalrshb_op:
490− if (insn.mm_i_format.rt != 0) /* Not mm_jr */
491− regs->regs[insn.mm_i_format.rt] =
492− regs->cp0_epc +
493− dec_insn.pc_inc +
494− dec_insn.next_pc_inc;
495− *contpc = regs->regs[insn.mm_i_format.rs];
496− return 1;
497− }
498− }
499− break;
500− case mm_pool32i_op:
501− switch (insn.mm_i_format.rt) {
502− case mm_bltzals_op:
503− case mm_bltzal_op:
504− regs->regs[31] = regs->cp0_epc +
505− dec_insn.pc_inc +
506− dec_insn.next_pc_inc;
507− /* Fall through */
508− case mm_bltz_op:
509− if ((long)regs->regs[insn.mm_i_format.rs] < 0)
510− *contpc = regs->cp0_epc +
511− dec_insn.pc_inc +
512− (insn.mm_i_format.simmediate << 1);
513− else
514− *contpc = regs->cp0_epc +
515− dec_insn.pc_inc +
516− dec_insn.next_pc_inc;
517− return 1;
518− case mm_bgezals_op:
519− case mm_bgezal_op:
520− regs->regs[31] = regs->cp0_epc +
521− dec_insn.pc_inc +
522− dec_insn.next_pc_inc;
523− /* Fall through */
524− case mm_bgez_op:
525− if ((long)regs->regs[insn.mm_i_format.rs] >= 0)
526− *contpc = regs->cp0_epc +
527− dec_insn.pc_inc +
528− (insn.mm_i_format.simmediate << 1);
529− else
530− *contpc = regs->cp0_epc +
531− dec_insn.pc_inc +
532− dec_insn.next_pc_inc;
533− return 1;
534− case mm_blez_op:
535− if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
536− *contpc = regs->cp0_epc +
537− dec_insn.pc_inc +
538− (insn.mm_i_format.simmediate << 1);
539− else
540− *contpc = regs->cp0_epc +
541− dec_insn.pc_inc +
542− dec_insn.next_pc_inc;
543− return 1;
544− case mm_bgtz_op:
545− if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
546− *contpc = regs->cp0_epc +
547− dec_insn.pc_inc +
548− (insn.mm_i_format.simmediate << 1);
549− else
550− *contpc = regs->cp0_epc +
551− dec_insn.pc_inc +
552− dec_insn.next_pc_inc;
553− return 1;
554− case mm_bc2f_op:
555− case mm_bc1f_op:
556− bc_false = 1;
557− /* Fall through */
558− case mm_bc2t_op:
559− case mm_bc1t_op:
560− preempt_disable();
561− if (is_fpu_owner())
562− asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
563− else
564− fcr31 = current->thread.fpu.fcr31;
565− preempt_enable();
566−
567− if (bc_false)
568− fcr31 = ~fcr31;
569−
570− bit = (insn.mm_i_format.rs >> 2);
571− bit += (bit != 0);
572− bit += 23;
573− if (fcr31 & (1 << bit))
574− *contpc = regs->cp0_epc +
575− dec_insn.pc_inc +
576− (insn.mm_i_format.simmediate << 1);
577− else
578− *contpc = regs->cp0_epc +
579− dec_insn.pc_inc + dec_insn.next_pc_inc;
580− return 1;
581− }
582− break;
583− case mm_pool16c_op:
584− switch (insn.mm_i_format.rt) {
585− case mm_jalr16_op:
586− case mm_jalrs16_op:
587− regs->regs[31] = regs->cp0_epc +
588− dec_insn.pc_inc + dec_insn.next_pc_inc;
589− /* Fall through */
590− case mm_jr16_op:
591− *contpc = regs->regs[insn.mm_i_format.rs];
592− return 1;
593− }
594− break;
595− case mm_beqz16_op:
596− if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] == 0)
597− *contpc = regs->cp0_epc +
598− dec_insn.pc_inc +
599− (insn.mm_b1_format.simmediate << 1);
600− else
601− *contpc = regs->cp0_epc +
602− dec_insn.pc_inc + dec_insn.next_pc_inc;
603− return 1;
604− case mm_bnez16_op:
605− if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] != 0)
606− *contpc = regs->cp0_epc +
607− dec_insn.pc_inc +
608− (insn.mm_b1_format.simmediate << 1);
609− else
610− *contpc = regs->cp0_epc +
611− dec_insn.pc_inc + dec_insn.next_pc_inc;
612− return 1;
613− case mm_b16_op:
614− *contpc = regs->cp0_epc + dec_insn.pc_inc +
615− (insn.mm_b0_format.simmediate << 1);
616− return 1;
617− case mm_beq32_op:
618− if (regs->regs[insn.mm_i_format.rs] ==
619− regs->regs[insn.mm_i_format.rt])
620− *contpc = regs->cp0_epc +
621− dec_insn.pc_inc +
622− (insn.mm_i_format.simmediate << 1);
623− else
624− *contpc = regs->cp0_epc +
625− dec_insn.pc_inc +
626− dec_insn.next_pc_inc;
627− return 1;
628− case mm_bne32_op:
629− if (regs->regs[insn.mm_i_format.rs] !=
630− regs->regs[insn.mm_i_format.rt])
631− *contpc = regs->cp0_epc +
632− dec_insn.pc_inc +
633− (insn.mm_i_format.simmediate << 1);
634− else
635− *contpc = regs->cp0_epc +
636− dec_insn.pc_inc + dec_insn.next_pc_inc;
637− return 1;
638− case mm_jalx32_op:
639− regs->regs[31] = regs->cp0_epc +
640− dec_insn.pc_inc + dec_insn.next_pc_inc;
641− *contpc = regs->cp0_epc + dec_insn.pc_inc;
642− *contpc >>= 28;
643− *contpc <<= 28;
644− *contpc |= (insn.j_format.target << 2);
645− return 1;
646− case mm_jals32_op:
647− case mm_jal32_op:
648− regs->regs[31] = regs->cp0_epc +
649− dec_insn.pc_inc + dec_insn.next_pc_inc;
650− /* Fall through */
651− case mm_j32_op:
652− *contpc = regs->cp0_epc + dec_insn.pc_inc;
653− *contpc >>= 27;
654− *contpc <<= 27;
655− *contpc |= (insn.j_format.target << 1);
656− set_isa16_mode(*contpc);
657− return 1;
658− }
659− return 0;
660−}
661−
662429 /*
663430 * Redundant with logic already in kernel/branch.c,
664431 * embedded in compute_return_epc. At some point,
@@ -817,7 +584,11 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, · 152 unmodified lines
817584 if (insn.i_format.rs == bc_op) {
818585 preempt_disable();
819586 if (is_fpu_owner())
820− asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
587+ asm volatile(
588+ ".set push\n"
589+ "\t.set mips1\n"
590+ "\tcfc1\t%0,$31\n"
591+ "\t.set pop" : "=r" (fcr31));
821592 else
822593 fcr31 = current->thread.fpu.fcr31;
823594 preempt_enable();
@@ -867,23 +638,25 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, · 43 unmodified lines
867638 */
868639 static inline int cop1_64bit(struct pt_regs *xcp)
869640 {
870−#if defined(CONFIG_64BIT) && !defined(CONFIG_MIPS32_O32)
871− return 1;
872−#elif defined(CONFIG_32BIT) && !defined(CONFIG_MIPS_O32_FP64_SUPPORT)
873− return 0;
874−#else
641+ if (config_enabled(CONFIG_64BIT) && !config_enabled(CONFIG_MIPS32_O32))
642+ return 1;
643+ else if (config_enabled(CONFIG_32BIT) &&
644+ !config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT))
645+ return 0;
646+
875647 return !test_thread_flag(TIF_32BIT_FPREGS);
876−#endif
877648 }
878649
879−#define SIFROMREG(si, x) do { \
650+#define SIFROMREG(si, x) \
651+do { \
880652 if (cop1_64bit(xcp)) \
881653 (si) = get_fpr32(&ctx->fpr[x], 0); \
882654 else \
883655 (si) = get_fpr32(&ctx->fpr[(x) & ~1], (x) & 1); \
884656 } while (0)
885657
886−#define SITOREG(si, x) do { \
658+#define SITOREG(si, x) \
659+do { \
887660 if (cop1_64bit(xcp)) { \
888661 unsigned i; \
889662 set_fpr32(&ctx->fpr[x], 0, si); \
@@ -896,17 +669,19 @@ static inline int cop1_64bit(struct pt_regs *xcp) · 6 unmodified lines
896669
897670 #define SIFROMHREG(si, x) ((si) = get_fpr32(&ctx->fpr[x], 1))
898671
899−#define SITOHREG(si, x) do { \
672+#define SITOHREG(si, x) \
673+do { \
900674 unsigned i; \
901675 set_fpr32(&ctx->fpr[x], 1, si); \
902676 for (i = 2; i < ARRAY_SIZE(ctx->fpr[x].val32); i++) \
903677 set_fpr32(&ctx->fpr[x], i, 0); \
904678 } while (0)
905679
906−#define DIFROMREG(di, x) \
680+#define DIFROMREG(di, x) \
907681 ((di) = get_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) == 0)], 0))
908682
909−#define DITOREG(di, x) do { \
683+#define DITOREG(di, x) \
684+do { \
910685 unsigned fpr, i; \
911686 fpr = (x) & ~(cop1_64bit(xcp) == 0); \
912687 set_fpr64(&ctx->fpr[fpr], 0, di); \
@@ -927,23 +702,36 @@ static inline int cop1_64bit(struct pt_regs *xcp) · 14 unmodified lines
927702 static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
928703 struct mm_decoded_insn dec_insn, void *__user *fault_addr)
929704 {
930− mips_instruction ir;
931705 unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc;
932− unsigned int cond;
933− int pc_inc;
706+ unsigned int cond, cbit;
707+ mips_instruction ir;
708+ int likely, pc_inc;
709+ u32 __user *wva;
710+ u64 __user *dva;
711+ u32 value;
712+ u32 wval;
713+ u64 dval;
714+ int sig;
715+
716+ /*
717+ * These are giving gcc a gentle hint about what to expect in
718+ * dec_inst in order to do better optimization.
719+ */
720+ if (!cpu_has_mmips && dec_insn.micro_mips_mode)
721+ unreachable();
934722
935723 /* XXX NEC Vr54xx bug workaround */
936− if (xcp->cp0_cause & CAUSEF_BD) {
724+ if (delay_slot(xcp)) {
937725 if (dec_insn.micro_mips_mode) {
938726 if (!mm_isBranchInstr(xcp, dec_insn, &contpc))
939− xcp->cp0_cause &= ~CAUSEF_BD;
727+ clear_delay_slot(xcp);
940728 } else {
941729 if (!isBranchInstr(xcp, dec_insn, &contpc))
942− xcp->cp0_cause &= ~CAUSEF_BD;
730+ clear_delay_slot(xcp);
943731 }
944732 }
945733
946− if (xcp->cp0_cause & CAUSEF_BD) {
734+ if (delay_slot(xcp)) {
947735 /*
948736 * The instruction to be emulated is in a branch delay slot
949737 * which means that we have to emulate the branch instruction
@@ -985,96 +773,85 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 35 unmodified lines
985773 return SIGILL;
986774 }
987775
988− emul:
776+emul:
989777 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, xcp, 0);
990778 MIPS_FPU_EMU_INC_STATS(emulated);
991779 switch (MIPSInst_OPCODE(ir)) {
992− case ldc1_op:{
993− u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
994− MIPSInst_SIMM(ir));
995− u64 val;
996−
780+ case ldc1_op:
781+ dva = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
782+ MIPSInst_SIMM(ir));
997783 MIPS_FPU_EMU_INC_STATS(loads);
998784
999− if (!access_ok(VERIFY_READ, va, sizeof(u64))) {
785+ if (!access_ok(VERIFY_READ, dva, sizeof(u64))) {
1000786 MIPS_FPU_EMU_INC_STATS(errors);
1001− *fault_addr = va;
787+ *fault_addr = dva;
1002788 return SIGBUS;
1003789 }
1004− if (__get_user(val, va)) {
790+ if (__get_user(dval, dva)) {
1005791 MIPS_FPU_EMU_INC_STATS(errors);
1006− *fault_addr = va;
792+ *fault_addr = dva;
1007793 return SIGSEGV;
1008794 }
1009− DITOREG(val, MIPSInst_RT(ir));
795+ DITOREG(dval, MIPSInst_RT(ir));
1010796 break;
1011− }
1012−
1013− case sdc1_op:{
1014− u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1015− MIPSInst_SIMM(ir));
1016− u64 val;
1017797
798+ case sdc1_op:
799+ dva = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
800+ MIPSInst_SIMM(ir));
1018801 MIPS_FPU_EMU_INC_STATS(stores);
1019− DIFROMREG(val, MIPSInst_RT(ir));
1020− if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) {
802+ DIFROMREG(dval, MIPSInst_RT(ir));
803+ if (!access_ok(VERIFY_WRITE, dva, sizeof(u64))) {
1021804 MIPS_FPU_EMU_INC_STATS(errors);
1022− *fault_addr = va;
805+ *fault_addr = dva;
1023806 return SIGBUS;
1024807 }
1025− if (__put_user(val, va)) {
808+ if (__put_user(dval, dva)) {
1026809 MIPS_FPU_EMU_INC_STATS(errors);
1027− *fault_addr = va;
810+ *fault_addr = dva;
1028811 return SIGSEGV;
1029812 }
1030813 break;
1031− }
1032−
1033− case lwc1_op:{
1034− u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1035− MIPSInst_SIMM(ir));
1036− u32 val;
1037814
815+ case lwc1_op:
816+ wva = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
817+ MIPSInst_SIMM(ir));
1038818 MIPS_FPU_EMU_INC_STATS(loads);
1039− if (!access_ok(VERIFY_READ, va, sizeof(u32))) {
819+ if (!access_ok(VERIFY_READ, wva, sizeof(u32))) {
1040820 MIPS_FPU_EMU_INC_STATS(errors);
1041− *fault_addr = va;
821+ *fault_addr = wva;
1042822 return SIGBUS;
1043823 }
1044− if (__get_user(val, va)) {
824+ if (__get_user(wval, wva)) {
1045825 MIPS_FPU_EMU_INC_STATS(errors);
1046− *fault_addr = va;
826+ *fault_addr = wva;
1047827 return SIGSEGV;
1048828 }
1049− SITOREG(val, MIPSInst_RT(ir));
829+ SITOREG(wval, MIPSInst_RT(ir));
1050830 break;
1051− }
1052−
1053− case swc1_op:{
1054− u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1055− MIPSInst_SIMM(ir));
1056− u32 val;
1057831
832+ case swc1_op:
833+ wva = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
834+ MIPSInst_SIMM(ir));
1058835 MIPS_FPU_EMU_INC_STATS(stores);
1059− SIFROMREG(val, MIPSInst_RT(ir));
1060− if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) {
836+ SIFROMREG(wval, MIPSInst_RT(ir));
837+ if (!access_ok(VERIFY_WRITE, wva, sizeof(u32))) {
1061838 MIPS_FPU_EMU_INC_STATS(errors);
1062− *fault_addr = va;
839+ *fault_addr = wva;
1063840 return SIGBUS;
1064841 }
1065− if (__put_user(val, va)) {
842+ if (__put_user(wval, wva)) {
1066843 MIPS_FPU_EMU_INC_STATS(errors);
1067− *fault_addr = va;
844+ *fault_addr = wva;
1068845 return SIGSEGV;
1069846 }
1070847 break;
1071− }
1072848
1073849 case cop1_op:
1074850 switch (MIPSInst_RS(ir)) {
1075−
1076−#if defined(__mips64)
1077851 case dmfc_op:
852+ if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
853+ return SIGILL;
854+
1078855 /* copregister fs -> gpr[rt] */
1079856 if (MIPSInst_RT(ir) != 0) {
1080857 DIFROMREG(xcp->regs[MIPSInst_RT(ir)],
@@ -1083,10 +860,12 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 2 unmodified lines
1083860 break;
1084861
1085862 case dmtc_op:
863+ if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
864+ return SIGILL;
865+
1086866 /* copregister fs <- rt */
1087867 DITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1088868 break;
1089−#endif
1090869
1091870 case mfhc_op:
1092871 if (!cpu_has_mips_r2)
@@ -1120,19 +899,14 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 27 unmodified lines
1120899 SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1121900 break;
1122901
1123− case cfc_op:{
902+ case cfc_op:
1124903 /* cop control register rd -> gpr[rt] */
1125− u32 value;
1126−
1127904 if (MIPSInst_RD(ir) == FPCREG_CSR) {
1128905 value = ctx->fcr31;
1129− value = (value & ~FPU_CSR_RM) |
1130− mips_rm[modeindex(value)];
1131−#ifdef CSRTRACE
1132− printk("%p gpr[%d]<-csr=%08x\n",
1133− (void *) (xcp->cp0_epc),
1134− MIPSInst_RT(ir), value);
1135−#endif
906+ value = (value & ~FPU_CSR_RM) | modeindex(value);
907+ pr_debug("%p gpr[%d]<-csr=%08x\n",
908+ (void *) (xcp->cp0_epc),
909+ MIPSInst_RT(ir), value);
1136910 }
1137911 else if (MIPSInst_RD(ir) == FPCREG_RID)
1138912 value = 0;
@@ -1141,12 +915,9 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 2 unmodified lines
1141915 if (MIPSInst_RT(ir))
1142916 xcp->regs[MIPSInst_RT(ir)] = value;
1143917 break;
1144− }
1145918
1146− case ctc_op:{
919+ case ctc_op:
1147920 /* copregister rd <- rt */
1148− u32 value;
1149−
1150921 if (MIPSInst_RT(ir) == 0)
1151922 value = 0;
1152923 else
@@ -1155,37 +926,33 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 2 unmodified lines
1155926 /* we only have one writable control reg
1156927 */
1157928 if (MIPSInst_RD(ir) == FPCREG_CSR) {
1158−#ifdef CSRTRACE
1159− printk("%p gpr[%d]->csr=%08x\n",
1160− (void *) (xcp->cp0_epc),
1161− MIPSInst_RT(ir), value);
1162−#endif
929+ pr_debug("%p gpr[%d]->csr=%08x\n",
930+ (void *) (xcp->cp0_epc),
931+ MIPSInst_RT(ir), value);
1163932
1164933 /*
1165934 * Don't write reserved bits,
1166935 * and convert to ieee library modes
1167936 */
1168− ctx->fcr31 = (value &
1169− ~(FPU_CSR_RSVD | FPU_CSR_RM)) |
1170− ieee_rm[modeindex(value)];
937+ ctx->fcr31 = (value & ~(FPU_CSR_RSVD | FPU_CSR_RM)) |
938+ modeindex(value);
1171939 }
1172940 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
1173941 return SIGFPE;
1174942 }
1175943 break;
1176− }
1177944
1178− case bc_op:{
1179− int likely = 0;
1180−
1181− if (xcp->cp0_cause & CAUSEF_BD)
945+ case bc_op:
946+ if (delay_slot(xcp))
1182947 return SIGILL;
1183948
1184−#if __mips >= 4
1185− cond = ctx->fcr31 & fpucondbit[MIPSInst_RT(ir) >> 2];
1186−#else
1187− cond = ctx->fcr31 & FPU_CSR_COND;
1188−#endif
949+ if (cpu_has_mips_4_5_r)
950+ cbit = fpucondbit[MIPSInst_RT(ir) >> 2];
951+ else
952+ cbit = FPU_CSR_COND;
953+ cond = ctx->fcr31 & cbit;
954+
955+ likely = 0;
1189956 switch (MIPSInst_RT(ir) & 3) {
1190957 case bcfl_op:
1191958 likely = 1;
@@ -1201,10 +968,10 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 9 unmodified lines
1201968 return SIGILL;
1202969 }
1203970
1204− xcp->cp0_cause |= CAUSEF_BD;
971+ set_delay_slot(xcp);
1205972 if (cond) {
1206− /* branch taken: emulate dslot
1207− * instruction
973+ /*
974+ * Branch taken: emulate dslot instruction
1208975 */
1209976 xcp->cp0_epc += dec_insn.pc_inc;
1210977
@@ -1238,23 +1005,37 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 27 unmodified lines
12381005
12391006 switch (MIPSInst_OPCODE(ir)) {
12401007 case lwc1_op:
1008+ goto emul;
1009+
12411010 case swc1_op:
1242−#if (__mips >= 2 || defined(__mips64))
1011+ goto emul;
1012+
12431013 case ldc1_op:
12441014 case sdc1_op:
1245−#endif
1015+ if (cpu_has_mips_2_3_4_5 ||
1016+ cpu_has_mips64)
1017+ goto emul;
1018+
1019+ return SIGILL;
1020+ goto emul;
1021+
12461022 case cop1_op:
1247−#if __mips >= 4 && __mips != 32
1248− case cop1x_op:
1249−#endif
1250− /* its one of ours */
12511023 goto emul;
1252−#if __mips >= 4
1024+
1025+ case cop1x_op:
1026+ if (cpu_has_mips_4_5 || cpu_has_mips64)
1027+ /* its one of ours */
1028+ goto emul;
1029+
1030+ return SIGILL;
1031+
12531032 case spec_op:
1033+ if (!cpu_has_mips_4_5_r)
1034+ return SIGILL;
1035+
12541036 if (MIPSInst_FUNC(ir) == movc_op)
12551037 goto emul;
12561038 break;
1257−#endif
12581039 }
12591040
12601041 /*
@@ -1262,10 +1043,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 1 unmodified line
12621043 * instruction in the dslot
12631044 */
12641045 return mips_dsemul(xcp, ir, contpc);
1265− }
1266− else {
1267− /* branch not taken */
1268− if (likely) {
1046+ } else if (likely) { /* branch not taken */
12691047 /*
12701048 * branch likely nullifies
12711049 * dslot if not taken
@@ -1277,34 +1055,31 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 5 unmodified lines
12771055 * dslot as normal insn
12781056 */
12791057 }
1280− }
12811058 break;
1282− }
12831059
12841060 default:
12851061 if (!(MIPSInst_RS(ir) & 0x10))
12861062 return SIGILL;
1287− {
1288− int sig;
12891063
1290− /* a real fpu computation instruction */
1291− if ((sig = fpu_emu(xcp, ctx, ir)))
1292− return sig;
1293− }
1064+ /* a real fpu computation instruction */
1065+ if ((sig = fpu_emu(xcp, ctx, ir)))
1066+ return sig;
12941067 }
12951068 break;
12961069
1297−#if __mips >= 4 && __mips != 32
1298− case cop1x_op:{
1299− int sig = fpux_emu(xcp, ctx, ir, fault_addr);
1070+ case cop1x_op:
1071+ if (!cpu_has_mips_4_5 && !cpu_has_mips64)
1072+ return SIGILL;
1073+
1074+ sig = fpux_emu(xcp, ctx, ir, fault_addr);
13001075 if (sig)
13011076 return sig;
13021077 break;
1303− }
1304−#endif
13051078
1306−#if __mips >= 4
13071079 case spec_op:
1080+ if (!cpu_has_mips_4_5_r)
1081+ return SIGILL;
1082+
13081083 if (MIPSInst_FUNC(ir) != movc_op)
13091084 return SIGILL;
13101085 cond = fpucondbit[MIPSInst_RT(ir) >> 2];
@@ -1312,8 +1087,6 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 1 unmodified line
13121087 xcp->regs[MIPSInst_RD(ir)] =
13131088 xcp->regs[MIPSInst_RS(ir)];
13141089 break;
1315−#endif
1316−
13171090 default:
13181091 sigill:
13191092 return SIGILL;
@@ -1321,7 +1094,7 @@ sigill: · 1 unmodified line
13211094
13221095 /* we did it !! */
13231096 xcp->cp0_epc = contpc;
1324− xcp->cp0_cause &= ~CAUSEF_BD;
1097+ clear_delay_slot(xcp);
13251098
13261099 return 0;
13271100 }
@@ -1342,44 +1115,42 @@ static const unsigned char cmptab[8] = { · 14 unmodified lines
13421115 };
13431116
13441117
1345−#if __mips >= 4 && __mips != 32
1346−
13471118 /*
13481119 * Additional MIPS4 instructions
13491120 */
13501121
1351−#define DEF3OP(name, p, f1, f2, f3) \
1352−static ieee754##p fpemu_##p##_##name(ieee754##p r, ieee754##p s, \
1353− ieee754##p t) \
1354−{ \
1355− struct _ieee754_csr ieee754_csr_save; \
1356− s = f1(s, t); \
1357− ieee754_csr_save = ieee754_csr; \
1358− s = f2(s, r); \
1359− ieee754_csr_save.cx |= ieee754_csr.cx; \
1360− ieee754_csr_save.sx |= ieee754_csr.sx; \
1361− s = f3(s); \
1362− ieee754_csr.cx |= ieee754_csr_save.cx; \
1363− ieee754_csr.sx |= ieee754_csr_save.sx; \
1364− return s; \
1122+#define DEF3OP(name, p, f1, f2, f3) \
1123+static union ieee754##p fpemu_##p##_##name(union ieee754##p r, \
1124+ union ieee754##p s, union ieee754##p t) \
1125+{ \
1126+ struct _ieee754_csr ieee754_csr_save; \
1127+ s = f1(s, t); \
1128+ ieee754_csr_save = ieee754_csr; \
1129+ s = f2(s, r); \
1130+ ieee754_csr_save.cx |= ieee754_csr.cx; \
1131+ ieee754_csr_save.sx |= ieee754_csr.sx; \
1132+ s = f3(s); \
1133+ ieee754_csr.cx |= ieee754_csr_save.cx; \
1134+ ieee754_csr.sx |= ieee754_csr_save.sx; \
1135+ return s; \
13651136 }
13661137
1367−static ieee754dp fpemu_dp_recip(ieee754dp d)
1138+static union ieee754dp fpemu_dp_recip(union ieee754dp d)
13681139 {
13691140 return ieee754dp_div(ieee754dp_one(0), d);
13701141 }
13711142
1372−static ieee754dp fpemu_dp_rsqrt(ieee754dp d)
1143+static union ieee754dp fpemu_dp_rsqrt(union ieee754dp d)
13731144 {
13741145 return ieee754dp_div(ieee754dp_one(0), ieee754dp_sqrt(d));
13751146 }
13761147
1377−static ieee754sp fpemu_sp_recip(ieee754sp s)
1148+static union ieee754sp fpemu_sp_recip(union ieee754sp s)
13781149 {
13791150 return ieee754sp_div(ieee754sp_one(0), s);
13801151 }
13811152
1382−static ieee754sp fpemu_sp_rsqrt(ieee754sp s)
1153+static union ieee754sp fpemu_sp_rsqrt(union ieee754sp s)
13831154 {
13841155 return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s));
13851156 }
@@ -1403,8 +1174,8 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 17 unmodified lines
14031174 switch (MIPSInst_FMA_FFMT(ir)) {
14041175 case s_fmt:{ /* 0 */
14051176
1406− ieee754sp(*handler) (ieee754sp, ieee754sp, ieee754sp);
1407− ieee754sp fd, fr, fs, ft;
1177+ union ieee754sp(*handler) (union ieee754sp, union ieee754sp, union ieee754sp);
1178+ union ieee754sp fd, fr, fs, ft;
14081179 u32 __user *va;
14091180 u32 val;
14101181
@@ -1467,18 +1238,26 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 56 unmodified lines
14671238 SPTOREG(fd, MIPSInst_FD(ir));
14681239
14691240 copcsr:
1470− if (ieee754_cxtest(IEEE754_INEXACT))
1241+ if (ieee754_cxtest(IEEE754_INEXACT)) {
1242+ MIPS_FPU_EMU_INC_STATS(ieee754_inexact);
14711243 rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
1472− if (ieee754_cxtest(IEEE754_UNDERFLOW))
1244+ }
1245+ if (ieee754_cxtest(IEEE754_UNDERFLOW)) {
1246+ MIPS_FPU_EMU_INC_STATS(ieee754_underflow);
14731247 rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
1474− if (ieee754_cxtest(IEEE754_OVERFLOW))
1248+ }
1249+ if (ieee754_cxtest(IEEE754_OVERFLOW)) {
1250+ MIPS_FPU_EMU_INC_STATS(ieee754_overflow);
14751251 rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
1476− if (ieee754_cxtest(IEEE754_INVALID_OPERATION))
1252+ }
1253+ if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) {
1254+ MIPS_FPU_EMU_INC_STATS(ieee754_invalidop);
14771255 rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
1256+ }
14781257
14791258 ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
14801259 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
1481− /*printk ("SIGFPE: fpu csr = %08x\n",
1260+ /*printk ("SIGFPE: FPU csr = %08x\n",
14821261 ctx->fcr31); */
14831262 return SIGFPE;
14841263 }
@@ -1492,8 +1271,8 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 7 unmodified lines
14921271 }
14931272
14941273 case d_fmt:{ /* 1 */
1495− ieee754dp(*handler) (ieee754dp, ieee754dp, ieee754dp);
1496− ieee754dp fd, fr, fs, ft;
1274+ union ieee754dp(*handler) (union ieee754dp, union ieee754dp, union ieee754dp);
1275+ union ieee754dp fd, fr, fs, ft;
14971276 u64 __user *va;
14981277 u64 val;
14991278
@@ -1574,7 +1353,6 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 74 unmodified lines
15741353
15751354 return 0;
15761355 }
1577−#endif
15781356
15791357
15801358
@@ -1586,23 +1364,25 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 5 unmodified lines
15861364 {
15871365 int rfmt; /* resulting format */
15881366 unsigned rcsr = 0; /* resulting csr */
1367+ unsigned int oldrm;
1368+ unsigned int cbit;
15891369 unsigned cond;
15901370 union {
1591− ieee754dp d;
1592− ieee754sp s;
1371+ union ieee754dp d;
1372+ union ieee754sp s;
15931373 int w;
1594−#ifdef __mips64
15951374 s64 l;
1596−#endif
15971375 } rv; /* resulting value */
1376+ u64 bits;
15981377
15991378 MIPS_FPU_EMU_INC_STATS(cp1ops);
16001379 switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
1601− case s_fmt:{ /* 0 */
1380+ case s_fmt: { /* 0 */
16021381 union {
1603− ieee754sp(*b) (ieee754sp, ieee754sp);
1604− ieee754sp(*u) (ieee754sp);
1382+ union ieee754sp(*b) (union ieee754sp, union ieee754sp);
1383+ union ieee754sp(*u) (union ieee754sp);
16051384 } handler;
1385+ union ieee754sp fs, ft;
16061386
16071387 switch (MIPSInst_FUNC(ir)) {
16081388 /* binary ops */
@@ -1620,148 +1400,167 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 11 unmodified lines
16201400 goto scopbop;
16211401
16221402 /* unary ops */
1623−#if __mips >= 2 || defined(__mips64)
16241403 case fsqrt_op:
1404+ if (!cpu_has_mips_4_5_r)
1405+ return SIGILL;
1406+
16251407 handler.u = ieee754sp_sqrt;
16261408 goto scopuop;
1627−#endif
1628−#if __mips >= 4 && __mips != 32
1409+
1410+ /*
1411+ * Note that on some MIPS IV implementations such as the
1412+ * R5000 and R8000 the FSQRT and FRECIP instructions do not
1413+ * achieve full IEEE-754 accuracy - however this emulator does.
1414+ */
16291415 case frsqrt_op:
1416+ if (!cpu_has_mips_4_5_r2)
1417+ return SIGILL;
1418+
16301419 handler.u = fpemu_sp_rsqrt;
16311420 goto scopuop;
1421+
16321422 case frecip_op:
1423+ if (!cpu_has_mips_4_5_r2)
1424+ return SIGILL;
1425+
16331426 handler.u = fpemu_sp_recip;
16341427 goto scopuop;
1635−#endif
1636−#if __mips >= 4
1428+
16371429 case fmovc_op:
1430+ if (!cpu_has_mips_4_5_r)
1431+ return SIGILL;
1432+
16381433 cond = fpucondbit[MIPSInst_FT(ir) >> 2];
16391434 if (((ctx->fcr31 & cond) != 0) !=
16401435 ((MIPSInst_FT(ir) & 1) != 0))
16411436 return 0;
16421437 SPFROMREG(rv.s, MIPSInst_FS(ir));
16431438 break;
1439+
16441440 case fmovz_op:
1441+ if (!cpu_has_mips_4_5_r)
1442+ return SIGILL;
1443+
16451444 if (xcp->regs[MIPSInst_FT(ir)] != 0)
16461445 return 0;
16471446 SPFROMREG(rv.s, MIPSInst_FS(ir));
16481447 break;
1448+
16491449 case fmovn_op:
1450+ if (!cpu_has_mips_4_5_r)
1451+ return SIGILL;
1452+
16501453 if (xcp->regs[MIPSInst_FT(ir)] == 0)
16511454 return 0;
16521455 SPFROMREG(rv.s, MIPSInst_FS(ir));
16531456 break;
1654−#endif
1457+
16551458 case fabs_op:
16561459 handler.u = ieee754sp_abs;
16571460 goto scopuop;
1461+
16581462 case fneg_op:
16591463 handler.u = ieee754sp_neg;
16601464 goto scopuop;
1465+
16611466 case fmov_op:
16621467 /* an easy one */
16631468 SPFROMREG(rv.s, MIPSInst_FS(ir));
16641469 goto copcsr;
16651470
16661471 /* binary op on handler */
1667− scopbop:
1668− {
1669− ieee754sp fs, ft;
1670−
1671− SPFROMREG(fs, MIPSInst_FS(ir));
1672− SPFROMREG(ft, MIPSInst_FT(ir));
1673−
1674− rv.s = (*handler.b) (fs, ft);
1675− goto copcsr;
1676− }
1677− scopuop:
1678− {
1679− ieee754sp fs;
1472+scopbop:
1473+ SPFROMREG(fs, MIPSInst_FS(ir));
1474+ SPFROMREG(ft, MIPSInst_FT(ir));
16801475
1681− SPFROMREG(fs, MIPSInst_FS(ir));
1682− rv.s = (*handler.u) (fs);
1683− goto copcsr;
1684− }
1685− copcsr:
1686− if (ieee754_cxtest(IEEE754_INEXACT))
1476+ rv.s = (*handler.b) (fs, ft);
1477+ goto copcsr;
1478+scopuop:
1479+ SPFROMREG(fs, MIPSInst_FS(ir));
1480+ rv.s = (*handler.u) (fs);
1481+ goto copcsr;
1482+copcsr:
1483+ if (ieee754_cxtest(IEEE754_INEXACT)) {
1484+ MIPS_FPU_EMU_INC_STATS(ieee754_inexact);
16871485 rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
1688− if (ieee754_cxtest(IEEE754_UNDERFLOW))
1486+ }
1487+ if (ieee754_cxtest(IEEE754_UNDERFLOW)) {
1488+ MIPS_FPU_EMU_INC_STATS(ieee754_underflow);
16891489 rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
1690− if (ieee754_cxtest(IEEE754_OVERFLOW))
1490+ }
1491+ if (ieee754_cxtest(IEEE754_OVERFLOW)) {
1492+ MIPS_FPU_EMU_INC_STATS(ieee754_overflow);
16911493 rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
1692− if (ieee754_cxtest(IEEE754_ZERO_DIVIDE))
1494+ }
1495+ if (ieee754_cxtest(IEEE754_ZERO_DIVIDE)) {
1496+ MIPS_FPU_EMU_INC_STATS(ieee754_zerodiv);
16931497 rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S;
1694− if (ieee754_cxtest(IEEE754_INVALID_OPERATION))
1498+ }
1499+ if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) {
1500+ MIPS_FPU_EMU_INC_STATS(ieee754_invalidop);
16951501 rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
1502+ }
16961503 break;
16971504
16981505 /* unary conv ops */
16991506 case fcvts_op:
17001507 return SIGILL; /* not defined */
1701− case fcvtd_op:{
1702− ieee754sp fs;
17031508
1509+ case fcvtd_op:
17041510 SPFROMREG(fs, MIPSInst_FS(ir));
17051511 rv.d = ieee754dp_fsp(fs);
17061512 rfmt = d_fmt;
17071513 goto copcsr;
1708− }
1709− case fcvtw_op:{
1710− ieee754sp fs;
17111514
1515+ case fcvtw_op:
17121516 SPFROMREG(fs, MIPSInst_FS(ir));
17131517 rv.w = ieee754sp_tint(fs);
17141518 rfmt = w_fmt;
17151519 goto copcsr;
1716− }
17171520
1718−#if __mips >= 2 || defined(__mips64)
17191521 case fround_op:
17201522 case ftrunc_op:
17211523 case fceil_op:
1722− case ffloor_op:{
1723− unsigned int oldrm = ieee754_csr.rm;
1724− ieee754sp fs;
1524+ case ffloor_op:
1525+ if (!cpu_has_mips_2_3_4_5 && !cpu_has_mips64)
1526+ return SIGILL;
17251527
1528+ oldrm = ieee754_csr.rm;
17261529 SPFROMREG(fs, MIPSInst_FS(ir));
1727− ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
1530+ ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
17281531 rv.w = ieee754sp_tint(fs);
17291532 ieee754_csr.rm = oldrm;
17301533 rfmt = w_fmt;
17311534 goto copcsr;
1732− }
1733−#endif /* __mips >= 2 */
17341535
1735−#if defined(__mips64)
1736− case fcvtl_op:{
1737− ieee754sp fs;
1536+ case fcvtl_op:
1537+ if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1538+ return SIGILL;
17381539
17391540 SPFROMREG(fs, MIPSInst_FS(ir));
17401541 rv.l = ieee754sp_tlong(fs);
17411542 rfmt = l_fmt;
17421543 goto copcsr;
1743− }
17441544
17451545 case froundl_op:
17461546 case ftruncl_op:
17471547 case fceill_op:
1748− case ffloorl_op:{
1749− unsigned int oldrm = ieee754_csr.rm;
1750− ieee754sp fs;
1548+ case ffloorl_op:
1549+ if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1550+ return SIGILL;
17511551
1552+ oldrm = ieee754_csr.rm;
17521553 SPFROMREG(fs, MIPSInst_FS(ir));
1753− ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
1554+ ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
17541555 rv.l = ieee754sp_tlong(fs);
17551556 ieee754_csr.rm = oldrm;
17561557 rfmt = l_fmt;
17571558 goto copcsr;
1758− }
1759−#endif /* defined(__mips64) */
17601559
17611560 default:
17621561 if (MIPSInst_FUNC(ir) >= fcmp_op) {
17631562 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
1764− ieee754sp fs, ft;
1563+ union ieee754sp fs, ft;
17651564
17661565 SPFROMREG(fs, MIPSInst_FS(ir));
17671566 SPFROMREG(ft, MIPSInst_FT(ir));
@@ -1774,19 +1573,18 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 6 unmodified lines
17741573 else
17751574 goto copcsr;
17761575
1777− }
1778− else {
1576+ } else
17791577 return SIGILL;
1780− }
17811578 break;
17821579 }
17831580 break;
17841581 }
17851582
1786− case d_fmt:{
1583+ case d_fmt: {
1584+ union ieee754dp fs, ft;
17871585 union {
1788− ieee754dp(*b) (ieee754dp, ieee754dp);
1789− ieee754dp(*u) (ieee754dp);
1586+ union ieee754dp(*b) (union ieee754dp, union ieee754dp);
1587+ union ieee754dp(*u) (union ieee754dp);
17901588 } handler;
17911589
17921590 switch (MIPSInst_FUNC(ir)) {
@@ -1805,21 +1603,33 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 12 unmodified lines
18051603 goto dcopbop;
18061604
18071605 /* unary ops */
1808−#if __mips >= 2 || defined(__mips64)
18091606 case fsqrt_op:
1607+ if (!cpu_has_mips_2_3_4_5_r)
1608+ return SIGILL;
1609+
18101610 handler.u = ieee754dp_sqrt;
18111611 goto dcopuop;
1812−#endif
1813−#if __mips >= 4 && __mips != 32
1612+ /*
1613+ * Note that on some MIPS IV implementations such as the
1614+ * R5000 and R8000 the FSQRT and FRECIP instructions do not
1615+ * achieve full IEEE-754 accuracy - however this emulator does.
1616+ */
18141617 case frsqrt_op:
1618+ if (!cpu_has_mips_4_5_r2)
1619+ return SIGILL;
1620+
18151621 handler.u = fpemu_dp_rsqrt;
18161622 goto dcopuop;
18171623 case frecip_op:
1624+ if (!cpu_has_mips_4_5_r2)
1625+ return SIGILL;
1626+
18181627 handler.u = fpemu_dp_recip;
18191628 goto dcopuop;
1820−#endif
1821−#if __mips >= 4
18221629 case fmovc_op:
1630+ if (!cpu_has_mips_4_5_r)
1631+ return SIGILL;
1632+
18231633 cond = fpucondbit[MIPSInst_FT(ir) >> 2];
18241634 if (((ctx->fcr31 & cond) != 0) !=
18251635 ((MIPSInst_FT(ir) & 1) != 0))
@@ -1827,16 +1637,21 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 1 unmodified line
18271637 DPFROMREG(rv.d, MIPSInst_FS(ir));
18281638 break;
18291639 case fmovz_op:
1640+ if (!cpu_has_mips_4_5_r)
1641+ return SIGILL;
1642+
18301643 if (xcp->regs[MIPSInst_FT(ir)] != 0)
18311644 return 0;
18321645 DPFROMREG(rv.d, MIPSInst_FS(ir));
18331646 break;
18341647 case fmovn_op:
1648+ if (!cpu_has_mips_4_5_r)
1649+ return SIGILL;
1650+
18351651 if (xcp->regs[MIPSInst_FT(ir)] == 0)
18361652 return 0;
18371653 DPFROMREG(rv.d, MIPSInst_FS(ir));
18381654 break;
1839−#endif
18401655 case fabs_op:
18411656 handler.u = ieee754dp_abs;
18421657 goto dcopuop;
@@ -1851,91 +1666,78 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 8 unmodified lines
18511666 goto copcsr;
18521667
18531668 /* binary op on handler */
1854− dcopbop:{
1855− ieee754dp fs, ft;
1856−
1857− DPFROMREG(fs, MIPSInst_FS(ir));
1858− DPFROMREG(ft, MIPSInst_FT(ir));
1859−
1860− rv.d = (*handler.b) (fs, ft);
1861− goto copcsr;
1862− }
1863− dcopuop:{
1864− ieee754dp fs;
1865−
1866− DPFROMREG(fs, MIPSInst_FS(ir));
1867− rv.d = (*handler.u) (fs);
1868− goto copcsr;
1869− }
1669+dcopbop:
1670+ DPFROMREG(fs, MIPSInst_FS(ir));
1671+ DPFROMREG(ft, MIPSInst_FT(ir));
18701672
1871− /* unary conv ops */
1872− case fcvts_op:{
1873− ieee754dp fs;
1673+ rv.d = (*handler.b) (fs, ft);
1674+ goto copcsr;
1675+dcopuop:
1676+ DPFROMREG(fs, MIPSInst_FS(ir));
1677+ rv.d = (*handler.u) (fs);
1678+ goto copcsr;
18741679
1680+ /*
1681+ * unary conv ops
1682+ */
1683+ case fcvts_op:
18751684 DPFROMREG(fs, MIPSInst_FS(ir));
18761685 rv.s = ieee754sp_fdp(fs);
18771686 rfmt = s_fmt;
18781687 goto copcsr;
1879− }
1688+
18801689 case fcvtd_op:
18811690 return SIGILL; /* not defined */
18821691
1883− case fcvtw_op:{
1884− ieee754dp fs;
1885−
1692+ case fcvtw_op:
18861693 DPFROMREG(fs, MIPSInst_FS(ir));
18871694 rv.w = ieee754dp_tint(fs); /* wrong */
18881695 rfmt = w_fmt;
18891696 goto copcsr;
1890− }
18911697
1892−#if __mips >= 2 || defined(__mips64)
18931698 case fround_op:
18941699 case ftrunc_op:
18951700 case fceil_op:
1896− case ffloor_op:{
1897− unsigned int oldrm = ieee754_csr.rm;
1898− ieee754dp fs;
1701+ case ffloor_op:
1702+ if (!cpu_has_mips_2_3_4_5_r)
1703+ return SIGILL;
18991704
1705+ oldrm = ieee754_csr.rm;
19001706 DPFROMREG(fs, MIPSInst_FS(ir));
1901− ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
1707+ ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
19021708 rv.w = ieee754dp_tint(fs);
19031709 ieee754_csr.rm = oldrm;
19041710 rfmt = w_fmt;
19051711 goto copcsr;
1906− }
1907−#endif
19081712
1909−#if defined(__mips64)
1910− case fcvtl_op:{
1911− ieee754dp fs;
1713+ case fcvtl_op:
1714+ if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1715+ return SIGILL;
19121716
19131717 DPFROMREG(fs, MIPSInst_FS(ir));
19141718 rv.l = ieee754dp_tlong(fs);
19151719 rfmt = l_fmt;
19161720 goto copcsr;
1917− }
19181721
19191722 case froundl_op:
19201723 case ftruncl_op:
19211724 case fceill_op:
1922− case ffloorl_op:{
1923− unsigned int oldrm = ieee754_csr.rm;
1924− ieee754dp fs;
1725+ case ffloorl_op:
1726+ if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1727+ return SIGILL;
19251728
1729+ oldrm = ieee754_csr.rm;
19261730 DPFROMREG(fs, MIPSInst_FS(ir));
1927− ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
1731+ ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
19281732 rv.l = ieee754dp_tlong(fs);
19291733 ieee754_csr.rm = oldrm;
19301734 rfmt = l_fmt;
19311735 goto copcsr;
1932− }
1933−#endif /* __mips >= 3 */
19341736
19351737 default:
19361738 if (MIPSInst_FUNC(ir) >= fcmp_op) {
19371739 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
1938− ieee754dp fs, ft;
1740+ union ieee754dp fs, ft;
19391741
19401742 DPFROMREG(fs, MIPSInst_FS(ir));
19411743 DPFROMREG(ft, MIPSInst_FT(ir));
@@ -1957,11 +1759,8 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 15 unmodified lines
19571759 break;
19581760 }
19591761 break;
1960− }
1961−
1962− case w_fmt:{
1963− ieee754sp fs;
19641762
1763+ case w_fmt:
19651764 switch (MIPSInst_FUNC(ir)) {
19661765 case fcvts_op:
19671766 /* convert word to single precision real */
@@ -1981,9 +1780,11 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 13 unmodified lines
19811780 break;
19821781 }
19831782
1984−#if defined(__mips64)
1985− case l_fmt:{
1986− u64 bits;
1783+ case l_fmt:
1784+
1785+ if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1786+ return SIGILL;
1787+
19871788 DIFROMREG(bits, MIPSInst_FS(ir));
19881789
19891790 switch (MIPSInst_FUNC(ir)) {
@@ -2001,8 +1802,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 11 unmodified lines
20011802 return SIGILL;
20021803 }
20031804 break;
2004− }
2005−#endif
20061805
20071806 default:
20081807 return SIGILL;
@@ -2017,7 +1816,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 8 unmodified lines
20171816 */
20181817 ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
20191818 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
2020− /*printk ("SIGFPE: fpu csr = %08x\n",ctx->fcr31); */
1819+ /*printk ("SIGFPE: FPU csr = %08x\n",ctx->fcr31); */
20211820 return SIGFPE;
20221821 }
20231822
@@ -2025,18 +1824,18 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 1 unmodified line
20251824 * Now we can safely write the result back to the register file.
20261825 */
20271826 switch (rfmt) {
2028− case -1:{
2029−#if __mips >= 4
2030− cond = fpucondbit[MIPSInst_FD(ir) >> 2];
2031−#else
2032− cond = FPU_CSR_COND;
2033−#endif
1827+ case -1:
1828+
1829+ if (cpu_has_mips_4_5_r)
1830+ cbit = fpucondbit[MIPSInst_RT(ir) >> 2];
1831+ else
1832+ cbit = FPU_CSR_COND;
20341833 if (rv.w)
2035− ctx->fcr31 |= cond;
1834+ ctx->fcr31 |= cbit;
20361835 else
2037− ctx->fcr31 &= ~cond;
1836+ ctx->fcr31 &= ~cbit;
20381837 break;
2039− }
1838+
20401839 case d_fmt:
20411840 DPTOREG(rv.d, MIPSInst_FD(ir));
20421841 break;
@@ -2046,11 +1845,12 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 3 unmodified lines
20461845 case w_fmt:
20471846 SITOREG(rv.w, MIPSInst_FD(ir));
20481847 break;
2049−#if defined(__mips64)
20501848 case l_fmt:
1849+ if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1850+ return SIGILL;
1851+
20511852 DITOREG(rv.l, MIPSInst_FD(ir));
20521853 break;
2053−#endif
20541854 default:
20551855 return SIGILL;
20561856 }
@@ -2138,11 +1938,7 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 81 unmodified lines
21381938 * ieee754_csr. But ieee754_csr.rm is ieee
21391939 * library modes. (not mips rounding mode)
21401940 */
2141− /* convert to ieee library modes */
2142− ieee754_csr.rm = ieee_rm[ieee754_csr.rm];
21431941 sig = cop1Emulate(xcp, ctx, dec_insn, fault_addr);
2144− /* revert to mips rounding mode */
2145− ieee754_csr.rm = mips_rm[ieee754_csr.rm];
21461942 }
21471943
21481944 if (has_fpu)
@@ -2155,58 +1951,8 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 6 unmodified lines
21551951
21561952 /* SIGILL indicates a non-fpu instruction */
21571953 if (sig == SIGILL && xcp->cp0_epc != oldepc)
2158− /* but if epc has advanced, then ignore it */
1954+ /* but if EPC has advanced, then ignore it */
21591955 sig = 0;
21601956
21611957 return sig;
21621958 }
2163−
2164−#ifdef CONFIG_DEBUG_FS
2165−
2166−static int fpuemu_stat_get(void *data, u64 *val)
2167−{
2168− int cpu;
2169− unsigned long sum = 0;
2170− for_each_online_cpu(cpu) {
2171− struct mips_fpu_emulator_stats *ps;
2172− local_t *pv;
2173− ps = &per_cpu(fpuemustats, cpu);
2174− pv = (void *)ps + (unsigned long)data;
2175− sum += local_read(pv);
2176− }
2177− *val = sum;
2178− return 0;
2179−}
2180−DEFINE_SIMPLE_ATTRIBUTE(fops_fpuemu_stat, fpuemu_stat_get, NULL, "%llu\n");
2181−
2182−extern struct dentry *mips_debugfs_dir;
2183−static int __init debugfs_fpuemu(void)
2184−{
2185− struct dentry *d, *dir;
2186−
2187− if (!mips_debugfs_dir)
2188− return -ENODEV;
2189− dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir);
2190− if (!dir)
2191− return -ENOMEM;
2192−
2193−#define FPU_STAT_CREATE(M) \
2194− do { \
2195− d = debugfs_create_file(#M , S_IRUGO, dir, \
2196− (void *)offsetof(struct mips_fpu_emulator_stats, M), \
2197− &fops_fpuemu_stat); \
2198− if (!d) \
2199− return -ENOMEM; \
2200− } while (0)
2201−
2202− FPU_STAT_CREATE(emulated);
2203− FPU_STAT_CREATE(loads);
2204− FPU_STAT_CREATE(stores);
2205− FPU_STAT_CREATE(cp1ops);
2206− FPU_STAT_CREATE(cp1xops);
2207− FPU_STAT_CREATE(errors);
2208−
2209− return 0;
2210−}
2211−__initcall(debugfs_fpuemu);
2212−#endif
arch/mips/math-emu/dp_add.c+36−35
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,24 +16,22 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
24− *
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2520 */
2621
27−
2822 #include "ieee754dp.h"
2923
30−ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y)
24+union ieee754dp ieee754dp_add(union ieee754dp x, union ieee754dp y)
3125 {
26+ int s;
27+
3228 COMPXDP;
3329 COMPYDP;
3430
3531 EXPLODEXDP;
3632 EXPLODEYDP;
3733
38− CLEARCX;
34+ ieee754_clearcx();
3935
4036 FLUSHXDP;
4137 FLUSHYDP;
@@ -52,8 +48,8 @@ ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y) · 10 unmodified lines
5248 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
5349 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
5450 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
55− SETCX(IEEE754_INVALID_OPERATION);
56− return ieee754dp_nanxcpt(ieee754dp_indef(), "add", x, y);
51+ ieee754_setcx(IEEE754_INVALID_OPERATION);
52+ return ieee754dp_nanxcpt(ieee754dp_indef());
5753
5854 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
5955 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -69,14 +65,14 @@ ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y) · 9 unmodified lines
6965 return x;
7066
7167
72− /* Infinity handling
73− */
74−
68+ /*
69+ * Infinity handling
70+ */
7571 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
7672 if (xs == ys)
7773 return x;
78− SETCX(IEEE754_INVALID_OPERATION);
79− return ieee754dp_xcpt(ieee754dp_indef(), "add", x, y);
74+ ieee754_setcx(IEEE754_INVALID_OPERATION);
75+ return ieee754dp_indef();
8076
8177 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
8278 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
@@ -88,15 +84,14 @@ ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y) · 5 unmodified lines
8884 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
8985 return x;
9086
91− /* Zero handling
92− */
93−
87+ /*
88+ * Zero handling
89+ */
9490 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
9591 if (xs == ys)
9692 return x;
9793 else
98− return ieee754dp_zero(ieee754_csr.rm ==
99− IEEE754_RD);
94+ return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
10095
10196 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
10297 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
@@ -125,20 +120,24 @@ ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y) · 22 unmodified lines
125120 assert(xm & DP_HIDDEN_BIT);
126121 assert(ym & DP_HIDDEN_BIT);
127122
128− /* provide guard,round and stick bit space */
123+ /*
124+ * Provide guard,round and stick bit space.
125+ */
129126 xm <<= 3;
130127 ym <<= 3;
131128
132129 if (xe > ye) {
133− /* have to shift y fraction right to align
130+ /*
131+ * Have to shift y fraction right to align.
134132 */
135− int s = xe - ye;
133+ s = xe - ye;
136134 ym = XDPSRS(ym, s);
137135 ye += s;
138136 } else if (ye > xe) {
139− /* have to shift x fraction right to align
137+ /*
138+ * Have to shift x fraction right to align.
140139 */
141− int s = ye - xe;
140+ s = ye - xe;
142141 xm = XDPSRS(xm, s);
143142 xe += s;
144143 }
@@ -146,14 +145,15 @@ ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y) · 1 unmodified line
146145 assert(xe <= DP_EMAX);
147146
148147 if (xs == ys) {
149− /* generate 28 bit result of adding two 27 bit numbers
150− * leaving result in xm,xs,xe
148+ /*
149+ * Generate 28 bit result of adding two 27 bit numbers
150+ * leaving result in xm, xs and xe.
151151 */
152152 xm = xm + ym;
153153 xe = xe;
154154 xs = xs;
155155
156− if (xm >> (DP_MBITS + 1 + 3)) { /* carry out */
156+ if (xm >> (DP_FBITS + 1 + 3)) { /* carry out */
157157 xm = XDPSRS1(xm);
158158 xe++;
159159 }
@@ -168,15 +168,16 @@ ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y) · 8 unmodified lines
168168 xs = ys;
169169 }
170170 if (xm == 0)
171− return ieee754dp_zero(ieee754_csr.rm ==
172− IEEE754_RD);
171+ return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
173172
174− /* normalize to rounding precision */
175− while ((xm >> (DP_MBITS + 3)) == 0) {
173+ /*
174+ * Normalize to rounding precision.
175+ */
176+ while ((xm >> (DP_FBITS + 3)) == 0) {
176177 xm <<= 1;
177178 xe--;
178179 }
179−
180180 }
181− DPNORMRET2(xs, xe, xm, "add", x, y);
181+
182+ return ieee754dp_format(xs, xe, xm);
182183 }
arch/mips/math-emu/dp_cmp.c+11−13
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,16 +16,16 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754dp.h"
2823
29−int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cmp, int sig)
24+int ieee754dp_cmp(union ieee754dp x, union ieee754dp y, int cmp, int sig)
3025 {
26+ s64 vx;
27+ s64 vy;
28+
3129 COMPXDP;
3230 COMPYDP;
3331
@@ -35,21 +33,21 @@ int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cmp, int sig) · 1 unmodified line
3533 EXPLODEYDP;
3634 FLUSHXDP;
3735 FLUSHYDP;
38− CLEARCX; /* Even clear inexact flag here */
36+ ieee754_clearcx(); /* Even clear inexact flag here */
3937
4038 if (ieee754dp_isnan(x) || ieee754dp_isnan(y)) {
4139 if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
42− SETCX(IEEE754_INVALID_OPERATION);
40+ ieee754_setcx(IEEE754_INVALID_OPERATION);
4341 if (cmp & IEEE754_CUN)
4442 return 1;
4543 if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
46− if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION))
47− return ieee754si_xcpt(0, "fcmpf", x);
44+ if (sig && ieee754_setandtestcx(IEEE754_INVALID_OPERATION))
45+ return 0;
4846 }
4947 return 0;
5048 } else {
51− s64 vx = x.bits;
52− s64 vy = y.bits;
49+ vx = x.bits;
50+ vy = y.bits;
5351
5452 if (vx < 0)
5553 vx = -vx ^ DP_SIGN_BIT;
arch/mips/math-emu/dp_div.c+46−48
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,23 +16,24 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754dp.h"
2823
29−ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y)
24+union ieee754dp ieee754dp_div(union ieee754dp x, union ieee754dp y)
3025 {
26+ u64 rm;
27+ int re;
28+ u64 bm;
29+
3130 COMPXDP;
3231 COMPYDP;
3332
3433 EXPLODEXDP;
3534 EXPLODEYDP;
3635
37− CLEARCX;
36+ ieee754_clearcx();
3837
3938 FLUSHXDP;
4039 FLUSHYDP;
@@ -51,8 +50,8 @@ ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y) · 10 unmodified lines
5150 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
5251 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
5352 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
54− SETCX(IEEE754_INVALID_OPERATION);
55− return ieee754dp_nanxcpt(ieee754dp_indef(), "div", x, y);
53+ ieee754_setcx(IEEE754_INVALID_OPERATION);
54+ return ieee754dp_nanxcpt(ieee754dp_indef());
5655
5756 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
5857 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -68,12 +67,12 @@ ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y) · 9 unmodified lines
6867 return x;
6968
7069
71− /* Infinity handling
72− */
73−
70+ /*
71+ * Infinity handling
72+ */
7473 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
75− SETCX(IEEE754_INVALID_OPERATION);
76− return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y);
74+ ieee754_setcx(IEEE754_INVALID_OPERATION);
75+ return ieee754dp_indef();
7776
7877 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
7978 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
@@ -85,17 +84,17 @@ ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y) · 5 unmodified lines
8584 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
8685 return ieee754dp_inf(xs ^ ys);
8786
88− /* Zero handling
89− */
90−
87+ /*
88+ * Zero handling
89+ */
9190 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
92− SETCX(IEEE754_INVALID_OPERATION);
93− return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y);
91+ ieee754_setcx(IEEE754_INVALID_OPERATION);
92+ return ieee754dp_indef();
9493
9594 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
9695 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
97− SETCX(IEEE754_ZERO_DIVIDE);
98− return ieee754dp_xcpt(ieee754dp_inf(xs ^ ys), "div", x, y);
96+ ieee754_setcx(IEEE754_ZERO_DIVIDE);
97+ return ieee754dp_inf(xs ^ ys);
9998
10099 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
101100 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
@@ -122,35 +121,34 @@ ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y) · 20 unmodified lines
122121 xm <<= 3;
123122 ym <<= 3;
124123
125− {
126− /* now the dirty work */
127−
128− u64 rm = 0;
129− int re = xe - ye;
130− u64 bm;
131−
132− for (bm = DP_MBIT(DP_MBITS + 2); bm; bm >>= 1) {
133− if (xm >= ym) {
134− xm -= ym;
135− rm |= bm;
136− if (xm == 0)
137− break;
138− }
139− xm <<= 1;
140− }
141− rm <<= 1;
142− if (xm)
143− rm |= 1; /* have remainder, set sticky */
124+ /* now the dirty work */
144125
145− assert(rm);
126+ rm = 0;
127+ re = xe - ye;
146128
147− /* normalise rm to rounding precision ?
148− */
149− while ((rm >> (DP_MBITS + 3)) == 0) {
150− rm <<= 1;
151− re--;
129+ for (bm = DP_MBIT(DP_FBITS + 2); bm; bm >>= 1) {
130+ if (xm >= ym) {
131+ xm -= ym;
132+ rm |= bm;
133+ if (xm == 0)
134+ break;
152135 }
136+ xm <<= 1;
137+ }
138+
139+ rm <<= 1;
140+ if (xm)
141+ rm |= 1; /* have remainder, set sticky */
153142
154− DPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y);
143+ assert(rm);
144+
145+ /*
146+ * Normalise rm to rounding precision ?
147+ */
148+ while ((rm >> (DP_FBITS + 3)) == 0) {
149+ rm <<= 1;
150+ re--;
155151 }
152+
153+ return ieee754dp_format(xs == ys ? 0 : 1, re, rm);
156154 }
arch/mips/math-emu/dp_fint.c+5−28
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,21 +16,18 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754dp.h"
2823
29−ieee754dp ieee754dp_fint(int x)
24+union ieee754dp ieee754dp_fint(int x)
3025 {
3126 u64 xm;
3227 int xe;
3328 int xs;
3429
35− CLEARCX;
30+ ieee754_clearcx();
3631
3732 if (x == 0)
3833 return ieee754dp_zero(0);
@@ -51,29 +46,11 @@ ieee754dp ieee754dp_fint(int x) · 12 unmodified lines
5146 xm = x;
5247 }
5348
54−#if 1
5549 /* normalize - result can never be inexact or overflow */
56− xe = DP_MBITS;
57− while ((xm >> DP_MBITS) == 0) {
50+ xe = DP_FBITS;
51+ while ((xm >> DP_FBITS) == 0) {
5852 xm <<= 1;
5953 xe--;
6054 }
6155 return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
62−#else
63− /* normalize */
64− xe = DP_MBITS + 3;
65− while ((xm >> (DP_MBITS + 3)) == 0) {
66− xm <<= 1;
67− xe--;
68− }
69− DPNORMRET1(xs, xe, xm, "fint", x);
70−#endif
71−}
72−
73−ieee754dp ieee754dp_funs(unsigned int u)
74−{
75− if ((int) u < 0)
76− return ieee754dp_add(ieee754dp_1e31(),
77− ieee754dp_fint(u & ~(1 << 31)));
78− return ieee754dp_fint(u);
7956 }
arch/mips/math-emu/dp_flong.c+8−20
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,21 +16,18 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754dp.h"
2823
29−ieee754dp ieee754dp_flong(s64 x)
24+union ieee754dp ieee754dp_flong(s64 x)
3025 {
3126 u64 xm;
3227 int xe;
3328 int xs;
3429
35− CLEARCX;
30+ ieee754_clearcx();
3631
3732 if (x == 0)
3833 return ieee754dp_zero(0);
@@ -52,26 +47,19 @@ ieee754dp ieee754dp_flong(s64 x) · 13 unmodified lines
5247 }
5348
5449 /* normalize */
55− xe = DP_MBITS + 3;
56− if (xm >> (DP_MBITS + 1 + 3)) {
50+ xe = DP_FBITS + 3;
51+ if (xm >> (DP_FBITS + 1 + 3)) {
5752 /* shunt out overflow bits */
58− while (xm >> (DP_MBITS + 1 + 3)) {
53+ while (xm >> (DP_FBITS + 1 + 3)) {
5954 XDPSRSX1();
6055 }
6156 } else {
6257 /* normalize in grs extended double precision */
63− while ((xm >> (DP_MBITS + 3)) == 0) {
58+ while ((xm >> (DP_FBITS + 3)) == 0) {
6459 xm <<= 1;
6560 xe--;
6661 }
6762 }
68− DPNORMRET1(xs, xe, xm, "dp_flong", x);
69−}
7063
71−ieee754dp ieee754dp_fulong(u64 u)
72−{
73− if ((s64) u < 0)
74− return ieee754dp_add(ieee754dp_1e63(),
75− ieee754dp_flong(u & ~(1ULL << 63)));
76− return ieee754dp_flong(u);
64+ return ieee754dp_format(xs, xe, xm);
7765 }
arch/mips/math-emu/dp_frexp.c+0−52
@@ -1,52 +0,0 @@
1−/* IEEE754 floating point arithmetic
2− * double precision: common utilities
3− */
4−/*
5− * MIPS floating point support
6− * Copyright (C) 1994-2000 Algorithmics Ltd.
7− *
8− * ########################################################################
9− *
10− * This program is free software; you can distribute it and/or modify it
11− * under the terms of the GNU General Public License (Version 2) as
12− * published by the Free Software Foundation.
13− *
14− * This program is distributed in the hope it will be useful, but WITHOUT
15− * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16− * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17− * for more details.
18− *
19− * You should have received a copy of the GNU General Public License along
20− * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
24− */
25−
26−
27−#include "ieee754dp.h"
28−
29−/* close to ieeep754dp_logb
30−*/
31−ieee754dp ieee754dp_frexp(ieee754dp x, int *eptr)
32−{
33− COMPXDP;
34− CLEARCX;
35− EXPLODEXDP;
36−
37− switch (xc) {
38− case IEEE754_CLASS_SNAN:
39− case IEEE754_CLASS_QNAN:
40− case IEEE754_CLASS_INF:
41− case IEEE754_CLASS_ZERO:
42− *eptr = 0;
43− return x;
44− case IEEE754_CLASS_DNORM:
45− DPDNORMX;
46− break;
47− case IEEE754_CLASS_NORM:
48− break;
49− }
50− *eptr = xe + 1;
51− return builddp(xs, -1 + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
52−}
arch/mips/math-emu/dp_fsp.c+16−16
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,56 +16,58 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
22+#include "ieee754sp.h"
2723 #include "ieee754dp.h"
2824
29−ieee754dp ieee754dp_fsp(ieee754sp x)
25+union ieee754dp ieee754dp_fsp(union ieee754sp x)
3026 {
3127 COMPXSP;
3228
3329 EXPLODEXSP;
3430
35− CLEARCX;
31+ ieee754_clearcx();
3632
3733 FLUSHXSP;
3834
3935 switch (xc) {
4036 case IEEE754_CLASS_SNAN:
41− SETCX(IEEE754_INVALID_OPERATION);
42− return ieee754dp_nanxcpt(ieee754dp_indef(), "fsp");
37+ ieee754_setcx(IEEE754_INVALID_OPERATION);
38+ return ieee754dp_nanxcpt(ieee754dp_indef());
39+
4340 case IEEE754_CLASS_QNAN:
4441 return ieee754dp_nanxcpt(builddp(xs,
4542 DP_EMAX + 1 + DP_EBIAS,
4643 ((u64) xm
47− << (DP_MBITS -
48− SP_MBITS))), "fsp",
49− x);
44+ << (DP_FBITS -
45+ SP_FBITS))));
5046 case IEEE754_CLASS_INF:
5147 return ieee754dp_inf(xs);
48+
5249 case IEEE754_CLASS_ZERO:
5350 return ieee754dp_zero(xs);
51+
5452 case IEEE754_CLASS_DNORM:
5553 /* normalize */
56− while ((xm >> SP_MBITS) == 0) {
54+ while ((xm >> SP_FBITS) == 0) {
5755 xm <<= 1;
5856 xe--;
5957 }
6058 break;
59+
6160 case IEEE754_CLASS_NORM:
6261 break;
6362 }
6463
65− /* CAN'T possibly overflow,underflow, or need rounding
64+ /*
65+ * Can't possibly overflow,underflow, or need rounding
6666 */
6767
6868 /* drop the hidden bit */
6969 xm &= ~SP_HIDDEN_BIT;
7070
7171 return builddp(xs, xe + DP_EBIAS,
72− (u64) xm << (DP_MBITS - SP_MBITS));
72+ (u64) xm << (DP_FBITS - SP_FBITS));
7373 }
arch/mips/math-emu/dp_logb.c+0−53
@@ -1,53 +0,0 @@
1−/* IEEE754 floating point arithmetic
2− * double precision: common utilities
3− */
4−/*
5− * MIPS floating point support
6− * Copyright (C) 1994-2000 Algorithmics Ltd.
7− *
8− * ########################################################################
9− *
10− * This program is free software; you can distribute it and/or modify it
11− * under the terms of the GNU General Public License (Version 2) as
12− * published by the Free Software Foundation.
13− *
14− * This program is distributed in the hope it will be useful, but WITHOUT
15− * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16− * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17− * for more details.
18− *
19− * You should have received a copy of the GNU General Public License along
20− * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
24− */
25−
26−
27−#include "ieee754dp.h"
28−
29−ieee754dp ieee754dp_logb(ieee754dp x)
30−{
31− COMPXDP;
32−
33− CLEARCX;
34−
35− EXPLODEXDP;
36−
37− switch (xc) {
38− case IEEE754_CLASS_SNAN:
39− return ieee754dp_nanxcpt(x, "logb", x);
40− case IEEE754_CLASS_QNAN:
41− return x;
42− case IEEE754_CLASS_INF:
43− return ieee754dp_inf(0);
44− case IEEE754_CLASS_ZERO:
45− return ieee754dp_inf(1);
46− case IEEE754_CLASS_DNORM:
47− DPDNORMX;
48− break;
49− case IEEE754_CLASS_NORM:
50− break;
51− }
52− return ieee754dp_fint(xe);
53−}
arch/mips/math-emu/dp_modf.c+0−79
@@ -1,79 +0,0 @@
1−/* IEEE754 floating point arithmetic
2− * double precision: common utilities
3− */
4−/*
5− * MIPS floating point support
6− * Copyright (C) 1994-2000 Algorithmics Ltd.
7− *
8− * ########################################################################
9− *
10− * This program is free software; you can distribute it and/or modify it
11− * under the terms of the GNU General Public License (Version 2) as
12− * published by the Free Software Foundation.
13− *
14− * This program is distributed in the hope it will be useful, but WITHOUT
15− * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16− * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17− * for more details.
18− *
19− * You should have received a copy of the GNU General Public License along
20− * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
24− */
25−
26−
27−#include "ieee754dp.h"
28−
29−/* modf function is always exact for a finite number
30−*/
31−ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp *ip)
32−{
33− COMPXDP;
34−
35− CLEARCX;
36−
37− EXPLODEXDP;
38−
39− switch (xc) {
40− case IEEE754_CLASS_SNAN:
41− case IEEE754_CLASS_QNAN:
42− case IEEE754_CLASS_INF:
43− case IEEE754_CLASS_ZERO:
44− *ip = x;
45− return x;
46− case IEEE754_CLASS_DNORM:
47− /* far to small */
48− *ip = ieee754dp_zero(xs);
49− return x;
50− case IEEE754_CLASS_NORM:
51− break;
52− }
53− if (xe < 0) {
54− *ip = ieee754dp_zero(xs);
55− return x;
56− }
57− if (xe >= DP_MBITS) {
58− *ip = x;
59− return ieee754dp_zero(xs);
60− }
61− /* generate ipart mantissa by clearing bottom bits
62− */
63− *ip = builddp(xs, xe + DP_EBIAS,
64− ((xm >> (DP_MBITS - xe)) << (DP_MBITS - xe)) &
65− ~DP_HIDDEN_BIT);
66−
67− /* generate fpart mantissa by clearing top bits
68− * and normalizing (must be able to normalize)
69− */
70− xm = (xm << (64 - (DP_MBITS - xe))) >> (64 - (DP_MBITS - xe));
71− if (xm == 0)
72− return ieee754dp_zero(xs);
73−
74− while ((xm >> DP_MBITS) == 0) {
75− xm <<= 1;
76− xe--;
77− }
78− return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
79−}
arch/mips/math-emu/dp_mul.c+70−73
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,23 +16,32 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754dp.h"
2823
29−ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y)
24+union ieee754dp ieee754dp_mul(union ieee754dp x, union ieee754dp y)
3025 {
26+ int re;
27+ int rs;
28+ u64 rm;
29+ unsigned lxm;
30+ unsigned hxm;
31+ unsigned lym;
32+ unsigned hym;
33+ u64 lrm;
34+ u64 hrm;
35+ u64 t;
36+ u64 at;
37+
3138 COMPXDP;
3239 COMPYDP;
3340
3441 EXPLODEXDP;
3542 EXPLODEYDP;
3643
37− CLEARCX;
44+ ieee754_clearcx();
3845
3946 FLUSHXDP;
4047 FLUSHYDP;
@@ -51,8 +58,8 @@ ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y) · 10 unmodified lines
5158 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
5259 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
5360 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
54− SETCX(IEEE754_INVALID_OPERATION);
55− return ieee754dp_nanxcpt(ieee754dp_indef(), "mul", x, y);
61+ ieee754_setcx(IEEE754_INVALID_OPERATION);
62+ return ieee754dp_nanxcpt(ieee754dp_indef());
5663
5764 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
5865 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -68,12 +75,13 @@ ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y) · 9 unmodified lines
6875 return x;
6976
7077
71− /* Infinity handling */
72−
78+ /*
79+ * Infinity handling
80+ */
7381 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
7482 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
75− SETCX(IEEE754_INVALID_OPERATION);
76− return ieee754dp_xcpt(ieee754dp_indef(), "mul", x, y);
83+ ieee754_setcx(IEEE754_INVALID_OPERATION);
84+ return ieee754dp_indef();
7785
7886 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
7987 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
@@ -107,70 +115,59 @@ ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y) · 27 unmodified lines
107115 /* rm = xm * ym, re = xe+ye basically */
108116 assert(xm & DP_HIDDEN_BIT);
109117 assert(ym & DP_HIDDEN_BIT);
110− {
111− int re = xe + ye;
112− int rs = xs ^ ys;
113− u64 rm;
114118
115− /* shunt to top of word */
116− xm <<= 64 - (DP_MBITS + 1);
117− ym <<= 64 - (DP_MBITS + 1);
119+ re = xe + ye;
120+ rs = xs ^ ys;
121+
122+ /* shunt to top of word */
123+ xm <<= 64 - (DP_FBITS + 1);
124+ ym <<= 64 - (DP_FBITS + 1);
118125
119− /* multiply 32bits xm,ym to give high 32bits rm with stickness
120− */
126+ /*
127+ * Multiply 32 bits xm, ym to give high 32 bits rm with stickness.
128+ */
121129
122− /* 32 * 32 => 64 */
130+ /* 32 * 32 => 64 */
123131 #define DPXMULT(x, y) ((u64)(x) * (u64)y)
124132
125− {
126− unsigned lxm = xm;
127− unsigned hxm = xm >> 32;
128− unsigned lym = ym;
129− unsigned hym = ym >> 32;
130− u64 lrm;
131− u64 hrm;
132−
133− lrm = DPXMULT(lxm, lym);
134− hrm = DPXMULT(hxm, hym);
135−
136− {
137− u64 t = DPXMULT(lxm, hym);
138− {
139− u64 at =
140− lrm + (t << 32);
141− hrm += at < lrm;
142− lrm = at;
143− }
144− hrm = hrm + (t >> 32);
145− }
146−
147− {
148− u64 t = DPXMULT(hxm, lym);
149− {
150− u64 at =
151− lrm + (t << 32);
152− hrm += at < lrm;
153− lrm = at;
154− }
155− hrm = hrm + (t >> 32);
156− }
157− rm = hrm | (lrm != 0);
158− }
159−
160− /*
161− * sticky shift down to normal rounding precision
162− */
163− if ((s64) rm < 0) {
164− rm =
165− (rm >> (64 - (DP_MBITS + 1 + 3))) |
166− ((rm << (DP_MBITS + 1 + 3)) != 0);
133+ lxm = xm;
134+ hxm = xm >> 32;
135+ lym = ym;
136+ hym = ym >> 32;
137+
138+ lrm = DPXMULT(lxm, lym);
139+ hrm = DPXMULT(hxm, hym);
140+
141+ t = DPXMULT(lxm, hym);
142+
143+ at = lrm + (t << 32);
144+ hrm += at < lrm;
145+ lrm = at;
146+
147+ hrm = hrm + (t >> 32);
148+
149+ t = DPXMULT(hxm, lym);
150+
151+ at = lrm + (t << 32);
152+ hrm += at < lrm;
153+ lrm = at;
154+
155+ hrm = hrm + (t >> 32);
156+
157+ rm = hrm | (lrm != 0);
158+
159+ /*
160+ * Sticky shift down to normal rounding precision.
161+ */
162+ if ((s64) rm < 0) {
163+ rm = (rm >> (64 - (DP_FBITS + 1 + 3))) |
164+ ((rm << (DP_FBITS + 1 + 3)) != 0);
167165 re++;
168− } else {
169− rm =
170− (rm >> (64 - (DP_MBITS + 1 + 3 + 1))) |
171− ((rm << (DP_MBITS + 1 + 3 + 1)) != 0);
172− }
173− assert(rm & (DP_HIDDEN_BIT << 3));
174− DPNORMRET2(rs, re, rm, "mul", x, y);
166+ } else {
167+ rm = (rm >> (64 - (DP_FBITS + 1 + 3 + 1))) |
168+ ((rm << (DP_FBITS + 1 + 3 + 1)) != 0);
175169 }
170+ assert(rm & (DP_HIDDEN_BIT << 3));
171+
172+ return ieee754dp_format(rs, re, rm);
176173 }
arch/mips/math-emu/dp_scalb.c+0−57
@@ -1,57 +0,0 @@
1−/* IEEE754 floating point arithmetic
2− * double precision: common utilities
3− */
4−/*
5− * MIPS floating point support
6− * Copyright (C) 1994-2000 Algorithmics Ltd.
7− *
8− * ########################################################################
9− *
10− * This program is free software; you can distribute it and/or modify it
11− * under the terms of the GNU General Public License (Version 2) as
12− * published by the Free Software Foundation.
13− *
14− * This program is distributed in the hope it will be useful, but WITHOUT
15− * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16− * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17− * for more details.
18− *
19− * You should have received a copy of the GNU General Public License along
20− * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
24− */
25−
26−
27−#include "ieee754dp.h"
28−
29−ieee754dp ieee754dp_scalb(ieee754dp x, int n)
30−{
31− COMPXDP;
32−
33− CLEARCX;
34−
35− EXPLODEXDP;
36−
37− switch (xc) {
38− case IEEE754_CLASS_SNAN:
39− return ieee754dp_nanxcpt(x, "scalb", x, n);
40− case IEEE754_CLASS_QNAN:
41− case IEEE754_CLASS_INF:
42− case IEEE754_CLASS_ZERO:
43− return x;
44− case IEEE754_CLASS_DNORM:
45− DPDNORMX;
46− break;
47− case IEEE754_CLASS_NORM:
48− break;
49− }
50− DPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n);
51−}
52−
53−
54−ieee754dp ieee754dp_ldexp(ieee754dp x, int n)
55−{
56− return ieee754dp_scalb(x, n);
57−}
arch/mips/math-emu/dp_simple.c+10−29
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,33 +16,17 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754dp.h"
2823
29−int ieee754dp_finite(ieee754dp x)
30−{
31− return DPBEXP(x) != DP_EMAX + 1 + DP_EBIAS;
32−}
33−
34−ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y)
35−{
36− CLEARCX;
37− DPSIGN(x) = DPSIGN(y);
38− return x;
39−}
40−
41−
42−ieee754dp ieee754dp_neg(ieee754dp x)
24+union ieee754dp ieee754dp_neg(union ieee754dp x)
4325 {
4426 COMPXDP;
4527
4628 EXPLODEXDP;
47− CLEARCX;
29+ ieee754_clearcx();
4830 FLUSHXDP;
4931
5032 /*
@@ -55,30 +37,29 @@ ieee754dp ieee754dp_neg(ieee754dp x) · 4 unmodified lines
5537 DPSIGN(x) ^= 1;
5638
5739 if (xc == IEEE754_CLASS_SNAN) {
58− ieee754dp y = ieee754dp_indef();
59− SETCX(IEEE754_INVALID_OPERATION);
40+ union ieee754dp y = ieee754dp_indef();
41+ ieee754_setcx(IEEE754_INVALID_OPERATION);
6042 DPSIGN(y) = DPSIGN(x);
61− return ieee754dp_nanxcpt(y, "neg");
43+ return ieee754dp_nanxcpt(y);
6244 }
6345
6446 return x;
6547 }
6648
67−
68−ieee754dp ieee754dp_abs(ieee754dp x)
49+union ieee754dp ieee754dp_abs(union ieee754dp x)
6950 {
7051 COMPXDP;
7152
7253 EXPLODEXDP;
73− CLEARCX;
54+ ieee754_clearcx();
7455 FLUSHXDP;
7556
7657 /* Clear sign ALWAYS, irrespective of NaN */
7758 DPSIGN(x) = 0;
7859
7960 if (xc == IEEE754_CLASS_SNAN) {
80− SETCX(IEEE754_INVALID_OPERATION);
81− return ieee754dp_nanxcpt(ieee754dp_indef(), "abs");
61+ ieee754_setcx(IEEE754_INVALID_OPERATION);
62+ return ieee754dp_nanxcpt(ieee754dp_indef());
8263 }
8364
8465 return x;
arch/mips/math-emu/dp_sqrt.c+23−23
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,12 +16,9 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754dp.h"
2823
2924 static const unsigned table[] = {
@@ -34,44 +29,49 @@ static const unsigned table[] = { · 4 unmodified lines
3429 1742, 661, 130
3530 };
3631
37−ieee754dp ieee754dp_sqrt(ieee754dp x)
32+union ieee754dp ieee754dp_sqrt(union ieee754dp x)
3833 {
3934 struct _ieee754_csr oldcsr;
40− ieee754dp y, z, t;
35+ union ieee754dp y, z, t;
4136 unsigned scalx, yh;
4237 COMPXDP;
4338
4439 EXPLODEXDP;
45− CLEARCX;
40+ ieee754_clearcx();
4641 FLUSHXDP;
4742
4843 /* x == INF or NAN? */
4944 switch (xc) {
5045 case IEEE754_CLASS_QNAN:
5146 /* sqrt(Nan) = Nan */
52− return ieee754dp_nanxcpt(x, "sqrt");
47+ return ieee754dp_nanxcpt(x);
48+
5349 case IEEE754_CLASS_SNAN:
54− SETCX(IEEE754_INVALID_OPERATION);
55− return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt");
50+ ieee754_setcx(IEEE754_INVALID_OPERATION);
51+ return ieee754dp_nanxcpt(ieee754dp_indef());
52+
5653 case IEEE754_CLASS_ZERO:
5754 /* sqrt(0) = 0 */
5855 return x;
56+
5957 case IEEE754_CLASS_INF:
6058 if (xs) {
6159 /* sqrt(-Inf) = Nan */
62− SETCX(IEEE754_INVALID_OPERATION);
63− return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt");
60+ ieee754_setcx(IEEE754_INVALID_OPERATION);
61+ return ieee754dp_nanxcpt(ieee754dp_indef());
6462 }
6563 /* sqrt(+Inf) = Inf */
6664 return x;
65+
6766 case IEEE754_CLASS_DNORM:
6867 DPDNORMX;
6968 /* fall through */
69+
7070 case IEEE754_CLASS_NORM:
7171 if (xs) {
7272 /* sqrt(-x) = Nan */
73− SETCX(IEEE754_INVALID_OPERATION);
74− return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt");
73+ ieee754_setcx(IEEE754_INVALID_OPERATION);
74+ return ieee754dp_nanxcpt(ieee754dp_indef());
7575 }
7676 break;
7777 }
@@ -80,7 +80,7 @@ ieee754dp ieee754dp_sqrt(ieee754dp x) · 2 unmodified lines
8080 oldcsr = ieee754_csr;
8181 ieee754_csr.mx &= ~IEEE754_INEXACT;
8282 ieee754_csr.sx &= ~IEEE754_INEXACT;
83− ieee754_csr.rm = IEEE754_RN;
83+ ieee754_csr.rm = FPU_CSR_RN;
8484
8585 /* adjust exponent to prevent overflow */
8686 scalx = 0;
@@ -110,19 +110,19 @@ ieee754dp ieee754dp_sqrt(ieee754dp x) · 23 unmodified lines
110110 /* triple to almost 56 sig. bits: y ~= sqrt(x) to within 1 ulp */
111111 /* t=y*y; z=t; pt[n0]+=0x00100000; t+=z; z=(x-z)*y; */
112112 z = t = ieee754dp_mul(y, y);
113− t.parts.bexp += 0x001;
113+ t.bexp += 0x001;
114114 t = ieee754dp_add(t, z);
115115 z = ieee754dp_mul(ieee754dp_sub(x, z), y);
116116
117117 /* t=z/(t+x) ; pt[n0]+=0x00100000; y+=t; */
118118 t = ieee754dp_div(z, ieee754dp_add(t, x));
119− t.parts.bexp += 0x001;
119+ t.bexp += 0x001;
120120 y = ieee754dp_add(y, t);
121121
122122 /* twiddle last bit to force y correctly rounded */
123123
124124 /* set RZ, clear INEX flag */
125− ieee754_csr.rm = IEEE754_RZ;
125+ ieee754_csr.rm = FPU_CSR_RZ;
126126 ieee754_csr.sx &= ~IEEE754_INEXACT;
127127
128128 /* t=x/y; ...chopped quotient, possibly inexact */
@@ -139,10 +139,10 @@ ieee754dp ieee754dp_sqrt(ieee754dp x) · 10 unmodified lines
139139 oldcsr.sx |= IEEE754_INEXACT;
140140
141141 switch (oldcsr.rm) {
142− case IEEE754_RP:
142+ case FPU_CSR_RU:
143143 y.bits += 1;
144144 /* drop through */
145− case IEEE754_RN:
145+ case FPU_CSR_RN:
146146 t.bits += 1;
147147 break;
148148 }
@@ -155,7 +155,7 @@ ieee754dp ieee754dp_sqrt(ieee754dp x) · 6 unmodified lines
155155 }
156156
157157 /* py[n0]=py[n0]+scalx; ...scale back y */
158− y.parts.bexp += scalx;
158+ y.bexp += scalx;
159159
160160 /* restore rounding mode, possibly set inexact */
161161 ieee754_csr = oldcsr;
arch/mips/math-emu/dp_sub.c+27−28
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,23 +16,22 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754dp.h"
2823
29−ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y)
24+union ieee754dp ieee754dp_sub(union ieee754dp x, union ieee754dp y)
3025 {
26+ int s;
27+
3128 COMPXDP;
3229 COMPYDP;
3330
3431 EXPLODEXDP;
3532 EXPLODEYDP;
3633
37− CLEARCX;
34+ ieee754_clearcx();
3835
3936 FLUSHXDP;
4037 FLUSHYDP;
@@ -51,8 +48,8 @@ ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y) · 10 unmodified lines
5148 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
5249 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
5350 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
54− SETCX(IEEE754_INVALID_OPERATION);
55− return ieee754dp_nanxcpt(ieee754dp_indef(), "sub", x, y);
51+ ieee754_setcx(IEEE754_INVALID_OPERATION);
52+ return ieee754dp_nanxcpt(ieee754dp_indef());
5653
5754 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
5855 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -68,14 +65,14 @@ ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y) · 9 unmodified lines
6865 return x;
6966
7067
71− /* Infinity handling
72− */
73−
68+ /*
69+ * Infinity handling
70+ */
7471 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
7572 if (xs != ys)
7673 return x;
77− SETCX(IEEE754_INVALID_OPERATION);
78− return ieee754dp_xcpt(ieee754dp_indef(), "sub", x, y);
74+ ieee754_setcx(IEEE754_INVALID_OPERATION);
75+ return ieee754dp_indef();
7976
8077 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
8178 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
@@ -87,15 +84,14 @@ ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y) · 5 unmodified lines
8784 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
8885 return x;
8986
90− /* Zero handling
91− */
92−
87+ /*
88+ * Zero handling
89+ */
9390 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
9491 if (xs != ys)
9592 return x;
9693 else
97− return ieee754dp_zero(ieee754_csr.rm ==
98− IEEE754_RD);
94+ return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
9995
10096 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
10197 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
@@ -136,15 +132,17 @@ ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y) · 34 unmodified lines
136132 ym <<= 3;
137133
138134 if (xe > ye) {
139− /* have to shift y fraction right to align
135+ /*
136+ * Have to shift y fraction right to align
140137 */
141− int s = xe - ye;
138+ s = xe - ye;
142139 ym = XDPSRS(ym, s);
143140 ye += s;
144141 } else if (ye > xe) {
145− /* have to shift x fraction right to align
142+ /*
143+ * Have to shift x fraction right to align
146144 */
147− int s = ye - xe;
145+ s = ye - xe;
148146 xm = XDPSRS(xm, s);
149147 xe += s;
150148 }
@@ -158,7 +156,7 @@ ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y) · 7 unmodified lines
158156 xe = xe;
159157 xs = xs;
160158
161− if (xm >> (DP_MBITS + 1 + 3)) { /* carry out */
159+ if (xm >> (DP_FBITS + 1 + 3)) { /* carry out */
162160 xm = XDPSRS1(xm); /* shift preserving sticky */
163161 xe++;
164162 }
@@ -173,7 +171,7 @@ ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y) · 8 unmodified lines
173171 xs = ys;
174172 }
175173 if (xm == 0) {
176− if (ieee754_csr.rm == IEEE754_RD)
174+ if (ieee754_csr.rm == FPU_CSR_RD)
177175 return ieee754dp_zero(1); /* round negative inf. => sign = -1 */
178176 else
179177 return ieee754dp_zero(0); /* other round modes => sign = 1 */
@@ -181,10 +179,11 @@ ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y) · 1 unmodified line
181179
182180 /* normalize to rounding precision
183181 */
184− while ((xm >> (DP_MBITS + 3)) == 0) {
182+ while ((xm >> (DP_FBITS + 3)) == 0) {
185183 xm <<= 1;
186184 xe--;
187185 }
188186 }
189− DPNORMRET2(xs, xe, xm, "sub", x, y);
187+
188+ return ieee754dp_format(xs, xe, xm);
190189 }
arch/mips/math-emu/dp_tint.c+26−43
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,20 +16,21 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
27−#include <linux/kernel.h>
2822 #include "ieee754dp.h"
2923
30−int ieee754dp_tint(ieee754dp x)
24+int ieee754dp_tint(union ieee754dp x)
3125 {
26+ u64 residue;
27+ int round;
28+ int sticky;
29+ int odd;
30+
3231 COMPXDP;
3332
34− CLEARCX;
33+ ieee754_clearcx();
3534
3635 EXPLODEXDP;
3736 FLUSHXDP;
@@ -40,10 +39,12 @@ int ieee754dp_tint(ieee754dp x) · 2 unmodified lines
4039 case IEEE754_CLASS_SNAN:
4140 case IEEE754_CLASS_QNAN:
4241 case IEEE754_CLASS_INF:
43− SETCX(IEEE754_INVALID_OPERATION);
44− return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
42+ ieee754_setcx(IEEE754_INVALID_OPERATION);
43+ return ieee754si_indef();
44+
4545 case IEEE754_CLASS_ZERO:
4646 return 0;
47+
4748 case IEEE754_CLASS_DNORM:
4849 case IEEE754_CLASS_NORM:
4950 break;
@@ -51,44 +52,39 @@ int ieee754dp_tint(ieee754dp x) · 1 unmodified line
5152 if (xe > 31) {
5253 /* Set invalid. We will only use overflow for floating
5354 point overflow */
54− SETCX(IEEE754_INVALID_OPERATION);
55− return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
55+ ieee754_setcx(IEEE754_INVALID_OPERATION);
56+ return ieee754si_indef();
5657 }
5758 /* oh gawd */
58− if (xe > DP_MBITS) {
59− xm <<= xe - DP_MBITS;
60− } else if (xe < DP_MBITS) {
61− u64 residue;
62− int round;
63− int sticky;
64− int odd;
65−
59+ if (xe > DP_FBITS) {
60+ xm <<= xe - DP_FBITS;
61+ } else if (xe < DP_FBITS) {
6662 if (xe < -1) {
6763 residue = xm;
6864 round = 0;
6965 sticky = residue != 0;
7066 xm = 0;
7167 } else {
72− residue = xm << (64 - DP_MBITS + xe);
68+ residue = xm << (64 - DP_FBITS + xe);
7369 round = (residue >> 63) != 0;
7470 sticky = (residue << 1) != 0;
75− xm >>= DP_MBITS - xe;
71+ xm >>= DP_FBITS - xe;
7672 }
7773 /* Note: At this point upper 32 bits of xm are guaranteed
7874 to be zero */
7975 odd = (xm & 0x1) != 0x0;
8076 switch (ieee754_csr.rm) {
81− case IEEE754_RN:
77+ case FPU_CSR_RN:
8278 if (round && (sticky || odd))
8379 xm++;
8480 break;
85− case IEEE754_RZ:
81+ case FPU_CSR_RZ:
8682 break;
87− case IEEE754_RU: /* toward +Infinity */
83+ case FPU_CSR_RU: /* toward +Infinity */
8884 if ((round || sticky) && !xs)
8985 xm++;
9086 break;
91− case IEEE754_RD: /* toward -Infinity */
87+ case FPU_CSR_RD: /* toward -Infinity */
9288 if ((round || sticky) && xs)
9389 xm++;
9490 break;
@@ -96,27 +92,14 @@ int ieee754dp_tint(ieee754dp x) · 1 unmodified line
9692 /* look for valid corner case 0x80000000 */
9793 if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) {
9894 /* This can happen after rounding */
99− SETCX(IEEE754_INVALID_OPERATION);
100− return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
95+ ieee754_setcx(IEEE754_INVALID_OPERATION);
96+ return ieee754si_indef();
10197 }
10298 if (round || sticky)
103− SETCX(IEEE754_INEXACT);
99+ ieee754_setcx(IEEE754_INEXACT);
104100 }
105101 if (xs)
106102 return -xm;
107103 else
108104 return xm;
109105 }
110−
111−
112−unsigned int ieee754dp_tuns(ieee754dp x)
113−{
114− ieee754dp hb = ieee754dp_1e31();
115−
116− /* what if x < 0 ?? */
117− if (ieee754dp_lt(x, hb))
118− return (unsigned) ieee754dp_tint(x);
119−
120− return (unsigned) ieee754dp_tint(ieee754dp_sub(x, hb)) |
121− ((unsigned) 1 << 31);
122−}
arch/mips/math-emu/dp_tlong.c+26−42
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,19 +16,21 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754dp.h"
2823
29−s64 ieee754dp_tlong(ieee754dp x)
24+s64 ieee754dp_tlong(union ieee754dp x)
3025 {
26+ u64 residue;
27+ int round;
28+ int sticky;
29+ int odd;
30+
3131 COMPXDP;
3232
33− CLEARCX;
33+ ieee754_clearcx();
3434
3535 EXPLODEXDP;
3636 FLUSHXDP;
@@ -39,10 +39,12 @@ s64 ieee754dp_tlong(ieee754dp x) · 2 unmodified lines
3939 case IEEE754_CLASS_SNAN:
4040 case IEEE754_CLASS_QNAN:
4141 case IEEE754_CLASS_INF:
42− SETCX(IEEE754_INVALID_OPERATION);
43− return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
42+ ieee754_setcx(IEEE754_INVALID_OPERATION);
43+ return ieee754di_indef();
44+
4445 case IEEE754_CLASS_ZERO:
4546 return 0;
47+
4648 case IEEE754_CLASS_DNORM:
4749 case IEEE754_CLASS_NORM:
4850 break;
@@ -53,18 +55,13 @@ s64 ieee754dp_tlong(ieee754dp x) · 4 unmodified lines
5355 return -0x8000000000000000LL;
5456 /* Set invalid. We will only use overflow for floating
5557 point overflow */
56− SETCX(IEEE754_INVALID_OPERATION);
57− return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
58+ ieee754_setcx(IEEE754_INVALID_OPERATION);
59+ return ieee754di_indef();
5860 }
5961 /* oh gawd */
60− if (xe > DP_MBITS) {
61− xm <<= xe - DP_MBITS;
62− } else if (xe < DP_MBITS) {
63− u64 residue;
64− int round;
65− int sticky;
66− int odd;
67−
62+ if (xe > DP_FBITS) {
63+ xm <<= xe - DP_FBITS;
64+ } else if (xe < DP_FBITS) {
6865 if (xe < -1) {
6966 residue = xm;
7067 round = 0;
@@ -75,51 +72,38 @@ s64 ieee754dp_tlong(ieee754dp x) · 4 unmodified lines
7572 * so we do it in two steps. Be aware that xe
7673 * may be -1 */
7774 residue = xm << (xe + 1);
78− residue <<= 63 - DP_MBITS;
75+ residue <<= 63 - DP_FBITS;
7976 round = (residue >> 63) != 0;
8077 sticky = (residue << 1) != 0;
81− xm >>= DP_MBITS - xe;
78+ xm >>= DP_FBITS - xe;
8279 }
8380 odd = (xm & 0x1) != 0x0;
8481 switch (ieee754_csr.rm) {
85− case IEEE754_RN:
82+ case FPU_CSR_RN:
8683 if (round && (sticky || odd))
8784 xm++;
8885 break;
89− case IEEE754_RZ:
86+ case FPU_CSR_RZ:
9087 break;
91− case IEEE754_RU: /* toward +Infinity */
88+ case FPU_CSR_RU: /* toward +Infinity */
9289 if ((round || sticky) && !xs)
9390 xm++;
9491 break;
95− case IEEE754_RD: /* toward -Infinity */
92+ case FPU_CSR_RD: /* toward -Infinity */
9693 if ((round || sticky) && xs)
9794 xm++;
9895 break;
9996 }
10097 if ((xm >> 63) != 0) {
10198 /* This can happen after rounding */
102− SETCX(IEEE754_INVALID_OPERATION);
103− return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
99+ ieee754_setcx(IEEE754_INVALID_OPERATION);
100+ return ieee754di_indef();
104101 }
105102 if (round || sticky)
106− SETCX(IEEE754_INEXACT);
103+ ieee754_setcx(IEEE754_INEXACT);
107104 }
108105 if (xs)
109106 return -xm;
110107 else
111108 return xm;
112109 }
113−
114−
115−u64 ieee754dp_tulong(ieee754dp x)
116−{
117− ieee754dp hb = ieee754dp_1e63();
118−
119− /* what if x < 0 ?? */
120− if (ieee754dp_lt(x, hb))
121− return (u64) ieee754dp_tlong(x);
122−
123− return (u64) ieee754dp_tlong(ieee754dp_sub(x, hb)) |
124− (1ULL << 63);
125−}
arch/mips/math-emu/dsemul.c+7−28
@@ -1,30 +1,12 @@
1−#include <linux/compiler.h>
2−#include <linux/mm.h>
3−#include <linux/signal.h>
4−#include <linux/smp.h>
5−
6−#include <asm/asm.h>
7−#include <asm/bootinfo.h>
8−#include <asm/byteorder.h>
9−#include <asm/cpu.h>
10−#include <asm/inst.h>
11−#include <asm/processor.h>
12−#include <asm/uaccess.h>
131 #include <asm/branch.h>
14−#include <asm/mipsregs.h>
152 #include <asm/cacheflush.h>
16−
173 #include <asm/fpu_emulator.h>
4+#include <asm/inst.h>
5+#include <asm/mipsregs.h>
6+#include <asm/uaccess.h>
187
198 #include "ieee754.h"
209
21−/* Strap kernel emulator for full MIPS IV emulation */
22−
23−#ifdef __mips
24−#undef __mips
25−#endif
26−#define __mips 4
27−
2810 /*
2911 * Emulate the arbritrary instruction ir at xcp->cp0_epc. Required when
3012 * we have to emulate the instruction in a COP1 branch delay slot. Do
@@ -59,13 +41,11 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) · 28 unmodified lines
5941 (ir == 0)) {
6042 /* NOP is easy */
6143 regs->cp0_epc = cpc;
62− regs->cp0_cause &= ~CAUSEF_BD;
44+ clear_delay_slot(regs);
6345 return 0;
6446 }
65−#ifdef DSEMUL_TRACE
66− printk("dsemul %lx %lx\n", regs->cp0_epc, cpc);
6747
68−#endif
48+ pr_debug("dsemul %lx %lx\n", regs->cp0_epc, cpc);
6949
7050 /*
7151 * The strategy is to push the instruction onto the user stack
@@ -167,9 +147,8 @@ int do_dsemulret(struct pt_regs *xcp) · 95 unmodified lines
167147 * emulating the branch delay instruction.
168148 */
169149
170−#ifdef DSEMUL_TRACE
171− printk("dsemulret\n");
172−#endif
150+ pr_debug("dsemulret\n");
151+
173152 if (__get_user(epc, &fr->epc)) { /* Saved EPC */
174153 /* This is not a good situation to be in */
175154 force_sig(SIGBUS, current);
arch/mips/math-emu/ieee754.c+54−92
@@ -10,8 +10,6 @@ · 9 unmodified lines
1010 * MIPS floating point support
1111 * Copyright (C) 1994-2000 Algorithmics Ltd.
1212 *
13− * ########################################################################
14− *
1513 * This program is free software; you can distribute it and/or modify it
1614 * under the terms of the GNU General Public License (Version 2) as
1715 * published by the Free Software Foundation.
@@ -23,105 +21,69 @@ · 5 unmodified lines
2321 *
2422 * You should have received a copy of the GNU General Public License along
2523 * with this program; if not, write to the Free Software Foundation, Inc.,
26− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
27− *
28− * ########################################################################
24+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2925 */
3026
27+#include <linux/compiler.h>
3128
32−#include "ieee754int.h"
29+#include "ieee754.h"
3330 #include "ieee754sp.h"
3431 #include "ieee754dp.h"
3532
36−#define DP_EBIAS 1023
37−#define DP_EMIN (-1022)
38−#define DP_EMAX 1023
39−
40−#define SP_EBIAS 127
41−#define SP_EMIN (-126)
42−#define SP_EMAX 127
43−
44−/* special constants
45−*/
46−
47−
48−#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__)
49−#define SPSTR(s, b, m) {m, b, s}
50−#define DPSTR(s, b, mh, ml) {ml, mh, b, s}
51−#endif
52−
53−#ifdef __MIPSEB__
54−#define SPSTR(s, b, m) {s, b, m}
55−#define DPSTR(s, b, mh, ml) {s, b, mh, ml}
56−#endif
33+/*
34+ * Special constants
35+ */
5736
58−const struct ieee754dp_konst __ieee754dp_spcvals[] = {
59− DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 0), /* + zero */
60− DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 0), /* - zero */
61− DPSTR(0, DP_EBIAS, 0, 0), /* + 1.0 */
62− DPSTR(1, DP_EBIAS, 0, 0), /* - 1.0 */
63− DPSTR(0, 3 + DP_EBIAS, 0x40000, 0), /* + 10.0 */
64− DPSTR(1, 3 + DP_EBIAS, 0x40000, 0), /* - 10.0 */
65− DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0, 0), /* + infinity */
66− DPSTR(1, DP_EMAX + 1 + DP_EBIAS, 0, 0), /* - infinity */
67− DPSTR(0, DP_EMAX+1+DP_EBIAS, 0x7FFFF, 0xFFFFFFFF), /* + indef quiet Nan */
68− DPSTR(0, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF), /* + max */
69− DPSTR(1, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF), /* - max */
70− DPSTR(0, DP_EMIN + DP_EBIAS, 0, 0), /* + min normal */
71− DPSTR(1, DP_EMIN + DP_EBIAS, 0, 0), /* - min normal */
72− DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 1), /* + min denormal */
73− DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 1), /* - min denormal */
74− DPSTR(0, 31 + DP_EBIAS, 0, 0), /* + 1.0e31 */
75− DPSTR(0, 63 + DP_EBIAS, 0, 0), /* + 1.0e63 */
76−};
37+#define DPCNST(s, b, m) \
38+{ \
39+ .sign = (s), \
40+ .bexp = (b) + DP_EBIAS, \
41+ .mant = (m) \
42+}
7743
78−const struct ieee754sp_konst __ieee754sp_spcvals[] = {
79− SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 0), /* + zero */
80− SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 0), /* - zero */
81− SPSTR(0, SP_EBIAS, 0), /* + 1.0 */
82− SPSTR(1, SP_EBIAS, 0), /* - 1.0 */
83− SPSTR(0, 3 + SP_EBIAS, 0x200000), /* + 10.0 */
84− SPSTR(1, 3 + SP_EBIAS, 0x200000), /* - 10.0 */
85− SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0), /* + infinity */
86− SPSTR(1, SP_EMAX + 1 + SP_EBIAS, 0), /* - infinity */
87− SPSTR(0, SP_EMAX+1+SP_EBIAS, 0x3FFFFF), /* + indef quiet Nan */
88− SPSTR(0, SP_EMAX + SP_EBIAS, 0x7FFFFF), /* + max normal */
89− SPSTR(1, SP_EMAX + SP_EBIAS, 0x7FFFFF), /* - max normal */
90− SPSTR(0, SP_EMIN + SP_EBIAS, 0), /* + min normal */
91− SPSTR(1, SP_EMIN + SP_EBIAS, 0), /* - min normal */
92− SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 1), /* + min denormal */
93− SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 1), /* - min denormal */
94− SPSTR(0, 31 + SP_EBIAS, 0), /* + 1.0e31 */
95− SPSTR(0, 63 + SP_EBIAS, 0), /* + 1.0e63 */
44+const union ieee754dp __ieee754dp_spcvals[] = {
45+ DPCNST(0, DP_EMIN - 1, 0x0000000000000ULL), /* + zero */
46+ DPCNST(1, DP_EMIN - 1, 0x0000000000000ULL), /* - zero */
47+ DPCNST(0, 0, 0x0000000000000ULL), /* + 1.0 */
48+ DPCNST(1, 0, 0x0000000000000ULL), /* - 1.0 */
49+ DPCNST(0, 3, 0x4000000000000ULL), /* + 10.0 */
50+ DPCNST(1, 3, 0x4000000000000ULL), /* - 10.0 */
51+ DPCNST(0, DP_EMAX + 1, 0x0000000000000ULL), /* + infinity */
52+ DPCNST(1, DP_EMAX + 1, 0x0000000000000ULL), /* - infinity */
53+ DPCNST(0, DP_EMAX + 1, 0x7FFFFFFFFFFFFULL), /* + indef quiet Nan */
54+ DPCNST(0, DP_EMAX, 0xFFFFFFFFFFFFFULL), /* + max */
55+ DPCNST(1, DP_EMAX, 0xFFFFFFFFFFFFFULL), /* - max */
56+ DPCNST(0, DP_EMIN, 0x0000000000000ULL), /* + min normal */
57+ DPCNST(1, DP_EMIN, 0x0000000000000ULL), /* - min normal */
58+ DPCNST(0, DP_EMIN - 1, 0x0000000000001ULL), /* + min denormal */
59+ DPCNST(1, DP_EMIN - 1, 0x0000000000001ULL), /* - min denormal */
60+ DPCNST(0, 31, 0x0000000000000ULL), /* + 1.0e31 */
61+ DPCNST(0, 63, 0x0000000000000ULL), /* + 1.0e63 */
9662 };
9763
98−
99−int ieee754si_xcpt(int r, const char *op, ...)
100−{
101− struct ieee754xctx ax;
102−
103− if (!TSTX())
104− return r;
105− ax.op = op;
106− ax.rt = IEEE754_RT_SI;
107− ax.rv.si = r;
108− va_start(ax.ap, op);
109− ieee754_xcpt(&ax);
110− va_end(ax.ap);
111− return ax.rv.si;
64+#define SPCNST(s, b, m) \
65+{ \
66+ .sign = (s), \
67+ .bexp = (b) + SP_EBIAS, \
68+ .mant = (m) \
11269 }
11370
114−s64 ieee754di_xcpt(s64 r, const char *op, ...)
115−{
116− struct ieee754xctx ax;
117−
118− if (!TSTX())
119− return r;
120− ax.op = op;
121− ax.rt = IEEE754_RT_DI;
122− ax.rv.di = r;
123− va_start(ax.ap, op);
124− ieee754_xcpt(&ax);
125− va_end(ax.ap);
126− return ax.rv.di;
127−}
71+const union ieee754sp __ieee754sp_spcvals[] = {
72+ SPCNST(0, SP_EMIN - 1, 0x000000), /* + zero */
73+ SPCNST(1, SP_EMIN - 1, 0x000000), /* - zero */
74+ SPCNST(0, 0, 0x000000), /* + 1.0 */
75+ SPCNST(1, 0, 0x000000), /* - 1.0 */
76+ SPCNST(0, 3, 0x200000), /* + 10.0 */
77+ SPCNST(1, 3, 0x200000), /* - 10.0 */
78+ SPCNST(0, SP_EMAX + 1, 0x000000), /* + infinity */
79+ SPCNST(1, SP_EMAX + 1, 0x000000), /* - infinity */
80+ SPCNST(0, SP_EMAX + 1, 0x3FFFFF), /* + indef quiet Nan */
81+ SPCNST(0, SP_EMAX, 0x7FFFFF), /* + max normal */
82+ SPCNST(1, SP_EMAX, 0x7FFFFF), /* - max normal */
83+ SPCNST(0, SP_EMIN, 0x000000), /* + min normal */
84+ SPCNST(1, SP_EMIN, 0x000000), /* - min normal */
85+ SPCNST(0, SP_EMIN - 1, 0x000001), /* + min denormal */
86+ SPCNST(1, SP_EMIN - 1, 0x000001), /* - min denormal */
87+ SPCNST(0, 31, 0x000000), /* + 1.0e31 */
88+ SPCNST(0, 63, 0x000000), /* + 1.0e63 */
89+};
arch/mips/math-emu/ieee754.h+92−230
@@ -13,7 +13,7 @@ · 12 unmodified lines
1313 *
1414 * You should have received a copy of the GNU General Public License along
1515 * with this program; if not, write to the Free Software Foundation, Inc.,
16− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1717 *
1818 * Nov 7, 2000
1919 * Modification to allow integration with Linux kernel
@@ -24,186 +24,93 @@ · 4 unmodified lines
2424 #ifndef __ARCH_MIPS_MATH_EMU_IEEE754_H
2525 #define __ARCH_MIPS_MATH_EMU_IEEE754_H
2626
27+#include <linux/compiler.h>
2728 #include <asm/byteorder.h>
29+#include <linux/kernel.h>
2830 #include <linux/types.h>
2931 #include <linux/sched.h>
32+#include <asm/bitfield.h>
3033
31−/*
32− * Not very pretty, but the Linux kernel's normal va_list definition
33− * does not allow it to be used as a structure element, as it is here.
34− */
35−#ifndef _STDARG_H
36−#include <stdarg.h>
37−#endif
38−
39−#ifdef __LITTLE_ENDIAN
40−struct ieee754dp_konst {
41− unsigned mantlo:32;
42− unsigned manthi:20;
43− unsigned bexp:11;
44− unsigned sign:1;
45−};
46−struct ieee754sp_konst {
47− unsigned mant:23;
48− unsigned bexp:8;
49− unsigned sign:1;
50−};
51−
52−typedef union _ieee754dp {
53− struct ieee754dp_konst oparts;
34+union ieee754dp {
5435 struct {
55− u64 mant:52;
56− unsigned int bexp:11;
57− unsigned int sign:1;
58− } parts;
36+ __BITFIELD_FIELD(unsigned int sign:1,
37+ __BITFIELD_FIELD(unsigned int bexp:11,
38+ __BITFIELD_FIELD(u64 mant:52,
39+ ;)))
40+ };
5941 u64 bits;
60− double d;
61−} ieee754dp;
62−
63−typedef union _ieee754sp {
64− struct ieee754sp_konst parts;
65− float f;
66− u32 bits;
67−} ieee754sp;
68−#endif
69−
70−#ifdef __BIG_ENDIAN
71−struct ieee754dp_konst {
72− unsigned sign:1;
73− unsigned bexp:11;
74− unsigned manthi:20;
75− unsigned mantlo:32;
7642 };
7743
78−typedef union _ieee754dp {
79− struct ieee754dp_konst oparts;
44+union ieee754sp {
8045 struct {
81− unsigned int sign:1;
82− unsigned int bexp:11;
83− u64 mant:52;
84− } parts;
85− double d;
86− u64 bits;
87−} ieee754dp;
88−
89−struct ieee754sp_konst {
90− unsigned sign:1;
91− unsigned bexp:8;
92− unsigned mant:23;
93−};
94−
95−typedef union _ieee754sp {
96− struct ieee754sp_konst parts;
97− float f;
46+ __BITFIELD_FIELD(unsigned sign:1,
47+ __BITFIELD_FIELD(unsigned bexp:8,
48+ __BITFIELD_FIELD(unsigned mant:23,
49+ ;)))
50+ };
9851 u32 bits;
99−} ieee754sp;
100−#endif
52+};
10153
10254 /*
10355 * single precision (often aka float)
10456 */
105−int ieee754sp_finite(ieee754sp x);
106−int ieee754sp_class(ieee754sp x);
107−
108−ieee754sp ieee754sp_abs(ieee754sp x);
109−ieee754sp ieee754sp_neg(ieee754sp x);
110−ieee754sp ieee754sp_scalb(ieee754sp x, int);
111−ieee754sp ieee754sp_logb(ieee754sp x);
112−
113−/* x with sign of y */
114−ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y);
115−
116−ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y);
117−ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y);
118−ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y);
119−ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y);
120−
121−ieee754sp ieee754sp_fint(int x);
122−ieee754sp ieee754sp_funs(unsigned x);
123−ieee754sp ieee754sp_flong(s64 x);
124−ieee754sp ieee754sp_fulong(u64 x);
125−ieee754sp ieee754sp_fdp(ieee754dp x);
126−
127−int ieee754sp_tint(ieee754sp x);
128−unsigned int ieee754sp_tuns(ieee754sp x);
129−s64 ieee754sp_tlong(ieee754sp x);
130−u64 ieee754sp_tulong(ieee754sp x);
131−
132−int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cop, int sig);
133−/*
134− * basic sp math
135− */
136−ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip);
137−ieee754sp ieee754sp_frexp(ieee754sp x, int *exp);
138−ieee754sp ieee754sp_ldexp(ieee754sp x, int exp);
57+int ieee754sp_class(union ieee754sp x);
13958
140−ieee754sp ieee754sp_ceil(ieee754sp x);
141−ieee754sp ieee754sp_floor(ieee754sp x);
142−ieee754sp ieee754sp_trunc(ieee754sp x);
59+union ieee754sp ieee754sp_abs(union ieee754sp x);
60+union ieee754sp ieee754sp_neg(union ieee754sp x);
14361
144−ieee754sp ieee754sp_sqrt(ieee754sp x);
62+union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y);
63+union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y);
64+union ieee754sp ieee754sp_mul(union ieee754sp x, union ieee754sp y);
65+union ieee754sp ieee754sp_div(union ieee754sp x, union ieee754sp y);
14566
146−/*
147− * double precision (often aka double)
148−*/
149−int ieee754dp_finite(ieee754dp x);
150−int ieee754dp_class(ieee754dp x);
67+union ieee754sp ieee754sp_fint(int x);
68+union ieee754sp ieee754sp_flong(s64 x);
69+union ieee754sp ieee754sp_fdp(union ieee754dp x);
15170
152−/* x with sign of y */
153−ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y);
71+int ieee754sp_tint(union ieee754sp x);
72+s64 ieee754sp_tlong(union ieee754sp x);
15473
155−ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y);
156−ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y);
157−ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y);
158−ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y);
74+int ieee754sp_cmp(union ieee754sp x, union ieee754sp y, int cop, int sig);
15975
160−ieee754dp ieee754dp_abs(ieee754dp x);
161−ieee754dp ieee754dp_neg(ieee754dp x);
162−ieee754dp ieee754dp_scalb(ieee754dp x, int);
76+union ieee754sp ieee754sp_sqrt(union ieee754sp x);
16377
164−/* return exponent as integer in floating point format
165− */
166−ieee754dp ieee754dp_logb(ieee754dp x);
78+/*
79+ * double precision (often aka double)
80+*/
81+int ieee754dp_class(union ieee754dp x);
16782
168−ieee754dp ieee754dp_fint(int x);
169−ieee754dp ieee754dp_funs(unsigned x);
170−ieee754dp ieee754dp_flong(s64 x);
171−ieee754dp ieee754dp_fulong(u64 x);
172−ieee754dp ieee754dp_fsp(ieee754sp x);
83+union ieee754dp ieee754dp_add(union ieee754dp x, union ieee754dp y);
84+union ieee754dp ieee754dp_sub(union ieee754dp x, union ieee754dp y);
85+union ieee754dp ieee754dp_mul(union ieee754dp x, union ieee754dp y);
86+union ieee754dp ieee754dp_div(union ieee754dp x, union ieee754dp y);
17387
174−ieee754dp ieee754dp_ceil(ieee754dp x);
175−ieee754dp ieee754dp_floor(ieee754dp x);
176−ieee754dp ieee754dp_trunc(ieee754dp x);
88+union ieee754dp ieee754dp_abs(union ieee754dp x);
89+union ieee754dp ieee754dp_neg(union ieee754dp x);
17790
178−int ieee754dp_tint(ieee754dp x);
179−unsigned int ieee754dp_tuns(ieee754dp x);
180−s64 ieee754dp_tlong(ieee754dp x);
181−u64 ieee754dp_tulong(ieee754dp x);
91+union ieee754dp ieee754dp_fint(int x);
92+union ieee754dp ieee754dp_flong(s64 x);
93+union ieee754dp ieee754dp_fsp(union ieee754sp x);
18294
183−int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cop, int sig);
184−/*
185− * basic sp math
186− */
187−ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip);
188−ieee754dp ieee754dp_frexp(ieee754dp x, int *exp);
189−ieee754dp ieee754dp_ldexp(ieee754dp x, int exp);
95+int ieee754dp_tint(union ieee754dp x);
96+s64 ieee754dp_tlong(union ieee754dp x);
19097
191−ieee754dp ieee754dp_ceil(ieee754dp x);
192−ieee754dp ieee754dp_floor(ieee754dp x);
193−ieee754dp ieee754dp_trunc(ieee754dp x);
98+int ieee754dp_cmp(union ieee754dp x, union ieee754dp y, int cop, int sig);
19499
195−ieee754dp ieee754dp_sqrt(ieee754dp x);
100+union ieee754dp ieee754dp_sqrt(union ieee754dp x);
196101
197102
198103
199104 /* 5 types of floating point number
200105 */
201−#define IEEE754_CLASS_NORM 0x00
202−#define IEEE754_CLASS_ZERO 0x01
203−#define IEEE754_CLASS_DNORM 0x02
204−#define IEEE754_CLASS_INF 0x03
205−#define IEEE754_CLASS_SNAN 0x04
206−#define IEEE754_CLASS_QNAN 0x05
106+enum {
107+ IEEE754_CLASS_NORM = 0x00,
108+ IEEE754_CLASS_ZERO = 0x01,
109+ IEEE754_CLASS_DNORM = 0x02,
110+ IEEE754_CLASS_INF = 0x03,
111+ IEEE754_CLASS_SNAN = 0x04,
112+ IEEE754_CLASS_QNAN = 0x05,
113+};
207114
208115 /* exception numbers */
209116 #define IEEE754_INEXACT 0x01
@@ -219,114 +126,84 @@ ieee754dp ieee754dp_sqrt(ieee754dp x); · 9 unmodified lines
219126 #define IEEE754_CGT 0x04
220127 #define IEEE754_CUN 0x08
221128
222−/* rounding mode
223−*/
224−#define IEEE754_RN 0 /* round to nearest */
225−#define IEEE754_RZ 1 /* round toward zero */
226−#define IEEE754_RD 2 /* round toward -Infinity */
227−#define IEEE754_RU 3 /* round toward +Infinity */
228−
229−/* other naming */
230−#define IEEE754_RM IEEE754_RD
231−#define IEEE754_RP IEEE754_RU
232−
233129 /* "normal" comparisons
234130 */
235−static inline int ieee754sp_eq(ieee754sp x, ieee754sp y)
131+static inline int ieee754sp_eq(union ieee754sp x, union ieee754sp y)
236132 {
237133 return ieee754sp_cmp(x, y, IEEE754_CEQ, 0);
238134 }
239135
240−static inline int ieee754sp_ne(ieee754sp x, ieee754sp y)
136+static inline int ieee754sp_ne(union ieee754sp x, union ieee754sp y)
241137 {
242138 return ieee754sp_cmp(x, y,
243139 IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
244140 }
245141
246−static inline int ieee754sp_lt(ieee754sp x, ieee754sp y)
142+static inline int ieee754sp_lt(union ieee754sp x, union ieee754sp y)
247143 {
248144 return ieee754sp_cmp(x, y, IEEE754_CLT, 0);
249145 }
250146
251−static inline int ieee754sp_le(ieee754sp x, ieee754sp y)
147+static inline int ieee754sp_le(union ieee754sp x, union ieee754sp y)
252148 {
253149 return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
254150 }
255151
256−static inline int ieee754sp_gt(ieee754sp x, ieee754sp y)
152+static inline int ieee754sp_gt(union ieee754sp x, union ieee754sp y)
257153 {
258154 return ieee754sp_cmp(x, y, IEEE754_CGT, 0);
259155 }
260156
261157
262−static inline int ieee754sp_ge(ieee754sp x, ieee754sp y)
158+static inline int ieee754sp_ge(union ieee754sp x, union ieee754sp y)
263159 {
264160 return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
265161 }
266162
267−static inline int ieee754dp_eq(ieee754dp x, ieee754dp y)
163+static inline int ieee754dp_eq(union ieee754dp x, union ieee754dp y)
268164 {
269165 return ieee754dp_cmp(x, y, IEEE754_CEQ, 0);
270166 }
271167
272−static inline int ieee754dp_ne(ieee754dp x, ieee754dp y)
168+static inline int ieee754dp_ne(union ieee754dp x, union ieee754dp y)
273169 {
274170 return ieee754dp_cmp(x, y,
275171 IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
276172 }
277173
278−static inline int ieee754dp_lt(ieee754dp x, ieee754dp y)
174+static inline int ieee754dp_lt(union ieee754dp x, union ieee754dp y)
279175 {
280176 return ieee754dp_cmp(x, y, IEEE754_CLT, 0);
281177 }
282178
283−static inline int ieee754dp_le(ieee754dp x, ieee754dp y)
179+static inline int ieee754dp_le(union ieee754dp x, union ieee754dp y)
284180 {
285181 return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
286182 }
287183
288−static inline int ieee754dp_gt(ieee754dp x, ieee754dp y)
184+static inline int ieee754dp_gt(union ieee754dp x, union ieee754dp y)
289185 {
290186 return ieee754dp_cmp(x, y, IEEE754_CGT, 0);
291187 }
292188
293−static inline int ieee754dp_ge(ieee754dp x, ieee754dp y)
189+static inline int ieee754dp_ge(union ieee754dp x, union ieee754dp y)
294190 {
295191 return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
296192 }
297193
298−
299−/*
300− * Like strtod
301− */
302−ieee754dp ieee754dp_fstr(const char *s, char **endp);
303−char *ieee754dp_tstr(ieee754dp x, int prec, int fmt, int af);
304−
305−
306194 /*
307195 * The control status register
308196 */
309197 struct _ieee754_csr {
310−#ifdef __BIG_ENDIAN
311− unsigned pad0:7;
312− unsigned nod:1; /* set 1 for no denormalised numbers */
313− unsigned c:1; /* condition */
314− unsigned pad1:5;
315− unsigned cx:6; /* exceptions this operation */
316− unsigned mx:5; /* exception enable mask */
317− unsigned sx:5; /* exceptions total */
318− unsigned rm:2; /* current rounding mode */
319−#endif
320−#ifdef __LITTLE_ENDIAN
321− unsigned rm:2; /* current rounding mode */
322− unsigned sx:5; /* exceptions total */
323− unsigned mx:5; /* exception enable mask */
324− unsigned cx:6; /* exceptions this operation */
325− unsigned pad1:5;
326− unsigned c:1; /* condition */
327− unsigned nod:1; /* set 1 for no denormalised numbers */
328− unsigned pad0:7;
329−#endif
198+ __BITFIELD_FIELD(unsigned pad0:7,
199+ __BITFIELD_FIELD(unsigned nod:1, /* set 1 for no denormalised numbers */
200+ __BITFIELD_FIELD(unsigned c:1, /* condition */
201+ __BITFIELD_FIELD(unsigned pad1:5,
202+ __BITFIELD_FIELD(unsigned cx:6, /* exceptions this operation */
203+ __BITFIELD_FIELD(unsigned mx:5, /* exception enable mask */
204+ __BITFIELD_FIELD(unsigned sx:5, /* exceptions total */
205+ __BITFIELD_FIELD(unsigned rm:2, /* current rounding mode */
206+ ;))))))))
330207 };
331208 #define ieee754_csr (*(struct _ieee754_csr *)(&current->thread.fpu.fcr31))
332209
@@ -377,8 +254,8 @@ static inline int ieee754_sxtest(unsigned n) · 44 unmodified lines
377254 }
378255
379256 /* debugging */
380−ieee754sp ieee754sp_dump(char *s, ieee754sp x);
381−ieee754dp ieee754dp_dump(char *s, ieee754dp x);
257+union ieee754sp ieee754sp_dump(char *s, union ieee754sp x);
258+union ieee754dp ieee754dp_dump(char *s, union ieee754dp x);
382259
383260 #define IEEE754_SPCVAL_PZERO 0
384261 #define IEEE754_SPCVAL_NZERO 1
@@ -398,10 +275,10 @@ ieee754dp ieee754dp_dump(char *s, ieee754dp x); · 13 unmodified lines
398275 #define IEEE754_SPCVAL_P1E31 15 /* + 1.0e31 */
399276 #define IEEE754_SPCVAL_P1E63 16 /* + 1.0e63 */
400277
401−extern const struct ieee754dp_konst __ieee754dp_spcvals[];
402−extern const struct ieee754sp_konst __ieee754sp_spcvals[];
403−#define ieee754dp_spcvals ((const ieee754dp *)__ieee754dp_spcvals)
404−#define ieee754sp_spcvals ((const ieee754sp *)__ieee754sp_spcvals)
278+extern const union ieee754dp __ieee754dp_spcvals[];
279+extern const union ieee754sp __ieee754sp_spcvals[];
280+#define ieee754dp_spcvals ((const union ieee754dp *)__ieee754dp_spcvals)
281+#define ieee754sp_spcvals ((const union ieee754sp *)__ieee754sp_spcvals)
405282
406283 /*
407284 * Return infinity with given sign
@@ -431,28 +308,15 @@ extern const struct ieee754sp_konst __ieee754sp_spcvals[]; · 23 unmodified lines
431308 /*
432309 * Indefinite integer value
433310 */
434−#define ieee754si_indef() INT_MAX
435−#ifdef LONG_LONG_MAX
436−#define ieee754di_indef() LONG_LONG_MAX
437−#else
438−#define ieee754di_indef() ((s64)(~0ULL>>1))
439−#endif
440−
441−/* IEEE exception context, passed to handler */
442−struct ieee754xctx {
443− const char *op; /* operation name */
444− int rt; /* result type */
445− union {
446− ieee754sp sp; /* single precision */
447− ieee754dp dp; /* double precision */
448−#ifdef IEEE854_XP
449− ieee754xp xp; /* extended precision */
450−#endif
451− int si; /* standard signed integer (32bits) */
452− s64 di; /* extended signed integer (64bits) */
453− } rv; /* default result format implied by op */
454− va_list ap;
455−};
311+static inline int ieee754si_indef(void)
312+{
313+ return INT_MAX;
314+}
315+
316+static inline s64 ieee754di_indef(void)
317+{
318+ return S64_MAX;
319+}
456320
457321 /* result types for xctx.rt */
458322 #define IEEE754_RT_SP 0
@@ -461,8 +325,6 @@ struct ieee754xctx { · 2 unmodified lines
461325 #define IEEE754_RT_SI 3
462326 #define IEEE754_RT_DI 4
463327
464−extern void ieee754_xcpt(struct ieee754xctx *xcp);
465−
466328 /* compat */
467329 #define ieee754dp_fix(x) ieee754dp_tint(x)
468330 #define ieee754sp_fix(x) ieee754sp_tint(x)
arch/mips/math-emu/ieee754d.c+7−32
@@ -16,7 +16,7 @@ · 15 unmodified lines
1616 *
1717 * You should have received a copy of the GNU General Public License along
1818 * with this program; if not, write to the Free Software Foundation, Inc.,
19− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2020 *
2121 * Nov 7, 2000
2222 * Modified to build and operate in Linux kernel environment.
@@ -25,38 +25,13 @@ · 2 unmodified lines
2525 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
2626 */
2727
28−#include <linux/kernel.h>
28+#include <linux/types.h>
29+#include <linux/printk.h>
2930 #include "ieee754.h"
31+#include "ieee754sp.h"
32+#include "ieee754dp.h"
3033
31−#define DP_EBIAS 1023
32−#define DP_EMIN (-1022)
33−#define DP_EMAX 1023
34−#define DP_FBITS 52
35−
36−#define SP_EBIAS 127
37−#define SP_EMIN (-126)
38−#define SP_EMAX 127
39−#define SP_FBITS 23
40−
41−#define DP_MBIT(x) ((u64)1 << (x))
42−#define DP_HIDDEN_BIT DP_MBIT(DP_FBITS)
43−#define DP_SIGN_BIT DP_MBIT(63)
44−
45−
46−#define SP_MBIT(x) ((u32)1 << (x))
47−#define SP_HIDDEN_BIT SP_MBIT(SP_FBITS)
48−#define SP_SIGN_BIT SP_MBIT(31)
49−
50−
51−#define SPSIGN(sp) (sp.parts.sign)
52−#define SPBEXP(sp) (sp.parts.bexp)
53−#define SPMANT(sp) (sp.parts.mant)
54−
55−#define DPSIGN(dp) (dp.parts.sign)
56−#define DPBEXP(dp) (dp.parts.bexp)
57−#define DPMANT(dp) (dp.parts.mant)
58−
59−ieee754dp ieee754dp_dump(char *m, ieee754dp x)
34+union ieee754dp ieee754dp_dump(char *m, union ieee754dp x)
6035 {
6136 int i;
6237
@@ -96,7 +71,7 @@ ieee754dp ieee754dp_dump(char *m, ieee754dp x) · 33 unmodified lines
9671 return x;
9772 }
9873
99−ieee754sp ieee754sp_dump(char *m, ieee754sp x)
74+union ieee754sp ieee754sp_dump(char *m, union ieee754sp x)
10075 {
10176 int i;
10277
arch/mips/math-emu/ieee754dp.c+42−80
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,104 +16,68 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
22+#include <linux/compiler.h>
2623
2724 #include "ieee754dp.h"
2825
29−int ieee754dp_class(ieee754dp x)
26+int ieee754dp_class(union ieee754dp x)
3027 {
3128 COMPXDP;
3229 EXPLODEXDP;
3330 return xc;
3431 }
3532
36−int ieee754dp_isnan(ieee754dp x)
33+int ieee754dp_isnan(union ieee754dp x)
3734 {
3835 return ieee754dp_class(x) >= IEEE754_CLASS_SNAN;
3936 }
4037
41−int ieee754dp_issnan(ieee754dp x)
38+static inline int ieee754dp_issnan(union ieee754dp x)
4239 {
4340 assert(ieee754dp_isnan(x));
44− return ((DPMANT(x) & DP_MBIT(DP_MBITS-1)) == DP_MBIT(DP_MBITS-1));
41+ return ((DPMANT(x) & DP_MBIT(DP_FBITS-1)) == DP_MBIT(DP_FBITS-1));
4542 }
4643
4744
48−ieee754dp ieee754dp_xcpt(ieee754dp r, const char *op, ...)
49−{
50− struct ieee754xctx ax;
51− if (!TSTX())
52− return r;
53−
54− ax.op = op;
55− ax.rt = IEEE754_RT_DP;
56− ax.rv.dp = r;
57− va_start(ax.ap, op);
58− ieee754_xcpt(&ax);
59− va_end(ax.ap);
60− return ax.rv.dp;
61−}
62−
63−ieee754dp ieee754dp_nanxcpt(ieee754dp r, const char *op, ...)
45+union ieee754dp __cold ieee754dp_nanxcpt(union ieee754dp r)
6446 {
65− struct ieee754xctx ax;
66−
6747 assert(ieee754dp_isnan(r));
6848
6949 if (!ieee754dp_issnan(r)) /* QNAN does not cause invalid op !! */
7050 return r;
7151
72− if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) {
52+ if (!ieee754_setandtestcx(IEEE754_INVALID_OPERATION)) {
7353 /* not enabled convert to a quiet NaN */
74− DPMANT(r) &= (~DP_MBIT(DP_MBITS-1));
54+ DPMANT(r) &= (~DP_MBIT(DP_FBITS-1));
7555 if (ieee754dp_isnan(r))
7656 return r;
7757 else
7858 return ieee754dp_indef();
7959 }
8060
81− ax.op = op;
82− ax.rt = 0;
83− ax.rv.dp = r;
84− va_start(ax.ap, op);
85− ieee754_xcpt(&ax);
86− va_end(ax.ap);
87− return ax.rv.dp;
61+ return r;
8862 }
8963
90−ieee754dp ieee754dp_bestnan(ieee754dp x, ieee754dp y)
91−{
92− assert(ieee754dp_isnan(x));
93− assert(ieee754dp_isnan(y));
94−
95− if (DPMANT(x) > DPMANT(y))
96− return x;
97− else
98− return y;
99−}
100−
101−
102−static u64 get_rounding(int sn, u64 xm)
64+static u64 ieee754dp_get_rounding(int sn, u64 xm)
10365 {
10466 /* inexact must round of 3 bits
10567 */
10668 if (xm & (DP_MBIT(3) - 1)) {
10769 switch (ieee754_csr.rm) {
108− case IEEE754_RZ:
70+ case FPU_CSR_RZ:
10971 break;
110− case IEEE754_RN:
72+ case FPU_CSR_RN:
11173 xm += 0x3 + ((xm >> 3) & 1);
11274 /* xm += (xm&0x8)?0x4:0x3 */
11375 break;
114− case IEEE754_RU: /* toward +Infinity */
76+ case FPU_CSR_RU: /* toward +Infinity */
11577 if (!sn) /* ?? */
11678 xm += 0x8;
11779 break;
118− case IEEE754_RD: /* toward -Infinity */
80+ case FPU_CSR_RD: /* toward -Infinity */
11981 if (sn) /* ?? */
12082 xm += 0x8;
12183 break;
@@ -130,11 +92,11 @@ static u64 get_rounding(int sn, u64 xm) · 8 unmodified lines
13092 * xe is an unbiased exponent
13193 * xm is 3bit extended precision value.
13294 */
133−ieee754dp ieee754dp_format(int sn, int xe, u64 xm)
95+union ieee754dp ieee754dp_format(int sn, int xe, u64 xm)
13496 {
13597 assert(xm); /* we don't gen exact zeros (probably should) */
13698
137− assert((xm >> (DP_MBITS + 1 + 3)) == 0); /* no execess */
99+ assert((xm >> (DP_FBITS + 1 + 3)) == 0); /* no execess */
138100 assert(xm & (DP_HIDDEN_BIT << 3));
139101
140102 if (xe < DP_EMIN) {
@@ -142,32 +104,32 @@ ieee754dp ieee754dp_format(int sn, int xe, u64 xm) · 1 unmodified line
142104 int es = DP_EMIN - xe;
143105
144106 if (ieee754_csr.nod) {
145− SETCX(IEEE754_UNDERFLOW);
146− SETCX(IEEE754_INEXACT);
107+ ieee754_setcx(IEEE754_UNDERFLOW);
108+ ieee754_setcx(IEEE754_INEXACT);
147109
148110 switch(ieee754_csr.rm) {
149− case IEEE754_RN:
150− case IEEE754_RZ:
111+ case FPU_CSR_RN:
112+ case FPU_CSR_RZ:
151113 return ieee754dp_zero(sn);
152− case IEEE754_RU: /* toward +Infinity */
153− if(sn == 0)
114+ case FPU_CSR_RU: /* toward +Infinity */
115+ if (sn == 0)
154116 return ieee754dp_min(0);
155117 else
156118 return ieee754dp_zero(1);
157− case IEEE754_RD: /* toward -Infinity */
158− if(sn == 0)
119+ case FPU_CSR_RD: /* toward -Infinity */
120+ if (sn == 0)
159121 return ieee754dp_zero(0);
160122 else
161123 return ieee754dp_min(1);
162124 }
163125 }
164126
165− if (xe == DP_EMIN - 1
166− && get_rounding(sn, xm) >> (DP_MBITS + 1 + 3))
127+ if (xe == DP_EMIN - 1 &&
128+ ieee754dp_get_rounding(sn, xm) >> (DP_FBITS + 1 + 3))
167129 {
168130 /* Not tiny after rounding */
169− SETCX(IEEE754_INEXACT);
170− xm = get_rounding(sn, xm);
131+ ieee754_setcx(IEEE754_INEXACT);
132+ xm = ieee754dp_get_rounding(sn, xm);
171133 xm >>= 1;
172134 /* Clear grs bits */
173135 xm &= ~(DP_MBIT(3) - 1);
@@ -183,17 +145,17 @@ ieee754dp ieee754dp_format(int sn, int xe, u64 xm) · 9 unmodified lines
183145 }
184146 }
185147 if (xm & (DP_MBIT(3) - 1)) {
186− SETCX(IEEE754_INEXACT);
148+ ieee754_setcx(IEEE754_INEXACT);
187149 if ((xm & (DP_HIDDEN_BIT << 3)) == 0) {
188− SETCX(IEEE754_UNDERFLOW);
150+ ieee754_setcx(IEEE754_UNDERFLOW);
189151 }
190152
191153 /* inexact must round of 3 bits
192154 */
193− xm = get_rounding(sn, xm);
155+ xm = ieee754dp_get_rounding(sn, xm);
194156 /* adjust exponent for rounding add overflowing
195157 */
196− if (xm >> (DP_MBITS + 3 + 1)) {
158+ if (xm >> (DP_FBITS + 3 + 1)) {
197159 /* add causes mantissa overflow */
198160 xm >>= 1;
199161 xe++;
@@ -202,24 +164,24 @@ ieee754dp ieee754dp_format(int sn, int xe, u64 xm) · 2 unmodified lines
202164 /* strip grs bits */
203165 xm >>= 3;
204166
205− assert((xm >> (DP_MBITS + 1)) == 0); /* no execess */
167+ assert((xm >> (DP_FBITS + 1)) == 0); /* no execess */
206168 assert(xe >= DP_EMIN);
207169
208170 if (xe > DP_EMAX) {
209− SETCX(IEEE754_OVERFLOW);
210− SETCX(IEEE754_INEXACT);
171+ ieee754_setcx(IEEE754_OVERFLOW);
172+ ieee754_setcx(IEEE754_INEXACT);
211173 /* -O can be table indexed by (rm,sn) */
212174 switch (ieee754_csr.rm) {
213− case IEEE754_RN:
175+ case FPU_CSR_RN:
214176 return ieee754dp_inf(sn);
215− case IEEE754_RZ:
177+ case FPU_CSR_RZ:
216178 return ieee754dp_max(sn);
217− case IEEE754_RU: /* toward +Infinity */
179+ case FPU_CSR_RU: /* toward +Infinity */
218180 if (sn == 0)
219181 return ieee754dp_inf(0);
220182 else
221183 return ieee754dp_max(1);
222− case IEEE754_RD: /* toward -Infinity */
184+ case FPU_CSR_RD: /* toward -Infinity */
223185 if (sn == 0)
224186 return ieee754dp_max(0);
225187 else
@@ -232,10 +194,10 @@ ieee754dp ieee754dp_format(int sn, int xe, u64 xm) · 6 unmodified lines
232194 /* we underflow (tiny/zero) */
233195 assert(xe == DP_EMIN);
234196 if (ieee754_csr.mx & IEEE754_UNDERFLOW)
235− SETCX(IEEE754_UNDERFLOW);
197+ ieee754_setcx(IEEE754_UNDERFLOW);
236198 return builddp(sn, DP_EMIN - 1 + DP_EBIAS, xm);
237199 } else {
238− assert((xm >> (DP_MBITS + 1)) == 0); /* no execess */
200+ assert((xm >> (DP_FBITS + 1)) == 0); /* no execess */
239201 assert(xm & DP_HIDDEN_BIT);
240202
241203 return builddp(sn, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
arch/mips/math-emu/ieee754dp.h+35−35
@@ -6,8 +6,6 @@ · 5 unmodified lines
66 * MIPS floating point support
77 * Copyright (C) 1994-2000 Algorithmics Ltd.
88 *
9− * ########################################################################
10− *
119 * This program is free software; you can distribute it and/or modify it
1210 * under the terms of the GNU General Public License (Version 2) as
1311 * published by the Free Software Foundation.
@@ -19,64 +17,66 @@ · 5 unmodified lines
1917 *
2018 * You should have received a copy of the GNU General Public License along
2119 * with this program; if not, write to the Free Software Foundation, Inc.,
22− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
23− *
24− * ########################################################################
20+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2521 */
2622
23+#include <linux/compiler.h>
2724
2825 #include "ieee754int.h"
2926
3027 #define assert(expr) ((void)0)
3128
29+#define DP_EBIAS 1023
30+#define DP_EMIN (-1022)
31+#define DP_EMAX 1023
32+#define DP_FBITS 52
33+#define DP_MBITS 52
34+
35+#define DP_MBIT(x) ((u64)1 << (x))
36+#define DP_HIDDEN_BIT DP_MBIT(DP_FBITS)
37+#define DP_SIGN_BIT DP_MBIT(63)
38+
39+#define DPSIGN(dp) (dp.sign)
40+#define DPBEXP(dp) (dp.bexp)
41+#define DPMANT(dp) (dp.mant)
42+
43+static inline int ieee754dp_finite(union ieee754dp x)
44+{
45+ return DPBEXP(x) != DP_EMAX + 1 + DP_EBIAS;
46+}
47+
3248 /* 3bit extended double precision sticky right shift */
3349 #define XDPSRS(v,rs) \
34− ((rs > (DP_MBITS+3))?1:((v) >> (rs)) | ((v) << (64-(rs)) != 0))
50+ ((rs > (DP_FBITS+3))?1:((v) >> (rs)) | ((v) << (64-(rs)) != 0))
3551
3652 #define XDPSRSX1() \
37− (xe++, (xm = (xm >> 1) | (xm & 1)))
53+ (xe++, (xm = (xm >> 1) | (xm & 1)))
3854
3955 #define XDPSRS1(v) \
40− (((v) >> 1) | ((v) & 1))
56+ (((v) >> 1) | ((v) & 1))
4157
4258 /* convert denormal to normalized with extended exponent */
4359 #define DPDNORMx(m,e) \
44− while( (m >> DP_MBITS) == 0) { m <<= 1; e--; }
60+ while ((m >> DP_FBITS) == 0) { m <<= 1; e--; }
4561 #define DPDNORMX DPDNORMx(xm, xe)
4662 #define DPDNORMY DPDNORMx(ym, ye)
4763
48−static inline ieee754dp builddp(int s, int bx, u64 m)
64+static inline union ieee754dp builddp(int s, int bx, u64 m)
4965 {
50− ieee754dp r;
66+ union ieee754dp r;
5167
5268 assert((s) == 0 || (s) == 1);
5369 assert((bx) >= DP_EMIN - 1 + DP_EBIAS
5470 && (bx) <= DP_EMAX + 1 + DP_EBIAS);
55− assert(((m) >> DP_MBITS) == 0);
71+ assert(((m) >> DP_FBITS) == 0);
5672
57− r.parts.sign = s;
58− r.parts.bexp = bx;
59− r.parts.mant = m;
60− return r;
61−}
73+ r.sign = s;
74+ r.bexp = bx;
75+ r.mant = m;
6276
63−extern int ieee754dp_isnan(ieee754dp);
64−extern int ieee754dp_issnan(ieee754dp);
65−extern int ieee754si_xcpt(int, const char *, ...);
66−extern s64 ieee754di_xcpt(s64, const char *, ...);
67−extern ieee754dp ieee754dp_xcpt(ieee754dp, const char *, ...);
68−extern ieee754dp ieee754dp_nanxcpt(ieee754dp, const char *, ...);
69−extern ieee754dp ieee754dp_bestnan(ieee754dp, ieee754dp);
70−extern ieee754dp ieee754dp_format(int, int, u64);
71−
72−
73−#define DPNORMRET2(s, e, m, name, a0, a1) \
74−{ \
75− ieee754dp V = ieee754dp_format(s, e, m); \
76− if(TSTX()) \
77− return ieee754dp_xcpt(V, name, a0, a1); \
78− else \
79− return V; \
77+ return r;
8078 }
8179
82−#define DPNORMRET1(s, e, m, name, a0) DPNORMRET2(s, e, m, name, a0, a0)
80+extern int ieee754dp_isnan(union ieee754dp);
81+extern union ieee754dp __cold ieee754dp_nanxcpt(union ieee754dp);
82+extern union ieee754dp ieee754dp_format(int, int, u64);
arch/mips/math-emu/ieee754int.h+89−112
@@ -6,8 +6,6 @@ · 5 unmodified lines
66 * MIPS floating point support
77 * Copyright (C) 1994-2000 Algorithmics Ltd.
88 *
9− * ########################################################################
10− *
119 * This program is free software; you can distribute it and/or modify it
1210 * under the terms of the GNU General Public License (Version 2) as
1311 * published by the Free Software Foundation.
@@ -19,146 +17,125 @@ · 5 unmodified lines
1917 *
2018 * You should have received a copy of the GNU General Public License along
2119 * with this program; if not, write to the Free Software Foundation, Inc.,
22− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
23− *
24− * ########################################################################
20+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2521 */
26−
22+#ifndef __IEEE754INT_H
23+#define __IEEE754INT_H
2724
2825 #include "ieee754.h"
2926
30−#define DP_EBIAS 1023
31−#define DP_EMIN (-1022)
32−#define DP_EMAX 1023
33−#define DP_MBITS 52
34−
35−#define SP_EBIAS 127
36−#define SP_EMIN (-126)
37−#define SP_EMAX 127
38−#define SP_MBITS 23
39−
40−#define DP_MBIT(x) ((u64)1 << (x))
41−#define DP_HIDDEN_BIT DP_MBIT(DP_MBITS)
42−#define DP_SIGN_BIT DP_MBIT(63)
43−
44−#define SP_MBIT(x) ((u32)1 << (x))
45−#define SP_HIDDEN_BIT SP_MBIT(SP_MBITS)
46−#define SP_SIGN_BIT SP_MBIT(31)
47−
48−
49−#define SPSIGN(sp) (sp.parts.sign)
50−#define SPBEXP(sp) (sp.parts.bexp)
51−#define SPMANT(sp) (sp.parts.mant)
52−
53−#define DPSIGN(dp) (dp.parts.sign)
54−#define DPBEXP(dp) (dp.parts.bexp)
55−#define DPMANT(dp) (dp.parts.mant)
56−
5727 #define CLPAIR(x, y) ((x)*6+(y))
5828
59−#define CLEARCX \
60− (ieee754_csr.cx = 0)
61−
62−#define SETCX(x) \
63− (ieee754_csr.cx |= (x), ieee754_csr.sx |= (x))
29+static inline void ieee754_clearcx(void)
30+{
31+ ieee754_csr.cx = 0;
32+}
6433
65−#define SETANDTESTCX(x) \
66− (SETCX(x), ieee754_csr.mx & (x))
34+static inline void ieee754_setcx(const unsigned int flags)
35+{
36+ ieee754_csr.cx |= flags;
37+ ieee754_csr.sx |= flags;
38+}
6739
68−#define TSTX() \
69− (ieee754_csr.cx & ieee754_csr.mx)
40+static inline int ieee754_setandtestcx(const unsigned int x)
41+{
42+ ieee754_setcx(x);
7043
44+ return ieee754_csr.mx & x;
45+}
7146
7247 #define COMPXSP \
73− unsigned xm; int xe; int xs __maybe_unused; int xc
48+ unsigned xm; int xe; int xs __maybe_unused; int xc
7449
7550 #define COMPYSP \
76− unsigned ym; int ye; int ys; int yc
77−
78−#define EXPLODESP(v, vc, vs, ve, vm) \
79−{\
80− vs = SPSIGN(v);\
81− ve = SPBEXP(v);\
82− vm = SPMANT(v);\
83− if(ve == SP_EMAX+1+SP_EBIAS){\
84− if(vm == 0)\
85− vc = IEEE754_CLASS_INF;\
86− else if(vm & SP_MBIT(SP_MBITS-1)) \
87− vc = IEEE754_CLASS_SNAN;\
88− else \
89− vc = IEEE754_CLASS_QNAN;\
90− } else if(ve == SP_EMIN-1+SP_EBIAS) {\
91− if(vm) {\
92− ve = SP_EMIN;\
93− vc = IEEE754_CLASS_DNORM;\
94− } else\
95− vc = IEEE754_CLASS_ZERO;\
96− } else {\
97− ve -= SP_EBIAS;\
98− vm |= SP_HIDDEN_BIT;\
99− vc = IEEE754_CLASS_NORM;\
100− }\
51+ unsigned ym; int ye; int ys; int yc
52+
53+#define EXPLODESP(v, vc, vs, ve, vm) \
54+{ \
55+ vs = SPSIGN(v); \
56+ ve = SPBEXP(v); \
57+ vm = SPMANT(v); \
58+ if (ve == SP_EMAX+1+SP_EBIAS) { \
59+ if (vm == 0) \
60+ vc = IEEE754_CLASS_INF; \
61+ else if (vm & SP_MBIT(SP_FBITS-1)) \
62+ vc = IEEE754_CLASS_SNAN; \
63+ else \
64+ vc = IEEE754_CLASS_QNAN; \
65+ } else if (ve == SP_EMIN-1+SP_EBIAS) { \
66+ if (vm) { \
67+ ve = SP_EMIN; \
68+ vc = IEEE754_CLASS_DNORM; \
69+ } else \
70+ vc = IEEE754_CLASS_ZERO; \
71+ } else { \
72+ ve -= SP_EBIAS; \
73+ vm |= SP_HIDDEN_BIT; \
74+ vc = IEEE754_CLASS_NORM; \
75+ } \
10176 }
10277 #define EXPLODEXSP EXPLODESP(x, xc, xs, xe, xm)
10378 #define EXPLODEYSP EXPLODESP(y, yc, ys, ye, ym)
10479
10580
10681 #define COMPXDP \
107−u64 xm; int xe; int xs __maybe_unused; int xc
82+ u64 xm; int xe; int xs __maybe_unused; int xc
10883
10984 #define COMPYDP \
110−u64 ym; int ye; int ys; int yc
111−
112−#define EXPLODEDP(v, vc, vs, ve, vm) \
113−{\
114− vm = DPMANT(v);\
115− vs = DPSIGN(v);\
116− ve = DPBEXP(v);\
117− if(ve == DP_EMAX+1+DP_EBIAS){\
118− if(vm == 0)\
119− vc = IEEE754_CLASS_INF;\
120− else if(vm & DP_MBIT(DP_MBITS-1)) \
121− vc = IEEE754_CLASS_SNAN;\
122− else \
123− vc = IEEE754_CLASS_QNAN;\
124− } else if(ve == DP_EMIN-1+DP_EBIAS) {\
125− if(vm) {\
126− ve = DP_EMIN;\
127− vc = IEEE754_CLASS_DNORM;\
128− } else\
129− vc = IEEE754_CLASS_ZERO;\
130− } else {\
131− ve -= DP_EBIAS;\
132− vm |= DP_HIDDEN_BIT;\
133− vc = IEEE754_CLASS_NORM;\
134− }\
85+ u64 ym; int ye; int ys; int yc
86+
87+#define EXPLODEDP(v, vc, vs, ve, vm) \
88+{ \
89+ vm = DPMANT(v); \
90+ vs = DPSIGN(v); \
91+ ve = DPBEXP(v); \
92+ if (ve == DP_EMAX+1+DP_EBIAS) { \
93+ if (vm == 0) \
94+ vc = IEEE754_CLASS_INF; \
95+ else if (vm & DP_MBIT(DP_FBITS-1)) \
96+ vc = IEEE754_CLASS_SNAN; \
97+ else \
98+ vc = IEEE754_CLASS_QNAN; \
99+ } else if (ve == DP_EMIN-1+DP_EBIAS) { \
100+ if (vm) { \
101+ ve = DP_EMIN; \
102+ vc = IEEE754_CLASS_DNORM; \
103+ } else \
104+ vc = IEEE754_CLASS_ZERO; \
105+ } else { \
106+ ve -= DP_EBIAS; \
107+ vm |= DP_HIDDEN_BIT; \
108+ vc = IEEE754_CLASS_NORM; \
109+ } \
135110 }
136111 #define EXPLODEXDP EXPLODEDP(x, xc, xs, xe, xm)
137112 #define EXPLODEYDP EXPLODEDP(y, yc, ys, ye, ym)
138113
139−#define FLUSHDP(v, vc, vs, ve, vm) \
140− if(vc==IEEE754_CLASS_DNORM) {\
141− if(ieee754_csr.nod) {\
142− SETCX(IEEE754_INEXACT);\
143− vc = IEEE754_CLASS_ZERO;\
144− ve = DP_EMIN-1+DP_EBIAS;\
145− vm = 0;\
146− v = ieee754dp_zero(vs);\
147− }\
114+#define FLUSHDP(v, vc, vs, ve, vm) \
115+ if (vc==IEEE754_CLASS_DNORM) { \
116+ if (ieee754_csr.nod) { \
117+ ieee754_setcx(IEEE754_INEXACT); \
118+ vc = IEEE754_CLASS_ZERO; \
119+ ve = DP_EMIN-1+DP_EBIAS; \
120+ vm = 0; \
121+ v = ieee754dp_zero(vs); \
122+ } \
148123 }
149124
150−#define FLUSHSP(v, vc, vs, ve, vm) \
151− if(vc==IEEE754_CLASS_DNORM) {\
152− if(ieee754_csr.nod) {\
153− SETCX(IEEE754_INEXACT);\
154− vc = IEEE754_CLASS_ZERO;\
155− ve = SP_EMIN-1+SP_EBIAS;\
156− vm = 0;\
157− v = ieee754sp_zero(vs);\
158− }\
125+#define FLUSHSP(v, vc, vs, ve, vm) \
126+ if (vc==IEEE754_CLASS_DNORM) { \
127+ if (ieee754_csr.nod) { \
128+ ieee754_setcx(IEEE754_INEXACT); \
129+ vc = IEEE754_CLASS_ZERO; \
130+ ve = SP_EMIN-1+SP_EBIAS; \
131+ vm = 0; \
132+ v = ieee754sp_zero(vs); \
133+ } \
159134 }
160135
161136 #define FLUSHXDP FLUSHDP(x, xc, xs, xe, xm)
162137 #define FLUSHYDP FLUSHDP(y, yc, ys, ye, ym)
163138 #define FLUSHXSP FLUSHSP(x, xc, xs, xe, xm)
164139 #define FLUSHYSP FLUSHSP(y, yc, ys, ye, ym)
140+
141+#endif /* __IEEE754INT_H */
arch/mips/math-emu/ieee754m.c+0−55
@@ -1,55 +0,0 @@
1−/*
2− * floor, trunc, ceil
3− */
4−/*
5− * MIPS floating point support
6− * Copyright (C) 1994-2000 Algorithmics Ltd.
7− *
8− * ########################################################################
9− *
10− * This program is free software; you can distribute it and/or modify it
11− * under the terms of the GNU General Public License (Version 2) as
12− * published by the Free Software Foundation.
13− *
14− * This program is distributed in the hope it will be useful, but WITHOUT
15− * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16− * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17− * for more details.
18− *
19− * You should have received a copy of the GNU General Public License along
20− * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
24− */
25−
26−
27−#include "ieee754.h"
28−
29−ieee754dp ieee754dp_floor(ieee754dp x)
30−{
31− ieee754dp i;
32−
33− if (ieee754dp_lt(ieee754dp_modf(x, &i), ieee754dp_zero(0)))
34− return ieee754dp_sub(i, ieee754dp_one(0));
35− else
36− return i;
37−}
38−
39−ieee754dp ieee754dp_ceil(ieee754dp x)
40−{
41− ieee754dp i;
42−
43− if (ieee754dp_gt(ieee754dp_modf(x, &i), ieee754dp_zero(0)))
44− return ieee754dp_add(i, ieee754dp_one(0));
45− else
46− return i;
47−}
48−
49−ieee754dp ieee754dp_trunc(ieee754dp x)
50−{
51− ieee754dp i;
52−
53− (void) ieee754dp_modf(x, &i);
54− return i;
55−}
arch/mips/math-emu/ieee754sp.c+43−83
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,105 +16,68 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
22+#include <linux/compiler.h>
2623
2724 #include "ieee754sp.h"
2825
29−int ieee754sp_class(ieee754sp x)
26+int ieee754sp_class(union ieee754sp x)
3027 {
3128 COMPXSP;
3229 EXPLODEXSP;
3330 return xc;
3431 }
3532
36−int ieee754sp_isnan(ieee754sp x)
33+int ieee754sp_isnan(union ieee754sp x)
3734 {
3835 return ieee754sp_class(x) >= IEEE754_CLASS_SNAN;
3936 }
4037
41−int ieee754sp_issnan(ieee754sp x)
38+static inline int ieee754sp_issnan(union ieee754sp x)
4239 {
4340 assert(ieee754sp_isnan(x));
44− return (SPMANT(x) & SP_MBIT(SP_MBITS-1));
41+ return (SPMANT(x) & SP_MBIT(SP_FBITS-1));
4542 }
4643
4744
48−ieee754sp ieee754sp_xcpt(ieee754sp r, const char *op, ...)
49−{
50− struct ieee754xctx ax;
51−
52− if (!TSTX())
53− return r;
54−
55− ax.op = op;
56− ax.rt = IEEE754_RT_SP;
57− ax.rv.sp = r;
58− va_start(ax.ap, op);
59− ieee754_xcpt(&ax);
60− va_end(ax.ap);
61− return ax.rv.sp;
62−}
63−
64−ieee754sp ieee754sp_nanxcpt(ieee754sp r, const char *op, ...)
45+union ieee754sp __cold ieee754sp_nanxcpt(union ieee754sp r)
6546 {
66− struct ieee754xctx ax;
67−
6847 assert(ieee754sp_isnan(r));
6948
7049 if (!ieee754sp_issnan(r)) /* QNAN does not cause invalid op !! */
7150 return r;
7251
73− if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) {
52+ if (!ieee754_setandtestcx(IEEE754_INVALID_OPERATION)) {
7453 /* not enabled convert to a quiet NaN */
75− SPMANT(r) &= (~SP_MBIT(SP_MBITS-1));
54+ SPMANT(r) &= (~SP_MBIT(SP_FBITS-1));
7655 if (ieee754sp_isnan(r))
7756 return r;
7857 else
7958 return ieee754sp_indef();
8059 }
8160
82− ax.op = op;
83− ax.rt = 0;
84− ax.rv.sp = r;
85− va_start(ax.ap, op);
86− ieee754_xcpt(&ax);
87− va_end(ax.ap);
88− return ax.rv.sp;
89−}
90−
91−ieee754sp ieee754sp_bestnan(ieee754sp x, ieee754sp y)
92−{
93− assert(ieee754sp_isnan(x));
94− assert(ieee754sp_isnan(y));
95−
96− if (SPMANT(x) > SPMANT(y))
97− return x;
98− else
99− return y;
61+ return r;
10062 }
10163
102−
103−static unsigned get_rounding(int sn, unsigned xm)
64+static unsigned ieee754sp_get_rounding(int sn, unsigned xm)
10465 {
10566 /* inexact must round of 3 bits
10667 */
10768 if (xm & (SP_MBIT(3) - 1)) {
10869 switch (ieee754_csr.rm) {
109− case IEEE754_RZ:
70+ case FPU_CSR_RZ:
11071 break;
111− case IEEE754_RN:
72+ case FPU_CSR_RN:
11273 xm += 0x3 + ((xm >> 3) & 1);
11374 /* xm += (xm&0x8)?0x4:0x3 */
11475 break;
115− case IEEE754_RU: /* toward +Infinity */
76+ case FPU_CSR_RU: /* toward +Infinity */
11677 if (!sn) /* ?? */
11778 xm += 0x8;
11879 break;
119− case IEEE754_RD: /* toward -Infinity */
80+ case FPU_CSR_RD: /* toward -Infinity */
12081 if (sn) /* ?? */
12182 xm += 0x8;
12283 break;
@@ -131,11 +92,11 @@ static unsigned get_rounding(int sn, unsigned xm) · 8 unmodified lines
13192 * xe is an unbiased exponent
13293 * xm is 3bit extended precision value.
13394 */
134−ieee754sp ieee754sp_format(int sn, int xe, unsigned xm)
95+union ieee754sp ieee754sp_format(int sn, int xe, unsigned xm)
13596 {
13697 assert(xm); /* we don't gen exact zeros (probably should) */
13798
138− assert((xm >> (SP_MBITS + 1 + 3)) == 0); /* no execess */
99+ assert((xm >> (SP_FBITS + 1 + 3)) == 0); /* no execess */
139100 assert(xm & (SP_HIDDEN_BIT << 3));
140101
141102 if (xe < SP_EMIN) {
@@ -143,38 +104,37 @@ ieee754sp ieee754sp_format(int sn, int xe, unsigned xm) · 1 unmodified line
143104 int es = SP_EMIN - xe;
144105
145106 if (ieee754_csr.nod) {
146− SETCX(IEEE754_UNDERFLOW);
147− SETCX(IEEE754_INEXACT);
107+ ieee754_setcx(IEEE754_UNDERFLOW);
108+ ieee754_setcx(IEEE754_INEXACT);
148109
149110 switch(ieee754_csr.rm) {
150− case IEEE754_RN:
151− case IEEE754_RZ:
111+ case FPU_CSR_RN:
112+ case FPU_CSR_RZ:
152113 return ieee754sp_zero(sn);
153− case IEEE754_RU: /* toward +Infinity */
154− if(sn == 0)
114+ case FPU_CSR_RU: /* toward +Infinity */
115+ if (sn == 0)
155116 return ieee754sp_min(0);
156117 else
157118 return ieee754sp_zero(1);
158− case IEEE754_RD: /* toward -Infinity */
159− if(sn == 0)
119+ case FPU_CSR_RD: /* toward -Infinity */
120+ if (sn == 0)
160121 return ieee754sp_zero(0);
161122 else
162123 return ieee754sp_min(1);
163124 }
164125 }
165126
166− if (xe == SP_EMIN - 1
167− && get_rounding(sn, xm) >> (SP_MBITS + 1 + 3))
127+ if (xe == SP_EMIN - 1 &&
128+ ieee754sp_get_rounding(sn, xm) >> (SP_FBITS + 1 + 3))
168129 {
169130 /* Not tiny after rounding */
170− SETCX(IEEE754_INEXACT);
171− xm = get_rounding(sn, xm);
131+ ieee754_setcx(IEEE754_INEXACT);
132+ xm = ieee754sp_get_rounding(sn, xm);
172133 xm >>= 1;
173134 /* Clear grs bits */
174135 xm &= ~(SP_MBIT(3) - 1);
175136 xe++;
176− }
177− else {
137+ } else {
178138 /* sticky right shift es bits
179139 */
180140 SPXSRSXn(es);
@@ -183,17 +143,17 @@ ieee754sp ieee754sp_format(int sn, int xe, unsigned xm) · 2 unmodified lines
183143 }
184144 }
185145 if (xm & (SP_MBIT(3) - 1)) {
186− SETCX(IEEE754_INEXACT);
146+ ieee754_setcx(IEEE754_INEXACT);
187147 if ((xm & (SP_HIDDEN_BIT << 3)) == 0) {
188− SETCX(IEEE754_UNDERFLOW);
148+ ieee754_setcx(IEEE754_UNDERFLOW);
189149 }
190150
191151 /* inexact must round of 3 bits
192152 */
193− xm = get_rounding(sn, xm);
153+ xm = ieee754sp_get_rounding(sn, xm);
194154 /* adjust exponent for rounding add overflowing
195155 */
196− if (xm >> (SP_MBITS + 1 + 3)) {
156+ if (xm >> (SP_FBITS + 1 + 3)) {
197157 /* add causes mantissa overflow */
198158 xm >>= 1;
199159 xe++;
@@ -202,24 +162,24 @@ ieee754sp ieee754sp_format(int sn, int xe, unsigned xm) · 2 unmodified lines
202162 /* strip grs bits */
203163 xm >>= 3;
204164
205− assert((xm >> (SP_MBITS + 1)) == 0); /* no execess */
165+ assert((xm >> (SP_FBITS + 1)) == 0); /* no execess */
206166 assert(xe >= SP_EMIN);
207167
208168 if (xe > SP_EMAX) {
209− SETCX(IEEE754_OVERFLOW);
210− SETCX(IEEE754_INEXACT);
169+ ieee754_setcx(IEEE754_OVERFLOW);
170+ ieee754_setcx(IEEE754_INEXACT);
211171 /* -O can be table indexed by (rm,sn) */
212172 switch (ieee754_csr.rm) {
213− case IEEE754_RN:
173+ case FPU_CSR_RN:
214174 return ieee754sp_inf(sn);
215− case IEEE754_RZ:
175+ case FPU_CSR_RZ:
216176 return ieee754sp_max(sn);
217− case IEEE754_RU: /* toward +Infinity */
177+ case FPU_CSR_RU: /* toward +Infinity */
218178 if (sn == 0)
219179 return ieee754sp_inf(0);
220180 else
221181 return ieee754sp_max(1);
222− case IEEE754_RD: /* toward -Infinity */
182+ case FPU_CSR_RD: /* toward -Infinity */
223183 if (sn == 0)
224184 return ieee754sp_max(0);
225185 else
@@ -232,10 +192,10 @@ ieee754sp ieee754sp_format(int sn, int xe, unsigned xm) · 6 unmodified lines
232192 /* we underflow (tiny/zero) */
233193 assert(xe == SP_EMIN);
234194 if (ieee754_csr.mx & IEEE754_UNDERFLOW)
235− SETCX(IEEE754_UNDERFLOW);
195+ ieee754_setcx(IEEE754_UNDERFLOW);
236196 return buildsp(sn, SP_EMIN - 1 + SP_EBIAS, xm);
237197 } else {
238− assert((xm >> (SP_MBITS + 1)) == 0); /* no execess */
198+ assert((xm >> (SP_FBITS + 1)) == 0); /* no execess */
239199 assert(xm & SP_HIDDEN_BIT);
240200
241201 return buildsp(sn, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
arch/mips/math-emu/ieee754sp.h+39−40
@@ -6,8 +6,6 @@ · 5 unmodified lines
66 * MIPS floating point support
77 * Copyright (C) 1994-2000 Algorithmics Ltd.
88 *
9− * ########################################################################
10− *
119 * This program is free software; you can distribute it and/or modify it
1210 * under the terms of the GNU General Public License (Version 2) as
1311 * published by the Free Software Foundation.
@@ -19,70 +17,71 @@ · 5 unmodified lines
1917 *
2018 * You should have received a copy of the GNU General Public License along
2119 * with this program; if not, write to the Free Software Foundation, Inc.,
22− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
23− *
24− * ########################################################################
20+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2521 */
2622
23+#include <linux/compiler.h>
2724
2825 #include "ieee754int.h"
2926
3027 #define assert(expr) ((void)0)
3128
29+#define SP_EBIAS 127
30+#define SP_EMIN (-126)
31+#define SP_EMAX 127
32+#define SP_FBITS 23
33+#define SP_MBITS 23
34+
35+#define SP_MBIT(x) ((u32)1 << (x))
36+#define SP_HIDDEN_BIT SP_MBIT(SP_FBITS)
37+#define SP_SIGN_BIT SP_MBIT(31)
38+
39+#define SPSIGN(sp) (sp.sign)
40+#define SPBEXP(sp) (sp.bexp)
41+#define SPMANT(sp) (sp.mant)
42+
43+static inline int ieee754sp_finite(union ieee754sp x)
44+{
45+ return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS;
46+}
47+
3248 /* 3bit extended single precision sticky right shift */
33−#define SPXSRSXn(rs) \
34− (xe += rs, \
35− xm = (rs > (SP_MBITS+3))?1:((xm) >> (rs)) | ((xm) << (32-(rs)) != 0))
49+#define SPXSRSXn(rs) \
50+ (xe += rs, \
51+ xm = (rs > (SP_FBITS+3))?1:((xm) >> (rs)) | ((xm) << (32-(rs)) != 0))
3652
3753 #define SPXSRSX1() \
38− (xe++, (xm = (xm >> 1) | (xm & 1)))
54+ (xe++, (xm = (xm >> 1) | (xm & 1)))
3955
40−#define SPXSRSYn(rs) \
41− (ye+=rs, \
42− ym = (rs > (SP_MBITS+3))?1:((ym) >> (rs)) | ((ym) << (32-(rs)) != 0))
56+#define SPXSRSYn(rs) \
57+ (ye+=rs, \
58+ ym = (rs > (SP_FBITS+3))?1:((ym) >> (rs)) | ((ym) << (32-(rs)) != 0))
4359
4460 #define SPXSRSY1() \
45− (ye++, (ym = (ym >> 1) | (ym & 1)))
61+ (ye++, (ym = (ym >> 1) | (ym & 1)))
4662
4763 /* convert denormal to normalized with extended exponent */
4864 #define SPDNORMx(m,e) \
49− while( (m >> SP_MBITS) == 0) { m <<= 1; e--; }
65+ while ((m >> SP_FBITS) == 0) { m <<= 1; e--; }
5066 #define SPDNORMX SPDNORMx(xm, xe)
5167 #define SPDNORMY SPDNORMx(ym, ye)
5268
53−static inline ieee754sp buildsp(int s, int bx, unsigned m)
69+static inline union ieee754sp buildsp(int s, int bx, unsigned m)
5470 {
55− ieee754sp r;
71+ union ieee754sp r;
5672
5773 assert((s) == 0 || (s) == 1);
5874 assert((bx) >= SP_EMIN - 1 + SP_EBIAS
5975 && (bx) <= SP_EMAX + 1 + SP_EBIAS);
60− assert(((m) >> SP_MBITS) == 0);
76+ assert(((m) >> SP_FBITS) == 0);
6177
62− r.parts.sign = s;
63− r.parts.bexp = bx;
64− r.parts.mant = m;
78+ r.sign = s;
79+ r.bexp = bx;
80+ r.mant = m;
6581
6682 return r;
6783 }
6884
69−extern int ieee754sp_isnan(ieee754sp);
70−extern int ieee754sp_issnan(ieee754sp);
71−extern int ieee754si_xcpt(int, const char *, ...);
72−extern s64 ieee754di_xcpt(s64, const char *, ...);
73−extern ieee754sp ieee754sp_xcpt(ieee754sp, const char *, ...);
74−extern ieee754sp ieee754sp_nanxcpt(ieee754sp, const char *, ...);
75−extern ieee754sp ieee754sp_bestnan(ieee754sp, ieee754sp);
76−extern ieee754sp ieee754sp_format(int, int, unsigned);
77−
78−
79−#define SPNORMRET2(s, e, m, name, a0, a1) \
80−{ \
81− ieee754sp V = ieee754sp_format(s, e, m); \
82− if(TSTX()) \
83− return ieee754sp_xcpt(V, name, a0, a1); \
84− else \
85− return V; \
86−}
87−
88−#define SPNORMRET1(s, e, m, name, a0) SPNORMRET2(s, e, m, name, a0, a0)
85+extern int ieee754sp_isnan(union ieee754sp);
86+extern union ieee754sp __cold ieee754sp_nanxcpt(union ieee754sp);
87+extern union ieee754sp ieee754sp_format(int, int, unsigned);
arch/mips/math-emu/ieee754xcpt.c+0−47
@@ -1,47 +0,0 @@
1−/*
2− * MIPS floating point support
3− * Copyright (C) 1994-2000 Algorithmics Ltd.
4− *
5− * ########################################################################
6− *
7− * This program is free software; you can distribute it and/or modify it
8− * under the terms of the GNU General Public License (Version 2) as
9− * published by the Free Software Foundation.
10− *
11− * This program is distributed in the hope it will be useful, but WITHOUT
12− * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13− * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14− * for more details.
15− *
16− * You should have received a copy of the GNU General Public License along
17− * with this program; if not, write to the Free Software Foundation, Inc.,
18− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
19− *
20− * ########################################################################
21− */
22−
23−/**************************************************************************
24− * Nov 7, 2000
25− * Added preprocessor hacks to map to Linux kernel diagnostics.
26− *
27− * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
28− * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
29− *************************************************************************/
30−
31−#include <linux/kernel.h>
32−#include "ieee754.h"
33−
34−/*
35− * Very naff exception handler (you can plug in your own and
36− * override this).
37− */
38−
39−static const char *const rtnames[] = {
40− "sp", "dp", "xp", "si", "di"
41−};
42−
43−void ieee754_xcpt(struct ieee754xctx *xcp)
44−{
45− printk(KERN_DEBUG "floating point exception in \"%s\", type=%s\n",
46− xcp->op, rtnames[xcp->rt]);
47−}
arch/mips/math-emu/kernel_linkage.c+0−45
@@ -1,45 +0,0 @@
1−/*
2− * Kevin D. Kissell, kevink@mips and Carsten Langgaard, carstenl@mips.com
3− * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
4− *
5− * This program is free software; you can distribute it and/or modify it
6− * under the terms of the GNU General Public License (Version 2) as
7− * published by the Free Software Foundation.
8− *
9− * This program is distributed in the hope it will be useful, but WITHOUT
10− * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11− * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12− * for more details.
13− *
14− * You should have received a copy of the GNU General Public License along
15− * with this program; if not, write to the Free Software Foundation, Inc.,
16− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17− *
18− * Routines corresponding to Linux kernel FP context
19− * manipulation primitives for the Algorithmics MIPS
20− * FPU Emulator
21− */
22−#include <linux/sched.h>
23−#include <asm/processor.h>
24−#include <asm/signal.h>
25−#include <asm/uaccess.h>
26−
27−#include <asm/fpu.h>
28−#include <asm/fpu_emulator.h>
29−
30−#define SIGNALLING_NAN 0x7ff800007ff80000LL
31−
32−void fpu_emulator_init_fpu(void)
33−{
34− static int first = 1;
35− int i;
36−
37− if (first) {
38− first = 0;
39− printk("Algorithmics/MIPS FPU Emulator v1.5\n");
40− }
41−
42− current->thread.fpu.fcr31 = 0;
43− for (i = 0; i < 32; i++)
44− set_fpr64(&current->thread.fpu.fpr[i], 0, SIGNALLING_NAN);
45−}
arch/mips/math-emu/me-debugfs.c+67−0
@@ -0,0 +1,67 @@
1+#include <linux/cpumask.h>
2+#include <linux/debugfs.h>
3+#include <linux/fs.h>
4+#include <linux/init.h>
5+#include <linux/percpu.h>
6+#include <linux/types.h>
7+#include <asm/fpu_emulator.h>
8+#include <asm/local.h>
9+
10+DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
11+
12+static int fpuemu_stat_get(void *data, u64 *val)
13+{
14+ int cpu;
15+ unsigned long sum = 0;
16+
17+ for_each_online_cpu(cpu) {
18+ struct mips_fpu_emulator_stats *ps;
19+ local_t *pv;
20+
21+ ps = &per_cpu(fpuemustats, cpu);
22+ pv = (void *)ps + (unsigned long)data;
23+ sum += local_read(pv);
24+ }
25+ *val = sum;
26+ return 0;
27+}
28+DEFINE_SIMPLE_ATTRIBUTE(fops_fpuemu_stat, fpuemu_stat_get, NULL, "%llu\n");
29+
30+extern struct dentry *mips_debugfs_dir;
31+static int __init debugfs_fpuemu(void)
32+{
33+ struct dentry *d, *dir;
34+
35+ if (!mips_debugfs_dir)
36+ return -ENODEV;
37+ dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir);
38+ if (!dir)
39+ return -ENOMEM;
40+
41+#define FPU_EMU_STAT_OFFSET(m) \
42+ offsetof(struct mips_fpu_emulator_stats, m)
43+
44+#define FPU_STAT_CREATE(m) \
45+do { \
46+ d = debugfs_create_file(#m , S_IRUGO, dir, \
47+ (void *)FPU_EMU_STAT_OFFSET(m), \
48+ &fops_fpuemu_stat); \
49+ if (!d) \
50+ return -ENOMEM; \
51+} while (0)
52+
53+ FPU_STAT_CREATE(emulated);
54+ FPU_STAT_CREATE(loads);
55+ FPU_STAT_CREATE(stores);
56+ FPU_STAT_CREATE(cp1ops);
57+ FPU_STAT_CREATE(cp1xops);
58+ FPU_STAT_CREATE(errors);
59+ FPU_STAT_CREATE(ieee754_inexact);
60+ FPU_STAT_CREATE(ieee754_underflow);
61+ FPU_STAT_CREATE(ieee754_overflow);
62+ FPU_STAT_CREATE(ieee754_zerodiv);
63+ FPU_STAT_CREATE(ieee754_invalidop);
64+
65+ return 0;
66+}
67+__initcall(debugfs_fpuemu);
arch/mips/math-emu/sp_add.c+38−34
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,23 +16,22 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754sp.h"
2823
29−ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y)
24+union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y)
3025 {
26+ int s;
27+
3128 COMPXSP;
3229 COMPYSP;
3330
3431 EXPLODEXSP;
3532 EXPLODEYSP;
3633
37− CLEARCX;
34+ ieee754_clearcx();
3835
3936 FLUSHXSP;
4037 FLUSHYSP;
@@ -51,8 +48,8 @@ ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y) · 10 unmodified lines
5148 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
5249 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
5350 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
54− SETCX(IEEE754_INVALID_OPERATION);
55− return ieee754sp_nanxcpt(ieee754sp_indef(), "add", x, y);
51+ ieee754_setcx(IEEE754_INVALID_OPERATION);
52+ return ieee754sp_nanxcpt(ieee754sp_indef());
5653
5754 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
5855 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -68,14 +65,14 @@ ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y) · 9 unmodified lines
6865 return x;
6966
7067
71− /* Infinity handling
72− */
73−
68+ /*
69+ * Infinity handling
70+ */
7471 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
7572 if (xs == ys)
7673 return x;
77− SETCX(IEEE754_INVALID_OPERATION);
78− return ieee754sp_xcpt(ieee754sp_indef(), "add", x, y);
74+ ieee754_setcx(IEEE754_INVALID_OPERATION);
75+ return ieee754sp_indef();
7976
8077 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
8178 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
@@ -87,15 +84,14 @@ ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y) · 5 unmodified lines
8784 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
8885 return x;
8986
90− /* Zero handling
91− */
92−
87+ /*
88+ * Zero handling
89+ */
9390 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
9491 if (xs == ys)
9592 return x;
9693 else
97− return ieee754sp_zero(ieee754_csr.rm ==
98− IEEE754_RD);
94+ return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
9995
10096 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
10197 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
@@ -108,6 +104,8 @@ ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y) · 6 unmodified lines
108104 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
109105 SPDNORMX;
110106
107+ /* FALL THROUGH */
108+
111109 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
112110 SPDNORMY;
113111 break;
@@ -122,33 +120,38 @@ ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y) · 8 unmodified lines
122120 assert(xm & SP_HIDDEN_BIT);
123121 assert(ym & SP_HIDDEN_BIT);
124122
125− /* provide guard,round and stick bit space */
123+ /*
124+ * Provide guard, round and stick bit space.
125+ */
126126 xm <<= 3;
127127 ym <<= 3;
128128
129129 if (xe > ye) {
130− /* have to shift y fraction right to align
130+ /*
131+ * Have to shift y fraction right to align.
131132 */
132− int s = xe - ye;
133+ s = xe - ye;
133134 SPXSRSYn(s);
134135 } else if (ye > xe) {
135− /* have to shift x fraction right to align
136+ /*
137+ * Have to shift x fraction right to align.
136138 */
137− int s = ye - xe;
139+ s = ye - xe;
138140 SPXSRSXn(s);
139141 }
140142 assert(xe == ye);
141143 assert(xe <= SP_EMAX);
142144
143145 if (xs == ys) {
144− /* generate 28 bit result of adding two 27 bit numbers
145− * leaving result in xm,xs,xe
146+ /*
147+ * Generate 28 bit result of adding two 27 bit numbers
148+ * leaving result in xm, xs and xe.
146149 */
147150 xm = xm + ym;
148151 xe = xe;
149152 xs = xs;
150153
151− if (xm >> (SP_MBITS + 1 + 3)) { /* carry out */
154+ if (xm >> (SP_FBITS + 1 + 3)) { /* carry out */
152155 SPXSRSX1();
153156 }
154157 } else {
@@ -162,15 +165,16 @@ ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y) · 7 unmodified lines
162165 xs = ys;
163166 }
164167 if (xm == 0)
165− return ieee754sp_zero(ieee754_csr.rm ==
166− IEEE754_RD);
168+ return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
167169
168− /* normalize in extended single precision */
169− while ((xm >> (SP_MBITS + 3)) == 0) {
170+ /*
171+ * Normalize in extended single precision
172+ */
173+ while ((xm >> (SP_FBITS + 3)) == 0) {
170174 xm <<= 1;
171175 xe--;
172176 }
173−
174177 }
175− SPNORMRET2(xs, xe, xm, "add", x, y);
178+
179+ return ieee754sp_format(xs, xe, xm);
176180 }
arch/mips/math-emu/sp_cmp.c+11−13
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,16 +16,16 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754sp.h"
2823
29−int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cmp, int sig)
24+int ieee754sp_cmp(union ieee754sp x, union ieee754sp y, int cmp, int sig)
3025 {
26+ int vx;
27+ int vy;
28+
3129 COMPXSP;
3230 COMPYSP;
3331
@@ -35,21 +33,21 @@ int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cmp, int sig) · 1 unmodified line
3533 EXPLODEYSP;
3634 FLUSHXSP;
3735 FLUSHYSP;
38− CLEARCX; /* Even clear inexact flag here */
36+ ieee754_clearcx(); /* Even clear inexact flag here */
3937
4038 if (ieee754sp_isnan(x) || ieee754sp_isnan(y)) {
4139 if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
42− SETCX(IEEE754_INVALID_OPERATION);
40+ ieee754_setcx(IEEE754_INVALID_OPERATION);
4341 if (cmp & IEEE754_CUN)
4442 return 1;
4543 if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
46− if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION))
47− return ieee754si_xcpt(0, "fcmpf", x);
44+ if (sig && ieee754_setandtestcx(IEEE754_INVALID_OPERATION))
45+ return 0;
4846 }
4947 return 0;
5048 } else {
51− int vx = x.bits;
52− int vy = y.bits;
49+ vx = x.bits;
50+ vy = y.bits;
5351
5452 if (vx < 0)
5553 vx = -vx ^ SP_SIGN_BIT;
arch/mips/math-emu/sp_div.c+45−48
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,23 +16,24 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754sp.h"
2823
29−ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y)
24+union ieee754sp ieee754sp_div(union ieee754sp x, union ieee754sp y)
3025 {
26+ unsigned rm;
27+ int re;
28+ unsigned bm;
29+
3130 COMPXSP;
3231 COMPYSP;
3332
3433 EXPLODEXSP;
3534 EXPLODEYSP;
3635
37− CLEARCX;
36+ ieee754_clearcx();
3837
3938 FLUSHXSP;
4039 FLUSHYSP;
@@ -51,8 +50,8 @@ ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y) · 10 unmodified lines
5150 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
5251 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
5352 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
54− SETCX(IEEE754_INVALID_OPERATION);
55− return ieee754sp_nanxcpt(ieee754sp_indef(), "div", x, y);
53+ ieee754_setcx(IEEE754_INVALID_OPERATION);
54+ return ieee754sp_nanxcpt(ieee754sp_indef());
5655
5756 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
5857 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -68,12 +67,12 @@ ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y) · 9 unmodified lines
6867 return x;
6968
7069
71− /* Infinity handling
72− */
73−
70+ /*
71+ * Infinity handling
72+ */
7473 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
75− SETCX(IEEE754_INVALID_OPERATION);
76− return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y);
74+ ieee754_setcx(IEEE754_INVALID_OPERATION);
75+ return ieee754sp_indef();
7776
7877 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
7978 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
@@ -85,17 +84,17 @@ ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y) · 5 unmodified lines
8584 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
8685 return ieee754sp_inf(xs ^ ys);
8786
88− /* Zero handling
89− */
90−
87+ /*
88+ * Zero handling
89+ */
9190 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
92− SETCX(IEEE754_INVALID_OPERATION);
93− return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y);
91+ ieee754_setcx(IEEE754_INVALID_OPERATION);
92+ return ieee754sp_indef();
9493
9594 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
9695 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
97− SETCX(IEEE754_ZERO_DIVIDE);
98− return ieee754sp_xcpt(ieee754sp_inf(xs ^ ys), "div", x, y);
96+ ieee754_setcx(IEEE754_ZERO_DIVIDE);
97+ return ieee754sp_inf(xs ^ ys);
9998
10099 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
101100 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
@@ -122,35 +121,33 @@ ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y) · 20 unmodified lines
122121 xm <<= 3;
123122 ym <<= 3;
124123
125− {
126− /* now the dirty work */
127−
128− unsigned rm = 0;
129− int re = xe - ye;
130− unsigned bm;
131−
132− for (bm = SP_MBIT(SP_MBITS + 2); bm; bm >>= 1) {
133− if (xm >= ym) {
134− xm -= ym;
135− rm |= bm;
136− if (xm == 0)
137− break;
138− }
139− xm <<= 1;
140− }
141− rm <<= 1;
142− if (xm)
143− rm |= 1; /* have remainder, set sticky */
124+ /* now the dirty work */
144125
145− assert(rm);
126+ rm = 0;
127+ re = xe - ye;
146128
147− /* normalise rm to rounding precision ?
148− */
149− while ((rm >> (SP_MBITS + 3)) == 0) {
150− rm <<= 1;
151− re--;
129+ for (bm = SP_MBIT(SP_FBITS + 2); bm; bm >>= 1) {
130+ if (xm >= ym) {
131+ xm -= ym;
132+ rm |= bm;
133+ if (xm == 0)
134+ break;
152135 }
136+ xm <<= 1;
137+ }
138+
139+ rm <<= 1;
140+ if (xm)
141+ rm |= 1; /* have remainder, set sticky */
153142
154− SPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y);
143+ assert(rm);
144+
145+ /* normalise rm to rounding precision ?
146+ */
147+ while ((rm >> (SP_FBITS + 3)) == 0) {
148+ rm <<= 1;
149+ re--;
155150 }
151+
152+ return ieee754sp_format(xs == ys ? 0 : 1, re, rm);
156153 }
arch/mips/math-emu/sp_fdp.c+28−28
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,59 +16,61 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754sp.h"
23+#include "ieee754dp.h"
2824
29−ieee754sp ieee754sp_fdp(ieee754dp x)
25+union ieee754sp ieee754sp_fdp(union ieee754dp x)
3026 {
27+ u32 rm;
28+
3129 COMPXDP;
32− ieee754sp nan;
30+ union ieee754sp nan;
3331
3432 EXPLODEXDP;
3533
36− CLEARCX;
34+ ieee754_clearcx();
3735
3836 FLUSHXDP;
3937
4038 switch (xc) {
4139 case IEEE754_CLASS_SNAN:
42− SETCX(IEEE754_INVALID_OPERATION);
43− return ieee754sp_nanxcpt(ieee754sp_indef(), "fdp");
40+ ieee754_setcx(IEEE754_INVALID_OPERATION);
41+ return ieee754sp_nanxcpt(ieee754sp_indef());
42+
4443 case IEEE754_CLASS_QNAN:
4544 nan = buildsp(xs, SP_EMAX + 1 + SP_EBIAS, (u32)
46− (xm >> (DP_MBITS - SP_MBITS)));
45+ (xm >> (DP_FBITS - SP_FBITS)));
4746 if (!ieee754sp_isnan(nan))
4847 nan = ieee754sp_indef();
49− return ieee754sp_nanxcpt(nan, "fdp", x);
48+ return ieee754sp_nanxcpt(nan);
49+
5050 case IEEE754_CLASS_INF:
5151 return ieee754sp_inf(xs);
52+
5253 case IEEE754_CLASS_ZERO:
5354 return ieee754sp_zero(xs);
55+
5456 case IEEE754_CLASS_DNORM:
5557 /* can't possibly be sp representable */
56− SETCX(IEEE754_UNDERFLOW);
57− SETCX(IEEE754_INEXACT);
58− if ((ieee754_csr.rm == IEEE754_RU && !xs) ||
59− (ieee754_csr.rm == IEEE754_RD && xs))
60− return ieee754sp_xcpt(ieee754sp_mind(xs), "fdp", x);
61− return ieee754sp_xcpt(ieee754sp_zero(xs), "fdp", x);
58+ ieee754_setcx(IEEE754_UNDERFLOW);
59+ ieee754_setcx(IEEE754_INEXACT);
60+ if ((ieee754_csr.rm == FPU_CSR_RU && !xs) ||
61+ (ieee754_csr.rm == FPU_CSR_RD && xs))
62+ return ieee754sp_mind(xs);
63+ return ieee754sp_zero(xs);
64+
6265 case IEEE754_CLASS_NORM:
6366 break;
6467 }
6568
66− {
67− u32 rm;
68−
69− /* convert from DP_MBITS to SP_MBITS+3 with sticky right shift
70− */
71− rm = (xm >> (DP_MBITS - (SP_MBITS + 3))) |
72− ((xm << (64 - (DP_MBITS - (SP_MBITS + 3)))) != 0);
69+ /*
70+ * Convert from DP_FBITS to SP_FBITS+3 with sticky right shift.
71+ */
72+ rm = (xm >> (DP_FBITS - (SP_FBITS + 3))) |
73+ ((xm << (64 - (DP_FBITS - (SP_FBITS + 3)))) != 0);
7374
74− SPNORMRET1(xs, xe, rm, "fdp", x);
75− }
75+ return ieee754sp_format(xs, xe, rm);
7676 }
arch/mips/math-emu/sp_fint.c+8−22
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,21 +16,18 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754sp.h"
2823
29−ieee754sp ieee754sp_fint(int x)
24+union ieee754sp ieee754sp_fint(int x)
3025 {
3126 unsigned xm;
3227 int xe;
3328 int xs;
3429
35− CLEARCX;
30+ ieee754_clearcx();
3631
3732 if (x == 0)
3833 return ieee754sp_zero(0);
@@ -50,30 +45,21 @@ ieee754sp ieee754sp_fint(int x) · 11 unmodified lines
5045 } else {
5146 xm = x;
5247 }
53− xe = SP_MBITS + 3;
48+ xe = SP_FBITS + 3;
5449
55− if (xm >> (SP_MBITS + 1 + 3)) {
50+ if (xm >> (SP_FBITS + 1 + 3)) {
5651 /* shunt out overflow bits
5752 */
58− while (xm >> (SP_MBITS + 1 + 3)) {
53+ while (xm >> (SP_FBITS + 1 + 3)) {
5954 SPXSRSX1();
6055 }
6156 } else {
6257 /* normalize in grs extended single precision
6358 */
64− while ((xm >> (SP_MBITS + 3)) == 0) {
59+ while ((xm >> (SP_FBITS + 3)) == 0) {
6560 xm <<= 1;
6661 xe--;
6762 }
6863 }
69− SPNORMRET1(xs, xe, xm, "fint", x);
70−}
71−
72−
73−ieee754sp ieee754sp_funs(unsigned int u)
74−{
75− if ((int) u < 0)
76− return ieee754sp_add(ieee754sp_1e31(),
77− ieee754sp_fint(u & ~(1 << 31)));
78− return ieee754sp_fint(u);
64+ return ieee754sp_format(xs, xe, xm);
7965 }
arch/mips/math-emu/sp_flong.c+8−22
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,21 +16,18 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754sp.h"
2823
29−ieee754sp ieee754sp_flong(s64 x)
24+union ieee754sp ieee754sp_flong(s64 x)
3025 {
3126 u64 xm; /* <--- need 64-bit mantissa temp */
3227 int xe;
3328 int xs;
3429
35− CLEARCX;
30+ ieee754_clearcx();
3631
3732 if (x == 0)
3833 return ieee754sp_zero(0);
@@ -50,29 +45,20 @@ ieee754sp ieee754sp_flong(s64 x) · 11 unmodified lines
5045 } else {
5146 xm = x;
5247 }
53− xe = SP_MBITS + 3;
48+ xe = SP_FBITS + 3;
5449
55− if (xm >> (SP_MBITS + 1 + 3)) {
50+ if (xm >> (SP_FBITS + 1 + 3)) {
5651 /* shunt out overflow bits
5752 */
58− while (xm >> (SP_MBITS + 1 + 3)) {
53+ while (xm >> (SP_FBITS + 1 + 3)) {
5954 SPXSRSX1();
6055 }
6156 } else {
6257 /* normalize in grs extended single precision */
63− while ((xm >> (SP_MBITS + 3)) == 0) {
58+ while ((xm >> (SP_FBITS + 3)) == 0) {
6459 xm <<= 1;
6560 xe--;
6661 }
6762 }
68− SPNORMRET1(xs, xe, xm, "sp_flong", x);
69−}
70−
71−
72−ieee754sp ieee754sp_fulong(u64 u)
73−{
74− if ((s64) u < 0)
75− return ieee754sp_add(ieee754sp_1e63(),
76− ieee754sp_flong(u & ~(1ULL << 63)));
77− return ieee754sp_flong(u);
63+ return ieee754sp_format(xs, xe, xm);
7864 }
arch/mips/math-emu/sp_frexp.c+0−52
@@ -1,52 +0,0 @@
1−/* IEEE754 floating point arithmetic
2− * single precision
3− */
4−/*
5− * MIPS floating point support
6− * Copyright (C) 1994-2000 Algorithmics Ltd.
7− *
8− * ########################################################################
9− *
10− * This program is free software; you can distribute it and/or modify it
11− * under the terms of the GNU General Public License (Version 2) as
12− * published by the Free Software Foundation.
13− *
14− * This program is distributed in the hope it will be useful, but WITHOUT
15− * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16− * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17− * for more details.
18− *
19− * You should have received a copy of the GNU General Public License along
20− * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
24− */
25−
26−
27−#include "ieee754sp.h"
28−
29−/* close to ieeep754sp_logb
30−*/
31−ieee754sp ieee754sp_frexp(ieee754sp x, int *eptr)
32−{
33− COMPXSP;
34− CLEARCX;
35− EXPLODEXSP;
36−
37− switch (xc) {
38− case IEEE754_CLASS_SNAN:
39− case IEEE754_CLASS_QNAN:
40− case IEEE754_CLASS_INF:
41− case IEEE754_CLASS_ZERO:
42− *eptr = 0;
43− return x;
44− case IEEE754_CLASS_DNORM:
45− SPDNORMX;
46− break;
47− case IEEE754_CLASS_NORM:
48− break;
49− }
50− *eptr = xe + 1;
51− return buildsp(xs, -1 + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
52−}
arch/mips/math-emu/sp_logb.c+0−53
@@ -1,53 +0,0 @@
1−/* IEEE754 floating point arithmetic
2− * single precision
3− */
4−/*
5− * MIPS floating point support
6− * Copyright (C) 1994-2000 Algorithmics Ltd.
7− *
8− * ########################################################################
9− *
10− * This program is free software; you can distribute it and/or modify it
11− * under the terms of the GNU General Public License (Version 2) as
12− * published by the Free Software Foundation.
13− *
14− * This program is distributed in the hope it will be useful, but WITHOUT
15− * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16− * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17− * for more details.
18− *
19− * You should have received a copy of the GNU General Public License along
20− * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
24− */
25−
26−
27−#include "ieee754sp.h"
28−
29−ieee754sp ieee754sp_logb(ieee754sp x)
30−{
31− COMPXSP;
32−
33− CLEARCX;
34−
35− EXPLODEXSP;
36−
37− switch (xc) {
38− case IEEE754_CLASS_SNAN:
39− return ieee754sp_nanxcpt(x, "logb", x);
40− case IEEE754_CLASS_QNAN:
41− return x;
42− case IEEE754_CLASS_INF:
43− return ieee754sp_inf(0);
44− case IEEE754_CLASS_ZERO:
45− return ieee754sp_inf(1);
46− case IEEE754_CLASS_DNORM:
47− SPDNORMX;
48− break;
49− case IEEE754_CLASS_NORM:
50− break;
51− }
52− return ieee754sp_fint(xe);
53−}
arch/mips/math-emu/sp_modf.c+0−79
@@ -1,79 +0,0 @@
1−/* IEEE754 floating point arithmetic
2− * single precision
3− */
4−/*
5− * MIPS floating point support
6− * Copyright (C) 1994-2000 Algorithmics Ltd.
7− *
8− * ########################################################################
9− *
10− * This program is free software; you can distribute it and/or modify it
11− * under the terms of the GNU General Public License (Version 2) as
12− * published by the Free Software Foundation.
13− *
14− * This program is distributed in the hope it will be useful, but WITHOUT
15− * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16− * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17− * for more details.
18− *
19− * You should have received a copy of the GNU General Public License along
20− * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
24− */
25−
26−
27−#include "ieee754sp.h"
28−
29−/* modf function is always exact for a finite number
30−*/
31−ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp *ip)
32−{
33− COMPXSP;
34−
35− CLEARCX;
36−
37− EXPLODEXSP;
38−
39− switch (xc) {
40− case IEEE754_CLASS_SNAN:
41− case IEEE754_CLASS_QNAN:
42− case IEEE754_CLASS_INF:
43− case IEEE754_CLASS_ZERO:
44− *ip = x;
45− return x;
46− case IEEE754_CLASS_DNORM:
47− /* far to small */
48− *ip = ieee754sp_zero(xs);
49− return x;
50− case IEEE754_CLASS_NORM:
51− break;
52− }
53− if (xe < 0) {
54− *ip = ieee754sp_zero(xs);
55− return x;
56− }
57− if (xe >= SP_MBITS) {
58− *ip = x;
59− return ieee754sp_zero(xs);
60− }
61− /* generate ipart mantissa by clearing bottom bits
62− */
63− *ip = buildsp(xs, xe + SP_EBIAS,
64− ((xm >> (SP_MBITS - xe)) << (SP_MBITS - xe)) &
65− ~SP_HIDDEN_BIT);
66−
67− /* generate fpart mantissa by clearing top bits
68− * and normalizing (must be able to normalize)
69− */
70− xm = (xm << (32 - (SP_MBITS - xe))) >> (32 - (SP_MBITS - xe));
71− if (xm == 0)
72− return ieee754sp_zero(xs);
73−
74− while ((xm >> SP_MBITS) == 0) {
75− xm <<= 1;
76− xe--;
77− }
78− return buildsp(xs, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
79−}
arch/mips/math-emu/sp_mul.c+67−72
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,23 +16,32 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754sp.h"
2823
29−ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y)
24+union ieee754sp ieee754sp_mul(union ieee754sp x, union ieee754sp y)
3025 {
26+ int re;
27+ int rs;
28+ unsigned rm;
29+ unsigned short lxm;
30+ unsigned short hxm;
31+ unsigned short lym;
32+ unsigned short hym;
33+ unsigned lrm;
34+ unsigned hrm;
35+ unsigned t;
36+ unsigned at;
37+
3138 COMPXSP;
3239 COMPYSP;
3340
3441 EXPLODEXSP;
3542 EXPLODEYSP;
3643
37− CLEARCX;
44+ ieee754_clearcx();
3845
3946 FLUSHXSP;
4047 FLUSHYSP;
@@ -51,8 +58,8 @@ ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y) · 10 unmodified lines
5158 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
5259 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
5360 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
54− SETCX(IEEE754_INVALID_OPERATION);
55− return ieee754sp_nanxcpt(ieee754sp_indef(), "mul", x, y);
61+ ieee754_setcx(IEEE754_INVALID_OPERATION);
62+ return ieee754sp_nanxcpt(ieee754sp_indef());
5663
5764 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
5865 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -68,12 +75,13 @@ ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y) · 9 unmodified lines
6875 return x;
6976
7077
71− /* Infinity handling */
72−
78+ /*
79+ * Infinity handling
80+ */
7381 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
7482 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
75− SETCX(IEEE754_INVALID_OPERATION);
76− return ieee754sp_xcpt(ieee754sp_indef(), "mul", x, y);
83+ ieee754_setcx(IEEE754_INVALID_OPERATION);
84+ return ieee754sp_indef();
7785
7886 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
7987 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
@@ -108,63 +116,50 @@ ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y) · 28 unmodified lines
108116 assert(xm & SP_HIDDEN_BIT);
109117 assert(ym & SP_HIDDEN_BIT);
110118
111− {
112− int re = xe + ye;
113− int rs = xs ^ ys;
114− unsigned rm;
115−
116− /* shunt to top of word */
117− xm <<= 32 - (SP_MBITS + 1);
118− ym <<= 32 - (SP_MBITS + 1);
119−
120− /* multiply 32bits xm,ym to give high 32bits rm with stickness
121− */
122− {
123− unsigned short lxm = xm & 0xffff;
124− unsigned short hxm = xm >> 16;
125− unsigned short lym = ym & 0xffff;
126− unsigned short hym = ym >> 16;
127− unsigned lrm;
128− unsigned hrm;
129−
130− lrm = lxm * lym; /* 16 * 16 => 32 */
131− hrm = hxm * hym; /* 16 * 16 => 32 */
132−
133− {
134− unsigned t = lxm * hym; /* 16 * 16 => 32 */
135− {
136− unsigned at = lrm + (t << 16);
137− hrm += at < lrm;
138− lrm = at;
139− }
140− hrm = hrm + (t >> 16);
141− }
142−
143− {
144− unsigned t = hxm * lym; /* 16 * 16 => 32 */
145− {
146− unsigned at = lrm + (t << 16);
147− hrm += at < lrm;
148− lrm = at;
149− }
150− hrm = hrm + (t >> 16);
151− }
152− rm = hrm | (lrm != 0);
153− }
154−
155− /*
156− * sticky shift down to normal rounding precision
157− */
158− if ((int) rm < 0) {
159− rm = (rm >> (32 - (SP_MBITS + 1 + 3))) |
160− ((rm << (SP_MBITS + 1 + 3)) != 0);
161− re++;
162− } else {
163− rm = (rm >> (32 - (SP_MBITS + 1 + 3 + 1))) |
164− ((rm << (SP_MBITS + 1 + 3 + 1)) != 0);
165− }
166− assert(rm & (SP_HIDDEN_BIT << 3));
167−
168− SPNORMRET2(rs, re, rm, "mul", x, y);
119+ re = xe + ye;
120+ rs = xs ^ ys;
121+
122+ /* shunt to top of word */
123+ xm <<= 32 - (SP_FBITS + 1);
124+ ym <<= 32 - (SP_FBITS + 1);
125+
126+ /*
127+ * Multiply 32 bits xm, ym to give high 32 bits rm with stickness.
128+ */
129+ lxm = xm & 0xffff;
130+ hxm = xm >> 16;
131+ lym = ym & 0xffff;
132+ hym = ym >> 16;
133+
134+ lrm = lxm * lym; /* 16 * 16 => 32 */
135+ hrm = hxm * hym; /* 16 * 16 => 32 */
136+
137+ t = lxm * hym; /* 16 * 16 => 32 */
138+ at = lrm + (t << 16);
139+ hrm += at < lrm;
140+ lrm = at;
141+ hrm = hrm + (t >> 16);
142+
143+ t = hxm * lym; /* 16 * 16 => 32 */
144+ at = lrm + (t << 16);
145+ hrm += at < lrm;
146+ lrm = at;
147+ hrm = hrm + (t >> 16);
148+
149+ rm = hrm | (lrm != 0);
150+
151+ /*
152+ * Sticky shift down to normal rounding precision.
153+ */
154+ if ((int) rm < 0) {
155+ rm = (rm >> (32 - (SP_FBITS + 1 + 3))) |
156+ ((rm << (SP_FBITS + 1 + 3)) != 0);
157+ re++;
158+ } else {
159+ rm = (rm >> (32 - (SP_FBITS + 1 + 3 + 1))) |
160+ ((rm << (SP_FBITS + 1 + 3 + 1)) != 0);
169161 }
162+ assert(rm & (SP_HIDDEN_BIT << 3));
163+
164+ return ieee754sp_format(rs, re, rm);
170165 }
arch/mips/math-emu/sp_scalb.c+0−57
@@ -1,57 +0,0 @@
1−/* IEEE754 floating point arithmetic
2− * single precision
3− */
4−/*
5− * MIPS floating point support
6− * Copyright (C) 1994-2000 Algorithmics Ltd.
7− *
8− * ########################################################################
9− *
10− * This program is free software; you can distribute it and/or modify it
11− * under the terms of the GNU General Public License (Version 2) as
12− * published by the Free Software Foundation.
13− *
14− * This program is distributed in the hope it will be useful, but WITHOUT
15− * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16− * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17− * for more details.
18− *
19− * You should have received a copy of the GNU General Public License along
20− * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
24− */
25−
26−
27−#include "ieee754sp.h"
28−
29−ieee754sp ieee754sp_scalb(ieee754sp x, int n)
30−{
31− COMPXSP;
32−
33− CLEARCX;
34−
35− EXPLODEXSP;
36−
37− switch (xc) {
38− case IEEE754_CLASS_SNAN:
39− return ieee754sp_nanxcpt(x, "scalb", x, n);
40− case IEEE754_CLASS_QNAN:
41− case IEEE754_CLASS_INF:
42− case IEEE754_CLASS_ZERO:
43− return x;
44− case IEEE754_CLASS_DNORM:
45− SPDNORMX;
46− break;
47− case IEEE754_CLASS_NORM:
48− break;
49− }
50− SPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n);
51−}
52−
53−
54−ieee754sp ieee754sp_ldexp(ieee754sp x, int n)
55−{
56− return ieee754sp_scalb(x, n);
57−}
arch/mips/math-emu/sp_simple.c+10−29
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,33 +16,17 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754sp.h"
2823
29−int ieee754sp_finite(ieee754sp x)
30−{
31− return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS;
32−}
33−
34−ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y)
35−{
36− CLEARCX;
37− SPSIGN(x) = SPSIGN(y);
38− return x;
39−}
40−
41−
42−ieee754sp ieee754sp_neg(ieee754sp x)
24+union ieee754sp ieee754sp_neg(union ieee754sp x)
4325 {
4426 COMPXSP;
4527
4628 EXPLODEXSP;
47− CLEARCX;
29+ ieee754_clearcx();
4830 FLUSHXSP;
4931
5032 /*
@@ -55,30 +37,29 @@ ieee754sp ieee754sp_neg(ieee754sp x) · 4 unmodified lines
5537 SPSIGN(x) ^= 1;
5638
5739 if (xc == IEEE754_CLASS_SNAN) {
58− ieee754sp y = ieee754sp_indef();
59− SETCX(IEEE754_INVALID_OPERATION);
40+ union ieee754sp y = ieee754sp_indef();
41+ ieee754_setcx(IEEE754_INVALID_OPERATION);
6042 SPSIGN(y) = SPSIGN(x);
61− return ieee754sp_nanxcpt(y, "neg");
43+ return ieee754sp_nanxcpt(y);
6244 }
6345
6446 return x;
6547 }
6648
67−
68−ieee754sp ieee754sp_abs(ieee754sp x)
49+union ieee754sp ieee754sp_abs(union ieee754sp x)
6950 {
7051 COMPXSP;
7152
7253 EXPLODEXSP;
73− CLEARCX;
54+ ieee754_clearcx();
7455 FLUSHXSP;
7556
7657 /* Clear sign ALWAYS, irrespective of NaN */
7758 SPSIGN(x) = 0;
7859
7960 if (xc == IEEE754_CLASS_SNAN) {
80− SETCX(IEEE754_INVALID_OPERATION);
81− return ieee754sp_nanxcpt(ieee754sp_indef(), "abs");
61+ ieee754_setcx(IEEE754_INVALID_OPERATION);
62+ return ieee754sp_nanxcpt(ieee754sp_indef());
8263 }
8364
8465 return x;
arch/mips/math-emu/sp_sqrt.c+17−18
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,15 +16,12 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754sp.h"
2823
29−ieee754sp ieee754sp_sqrt(ieee754sp x)
24+union ieee754sp ieee754sp_sqrt(union ieee754sp x)
3025 {
3126 int ix, s, q, m, t, i;
3227 unsigned int r;
@@ -35,34 +30,38 @@ ieee754sp ieee754sp_sqrt(ieee754sp x) · 2 unmodified lines
3530 /* take care of Inf and NaN */
3631
3732 EXPLODEXSP;
38− CLEARCX;
33+ ieee754_clearcx();
3934 FLUSHXSP;
4035
4136 /* x == INF or NAN? */
4237 switch (xc) {
4338 case IEEE754_CLASS_QNAN:
4439 /* sqrt(Nan) = Nan */
45− return ieee754sp_nanxcpt(x, "sqrt");
40+ return ieee754sp_nanxcpt(x);
41+
4642 case IEEE754_CLASS_SNAN:
47− SETCX(IEEE754_INVALID_OPERATION);
48− return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
43+ ieee754_setcx(IEEE754_INVALID_OPERATION);
44+ return ieee754sp_nanxcpt(ieee754sp_indef());
45+
4946 case IEEE754_CLASS_ZERO:
5047 /* sqrt(0) = 0 */
5148 return x;
49+
5250 case IEEE754_CLASS_INF:
5351 if (xs) {
5452 /* sqrt(-Inf) = Nan */
55− SETCX(IEEE754_INVALID_OPERATION);
56− return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
53+ ieee754_setcx(IEEE754_INVALID_OPERATION);
54+ return ieee754sp_nanxcpt(ieee754sp_indef());
5755 }
5856 /* sqrt(+Inf) = Inf */
5957 return x;
58+
6059 case IEEE754_CLASS_DNORM:
6160 case IEEE754_CLASS_NORM:
6261 if (xs) {
6362 /* sqrt(-x) = Nan */
64− SETCX(IEEE754_INVALID_OPERATION);
65− return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
63+ ieee754_setcx(IEEE754_INVALID_OPERATION);
64+ return ieee754sp_nanxcpt(ieee754sp_indef());
6665 }
6766 break;
6867 }
@@ -99,12 +98,12 @@ ieee754sp ieee754sp_sqrt(ieee754sp x) · 30 unmodified lines
9998 }
10099
101100 if (ix != 0) {
102− SETCX(IEEE754_INEXACT);
101+ ieee754_setcx(IEEE754_INEXACT);
103102 switch (ieee754_csr.rm) {
104− case IEEE754_RP:
103+ case FPU_CSR_RU:
105104 q += 2;
106105 break;
107− case IEEE754_RN:
106+ case FPU_CSR_RN:
108107 q += (q & 1);
109108 break;
110109 }
arch/mips/math-emu/sp_sub.c+28−29
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,23 +16,22 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754sp.h"
2823
29−ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y)
24+union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y)
3025 {
26+ int s;
27+
3128 COMPXSP;
3229 COMPYSP;
3330
3431 EXPLODEXSP;
3532 EXPLODEYSP;
3633
37− CLEARCX;
34+ ieee754_clearcx();
3835
3936 FLUSHXSP;
4037 FLUSHYSP;
@@ -51,8 +48,8 @@ ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y) · 10 unmodified lines
5148 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
5249 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
5350 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
54− SETCX(IEEE754_INVALID_OPERATION);
55− return ieee754sp_nanxcpt(ieee754sp_indef(), "sub", x, y);
51+ ieee754_setcx(IEEE754_INVALID_OPERATION);
52+ return ieee754sp_nanxcpt(ieee754sp_indef());
5653
5754 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
5855 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -68,14 +65,14 @@ ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y) · 9 unmodified lines
6865 return x;
6966
7067
71− /* Infinity handling
72− */
73−
68+ /*
69+ * Infinity handling
70+ */
7471 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
7572 if (xs != ys)
7673 return x;
77− SETCX(IEEE754_INVALID_OPERATION);
78− return ieee754sp_xcpt(ieee754sp_indef(), "sub", x, y);
74+ ieee754_setcx(IEEE754_INVALID_OPERATION);
75+ return ieee754sp_indef();
7976
8077 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
8178 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
@@ -87,15 +84,14 @@ ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y) · 5 unmodified lines
8784 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
8885 return x;
8986
90− /* Zero handling
91− */
92−
87+ /*
88+ * Zero handling
89+ */
9390 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
9491 if (xs != ys)
9592 return x;
9693 else
97− return ieee754sp_zero(ieee754_csr.rm ==
98− IEEE754_RD);
94+ return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
9995
10096 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
10197 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
@@ -104,7 +100,7 @@ ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y) · 2 unmodified lines
104100 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
105101 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
106102 /* quick fix up */
107− DPSIGN(y) ^= 1;
103+ SPSIGN(y) ^= 1;
108104 return y;
109105
110106 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
@@ -133,14 +129,16 @@ ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y) · 22 unmodified lines
133129 ym <<= 3;
134130
135131 if (xe > ye) {
136− /* have to shift y fraction right to align
132+ /*
133+ * have to shift y fraction right to align
137134 */
138− int s = xe - ye;
135+ s = xe - ye;
139136 SPXSRSYn(s);
140137 } else if (ye > xe) {
141− /* have to shift x fraction right to align
138+ /*
139+ * have to shift x fraction right to align
142140 */
143− int s = ye - xe;
141+ s = ye - xe;
144142 SPXSRSXn(s);
145143 }
146144 assert(xe == ye);
@@ -153,7 +151,7 @@ ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y) · 6 unmodified lines
153151 xe = xe;
154152 xs = xs;
155153
156− if (xm >> (SP_MBITS + 1 + 3)) { /* carry out */
154+ if (xm >> (SP_FBITS + 1 + 3)) { /* carry out */
157155 SPXSRSX1(); /* shift preserving sticky */
158156 }
159157 } else {
@@ -167,17 +165,18 @@ ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y) · 7 unmodified lines
167165 xs = ys;
168166 }
169167 if (xm == 0) {
170− if (ieee754_csr.rm == IEEE754_RD)
168+ if (ieee754_csr.rm == FPU_CSR_RD)
171169 return ieee754sp_zero(1); /* round negative inf. => sign = -1 */
172170 else
173171 return ieee754sp_zero(0); /* other round modes => sign = 1 */
174172 }
175173 /* normalize to rounding precision
176174 */
177− while ((xm >> (SP_MBITS + 3)) == 0) {
175+ while ((xm >> (SP_FBITS + 3)) == 0) {
178176 xm <<= 1;
179177 xe--;
180178 }
181179 }
182− SPNORMRET2(xs, xe, xm, "sub", x, y);
180+
181+ return ieee754sp_format(xs, xe, xm);
183182 }
arch/mips/math-emu/sp_tint.c+25−42
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,20 +16,21 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
27−#include <linux/kernel.h>
2822 #include "ieee754sp.h"
2923
30−int ieee754sp_tint(ieee754sp x)
24+int ieee754sp_tint(union ieee754sp x)
3125 {
26+ u32 residue;
27+ int round;
28+ int sticky;
29+ int odd;
30+
3231 COMPXSP;
3332
34− CLEARCX;
33+ ieee754_clearcx();
3534
3635 EXPLODEXSP;
3736 FLUSHXSP;
@@ -40,10 +39,12 @@ int ieee754sp_tint(ieee754sp x) · 2 unmodified lines
4039 case IEEE754_CLASS_SNAN:
4140 case IEEE754_CLASS_QNAN:
4241 case IEEE754_CLASS_INF:
43− SETCX(IEEE754_INVALID_OPERATION);
44− return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
42+ ieee754_setcx(IEEE754_INVALID_OPERATION);
43+ return ieee754si_indef();
44+
4545 case IEEE754_CLASS_ZERO:
4646 return 0;
47+
4748 case IEEE754_CLASS_DNORM:
4849 case IEEE754_CLASS_NORM:
4950 break;
@@ -54,18 +55,13 @@ int ieee754sp_tint(ieee754sp x) · 4 unmodified lines
5455 return -0x80000000;
5556 /* Set invalid. We will only use overflow for floating
5657 point overflow */
57− SETCX(IEEE754_INVALID_OPERATION);
58− return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
58+ ieee754_setcx(IEEE754_INVALID_OPERATION);
59+ return ieee754si_indef();
5960 }
6061 /* oh gawd */
61− if (xe > SP_MBITS) {
62− xm <<= xe - SP_MBITS;
62+ if (xe > SP_FBITS) {
63+ xm <<= xe - SP_FBITS;
6364 } else {
64− u32 residue;
65− int round;
66− int sticky;
67− int odd;
68−
6965 if (xe < -1) {
7066 residue = xm;
7167 round = 0;
@@ -76,51 +72,38 @@ int ieee754sp_tint(ieee754sp x) · 4 unmodified lines
7672 * so we do it in two steps. Be aware that xe
7773 * may be -1 */
7874 residue = xm << (xe + 1);
79− residue <<= 31 - SP_MBITS;
75+ residue <<= 31 - SP_FBITS;
8076 round = (residue >> 31) != 0;
8177 sticky = (residue << 1) != 0;
82− xm >>= SP_MBITS - xe;
78+ xm >>= SP_FBITS - xe;
8379 }
8480 odd = (xm & 0x1) != 0x0;
8581 switch (ieee754_csr.rm) {
86− case IEEE754_RN:
82+ case FPU_CSR_RN:
8783 if (round && (sticky || odd))
8884 xm++;
8985 break;
90− case IEEE754_RZ:
86+ case FPU_CSR_RZ:
9187 break;
92− case IEEE754_RU: /* toward +Infinity */
88+ case FPU_CSR_RU: /* toward +Infinity */
9389 if ((round || sticky) && !xs)
9490 xm++;
9591 break;
96− case IEEE754_RD: /* toward -Infinity */
92+ case FPU_CSR_RD: /* toward -Infinity */
9793 if ((round || sticky) && xs)
9894 xm++;
9995 break;
10096 }
10197 if ((xm >> 31) != 0) {
10298 /* This can happen after rounding */
103− SETCX(IEEE754_INVALID_OPERATION);
104− return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
99+ ieee754_setcx(IEEE754_INVALID_OPERATION);
100+ return ieee754si_indef();
105101 }
106102 if (round || sticky)
107− SETCX(IEEE754_INEXACT);
103+ ieee754_setcx(IEEE754_INEXACT);
108104 }
109105 if (xs)
110106 return -xm;
111107 else
112108 return xm;
113109 }
114−
115−
116−unsigned int ieee754sp_tuns(ieee754sp x)
117−{
118− ieee754sp hb = ieee754sp_1e31();
119−
120− /* what if x < 0 ?? */
121− if (ieee754sp_lt(x, hb))
122− return (unsigned) ieee754sp_tint(x);
123−
124− return (unsigned) ieee754sp_tint(ieee754sp_sub(x, hb)) |
125− ((unsigned) 1 << 31);
126−}
arch/mips/math-emu/sp_tlong.c+27−42
@@ -5,8 +5,6 @@ · 4 unmodified lines
55 * MIPS floating point support
66 * Copyright (C) 1994-2000 Algorithmics Ltd.
77 *
8− * ########################################################################
9− *
108 * This program is free software; you can distribute it and/or modify it
119 * under the terms of the GNU General Public License (Version 2) as
1210 * published by the Free Software Foundation.
@@ -18,19 +16,22 @@ · 5 unmodified lines
1816 *
1917 * You should have received a copy of the GNU General Public License along
2018 * with this program; if not, write to the Free Software Foundation, Inc.,
21− * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22− *
23− * ########################################################################
19+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2420 */
2521
26−
2722 #include "ieee754sp.h"
23+#include "ieee754dp.h"
2824
29−s64 ieee754sp_tlong(ieee754sp x)
25+s64 ieee754sp_tlong(union ieee754sp x)
3026 {
27+ u32 residue;
28+ int round;
29+ int sticky;
30+ int odd;
31+
3132 COMPXDP; /* <-- need 64-bit mantissa tmp */
3233
33− CLEARCX;
34+ ieee754_clearcx();
3435
3536 EXPLODEXSP;
3637 FLUSHXSP;
@@ -39,10 +40,12 @@ s64 ieee754sp_tlong(ieee754sp x) · 2 unmodified lines
3940 case IEEE754_CLASS_SNAN:
4041 case IEEE754_CLASS_QNAN:
4142 case IEEE754_CLASS_INF:
42− SETCX(IEEE754_INVALID_OPERATION);
43− return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
43+ ieee754_setcx(IEEE754_INVALID_OPERATION);
44+ return ieee754di_indef();
45+
4446 case IEEE754_CLASS_ZERO:
4547 return 0;
48+
4649 case IEEE754_CLASS_DNORM:
4750 case IEEE754_CLASS_NORM:
4851 break;
@@ -53,69 +56,51 @@ s64 ieee754sp_tlong(ieee754sp x) · 4 unmodified lines
5356 return -0x8000000000000000LL;
5457 /* Set invalid. We will only use overflow for floating
5558 point overflow */
56− SETCX(IEEE754_INVALID_OPERATION);
57− return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
59+ ieee754_setcx(IEEE754_INVALID_OPERATION);
60+ return ieee754di_indef();
5861 }
5962 /* oh gawd */
60− if (xe > SP_MBITS) {
61− xm <<= xe - SP_MBITS;
62− } else if (xe < SP_MBITS) {
63− u32 residue;
64− int round;
65− int sticky;
66− int odd;
67−
63+ if (xe > SP_FBITS) {
64+ xm <<= xe - SP_FBITS;
65+ } else if (xe < SP_FBITS) {
6866 if (xe < -1) {
6967 residue = xm;
7068 round = 0;
7169 sticky = residue != 0;
7270 xm = 0;
7371 } else {
74− residue = xm << (32 - SP_MBITS + xe);
72+ residue = xm << (32 - SP_FBITS + xe);
7573 round = (residue >> 31) != 0;
7674 sticky = (residue << 1) != 0;
77− xm >>= SP_MBITS - xe;
75+ xm >>= SP_FBITS - xe;
7876 }
7977 odd = (xm & 0x1) != 0x0;
8078 switch (ieee754_csr.rm) {
81− case IEEE754_RN:
79+ case FPU_CSR_RN:
8280 if (round && (sticky || odd))
8381 xm++;
8482 break;
85− case IEEE754_RZ:
83+ case FPU_CSR_RZ:
8684 break;
87− case IEEE754_RU: /* toward +Infinity */
85+ case FPU_CSR_RU: /* toward +Infinity */
8886 if ((round || sticky) && !xs)
8987 xm++;
9088 break;
91− case IEEE754_RD: /* toward -Infinity */
89+ case FPU_CSR_RD: /* toward -Infinity */
9290 if ((round || sticky) && xs)
9391 xm++;
9492 break;
9593 }
9694 if ((xm >> 63) != 0) {
9795 /* This can happen after rounding */
98− SETCX(IEEE754_INVALID_OPERATION);
99− return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
96+ ieee754_setcx(IEEE754_INVALID_OPERATION);
97+ return ieee754di_indef();
10098 }
10199 if (round || sticky)
102− SETCX(IEEE754_INEXACT);
100+ ieee754_setcx(IEEE754_INEXACT);
103101 }
104102 if (xs)
105103 return -xm;
106104 else
107105 return xm;
108106 }
109−
110−
111−u64 ieee754sp_tulong(ieee754sp x)
112−{
113− ieee754sp hb = ieee754sp_1e63();
114−
115− /* what if x < 0 ?? */
116− if (ieee754sp_lt(x, hb))
117− return (u64) ieee754sp_tlong(x);
118−
119− return (u64) ieee754sp_tlong(ieee754sp_sub(x, hb)) |
120− (1ULL << 63);
121−}
arch/mips/mm/c-octeon.c+2−0
@@ -137,8 +137,10 @@ static void octeon_flush_cache_sigtramp(unsigned long addr) · 136 unmodified lines
137137 {
138138 struct vm_area_struct *vma;
139139
140+ down_read(&current->mm->mmap_sem);
140141 vma = find_vma(current->mm, addr);
141142 octeon_flush_icache_all_cores(vma);
143+ up_read(&current->mm->mmap_sem);
142144 }
143145
144146
arch/mips/mm/c-r4k.c+70−7
@@ -7,6 +7,7 @@ · 6 unmodified lines
77 * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle (ralf@gnu.org)
88 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
99 */
10+#include <linux/cpu_pm.h>
1011 #include <linux/hardirq.h>
1112 #include <linux/init.h>
1213 #include <linux/highmem.h>
@@ -50,7 +51,7 @@ static inline void r4k_on_each_cpu(void (*func) (void *info), void *info) · 37 unmodified lines
5051 {
5152 preempt_disable();
5253
53−#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
54+#ifndef CONFIG_MIPS_MT_SMP
5455 smp_call_function(func, info, 1);
5556 #endif
5657 func(info);
@@ -105,22 +106,37 @@ static inline void r4k_blast_dcache_page_dc32(unsigned long addr) · 48 unmodified lines
105106
106107 static inline void r4k_blast_dcache_page_dc64(unsigned long addr)
107108 {
108− R4600_HIT_CACHEOP_WAR_IMPL;
109109 blast_dcache64_page(addr);
110110 }
111111
112+static inline void r4k_blast_dcache_page_dc128(unsigned long addr)
113+{
114+ blast_dcache128_page(addr);
115+}
116+
112117 static void r4k_blast_dcache_page_setup(void)
113118 {
114119 unsigned long dc_lsize = cpu_dcache_line_size();
115120
116− if (dc_lsize == 0)
121+ switch (dc_lsize) {
122+ case 0:
117123 r4k_blast_dcache_page = (void *)cache_noop;
118− else if (dc_lsize == 16)
124+ break;
125+ case 16:
119126 r4k_blast_dcache_page = blast_dcache16_page;
120− else if (dc_lsize == 32)
127+ break;
128+ case 32:
121129 r4k_blast_dcache_page = r4k_blast_dcache_page_dc32;
122− else if (dc_lsize == 64)
130+ break;
131+ case 64:
123132 r4k_blast_dcache_page = r4k_blast_dcache_page_dc64;
133+ break;
134+ case 128:
135+ r4k_blast_dcache_page = r4k_blast_dcache_page_dc128;
136+ break;
137+ default:
138+ break;
139+ }
124140 }
125141
126142 #ifndef CONFIG_EVA
@@ -159,6 +175,8 @@ static void r4k_blast_dcache_page_indexed_setup(void) · 32 unmodified lines
159175 r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed;
160176 else if (dc_lsize == 64)
161177 r4k_blast_dcache_page_indexed = blast_dcache64_page_indexed;
178+ else if (dc_lsize == 128)
179+ r4k_blast_dcache_page_indexed = blast_dcache128_page_indexed;
162180 }
163181
164182 void (* r4k_blast_dcache)(void);
@@ -176,6 +194,8 @@ static void r4k_blast_dcache_setup(void) · 11 unmodified lines
176194 r4k_blast_dcache = blast_dcache32;
177195 else if (dc_lsize == 64)
178196 r4k_blast_dcache = blast_dcache64;
197+ else if (dc_lsize == 128)
198+ r4k_blast_dcache = blast_dcache128;
179199 }
180200
181201 /* force code alignment (used for TX49XX_ICACHE_INDEX_INV_WAR) */
@@ -265,6 +285,8 @@ static void r4k_blast_icache_page_setup(void) · 83 unmodified lines
265285 r4k_blast_icache_page = blast_icache32_page;
266286 else if (ic_lsize == 64)
267287 r4k_blast_icache_page = blast_icache64_page;
288+ else if (ic_lsize == 128)
289+ r4k_blast_icache_page = blast_icache128_page;
268290 }
269291
270292 #ifndef CONFIG_EVA
@@ -338,6 +360,8 @@ static void r4k_blast_icache_setup(void) · 67 unmodified lines
338360 r4k_blast_icache = blast_icache32;
339361 } else if (ic_lsize == 64)
340362 r4k_blast_icache = blast_icache64;
363+ else if (ic_lsize == 128)
364+ r4k_blast_icache = blast_icache128;
341365 }
342366
343367 static void (* r4k_blast_scache_page)(unsigned long addr);
@@ -428,7 +452,7 @@ static void r4k___flush_cache_all(void) · 84 unmodified lines
428452
429453 static inline int has_valid_asid(const struct mm_struct *mm)
430454 {
431−#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
455+#ifdef CONFIG_MIPS_MT_SMP
432456 int i;
433457
434458 for_each_online_cpu(i)
@@ -1094,6 +1118,21 @@ static void probe_pcache(void) · 659 unmodified lines
10941118 c->dcache.waybit = 0;
10951119 break;
10961120
1121+ case CPU_CAVIUM_OCTEON3:
1122+ /* For now lie about the number of ways. */
1123+ c->icache.linesz = 128;
1124+ c->icache.sets = 16;
1125+ c->icache.ways = 8;
1126+ c->icache.flags |= MIPS_CACHE_VTAG;
1127+ icache_size = c->icache.sets * c->icache.ways * c->icache.linesz;
1128+
1129+ c->dcache.linesz = 128;
1130+ c->dcache.ways = 8;
1131+ c->dcache.sets = 8;
1132+ dcache_size = c->dcache.sets * c->dcache.ways * c->dcache.linesz;
1133+ c->options |= MIPS_CPU_PREFETCH;
1134+ break;
1135+
10971136 default:
10981137 if (!(config & MIPS_CONF_M))
10991138 panic("Don't know how to probe P-caches on this cpu.");
@@ -1414,6 +1453,7 @@ static void setup_scache(void) · 314 unmodified lines
14141453 loongson3_sc_init();
14151454 return;
14161455
1456+ case CPU_CAVIUM_OCTEON3:
14171457 case CPU_XLP:
14181458 /* don't need to worry about L2, fully coherent */
14191459 return;
@@ -1644,3 +1684,26 @@ void r4k_cache_init(void) · 224 unmodified lines
16441684 coherency_setup();
16451685 board_cache_error_setup = r4k_cache_error_setup;
16461686 }
1687+
1688+static int r4k_cache_pm_notifier(struct notifier_block *self, unsigned long cmd,
1689+ void *v)
1690+{
1691+ switch (cmd) {
1692+ case CPU_PM_ENTER_FAILED:
1693+ case CPU_PM_EXIT:
1694+ coherency_setup();
1695+ break;
1696+ }
1697+
1698+ return NOTIFY_OK;
1699+}
1700+
1701+static struct notifier_block r4k_cache_pm_notifier_block = {
1702+ .notifier_call = r4k_cache_pm_notifier,
1703+};
1704+
1705+int __init r4k_cache_init_pm(void)
1706+{
1707+ return cpu_pm_register_notifier(&r4k_cache_pm_notifier_block);
1708+}
1709+arch_initcall(r4k_cache_init_pm);
arch/mips/mm/init.c+17−65
@@ -44,27 +44,6 @@ · 43 unmodified lines
4444 #include <asm/tlb.h>
4545 #include <asm/fixmap.h>
4646
47−/* Atomicity and interruptability */
48−#ifdef CONFIG_MIPS_MT_SMTC
49−
50−#include <asm/mipsmtregs.h>
51−
52−#define ENTER_CRITICAL(flags) \
53− { \
54− unsigned int mvpflags; \
55− local_irq_save(flags);\
56− mvpflags = dvpe()
57−#define EXIT_CRITICAL(flags) \
58− evpe(mvpflags); \
59− local_irq_restore(flags); \
60− }
61−#else
62−
63−#define ENTER_CRITICAL(flags) local_irq_save(flags)
64−#define EXIT_CRITICAL(flags) local_irq_restore(flags)
65−
66−#endif /* CONFIG_MIPS_MT_SMTC */
67−
6847 /*
6948 * We have up to 8 empty zeroed pages so we can map one of the right colour
7049 * when needed. This is necessary only on R4000 / R4400 SC and MC versions
@@ -100,21 +79,7 @@ void setup_zero_pages(void) · 29 unmodified lines
10079 zero_page_mask = ((PAGE_SIZE << order) - 1) & PAGE_MASK;
10180 }
10281
103−#ifdef CONFIG_MIPS_MT_SMTC
104−static pte_t *kmap_coherent_pte;
105−static void __init kmap_coherent_init(void)
106−{
107− unsigned long vaddr;
108−
109− /* cache the first coherent kmap pte */
110− vaddr = __fix_to_virt(FIX_CMAP_BEGIN);
111− kmap_coherent_pte = kmap_get_fixmap_pte(vaddr);
112−}
113−#else
114−static inline void kmap_coherent_init(void) {}
115−#endif
116−
117−void *kmap_coherent(struct page *page, unsigned long addr)
82+static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot)
11883 {
11984 enum fixed_addresses idx;
12085 unsigned long vaddr, flags, entrylo;
@@ -126,58 +91,48 @@ void *kmap_coherent(struct page *page, unsigned long addr) · 5 unmodified lines
12691
12792 pagefault_disable();
12893 idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1);
129−#ifdef CONFIG_MIPS_MT_SMTC
130− idx += FIX_N_COLOURS * smp_processor_id() +
131− (in_interrupt() ? (FIX_N_COLOURS * NR_CPUS) : 0);
132−#else
13394 idx += in_interrupt() ? FIX_N_COLOURS : 0;
134−#endif
13595 vaddr = __fix_to_virt(FIX_CMAP_END - idx);
136− pte = mk_pte(page, PAGE_KERNEL);
96+ pte = mk_pte(page, prot);
13797 #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
13898 entrylo = pte.pte_high;
13999 #else
140100 entrylo = pte_to_entrylo(pte_val(pte));
141101 #endif
142102
143− ENTER_CRITICAL(flags);
103+ local_irq_save(flags);
144104 old_ctx = read_c0_entryhi();
145105 write_c0_entryhi(vaddr & (PAGE_MASK << 1));
146106 write_c0_entrylo0(entrylo);
147107 write_c0_entrylo1(entrylo);
148−#ifdef CONFIG_MIPS_MT_SMTC
149− set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte);
150− /* preload TLB instead of local_flush_tlb_one() */
151− mtc0_tlbw_hazard();
152− tlb_probe();
153− tlb_probe_hazard();
154− tlbidx = read_c0_index();
155− mtc0_tlbw_hazard();
156− if (tlbidx < 0)
157− tlb_write_random();
158− else
159− tlb_write_indexed();
160−#else
161108 tlbidx = read_c0_wired();
162109 write_c0_wired(tlbidx + 1);
163110 write_c0_index(tlbidx);
164111 mtc0_tlbw_hazard();
165112 tlb_write_indexed();
166−#endif
167113 tlbw_use_hazard();
168114 write_c0_entryhi(old_ctx);
169− EXIT_CRITICAL(flags);
115+ local_irq_restore(flags);
170116
171117 return (void*) vaddr;
172118 }
173119
120+void *kmap_coherent(struct page *page, unsigned long addr)
121+{
122+ return __kmap_pgprot(page, addr, PAGE_KERNEL);
123+}
124+
125+void *kmap_noncoherent(struct page *page, unsigned long addr)
126+{
127+ return __kmap_pgprot(page, addr, PAGE_KERNEL_NC);
128+}
129+
174130 void kunmap_coherent(void)
175131 {
176−#ifndef CONFIG_MIPS_MT_SMTC
177132 unsigned int wired;
178133 unsigned long flags, old_ctx;
179134
180− ENTER_CRITICAL(flags);
135+ local_irq_save(flags);
181136 old_ctx = read_c0_entryhi();
182137 wired = read_c0_wired() - 1;
183138 write_c0_wired(wired);
@@ -189,8 +144,7 @@ void kunmap_coherent(void) · 5 unmodified lines
189144 tlb_write_indexed();
190145 tlbw_use_hazard();
191146 write_c0_entryhi(old_ctx);
192− EXIT_CRITICAL(flags);
193−#endif
147+ local_irq_restore(flags);
194148 pagefault_enable();
195149 }
196150
@@ -256,7 +210,7 @@ EXPORT_SYMBOL_GPL(copy_from_user_page); · 59 unmodified lines
256210 void __init fixrange_init(unsigned long start, unsigned long end,
257211 pgd_t *pgd_base)
258212 {
259−#if defined(CONFIG_HIGHMEM) || defined(CONFIG_MIPS_MT_SMTC)
213+#ifdef CONFIG_HIGHMEM
260214 pgd_t *pgd;
261215 pud_t *pud;
262216 pmd_t *pmd;
@@ -327,8 +281,6 @@ void __init paging_init(void) · 64 unmodified lines
327281 #ifdef CONFIG_HIGHMEM
328282 kmap_init();
329283 #endif
330− kmap_coherent_init();
331−
332284 #ifdef CONFIG_ZONE_DMA
333285 max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
334286 #endif
arch/mips/mm/tlb-r4k.c+49−39
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 * Carsten Langgaard, carstenl@mips.com
99 * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved.
1010 */
11+#include <linux/cpu_pm.h>
1112 #include <linux/init.h>
1213 #include <linux/sched.h>
1314 #include <linux/smp.h>
@@ -25,28 +26,6 @@ · 11 unmodified lines
2526
2627 extern void build_tlb_refill_handler(void);
2728
28−/* Atomicity and interruptability */
29−#ifdef CONFIG_MIPS_MT_SMTC
30−
31−#include <asm/smtc.h>
32−#include <asm/mipsmtregs.h>
33−
34−#define ENTER_CRITICAL(flags) \
35− { \
36− unsigned int mvpflags; \
37− local_irq_save(flags);\
38− mvpflags = dvpe()
39−#define EXIT_CRITICAL(flags) \
40− evpe(mvpflags); \
41− local_irq_restore(flags); \
42− }
43−#else
44−
45−#define ENTER_CRITICAL(flags) local_irq_save(flags)
46−#define EXIT_CRITICAL(flags) local_irq_restore(flags)
47−
48−#endif /* CONFIG_MIPS_MT_SMTC */
49−
5029 /*
5130 * LOONGSON2/3 has a 4 entry itlb which is a subset of dtlb,
5231 * unfortunately, itlb is not totally transparent to software.
@@ -75,7 +54,7 @@ void local_flush_tlb_all(void) · 22 unmodified lines
7554 unsigned long old_ctx;
7655 int entry, ftlbhighset;
7756
78− ENTER_CRITICAL(flags);
57+ local_irq_save(flags);
7958 /* Save old context and create impossible VPN2 value */
8059 old_ctx = read_c0_entryhi();
8160 write_c0_entrylo0(0);
@@ -112,7 +91,7 @@ void local_flush_tlb_all(void) · 30 unmodified lines
11291 tlbw_use_hazard();
11392 write_c0_entryhi(old_ctx);
11493 flush_itlb();
115− EXIT_CRITICAL(flags);
94+ local_irq_restore(flags);
11695 }
11796 EXPORT_SYMBOL(local_flush_tlb_all);
11897
@@ -142,7 +121,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, · 23 unmodified lines
142121 if (cpu_context(cpu, mm) != 0) {
143122 unsigned long size, flags;
144123
145− ENTER_CRITICAL(flags);
124+ local_irq_save(flags);
146125 start = round_down(start, PAGE_SIZE << 1);
147126 end = round_up(end, PAGE_SIZE << 1);
148127 size = (end - start) >> (PAGE_SHIFT + 1);
@@ -176,7 +155,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, · 27 unmodified lines
176155 drop_mmu_context(mm, cpu);
177156 }
178157 flush_itlb();
179− EXIT_CRITICAL(flags);
158+ local_irq_restore(flags);
180159 }
181160 }
182161
@@ -184,7 +163,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) · 1 unmodified line
184163 {
185164 unsigned long size, flags;
186165
187− ENTER_CRITICAL(flags);
166+ local_irq_save(flags);
188167 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
189168 size = (size + 1) >> 1;
190169 if (size <= (current_cpu_data.tlbsizeftlbsets ?
@@ -220,7 +199,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) · 29 unmodified lines
220199 local_flush_tlb_all();
221200 }
222201 flush_itlb();
223− EXIT_CRITICAL(flags);
202+ local_irq_restore(flags);
224203 }
225204
226205 void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
@@ -233,7 +212,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) · 6 unmodified lines
233212
234213 newpid = cpu_asid(cpu, vma->vm_mm);
235214 page &= (PAGE_MASK << 1);
236− ENTER_CRITICAL(flags);
215+ local_irq_save(flags);
237216 oldpid = read_c0_entryhi();
238217 write_c0_entryhi(page | newpid);
239218 mtc0_tlbw_hazard();
@@ -253,7 +232,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) · 13 unmodified lines
253232 finish:
254233 write_c0_entryhi(oldpid);
255234 flush_itlb_vm(vma);
256− EXIT_CRITICAL(flags);
235+ local_irq_restore(flags);
257236 }
258237 }
259238
@@ -266,7 +245,7 @@ void local_flush_tlb_one(unsigned long page) · 6 unmodified lines
266245 unsigned long flags;
267246 int oldpid, idx;
268247
269− ENTER_CRITICAL(flags);
248+ local_irq_save(flags);
270249 oldpid = read_c0_entryhi();
271250 page &= (PAGE_MASK << 1);
272251 write_c0_entryhi(page);
@@ -285,7 +264,7 @@ void local_flush_tlb_one(unsigned long page) · 12 unmodified lines
285264 }
286265 write_c0_entryhi(oldpid);
287266 flush_itlb();
288− EXIT_CRITICAL(flags);
267+ local_irq_restore(flags);
289268 }
290269
291270 /*
@@ -308,7 +287,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) · 16 unmodified lines
308287 if (current->active_mm != vma->vm_mm)
309288 return;
310289
311− ENTER_CRITICAL(flags);
290+ local_irq_save(flags);
312291
313292 pid = read_c0_entryhi() & ASID_MASK;
314293 address &= (PAGE_MASK << 1);
@@ -358,7 +337,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) · 43 unmodified lines
358337 }
359338 tlbw_use_hazard();
360339 flush_itlb_vm(vma);
361− EXIT_CRITICAL(flags);
340+ local_irq_restore(flags);
362341 }
363342
364343 void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
@@ -369,7 +348,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, · 4 unmodified lines
369348 unsigned long old_pagemask;
370349 unsigned long old_ctx;
371350
372− ENTER_CRITICAL(flags);
351+ local_irq_save(flags);
373352 /* Save old context and create impossible VPN2 value */
374353 old_ctx = read_c0_entryhi();
375354 old_pagemask = read_c0_pagemask();
@@ -389,7 +368,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, · 13 unmodified lines
389368 tlbw_use_hazard(); /* What is the hazard here? */
390369 write_c0_pagemask(old_pagemask);
391370 local_flush_tlb_all();
392− EXIT_CRITICAL(flags);
371+ local_irq_restore(flags);
393372 }
394373
395374 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
@@ -399,13 +378,13 @@ int __init has_transparent_hugepage(void) · 3 unmodified lines
399378 unsigned int mask;
400379 unsigned long flags;
401380
402− ENTER_CRITICAL(flags);
381+ local_irq_save(flags);
403382 write_c0_pagemask(PM_HUGE_MASK);
404383 back_to_back_c0_hazard();
405384 mask = read_c0_pagemask();
406385 write_c0_pagemask(PM_DEFAULT_MASK);
407386
408− EXIT_CRITICAL(flags);
387+ local_irq_restore(flags);
409388
410389 return mask == PM_HUGE_MASK;
411390 }
@@ -421,7 +400,10 @@ static int __init set_ntlb(char *str) · 9 unmodified lines
421400
422401 __setup("ntlb=", set_ntlb);
423402
424−void tlb_init(void)
403+/*
404+ * Configure TLB (for init or after a CPU has been powered off).
405+ */
406+static void r4k_tlb_configure(void)
425407 {
426408 /*
427409 * You should never change this register:
@@ -453,6 +435,11 @@ void tlb_init(void) · 25 unmodified lines
453435 local_flush_tlb_all();
454436
455437 /* Did I tell you that ARC SUCKS? */
438+}
439+
440+void tlb_init(void)
441+{
442+ r4k_tlb_configure();
456443
457444 if (ntlb) {
458445 if (ntlb > 1 && ntlb <= current_cpu_data.tlbsize) {
@@ -466,3 +453,26 @@ void tlb_init(void) · 7 unmodified lines
466453
467454 build_tlb_refill_handler();
468455 }
456+
457+static int r4k_tlb_pm_notifier(struct notifier_block *self, unsigned long cmd,
458+ void *v)
459+{
460+ switch (cmd) {
461+ case CPU_PM_ENTER_FAILED:
462+ case CPU_PM_EXIT:
463+ r4k_tlb_configure();
464+ break;
465+ }
466+
467+ return NOTIFY_OK;
468+}
469+
470+static struct notifier_block r4k_tlb_pm_notifier_block = {
471+ .notifier_call = r4k_tlb_pm_notifier,
472+};
473+
474+static int __init r4k_tlb_init_pm(void)
475+{
476+ return cpu_pm_register_notifier(&r4k_tlb_pm_notifier_block);
477+}
478+arch_initcall(r4k_tlb_init_pm);
arch/mips/mm/tlbex.c+1−1
@@ -1256,7 +1256,7 @@ static void build_r4000_tlb_refill_handler(void) · 1255 unmodified lines
12561256 memset(relocs, 0, sizeof(relocs));
12571257 memset(final_handler, 0, sizeof(final_handler));
12581258
1259− if ((scratch_reg >= 0 || scratchpad_available()) && use_bbit_insns()) {
1259+ if (IS_ENABLED(CONFIG_64BIT) && (scratch_reg >= 0 || scratchpad_available()) && use_bbit_insns()) {
12601260 htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, K0, K1,
12611261 scratch_reg);
12621262 vmalloc_mode = refill_scratch;
arch/mips/mm/uasm-micromips.c+14−0
@@ -63,6 +63,7 @@ static struct insn insn_table_MM[] = { · 62 unmodified lines
6363 { insn_cache, M(mm_pool32b_op, 0, 0, mm_cache_func, 0, 0), RT | RS | SIMM },
6464 { insn_daddu, 0, 0 },
6565 { insn_daddiu, 0, 0 },
66+ { insn_divu, M(mm_pool32a_op, 0, 0, 0, mm_divu_op, mm_pool32axf_op), RT | RS },
6667 { insn_dmfc0, 0, 0 },
6768 { insn_dmtc0, 0, 0 },
6869 { insn_dsll, 0, 0 },
@@ -78,14 +79,20 @@ static struct insn insn_table_MM[] = { · 9 unmodified lines
7879 { insn_ext, M(mm_pool32a_op, 0, 0, 0, 0, mm_ext_op), RT | RS | RD | RE },
7980 { insn_j, M(mm_j32_op, 0, 0, 0, 0, 0), JIMM },
8081 { insn_jal, M(mm_jal32_op, 0, 0, 0, 0, 0), JIMM },
82+ { insn_jalr, M(mm_pool32a_op, 0, 0, 0, mm_jalr_op, mm_pool32axf_op), RT | RS },
8183 { insn_jr, M(mm_pool32a_op, 0, 0, 0, mm_jalr_op, mm_pool32axf_op), RS },
84+ { insn_lb, M(mm_lb32_op, 0, 0, 0, 0, 0), RT | RS | SIMM },
8285 { insn_ld, 0, 0 },
86+ { insn_lh, M(mm_lh32_op, 0, 0, 0, 0, 0), RS | RS | SIMM },
8387 { insn_ll, M(mm_pool32c_op, 0, 0, (mm_ll_func << 1), 0, 0), RS | RT | SIMM },
8488 { insn_lld, 0, 0 },
8589 { insn_lui, M(mm_pool32i_op, mm_lui_op, 0, 0, 0, 0), RS | SIMM },
8690 { insn_lw, M(mm_lw32_op, 0, 0, 0, 0, 0), RT | RS | SIMM },
8791 { insn_mfc0, M(mm_pool32a_op, 0, 0, 0, mm_mfc0_op, mm_pool32axf_op), RT | RS | RD },
92+ { insn_mfhi, M(mm_pool32a_op, 0, 0, 0, mm_mfhi32_op, mm_pool32axf_op), RS },
93+ { insn_mflo, M(mm_pool32a_op, 0, 0, 0, mm_mflo32_op, mm_pool32axf_op), RS },
8894 { insn_mtc0, M(mm_pool32a_op, 0, 0, 0, mm_mtc0_op, mm_pool32axf_op), RT | RS | RD },
95+ { insn_mul, M(mm_pool32a_op, 0, 0, 0, 0, mm_mul_op), RT | RS | RD },
8996 { insn_or, M(mm_pool32a_op, 0, 0, 0, 0, mm_or32_op), RT | RS | RD },
9097 { insn_ori, M(mm_ori32_op, 0, 0, 0, 0, 0), RT | RS | UIMM },
9198 { insn_pref, M(mm_pool32c_op, 0, 0, (mm_pref_func << 1), 0, 0), RT | RS | SIMM },
@@ -94,15 +101,22 @@ static struct insn insn_table_MM[] = { · 2 unmodified lines
94101 { insn_scd, 0, 0 },
95102 { insn_sd, 0, 0 },
96103 { insn_sll, M(mm_pool32a_op, 0, 0, 0, 0, mm_sll32_op), RT | RS | RD },
104+ { insn_sllv, M(mm_pool32a_op, 0, 0, 0, 0, mm_sllv32_op), RT | RS | RD },
105+ { insn_sltiu, M(mm_sltiu32_op, 0, 0, 0, 0, 0), RT | RS | SIMM },
106+ { insn_sltu, M(mm_pool32a_op, 0, 0, 0, 0, mm_sltu_op), RT | RS | RD },
97107 { insn_sra, M(mm_pool32a_op, 0, 0, 0, 0, mm_sra_op), RT | RS | RD },
98108 { insn_srl, M(mm_pool32a_op, 0, 0, 0, 0, mm_srl32_op), RT | RS | RD },
109+ { insn_srlv, M(mm_pool32a_op, 0, 0, 0, 0, mm_srlv32_op), RT | RS | RD },
99110 { insn_rotr, M(mm_pool32a_op, 0, 0, 0, 0, mm_rotr_op), RT | RS | RD },
100111 { insn_subu, M(mm_pool32a_op, 0, 0, 0, 0, mm_subu32_op), RT | RS | RD },
101112 { insn_sw, M(mm_sw32_op, 0, 0, 0, 0, 0), RT | RS | SIMM },
113+ { insn_sync, M(mm_pool32a_op, 0, 0, 0, mm_sync_op, mm_pool32axf_op), RS },
102114 { insn_tlbp, M(mm_pool32a_op, 0, 0, 0, mm_tlbp_op, mm_pool32axf_op), 0 },
103115 { insn_tlbr, M(mm_pool32a_op, 0, 0, 0, mm_tlbr_op, mm_pool32axf_op), 0 },
104116 { insn_tlbwi, M(mm_pool32a_op, 0, 0, 0, mm_tlbwi_op, mm_pool32axf_op), 0 },
105117 { insn_tlbwr, M(mm_pool32a_op, 0, 0, 0, mm_tlbwr_op, mm_pool32axf_op), 0 },
118+ { insn_wait, M(mm_pool32a_op, 0, 0, 0, mm_wait_op, mm_pool32axf_op), SCIMM },
119+ { insn_wsbh, M(mm_pool32a_op, 0, 0, 0, mm_wsbh_op, mm_pool32axf_op), RT | RS },
106120 { insn_xor, M(mm_pool32a_op, 0, 0, 0, 0, mm_xor32_op), RT | RS | RD },
107121 { insn_xori, M(mm_xori32_op, 0, 0, 0, 0, 0), RT | RS | UIMM },
108122 { insn_dins, 0, 0 },
arch/mips/mm/uasm-mips.c+15−0
@@ -67,6 +67,7 @@ static struct insn insn_table[] = { · 66 unmodified lines
6767 { insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD },
6868 { insn_dinsm, M(spec3_op, 0, 0, 0, 0, dinsm_op), RS | RT | RD | RE },
6969 { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
70+ { insn_divu, M(spec_op, 0, 0, 0, 0, divu_op), RS | RT },
7071 { insn_dmfc0, M(cop0_op, dmfc_op, 0, 0, 0, 0), RT | RD | SET},
7172 { insn_dmtc0, M(cop0_op, dmtc_op, 0, 0, 0, 0), RT | RD | SET},
7273 { insn_drotr32, M(spec_op, 1, 0, 0, 0, dsrl32_op), RT | RD | RE },
@@ -82,17 +83,23 @@ static struct insn insn_table[] = { · 9 unmodified lines
8283 { insn_ins, M(spec3_op, 0, 0, 0, 0, ins_op), RS | RT | RD | RE },
8384 { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM },
8485 { insn_jal, M(jal_op, 0, 0, 0, 0, 0), JIMM },
86+ { insn_jalr, M(spec_op, 0, 0, 0, 0, jalr_op), RS | RD },
8587 { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM },
8688 { insn_jr, M(spec_op, 0, 0, 0, 0, jr_op), RS },
89+ { insn_lb, M(lb_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
8790 { insn_ld, M(ld_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
8891 { insn_ldx, M(spec3_op, 0, 0, 0, ldx_op, lx_op), RS | RT | RD },
92+ { insn_lh, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
8993 { insn_lld, M(lld_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
9094 { insn_ll, M(ll_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
9195 { insn_lui, M(lui_op, 0, 0, 0, 0, 0), RT | SIMM },
9296 { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
9397 { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD },
9498 { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET},
99+ { insn_mfhi, M(spec_op, 0, 0, 0, 0, mfhi_op), RD },
100+ { insn_mflo, M(spec_op, 0, 0, 0, 0, mflo_op), RD },
95101 { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET},
102+ { insn_mul, M(spec2_op, 0, 0, 0, 0, mul_op), RS | RT | RD},
96103 { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
97104 { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD },
98105 { insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
@@ -102,17 +109,25 @@ static struct insn insn_table[] = { · 3 unmodified lines
102109 { insn_sc, M(sc_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
103110 { insn_sd, M(sd_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
104111 { insn_sll, M(spec_op, 0, 0, 0, 0, sll_op), RT | RD | RE },
112+ { insn_sllv, M(spec_op, 0, 0, 0, 0, sllv_op), RS | RT | RD },
113+ { insn_sltiu, M(sltiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
114+ { insn_sltu, M(spec_op, 0, 0, 0, 0, sltu_op), RS | RT | RD },
105115 { insn_sra, M(spec_op, 0, 0, 0, 0, sra_op), RT | RD | RE },
106116 { insn_srl, M(spec_op, 0, 0, 0, 0, srl_op), RT | RD | RE },
117+ { insn_srlv, M(spec_op, 0, 0, 0, 0, srlv_op), RS | RT | RD },
107118 { insn_subu, M(spec_op, 0, 0, 0, 0, subu_op), RS | RT | RD },
108119 { insn_sw, M(sw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
120+ { insn_sync, M(spec_op, 0, 0, 0, 0, sync_op), RE },
109121 { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM},
110122 { insn_tlbp, M(cop0_op, cop_op, 0, 0, 0, tlbp_op), 0 },
111123 { insn_tlbr, M(cop0_op, cop_op, 0, 0, 0, tlbr_op), 0 },
112124 { insn_tlbwi, M(cop0_op, cop_op, 0, 0, 0, tlbwi_op), 0 },
113125 { insn_tlbwr, M(cop0_op, cop_op, 0, 0, 0, tlbwr_op), 0 },
126+ { insn_wait, M(cop0_op, cop_op, 0, 0, 0, wait_op), SCIMM },
127+ { insn_wsbh, M(spec3_op, 0, 0, 0, wsbh_op, bshfl_op), RT | RD },
114128 { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
115129 { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD },
130+ { insn_yield, M(spec3_op, 0, 0, 0, 0, yield_op), RS | RD },
116131 { insn_invalid, 0, 0 }
117132 };
118133
arch/mips/mm/uasm.c+45−6
@@ -47,14 +47,16 @@ enum opcode { · 46 unmodified lines
4747 insn_addiu, insn_addu, insn_and, insn_andi, insn_bbit0, insn_bbit1,
4848 insn_beq, insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
4949 insn_bne, insn_cache, insn_daddiu, insn_daddu, insn_dins, insn_dinsm,
50− insn_dmfc0, insn_dmtc0, insn_drotr, insn_drotr32, insn_dsll,
50+ insn_divu, insn_dmfc0, insn_dmtc0, insn_drotr, insn_drotr32, insn_dsll,
5151 insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret,
52− insn_ext, insn_ins, insn_j, insn_jal, insn_jr, insn_ld, insn_ldx,
53− insn_ll, insn_lld, insn_lui, insn_lw, insn_lwx, insn_mfc0, insn_mtc0,
52+ insn_ext, insn_ins, insn_j, insn_jal, insn_jalr, insn_jr, insn_lb,
53+ insn_ld, insn_ldx, insn_lh, insn_ll, insn_lld, insn_lui, insn_lw,
54+ insn_lwx, insn_mfc0, insn_mfhi, insn_mflo, insn_mtc0, insn_mul,
5455 insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr, insn_sc, insn_scd,
55− insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw,
56− insn_syscall, insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor,
57− insn_xori,
56+ insn_sd, insn_sll, insn_sllv, insn_sltiu, insn_sltu, insn_sra,
57+ insn_srl, insn_srlv, insn_subu, insn_sw, insn_sync, insn_syscall,
58+ insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_wait, insn_wsbh,
59+ insn_xor, insn_xori, insn_yield,
5860 };
5961
6062 struct insn {
@@ -144,6 +146,13 @@ Ip_u2u1u3(op) \ · 83 unmodified lines
144146 } \
145147 UASM_EXPORT_SYMBOL(uasm_i##op);
146148
149+#define I_u3u2u1(op) \
150+Ip_u3u2u1(op) \
151+{ \
152+ build_insn(buf, insn##op, c, b, a); \
153+} \
154+UASM_EXPORT_SYMBOL(uasm_i##op);
155+
147156 #define I_u3u1u2(op) \
148157 Ip_u3u1u2(op) \
149158 { \
@@ -200,6 +209,13 @@ Ip_u1u2(op) \ · 50 unmodified lines
200209 } \
201210 UASM_EXPORT_SYMBOL(uasm_i##op);
202211
212+#define I_u2u1(op) \
213+Ip_u1u2(op) \
214+{ \
215+ build_insn(buf, insn##op, b, a); \
216+} \
217+UASM_EXPORT_SYMBOL(uasm_i##op);
218+
203219 #define I_u1s2(op) \
204220 Ip_u1s2(op) \
205221 { \
@@ -237,6 +253,7 @@ I_u1u2u3(_dmfc0) · 31 unmodified lines
237253 I_u1u2u3(_dmtc0)
238254 I_u2u1s3(_daddiu)
239255 I_u3u1u2(_daddu)
256+I_u1u2(_divu)
240257 I_u2u1u3(_dsll)
241258 I_u2u1u3(_dsll32)
242259 I_u2u1u3(_dsra)
@@ -250,14 +267,20 @@ I_u2u1msbdu3(_ext) · 7 unmodified lines
250267 I_u2u1msbu3(_ins)
251268 I_u1(_j)
252269 I_u1(_jal)
270+I_u2u1(_jalr)
253271 I_u1(_jr)
272+I_u2s3u1(_lb)
254273 I_u2s3u1(_ld)
274+I_u2s3u1(_lh)
255275 I_u2s3u1(_ll)
256276 I_u2s3u1(_lld)
257277 I_u1s2(_lui)
258278 I_u2s3u1(_lw)
259279 I_u1u2u3(_mfc0)
280+I_u1(_mfhi)
281+I_u1(_mflo)
260282 I_u1u2u3(_mtc0)
283+I_u3u1u2(_mul)
261284 I_u2u1u3(_ori)
262285 I_u3u1u2(_or)
263286 I_0(_rfe)
@@ -265,17 +288,25 @@ I_u2s3u1(_sc) · 1 unmodified line
265288 I_u2s3u1(_scd)
266289 I_u2s3u1(_sd)
267290 I_u2u1u3(_sll)
291+I_u3u2u1(_sllv)
292+I_u2u1s3(_sltiu)
293+I_u3u1u2(_sltu)
268294 I_u2u1u3(_sra)
269295 I_u2u1u3(_srl)
296+I_u3u2u1(_srlv)
270297 I_u2u1u3(_rotr)
271298 I_u3u1u2(_subu)
272299 I_u2s3u1(_sw)
300+I_u1(_sync)
273301 I_0(_tlbp)
274302 I_0(_tlbr)
275303 I_0(_tlbwi)
276304 I_0(_tlbwr)
305+I_u1(_wait);
306+I_u2u1(_wsbh)
277307 I_u3u1u2(_xor)
278308 I_u2u1u3(_xori)
309+I_u2u1(_yield)
279310 I_u2u1msbu3(_dins);
280311 I_u2u1msb32u3(_dinsm);
281312 I_u1(_syscall);
@@ -469,6 +500,14 @@ void ISAFUNC(uasm_il_b)(u32 **p, struct uasm_reloc **r, int lid) · 187 unmodified lines
469500 }
470501 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_b));
471502
503+void ISAFUNC(uasm_il_beq)(u32 **p, struct uasm_reloc **r, unsigned int r1,
504+ unsigned int r2, int lid)
505+{
506+ uasm_r_mips_pc16(r, *p, lid);
507+ ISAFUNC(uasm_i_beq)(p, r1, r2, 0);
508+}
509+UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_beq));
510+
472511 void ISAFUNC(uasm_il_beqz)(u32 **p, struct uasm_reloc **r, unsigned int reg,
473512 int lid)
474513 {
arch/mips/mti-malta/Makefile+1−2
@@ -9,5 +9,4 @@ obj-y := malta-amon.o malta-display.o malta-init.o \ · 8 unmodified lines
99 malta-int.o malta-memory.o malta-platform.o \
1010 malta-reset.o malta-setup.o malta-time.o
1111
12−# FIXME FIXME FIXME
13−obj-$(CONFIG_MIPS_MT_SMTC) += malta-smtc.o
12+obj-$(CONFIG_MIPS_MALTA_PM) += malta-pm.o
arch/mips/mti-malta/malta-init.c+0−6
@@ -116,8 +116,6 @@ phys_t mips_cpc_default_phys_base(void) · 115 unmodified lines
116116 return CPC_BASE_ADDR;
117117 }
118118
119−extern struct plat_smp_ops msmtc_smp_ops;
120−
121119 void __init prom_init(void)
122120 {
123121 mips_display_message("LINUX");
@@ -304,8 +302,4 @@ mips_pci_controller: · 180 unmodified lines
304302 return;
305303 if (!register_vsmp_smp_ops())
306304 return;
307−
308−#ifdef CONFIG_MIPS_MT_SMTC
309− register_smp_ops(&msmtc_smp_ops);
310−#endif
311305 }
arch/mips/mti-malta/malta-int.c+0−19
@@ -504,28 +504,9 @@ void __init arch_init_irq(void) · 503 unmodified lines
504504 } else if (cpu_has_vint) {
505505 set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch);
506506 set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch);
507−#ifdef CONFIG_MIPS_MT_SMTC
508− setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq,
509− (0x100 << MIPSCPU_INT_I8259A));
510− setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
511− &corehi_irqaction, (0x100 << MIPSCPU_INT_COREHI));
512− /*
513− * Temporary hack to ensure that the subsidiary device
514− * interrupts coing in via the i8259A, but associated
515− * with low IRQ numbers, will restore the Status.IM
516− * value associated with the i8259A.
517− */
518− {
519− int i;
520−
521− for (i = 0; i < 16; i++)
522− irq_hwmask[i] = (0x100 << MIPSCPU_INT_I8259A);
523− }
524−#else /* Not SMTC */
525507 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq);
526508 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
527509 &corehi_irqaction);
528−#endif /* CONFIG_MIPS_MT_SMTC */
529510 } else {
530511 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq);
531512 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
arch/mips/mti-malta/malta-memory.c+2−2
@@ -26,8 +26,8 @@ unsigned long physical_memsize = 0L; · 25 unmodified lines
2626
2727 fw_memblock_t * __init fw_getmdesc(int eva)
2828 {
29− char *memsize_str, *ememsize_str __maybe_unused = NULL, *ptr;
30− unsigned long memsize = 0, ememsize __maybe_unused = 0;
29+ char *memsize_str, *ememsize_str = NULL, *ptr;
30+ unsigned long memsize = 0, ememsize = 0;
3131 static char cmdline[COMMAND_LINE_SIZE] __initdata;
3232 int tmp;
3333
arch/mips/mti-malta/malta-pm.c+96−0
@@ -0,0 +1,96 @@
1+/*
2+ * Copyright (C) 2014 Imagination Technologies
3+ * Author: Paul Burton <paul.burton@imgtec.com>
4+ *
5+ * This program is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License as published by the
7+ * Free Software Foundation; either version 2 of the License, or (at your
8+ * option) any later version.
9+ */
10+
11+#include <linux/delay.h>
12+#include <linux/init.h>
13+#include <linux/io.h>
14+#include <linux/pci.h>
15+
16+#include <asm/mach-malta/malta-pm.h>
17+
18+static struct pci_bus *pm_pci_bus;
19+static resource_size_t pm_io_offset;
20+
21+int mips_pm_suspend(unsigned state)
22+{
23+ int spec_devid;
24+ u16 sts;
25+
26+ if (!pm_pci_bus || !pm_io_offset)
27+ return -ENODEV;
28+
29+ /* Ensure the power button status is clear */
30+ while (1) {
31+ sts = inw(pm_io_offset + PIIX4_FUNC3IO_PMSTS);
32+ if (!(sts & PIIX4_FUNC3IO_PMSTS_PWRBTN_STS))
33+ break;
34+ outw(sts, pm_io_offset + PIIX4_FUNC3IO_PMSTS);
35+ }
36+
37+ /* Enable entry to suspend */
38+ outw(state | PIIX4_FUNC3IO_PMCNTRL_SUS_EN,
39+ pm_io_offset + PIIX4_FUNC3IO_PMCNTRL);
40+
41+ /* If the special cycle occurs too soon this doesn't work... */
42+ mdelay(10);
43+
44+ /*
45+ * The PIIX4 will enter the suspend state only after seeing a special
46+ * cycle with the correct magic data on the PCI bus. Generate that
47+ * cycle now.
48+ */
49+ spec_devid = PCI_DEVID(0, PCI_DEVFN(0x1f, 0x7));
50+ pci_bus_write_config_dword(pm_pci_bus, spec_devid, 0,
51+ PIIX4_SUSPEND_MAGIC);
52+
53+ /* Give the system some time to power down */
54+ mdelay(1000);
55+
56+ return 0;
57+}
58+
59+static int __init malta_pm_setup(void)
60+{
61+ struct pci_dev *dev;
62+ int res, io_region = PCI_BRIDGE_RESOURCES;
63+
64+ /* Find a reference to the PCI bus */
65+ pm_pci_bus = pci_find_next_bus(NULL);
66+ if (!pm_pci_bus) {
67+ pr_warn("malta-pm: failed to find reference to PCI bus\n");
68+ return -ENODEV;
69+ }
70+
71+ /* Find the PIIX4 PM device */
72+ dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
73+ PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID,
74+ PCI_ANY_ID, NULL);
75+ if (!dev) {
76+ pr_warn("malta-pm: failed to find PIIX4 PM\n");
77+ return -ENODEV;
78+ }
79+
80+ /* Request access to the PIIX4 PM IO registers */
81+ res = pci_request_region(dev, io_region, "PIIX4 PM IO registers");
82+ if (res) {
83+ pr_warn("malta-pm: failed to request PM IO registers (%d)\n",
84+ res);
85+ pci_dev_put(dev);
86+ return -ENODEV;
87+ }
88+
89+ /* Find the offset to the PIIX4 PM IO registers */
90+ pm_io_offset = pci_resource_start(dev, io_region);
91+
92+ pci_dev_put(dev);
93+ return 0;
94+}
95+
96+late_initcall(malta_pm_setup);
arch/mips/mti-malta/malta-reset.c+10−4
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010 #include <linux/pm.h>
1111
1212 #include <asm/reboot.h>
13+#include <asm/mach-malta/malta-pm.h>
1314
1415 #define SOFTRES_REG 0x1f000500
1516 #define GORESET 0x42
@@ -24,17 +25,22 @@ static void mips_machine_restart(char *command) · 8 unmodified lines
2425
2526 static void mips_machine_halt(void)
2627 {
27− unsigned int __iomem *softres_reg =
28− ioremap(SOFTRES_REG, sizeof(unsigned int));
28+ while (true);
29+}
2930
30− __raw_writel(GORESET, softres_reg);
31+static void mips_machine_power_off(void)
32+{
33+ mips_pm_suspend(PIIX4_FUNC3IO_PMCNTRL_SUS_TYP_SOFF);
34+
35+ pr_info("Failed to power down, resetting\n");
36+ mips_machine_restart(NULL);
3137 }
3238
3339 static int __init mips_reboot_setup(void)
3440 {
3541 _machine_restart = mips_machine_restart;
3642 _machine_halt = mips_machine_halt;
37− pm_power_off = mips_machine_halt;
43+ pm_power_off = mips_machine_power_off;
3844
3945 return 0;
4046 }
arch/mips/mti-malta/malta-setup.c+0−4
@@ -77,11 +77,7 @@ const char *get_system_type(void) · 76 unmodified lines
7777 return "MIPS Malta";
7878 }
7979
80−#if defined(CONFIG_MIPS_MT_SMTC)
81−const char display_string[] = " SMTC LINUX ON MALTA ";
82−#else
8380 const char display_string[] = " LINUX ON MALTA ";
84−#endif /* CONFIG_MIPS_MT_SMTC */
8581
8682 #ifdef CONFIG_BLK_DEV_FD
8783 static void __init fd_activate(void)
arch/mips/mti-malta/malta-smtc.c+0−162
@@ -1,162 +0,0 @@
1−/*
2− * Malta Platform-specific hooks for SMP operation
3− */
4−#include <linux/irq.h>
5−#include <linux/init.h>
6−
7−#include <asm/mipsregs.h>
8−#include <asm/mipsmtregs.h>
9−#include <asm/smtc.h>
10−#include <asm/smtc_ipi.h>
11−
12−/* VPE/SMP Prototype implements platform interfaces directly */
13−
14−/*
15− * Cause the specified action to be performed on a targeted "CPU"
16− */
17−
18−static void msmtc_send_ipi_single(int cpu, unsigned int action)
19−{
20− /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
21− smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
22−}
23−
24−static void msmtc_send_ipi_mask(const struct cpumask *mask, unsigned int action)
25−{
26− unsigned int i;
27−
28− for_each_cpu(i, mask)
29− msmtc_send_ipi_single(i, action);
30−}
31−
32−/*
33− * Post-config but pre-boot cleanup entry point
34− */
35−static void msmtc_init_secondary(void)
36−{
37− int myvpe;
38−
39− /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */
40− myvpe = read_c0_tcbind() & TCBIND_CURVPE;
41− if (myvpe != 0) {
42− /* Ideally, this should be done only once per VPE, but... */
43− clear_c0_status(ST0_IM);
44− set_c0_status((0x100 << cp0_compare_irq)
45− | (0x100 << MIPS_CPU_IPI_IRQ));
46− if (cp0_perfcount_irq >= 0)
47− set_c0_status(0x100 << cp0_perfcount_irq);
48− }
49−
50− smtc_init_secondary();
51−}
52−
53−/*
54− * Platform "CPU" startup hook
55− */
56−static void msmtc_boot_secondary(int cpu, struct task_struct *idle)
57−{
58− smtc_boot_secondary(cpu, idle);
59−}
60−
61−/*
62− * SMP initialization finalization entry point
63− */
64−static void msmtc_smp_finish(void)
65−{
66− smtc_smp_finish();
67−}
68−
69−/*
70− * Hook for after all CPUs are online
71− */
72−
73−static void msmtc_cpus_done(void)
74−{
75−}
76−
77−/*
78− * Platform SMP pre-initialization
79− *
80− * As noted above, we can assume a single CPU for now
81− * but it may be multithreaded.
82− */
83−
84−static void __init msmtc_smp_setup(void)
85−{
86− /*
87− * we won't get the definitive value until
88− * we've run smtc_prepare_cpus later, but
89− * we would appear to need an upper bound now.
90− */
91− smp_num_siblings = smtc_build_cpu_map(0);
92−}
93−
94−static void __init msmtc_prepare_cpus(unsigned int max_cpus)
95−{
96− smtc_prepare_cpus(max_cpus);
97−}
98−
99−struct plat_smp_ops msmtc_smp_ops = {
100− .send_ipi_single = msmtc_send_ipi_single,
101− .send_ipi_mask = msmtc_send_ipi_mask,
102− .init_secondary = msmtc_init_secondary,
103− .smp_finish = msmtc_smp_finish,
104− .cpus_done = msmtc_cpus_done,
105− .boot_secondary = msmtc_boot_secondary,
106− .smp_setup = msmtc_smp_setup,
107− .prepare_cpus = msmtc_prepare_cpus,
108−};
109−
110−#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
111−/*
112− * IRQ affinity hook
113− */
114−
115−
116−int plat_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity,
117− bool force)
118−{
119− cpumask_t tmask;
120− int cpu = 0;
121− void smtc_set_irq_affinity(unsigned int irq, cpumask_t aff);
122−
123− /*
124− * On the legacy Malta development board, all I/O interrupts
125− * are routed through the 8259 and combined in a single signal
126− * to the CPU daughterboard, and on the CoreFPGA2/3 34K models,
127− * that signal is brought to IP2 of both VPEs. To avoid racing
128− * concurrent interrupt service events, IP2 is enabled only on
129− * one VPE, by convention VPE0. So long as no bits are ever
130− * cleared in the affinity mask, there will never be any
131− * interrupt forwarding. But as soon as a program or operator
132− * sets affinity for one of the related IRQs, we need to make
133− * sure that we don't ever try to forward across the VPE boundary,
134− * at least not until we engineer a system where the interrupt
135− * _ack() or _end() function can somehow know that it corresponds
136− * to an interrupt taken on another VPE, and perform the appropriate
137− * restoration of Status.IM state using MFTR/MTTR instead of the
138− * normal local behavior. We also ensure that no attempt will
139− * be made to forward to an offline "CPU".
140− */
141−
142− cpumask_copy(&tmask, affinity);
143− for_each_cpu(cpu, affinity) {
144− if ((cpu_data[cpu].vpe_id != 0) || !cpu_online(cpu))
145− cpu_clear(cpu, tmask);
146− }
147− cpumask_copy(d->affinity, &tmask);
148−
149− if (cpus_empty(tmask))
150− /*
151− * We could restore a default mask here, but the
152− * runtime code can anyway deal with the null set
153− */
154− printk(KERN_WARNING
155− "IRQ affinity leaves no legal CPU for IRQ %d\n", d->irq);
156−
157− /* Do any generic SMTC IRQ affinity setup */
158− smtc_set_irq_affinity(d->irq, tmask);
159−
160− return IRQ_SET_MASK_OK_NOCOPY;
161−}
162−#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
arch/mips/mti-sead3/sead3-pic32-i2c-drv.c+13−23
@@ -312,16 +312,13 @@ static int i2c_platform_probe(struct platform_device *pdev) · 311 unmodified lines
312312
313313 pr_debug("i2c_platform_probe\n");
314314 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
315− if (!r) {
316− ret = -ENODEV;
317− goto out;
318− }
315+ if (!r)
316+ return -ENODEV;
319317
320− priv = kzalloc(sizeof(struct i2c_platform_data), GFP_KERNEL);
321− if (!priv) {
322− ret = -ENOMEM;
323− goto out;
324− }
318+ priv = devm_kzalloc(&pdev->dev, sizeof(struct i2c_platform_data),
319+ GFP_KERNEL);
320+ if (!priv)
321+ return -ENOMEM;
325322
326323 /* FIXME: need to allocate resource in PIC32 space */
327324 #if 0
@@ -330,10 +327,8 @@ static int i2c_platform_probe(struct platform_device *pdev) · 2 unmodified lines
330327 #else
331328 priv->base = r->start;
332329 #endif
333− if (!priv->base) {
334− ret = -EBUSY;
335− goto out_mem;
336− }
330+ if (!priv->base)
331+ return -EBUSY;
337332
338333 priv->xfer_timeout = 200;
339334 priv->ack_timeout = 200;
@@ -348,17 +343,13 @@ static int i2c_platform_probe(struct platform_device *pdev) · 8 unmodified lines
348343 i2c_platform_setup(priv);
349344
350345 ret = i2c_add_numbered_adapter(&priv->adap);
351− if (ret == 0) {
352− platform_set_drvdata(pdev, priv);
353− return 0;
346+ if (ret) {
347+ i2c_platform_disable(priv);
348+ return ret;
354349 }
355350
356− i2c_platform_disable(priv);
357−
358−out_mem:
359− kfree(priv);
360−out:
361− return ret;
351+ platform_set_drvdata(pdev, priv);
352+ return 0;
362353 }
363354
364355 static int i2c_platform_remove(struct platform_device *pdev)
@@ -369,7 +360,6 @@ static int i2c_platform_remove(struct platform_device *pdev) · 4 unmodified lines
369360 platform_set_drvdata(pdev, NULL);
370361 i2c_del_adapter(&priv->adap);
371362 i2c_platform_disable(priv);
372− kfree(priv);
373363 return 0;
374364 }
375365
arch/mips/net/Makefile+3−0
@@ -0,0 +1,3 @@
1+# MIPS networking code
2+
3+obj-$(CONFIG_BPF_JIT) += bpf_jit.o
arch/mips/net/bpf_jit.c+1399−0
@@ -0,0 +1,1399 @@
1+/*
2+ * Just-In-Time compiler for BPF filters on MIPS
3+ *
4+ * Copyright (c) 2014 Imagination Technologies Ltd.
5+ * Author: Markos Chandras <markos.chandras@imgtec.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify it
8+ * under the terms of the GNU General Public License as published by the
9+ * Free Software Foundation; version 2 of the License.
10+ */
11+
12+#include <linux/bitops.h>
13+#include <linux/compiler.h>
14+#include <linux/errno.h>
15+#include <linux/filter.h>
16+#include <linux/if_vlan.h>
17+#include <linux/kconfig.h>
18+#include <linux/moduleloader.h>
19+#include <linux/netdevice.h>
20+#include <linux/string.h>
21+#include <linux/slab.h>
22+#include <linux/types.h>
23+#include <asm/bitops.h>
24+#include <asm/cacheflush.h>
25+#include <asm/cpu-features.h>
26+#include <asm/uasm.h>
27+
28+#include "bpf_jit.h"
29+
30+/* ABI
31+ *
32+ * s0 1st scratch register
33+ * s1 2nd scratch register
34+ * s2 offset register
35+ * s3 BPF register A
36+ * s4 BPF register X
37+ * s5 *skb
38+ * s6 *scratch memory
39+ *
40+ * On entry (*bpf_func)(*skb, *filter)
41+ * a0 = MIPS_R_A0 = skb;
42+ * a1 = MIPS_R_A1 = filter;
43+ *
44+ * Stack
45+ * ...
46+ * M[15]
47+ * M[14]
48+ * M[13]
49+ * ...
50+ * M[0] <-- r_M
51+ * saved reg k-1
52+ * saved reg k-2
53+ * ...
54+ * saved reg 0 <-- r_sp
55+ * <no argument area>
56+ *
57+ * Packet layout
58+ *
59+ * <--------------------- len ------------------------>
60+ * <--skb-len(r_skb_hl)-->< ----- skb->data_len ------>
61+ * ----------------------------------------------------
62+ * | skb->data |
63+ * ----------------------------------------------------
64+ */
65+
66+#define RSIZE (sizeof(unsigned long))
67+#define ptr typeof(unsigned long)
68+
69+/* ABI specific return values */
70+#ifdef CONFIG_32BIT /* O32 */
71+#ifdef CONFIG_CPU_LITTLE_ENDIAN
72+#define r_err MIPS_R_V1
73+#define r_val MIPS_R_V0
74+#else /* CONFIG_CPU_LITTLE_ENDIAN */
75+#define r_err MIPS_R_V0
76+#define r_val MIPS_R_V1
77+#endif
78+#else /* N64 */
79+#define r_err MIPS_R_V0
80+#define r_val MIPS_R_V0
81+#endif
82+
83+#define r_ret MIPS_R_V0
84+
85+/*
86+ * Use 2 scratch registers to avoid pipeline interlocks.
87+ * There is no overhead during epilogue and prologue since
88+ * any of the $s0-$s6 registers will only be preserved if
89+ * they are going to actually be used.
90+ */
91+#define r_s0 MIPS_R_S0 /* scratch reg 1 */
92+#define r_s1 MIPS_R_S1 /* scratch reg 2 */
93+#define r_off MIPS_R_S2
94+#define r_A MIPS_R_S3
95+#define r_X MIPS_R_S4
96+#define r_skb MIPS_R_S5
97+#define r_M MIPS_R_S6
98+#define r_tmp_imm MIPS_R_T6 /* No need to preserve this */
99+#define r_tmp MIPS_R_T7 /* No need to preserve this */
100+#define r_zero MIPS_R_ZERO
101+#define r_sp MIPS_R_SP
102+#define r_ra MIPS_R_RA
103+
104+#define SCRATCH_OFF(k) (4 * (k))
105+
106+/* JIT flags */
107+#define SEEN_CALL (1 << BPF_MEMWORDS)
108+#define SEEN_SREG_SFT (BPF_MEMWORDS + 1)
109+#define SEEN_SREG_BASE (1 << SEEN_SREG_SFT)
110+#define SEEN_SREG(x) (SEEN_SREG_BASE << (x))
111+#define SEEN_S0 SEEN_SREG(0)
112+#define SEEN_S1 SEEN_SREG(1)
113+#define SEEN_OFF SEEN_SREG(2)
114+#define SEEN_A SEEN_SREG(3)
115+#define SEEN_X SEEN_SREG(4)
116+#define SEEN_SKB SEEN_SREG(5)
117+#define SEEN_MEM SEEN_SREG(6)
118+
119+/* Arguments used by JIT */
120+#define ARGS_USED_BY_JIT 2 /* only applicable to 64-bit */
121+
122+#define FLAG_NEED_X_RESET (1 << 0)
123+
124+#define SBIT(x) (1 << (x)) /* Signed version of BIT() */
125+
126+/**
127+ * struct jit_ctx - JIT context
128+ * @skf: The sk_filter
129+ * @prologue_bytes: Number of bytes for prologue
130+ * @idx: Instruction index
131+ * @flags: JIT flags
132+ * @offsets: Instruction offsets
133+ * @target: Memory location for the compiled filter
134+ */
135+struct jit_ctx {
136+ const struct sk_filter *skf;
137+ unsigned int prologue_bytes;
138+ u32 idx;
139+ u32 flags;
140+ u32 *offsets;
141+ u32 *target;
142+};
143+
144+
145+static inline int optimize_div(u32 *k)
146+{
147+ /* power of 2 divides can be implemented with right shift */
148+ if (!(*k & (*k-1))) {
149+ *k = ilog2(*k);
150+ return 1;
151+ }
152+
153+ return 0;
154+}
155+
156+/* Simply emit the instruction if the JIT memory space has been allocated */
157+#define emit_instr(ctx, func, ...) \
158+do { \
159+ if ((ctx)->target != NULL) { \
160+ u32 *p = &(ctx)->target[ctx->idx]; \
161+ uasm_i_##func(&p, ##__VA_ARGS__); \
162+ } \
163+ (ctx)->idx++; \
164+} while (0)
165+
166+/* Determine if immediate is within the 16-bit signed range */
167+static inline bool is_range16(s32 imm)
168+{
169+ if (imm >= SBIT(15) || imm < -SBIT(15))
170+ return true;
171+ return false;
172+}
173+
174+static inline void emit_addu(unsigned int dst, unsigned int src1,
175+ unsigned int src2, struct jit_ctx *ctx)
176+{
177+ emit_instr(ctx, addu, dst, src1, src2);
178+}
179+
180+static inline void emit_nop(struct jit_ctx *ctx)
181+{
182+ emit_instr(ctx, nop);
183+}
184+
185+/* Load a u32 immediate to a register */
186+static inline void emit_load_imm(unsigned int dst, u32 imm, struct jit_ctx *ctx)
187+{
188+ if (ctx->target != NULL) {
189+ /* addiu can only handle s16 */
190+ if (is_range16(imm)) {
191+ u32 *p = &ctx->target[ctx->idx];
192+ uasm_i_lui(&p, r_tmp_imm, (s32)imm >> 16);
193+ p = &ctx->target[ctx->idx + 1];
194+ uasm_i_ori(&p, dst, r_tmp_imm, imm & 0xffff);
195+ } else {
196+ u32 *p = &ctx->target[ctx->idx];
197+ uasm_i_addiu(&p, dst, r_zero, imm);
198+ }
199+ }
200+ ctx->idx++;
201+
202+ if (is_range16(imm))
203+ ctx->idx++;
204+}
205+
206+static inline void emit_or(unsigned int dst, unsigned int src1,
207+ unsigned int src2, struct jit_ctx *ctx)
208+{
209+ emit_instr(ctx, or, dst, src1, src2);
210+}
211+
212+static inline void emit_ori(unsigned int dst, unsigned src, u32 imm,
213+ struct jit_ctx *ctx)
214+{
215+ if (imm >= BIT(16)) {
216+ emit_load_imm(r_tmp, imm, ctx);
217+ emit_or(dst, src, r_tmp, ctx);
218+ } else {
219+ emit_instr(ctx, ori, dst, src, imm);
220+ }
221+}
222+
223+
224+static inline void emit_daddu(unsigned int dst, unsigned int src1,
225+ unsigned int src2, struct jit_ctx *ctx)
226+{
227+ emit_instr(ctx, daddu, dst, src1, src2);
228+}
229+
230+static inline void emit_daddiu(unsigned int dst, unsigned int src,
231+ int imm, struct jit_ctx *ctx)
232+{
233+ /*
234+ * Only used for stack, so the imm is relatively small
235+ * and it fits in 15-bits
236+ */
237+ emit_instr(ctx, daddiu, dst, src, imm);
238+}
239+
240+static inline void emit_addiu(unsigned int dst, unsigned int src,
241+ u32 imm, struct jit_ctx *ctx)
242+{
243+ if (is_range16(imm)) {
244+ emit_load_imm(r_tmp, imm, ctx);
245+ emit_addu(dst, r_tmp, src, ctx);
246+ } else {
247+ emit_instr(ctx, addiu, dst, src, imm);
248+ }
249+}
250+
251+static inline void emit_and(unsigned int dst, unsigned int src1,
252+ unsigned int src2, struct jit_ctx *ctx)
253+{
254+ emit_instr(ctx, and, dst, src1, src2);
255+}
256+
257+static inline void emit_andi(unsigned int dst, unsigned int src,
258+ u32 imm, struct jit_ctx *ctx)
259+{
260+ /* If imm does not fit in u16 then load it to register */
261+ if (imm >= BIT(16)) {
262+ emit_load_imm(r_tmp, imm, ctx);
263+ emit_and(dst, src, r_tmp, ctx);
264+ } else {
265+ emit_instr(ctx, andi, dst, src, imm);
266+ }
267+}
268+
269+static inline void emit_xor(unsigned int dst, unsigned int src1,
270+ unsigned int src2, struct jit_ctx *ctx)
271+{
272+ emit_instr(ctx, xor, dst, src1, src2);
273+}
274+
275+static inline void emit_xori(ptr dst, ptr src, u32 imm, struct jit_ctx *ctx)
276+{
277+ /* If imm does not fit in u16 then load it to register */
278+ if (imm >= BIT(16)) {
279+ emit_load_imm(r_tmp, imm, ctx);
280+ emit_xor(dst, src, r_tmp, ctx);
281+ } else {
282+ emit_instr(ctx, xori, dst, src, imm);
283+ }
284+}
285+
286+static inline void emit_stack_offset(int offset, struct jit_ctx *ctx)
287+{
288+ if (config_enabled(CONFIG_64BIT))
289+ emit_instr(ctx, daddiu, r_sp, r_sp, offset);
290+ else
291+ emit_instr(ctx, addiu, r_sp, r_sp, offset);
292+
293+}
294+
295+static inline void emit_subu(unsigned int dst, unsigned int src1,
296+ unsigned int src2, struct jit_ctx *ctx)
297+{
298+ emit_instr(ctx, subu, dst, src1, src2);
299+}
300+
301+static inline void emit_neg(unsigned int reg, struct jit_ctx *ctx)
302+{
303+ emit_subu(reg, r_zero, reg, ctx);
304+}
305+
306+static inline void emit_sllv(unsigned int dst, unsigned int src,
307+ unsigned int sa, struct jit_ctx *ctx)
308+{
309+ emit_instr(ctx, sllv, dst, src, sa);
310+}
311+
312+static inline void emit_sll(unsigned int dst, unsigned int src,
313+ unsigned int sa, struct jit_ctx *ctx)
314+{
315+ /* sa is 5-bits long */
316+ BUG_ON(sa >= BIT(5));
317+ emit_instr(ctx, sll, dst, src, sa);
318+}
319+
320+static inline void emit_srlv(unsigned int dst, unsigned int src,
321+ unsigned int sa, struct jit_ctx *ctx)
322+{
323+ emit_instr(ctx, srlv, dst, src, sa);
324+}
325+
326+static inline void emit_srl(unsigned int dst, unsigned int src,
327+ unsigned int sa, struct jit_ctx *ctx)
328+{
329+ /* sa is 5-bits long */
330+ BUG_ON(sa >= BIT(5));
331+ emit_instr(ctx, srl, dst, src, sa);
332+}
333+
334+static inline void emit_sltu(unsigned int dst, unsigned int src1,
335+ unsigned int src2, struct jit_ctx *ctx)
336+{
337+ emit_instr(ctx, sltu, dst, src1, src2);
338+}
339+
340+static inline void emit_sltiu(unsigned dst, unsigned int src,
341+ unsigned int imm, struct jit_ctx *ctx)
342+{
343+ /* 16 bit immediate */
344+ if (is_range16((s32)imm)) {
345+ emit_load_imm(r_tmp, imm, ctx);
346+ emit_sltu(dst, src, r_tmp, ctx);
347+ } else {
348+ emit_instr(ctx, sltiu, dst, src, imm);
349+ }
350+
351+}
352+
353+/* Store register on the stack */
354+static inline void emit_store_stack_reg(ptr reg, ptr base,
355+ unsigned int offset,
356+ struct jit_ctx *ctx)
357+{
358+ if (config_enabled(CONFIG_64BIT))
359+ emit_instr(ctx, sd, reg, offset, base);
360+ else
361+ emit_instr(ctx, sw, reg, offset, base);
362+}
363+
364+static inline void emit_store(ptr reg, ptr base, unsigned int offset,
365+ struct jit_ctx *ctx)
366+{
367+ emit_instr(ctx, sw, reg, offset, base);
368+}
369+
370+static inline void emit_load_stack_reg(ptr reg, ptr base,
371+ unsigned int offset,
372+ struct jit_ctx *ctx)
373+{
374+ if (config_enabled(CONFIG_64BIT))
375+ emit_instr(ctx, ld, reg, offset, base);
376+ else
377+ emit_instr(ctx, lw, reg, offset, base);
378+}
379+
380+static inline void emit_load(unsigned int reg, unsigned int base,
381+ unsigned int offset, struct jit_ctx *ctx)
382+{
383+ emit_instr(ctx, lw, reg, offset, base);
384+}
385+
386+static inline void emit_load_byte(unsigned int reg, unsigned int base,
387+ unsigned int offset, struct jit_ctx *ctx)
388+{
389+ emit_instr(ctx, lb, reg, offset, base);
390+}
391+
392+static inline void emit_half_load(unsigned int reg, unsigned int base,
393+ unsigned int offset, struct jit_ctx *ctx)
394+{
395+ emit_instr(ctx, lh, reg, offset, base);
396+}
397+
398+static inline void emit_mul(unsigned int dst, unsigned int src1,
399+ unsigned int src2, struct jit_ctx *ctx)
400+{
401+ emit_instr(ctx, mul, dst, src1, src2);
402+}
403+
404+static inline void emit_div(unsigned int dst, unsigned int src,
405+ struct jit_ctx *ctx)
406+{
407+ if (ctx->target != NULL) {
408+ u32 *p = &ctx->target[ctx->idx];
409+ uasm_i_divu(&p, dst, src);
410+ p = &ctx->target[ctx->idx + 1];
411+ uasm_i_mfhi(&p, dst);
412+ }
413+ ctx->idx += 2; /* 2 insts */
414+}
415+
416+static inline void emit_mod(unsigned int dst, unsigned int src,
417+ struct jit_ctx *ctx)
418+{
419+ if (ctx->target != NULL) {
420+ u32 *p = &ctx->target[ctx->idx];
421+ uasm_i_divu(&p, dst, src);
422+ p = &ctx->target[ctx->idx + 1];
423+ uasm_i_mflo(&p, dst);
424+ }
425+ ctx->idx += 2; /* 2 insts */
426+}
427+
428+static inline void emit_dsll(unsigned int dst, unsigned int src,
429+ unsigned int sa, struct jit_ctx *ctx)
430+{
431+ emit_instr(ctx, dsll, dst, src, sa);
432+}
433+
434+static inline void emit_dsrl32(unsigned int dst, unsigned int src,
435+ unsigned int sa, struct jit_ctx *ctx)
436+{
437+ emit_instr(ctx, dsrl32, dst, src, sa);
438+}
439+
440+static inline void emit_wsbh(unsigned int dst, unsigned int src,
441+ struct jit_ctx *ctx)
442+{
443+ emit_instr(ctx, wsbh, dst, src);
444+}
445+
446+/* load a function pointer to register */
447+static inline void emit_load_func(unsigned int reg, ptr imm,
448+ struct jit_ctx *ctx)
449+{
450+ if (config_enabled(CONFIG_64BIT)) {
451+ /* At this point imm is always 64-bit */
452+ emit_load_imm(r_tmp, (u64)imm >> 32, ctx);
453+ emit_dsll(r_tmp_imm, r_tmp, 16, ctx); /* left shift by 16 */
454+ emit_ori(r_tmp, r_tmp_imm, (imm >> 16) & 0xffff, ctx);
455+ emit_dsll(r_tmp_imm, r_tmp, 16, ctx); /* left shift by 16 */
456+ emit_ori(reg, r_tmp_imm, imm & 0xffff, ctx);
457+ } else {
458+ emit_load_imm(reg, imm, ctx);
459+ }
460+}
461+
462+/* Move to real MIPS register */
463+static inline void emit_reg_move(ptr dst, ptr src, struct jit_ctx *ctx)
464+{
465+ if (config_enabled(CONFIG_64BIT))
466+ emit_daddu(dst, src, r_zero, ctx);
467+ else
468+ emit_addu(dst, src, r_zero, ctx);
469+}
470+
471+/* Move to JIT (32-bit) register */
472+static inline void emit_jit_reg_move(ptr dst, ptr src, struct jit_ctx *ctx)
473+{
474+ emit_addu(dst, src, r_zero, ctx);
475+}
476+
477+/* Compute the immediate value for PC-relative branches. */
478+static inline u32 b_imm(unsigned int tgt, struct jit_ctx *ctx)
479+{
480+ if (ctx->target == NULL)
481+ return 0;
482+
483+ /*
484+ * We want a pc-relative branch. We only do forward branches
485+ * so tgt is always after pc. tgt is the instruction offset
486+ * we want to jump to.
487+
488+ * Branch on MIPS:
489+ * I: target_offset <- sign_extend(offset)
490+ * I+1: PC += target_offset (delay slot)
491+ *
492+ * ctx->idx currently points to the branch instruction
493+ * but the offset is added to the delay slot so we need
494+ * to subtract 4.
495+ */
496+ return ctx->offsets[tgt] -
497+ (ctx->idx * 4 - ctx->prologue_bytes) - 4;
498+}
499+
500+static inline void emit_bcond(int cond, unsigned int reg1, unsigned int reg2,
501+ unsigned int imm, struct jit_ctx *ctx)
502+{
503+ if (ctx->target != NULL) {
504+ u32 *p = &ctx->target[ctx->idx];
505+
506+ switch (cond) {
507+ case MIPS_COND_EQ:
508+ uasm_i_beq(&p, reg1, reg2, imm);
509+ break;
510+ case MIPS_COND_NE:
511+ uasm_i_bne(&p, reg1, reg2, imm);
512+ break;
513+ case MIPS_COND_ALL:
514+ uasm_i_b(&p, imm);
515+ break;
516+ default:
517+ pr_warn("%s: Unhandled branch conditional: %d\n",
518+ __func__, cond);
519+ }
520+ }
521+ ctx->idx++;
522+}
523+
524+static inline void emit_b(unsigned int imm, struct jit_ctx *ctx)
525+{
526+ emit_bcond(MIPS_COND_ALL, r_zero, r_zero, imm, ctx);
527+}
528+
529+static inline void emit_jalr(unsigned int link, unsigned int reg,
530+ struct jit_ctx *ctx)
531+{
532+ emit_instr(ctx, jalr, link, reg);
533+}
534+
535+static inline void emit_jr(unsigned int reg, struct jit_ctx *ctx)
536+{
537+ emit_instr(ctx, jr, reg);
538+}
539+
540+static inline u16 align_sp(unsigned int num)
541+{
542+ /* Double word alignment for 32-bit, quadword for 64-bit */
543+ unsigned int align = config_enabled(CONFIG_64BIT) ? 16 : 8;
544+ num = (num + (align - 1)) & -align;
545+ return num;
546+}
547+
548+static inline void update_on_xread(struct jit_ctx *ctx)
549+{
550+ if (!(ctx->flags & SEEN_X))
551+ ctx->flags |= FLAG_NEED_X_RESET;
552+
553+ ctx->flags |= SEEN_X;
554+}
555+
556+static bool is_load_to_a(u16 inst)
557+{
558+ switch (inst) {
559+ case BPF_S_LD_W_LEN:
560+ case BPF_S_LD_W_ABS:
561+ case BPF_S_LD_H_ABS:
562+ case BPF_S_LD_B_ABS:
563+ case BPF_S_ANC_CPU:
564+ case BPF_S_ANC_IFINDEX:
565+ case BPF_S_ANC_MARK:
566+ case BPF_S_ANC_PROTOCOL:
567+ case BPF_S_ANC_RXHASH:
568+ case BPF_S_ANC_VLAN_TAG:
569+ case BPF_S_ANC_VLAN_TAG_PRESENT:
570+ case BPF_S_ANC_QUEUE:
571+ return true;
572+ default:
573+ return false;
574+ }
575+}
576+
577+static void save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset)
578+{
579+ int i = 0, real_off = 0;
580+ u32 sflags, tmp_flags;
581+
582+ /* Adjust the stack pointer */
583+ emit_stack_offset(-align_sp(offset), ctx);
584+
585+ if (ctx->flags & SEEN_CALL) {
586+ /* Argument save area */
587+ if (config_enabled(CONFIG_64BIT))
588+ /* Bottom of current frame */
589+ real_off = align_sp(offset) - RSIZE;
590+ else
591+ /* Top of previous frame */
592+ real_off = align_sp(offset) + RSIZE;
593+ emit_store_stack_reg(MIPS_R_A0, r_sp, real_off, ctx);
594+ emit_store_stack_reg(MIPS_R_A1, r_sp, real_off + RSIZE, ctx);
595+
596+ real_off = 0;
597+ }
598+
599+ tmp_flags = sflags = ctx->flags >> SEEN_SREG_SFT;
600+ /* sflags is essentially a bitmap */
601+ while (tmp_flags) {
602+ if ((sflags >> i) & 0x1) {
603+ emit_store_stack_reg(MIPS_R_S0 + i, r_sp, real_off,
604+ ctx);
605+ real_off += RSIZE;
606+ }
607+ i++;
608+ tmp_flags >>= 1;
609+ }
610+
611+ /* save return address */
612+ if (ctx->flags & SEEN_CALL) {
613+ emit_store_stack_reg(r_ra, r_sp, real_off, ctx);
614+ real_off += RSIZE;
615+ }
616+
617+ /* Setup r_M leaving the alignment gap if necessary */
618+ if (ctx->flags & SEEN_MEM) {
619+ if (real_off % (RSIZE * 2))
620+ real_off += RSIZE;
621+ emit_addiu(r_M, r_sp, real_off, ctx);
622+ }
623+}
624+
625+static void restore_bpf_jit_regs(struct jit_ctx *ctx,
626+ unsigned int offset)
627+{
628+ int i, real_off = 0;
629+ u32 sflags, tmp_flags;
630+
631+ if (ctx->flags & SEEN_CALL) {
632+ if (config_enabled(CONFIG_64BIT))
633+ /* Bottom of current frame */
634+ real_off = align_sp(offset) - RSIZE;
635+ else
636+ /* Top of previous frame */
637+ real_off = align_sp(offset) + RSIZE;
638+ emit_load_stack_reg(MIPS_R_A0, r_sp, real_off, ctx);
639+ emit_load_stack_reg(MIPS_R_A1, r_sp, real_off + RSIZE, ctx);
640+
641+ real_off = 0;
642+ }
643+
644+ tmp_flags = sflags = ctx->flags >> SEEN_SREG_SFT;
645+ /* sflags is a bitmap */
646+ i = 0;
647+ while (tmp_flags) {
648+ if ((sflags >> i) & 0x1) {
649+ emit_load_stack_reg(MIPS_R_S0 + i, r_sp, real_off,
650+ ctx);
651+ real_off += RSIZE;
652+ }
653+ i++;
654+ tmp_flags >>= 1;
655+ }
656+
657+ /* restore return address */
658+ if (ctx->flags & SEEN_CALL)
659+ emit_load_stack_reg(r_ra, r_sp, real_off, ctx);
660+
661+ /* Restore the sp and discard the scrach memory */
662+ emit_stack_offset(align_sp(offset), ctx);
663+}
664+
665+static unsigned int get_stack_depth(struct jit_ctx *ctx)
666+{
667+ int sp_off = 0;
668+
669+
670+ /* How may s* regs do we need to preserved? */
671+ sp_off += hweight32(ctx->flags >> SEEN_SREG_SFT) * RSIZE;
672+
673+ if (ctx->flags & SEEN_MEM)
674+ sp_off += 4 * BPF_MEMWORDS; /* BPF_MEMWORDS are 32-bit */
675+
676+ if (ctx->flags & SEEN_CALL)
677+ /*
678+ * The JIT code make calls to external functions using 2
679+ * arguments. Therefore, for o32 we don't need to allocate
680+ * space because we don't care if the argumetns are lost
681+ * across calls. We do need however to preserve incoming
682+ * arguments but the space is already allocated for us by
683+ * the caller. On the other hand, for n64, we need to allocate
684+ * this space ourselves. We need to preserve $ra as well.
685+ */
686+ sp_off += config_enabled(CONFIG_64BIT) ?
687+ (ARGS_USED_BY_JIT + 1) * RSIZE : RSIZE;
688+
689+ /*
690+ * Subtract the bytes for the last registers since we only care about
691+ * the location on the stack pointer.
692+ */
693+ return sp_off - RSIZE;
694+}
695+
696+static void build_prologue(struct jit_ctx *ctx)
697+{
698+ u16 first_inst = ctx->skf->insns[0].code;
699+ int sp_off;
700+
701+ /* Calculate the total offset for the stack pointer */
702+ sp_off = get_stack_depth(ctx);
703+ save_bpf_jit_regs(ctx, sp_off);
704+
705+ if (ctx->flags & SEEN_SKB)
706+ emit_reg_move(r_skb, MIPS_R_A0, ctx);
707+
708+ if (ctx->flags & FLAG_NEED_X_RESET)
709+ emit_jit_reg_move(r_X, r_zero, ctx);
710+
711+ /* Do not leak kernel data to userspace */
712+ if ((first_inst != BPF_S_RET_K) && !(is_load_to_a(first_inst)))
713+ emit_jit_reg_move(r_A, r_zero, ctx);
714+}
715+
716+static void build_epilogue(struct jit_ctx *ctx)
717+{
718+ unsigned int sp_off;
719+
720+ /* Calculate the total offset for the stack pointer */
721+
722+ sp_off = get_stack_depth(ctx);
723+ restore_bpf_jit_regs(ctx, sp_off);
724+
725+ /* Return */
726+ emit_jr(r_ra, ctx);
727+ emit_nop(ctx);
728+}
729+
730+static u64 jit_get_skb_b(struct sk_buff *skb, unsigned offset)
731+{
732+ u8 ret;
733+ int err;
734+
735+ err = skb_copy_bits(skb, offset, &ret, 1);
736+
737+ return (u64)err << 32 | ret;
738+}
739+
740+static u64 jit_get_skb_h(struct sk_buff *skb, unsigned offset)
741+{
742+ u16 ret;
743+ int err;
744+
745+ err = skb_copy_bits(skb, offset, &ret, 2);
746+
747+ return (u64)err << 32 | ntohs(ret);
748+}
749+
750+static u64 jit_get_skb_w(struct sk_buff *skb, unsigned offset)
751+{
752+ u32 ret;
753+ int err;
754+
755+ err = skb_copy_bits(skb, offset, &ret, 4);
756+
757+ return (u64)err << 32 | ntohl(ret);
758+}
759+
760+#define PKT_TYPE_MAX 7
761+static int pkt_type_offset(void)
762+{
763+ struct sk_buff skb_probe = {
764+ .pkt_type = ~0,
765+ };
766+ char *ct = (char *)&skb_probe;
767+ unsigned int off;
768+
769+ for (off = 0; off < sizeof(struct sk_buff); off++) {
770+ if (ct[off] == PKT_TYPE_MAX)
771+ return off;
772+ }
773+ pr_err_once("Please fix pkt_type_offset(), as pkt_type couldn't be found\n");
774+ return -1;
775+}
776+
777+static int build_body(struct jit_ctx *ctx)
778+{
779+ void *load_func[] = {jit_get_skb_b, jit_get_skb_h, jit_get_skb_w};
780+ const struct sk_filter *prog = ctx->skf;
781+ const struct sock_filter *inst;
782+ unsigned int i, off, load_order, condt;
783+ u32 k, b_off __maybe_unused;
784+
785+ for (i = 0; i < prog->len; i++) {
786+ inst = &(prog->insns[i]);
787+ pr_debug("%s: code->0x%02x, jt->0x%x, jf->0x%x, k->0x%x\n",
788+ __func__, inst->code, inst->jt, inst->jf, inst->k);
789+ k = inst->k;
790+
791+ if (ctx->target == NULL)
792+ ctx->offsets[i] = ctx->idx * 4;
793+
794+ switch (inst->code) {
795+ case BPF_S_LD_IMM:
796+ /* A <- k ==> li r_A, k */
797+ ctx->flags |= SEEN_A;
798+ emit_load_imm(r_A, k, ctx);
799+ break;
800+ case BPF_S_LD_W_LEN:
801+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
802+ /* A <- len ==> lw r_A, offset(skb) */
803+ ctx->flags |= SEEN_SKB | SEEN_A;
804+ off = offsetof(struct sk_buff, len);
805+ emit_load(r_A, r_skb, off, ctx);
806+ break;
807+ case BPF_S_LD_MEM:
808+ /* A <- M[k] ==> lw r_A, offset(M) */
809+ ctx->flags |= SEEN_MEM | SEEN_A;
810+ emit_load(r_A, r_M, SCRATCH_OFF(k), ctx);
811+ break;
812+ case BPF_S_LD_W_ABS:
813+ /* A <- P[k:4] */
814+ load_order = 2;
815+ goto load;
816+ case BPF_S_LD_H_ABS:
817+ /* A <- P[k:2] */
818+ load_order = 1;
819+ goto load;
820+ case BPF_S_LD_B_ABS:
821+ /* A <- P[k:1] */
822+ load_order = 0;
823+load:
824+ emit_load_imm(r_off, k, ctx);
825+load_common:
826+ ctx->flags |= SEEN_CALL | SEEN_OFF | SEEN_S0 |
827+ SEEN_SKB | SEEN_A;
828+
829+ emit_load_func(r_s0, (ptr)load_func[load_order],
830+ ctx);
831+ emit_reg_move(MIPS_R_A0, r_skb, ctx);
832+ emit_jalr(MIPS_R_RA, r_s0, ctx);
833+ /* Load second argument to delay slot */
834+ emit_reg_move(MIPS_R_A1, r_off, ctx);
835+ /* Check the error value */
836+ if (config_enabled(CONFIG_64BIT)) {
837+ /* Get error code from the top 32-bits */
838+ emit_dsrl32(r_s0, r_val, 0, ctx);
839+ /* Branch to 3 instructions ahead */
840+ emit_bcond(MIPS_COND_NE, r_s0, r_zero, 3 << 2,
841+ ctx);
842+ } else {
843+ /* Branch to 3 instructions ahead */
844+ emit_bcond(MIPS_COND_NE, r_err, r_zero, 3 << 2,
845+ ctx);
846+ }
847+ emit_nop(ctx);
848+ /* We are good */
849+ emit_b(b_imm(i + 1, ctx), ctx);
850+ emit_jit_reg_move(r_A, r_val, ctx);
851+ /* Return with error */
852+ emit_b(b_imm(prog->len, ctx), ctx);
853+ emit_reg_move(r_ret, r_zero, ctx);
854+ break;
855+ case BPF_S_LD_W_IND:
856+ /* A <- P[X + k:4] */
857+ load_order = 2;
858+ goto load_ind;
859+ case BPF_S_LD_H_IND:
860+ /* A <- P[X + k:2] */
861+ load_order = 1;
862+ goto load_ind;
863+ case BPF_S_LD_B_IND:
864+ /* A <- P[X + k:1] */
865+ load_order = 0;
866+load_ind:
867+ update_on_xread(ctx);
868+ ctx->flags |= SEEN_OFF | SEEN_X;
869+ emit_addiu(r_off, r_X, k, ctx);
870+ goto load_common;
871+ case BPF_S_LDX_IMM:
872+ /* X <- k */
873+ ctx->flags |= SEEN_X;
874+ emit_load_imm(r_X, k, ctx);
875+ break;
876+ case BPF_S_LDX_MEM:
877+ /* X <- M[k] */
878+ ctx->flags |= SEEN_X | SEEN_MEM;
879+ emit_load(r_X, r_M, SCRATCH_OFF(k), ctx);
880+ break;
881+ case BPF_S_LDX_W_LEN:
882+ /* X <- len */
883+ ctx->flags |= SEEN_X | SEEN_SKB;
884+ off = offsetof(struct sk_buff, len);
885+ emit_load(r_X, r_skb, off, ctx);
886+ break;
887+ case BPF_S_LDX_B_MSH:
888+ /* X <- 4 * (P[k:1] & 0xf) */
889+ ctx->flags |= SEEN_X | SEEN_CALL | SEEN_S0 | SEEN_SKB;
890+ /* Load offset to a1 */
891+ emit_load_func(r_s0, (ptr)jit_get_skb_b, ctx);
892+ /*
893+ * This may emit two instructions so it may not fit
894+ * in the delay slot. So use a0 in the delay slot.
895+ */
896+ emit_load_imm(MIPS_R_A1, k, ctx);
897+ emit_jalr(MIPS_R_RA, r_s0, ctx);
898+ emit_reg_move(MIPS_R_A0, r_skb, ctx); /* delay slot */
899+ /* Check the error value */
900+ if (config_enabled(CONFIG_64BIT)) {
901+ /* Top 32-bits of $v0 on 64-bit */
902+ emit_dsrl32(r_s0, r_val, 0, ctx);
903+ emit_bcond(MIPS_COND_NE, r_s0, r_zero,
904+ 3 << 2, ctx);
905+ } else {
906+ emit_bcond(MIPS_COND_NE, r_err, r_zero,
907+ 3 << 2, ctx);
908+ }
909+ /* No need for delay slot */
910+ /* We are good */
911+ /* X <- P[1:K] & 0xf */
912+ emit_andi(r_X, r_val, 0xf, ctx);
913+ /* X << 2 */
914+ emit_b(b_imm(i + 1, ctx), ctx);
915+ emit_sll(r_X, r_X, 2, ctx); /* delay slot */
916+ /* Return with error */
917+ emit_b(b_imm(prog->len, ctx), ctx);
918+ emit_load_imm(r_ret, 0, ctx); /* delay slot */
919+ break;
920+ case BPF_S_ST:
921+ /* M[k] <- A */
922+ ctx->flags |= SEEN_MEM | SEEN_A;
923+ emit_store(r_A, r_M, SCRATCH_OFF(k), ctx);
924+ break;
925+ case BPF_S_STX:
926+ /* M[k] <- X */
927+ ctx->flags |= SEEN_MEM | SEEN_X;
928+ emit_store(r_X, r_M, SCRATCH_OFF(k), ctx);
929+ break;
930+ case BPF_S_ALU_ADD_K:
931+ /* A += K */
932+ ctx->flags |= SEEN_A;
933+ emit_addiu(r_A, r_A, k, ctx);
934+ break;
935+ case BPF_S_ALU_ADD_X:
936+ /* A += X */
937+ ctx->flags |= SEEN_A | SEEN_X;
938+ emit_addu(r_A, r_A, r_X, ctx);
939+ break;
940+ case BPF_S_ALU_SUB_K:
941+ /* A -= K */
942+ ctx->flags |= SEEN_A;
943+ emit_addiu(r_A, r_A, -k, ctx);
944+ break;
945+ case BPF_S_ALU_SUB_X:
946+ /* A -= X */
947+ ctx->flags |= SEEN_A | SEEN_X;
948+ emit_subu(r_A, r_A, r_X, ctx);
949+ break;
950+ case BPF_S_ALU_MUL_K:
951+ /* A *= K */
952+ /* Load K to scratch register before MUL */
953+ ctx->flags |= SEEN_A | SEEN_S0;
954+ emit_load_imm(r_s0, k, ctx);
955+ emit_mul(r_A, r_A, r_s0, ctx);
956+ break;
957+ case BPF_S_ALU_MUL_X:
958+ /* A *= X */
959+ update_on_xread(ctx);
960+ ctx->flags |= SEEN_A | SEEN_X;
961+ emit_mul(r_A, r_A, r_X, ctx);
962+ break;
963+ case BPF_S_ALU_DIV_K:
964+ /* A /= k */
965+ if (k == 1)
966+ break;
967+ if (optimize_div(&k)) {
968+ ctx->flags |= SEEN_A;
969+ emit_srl(r_A, r_A, k, ctx);
970+ break;
971+ }
972+ ctx->flags |= SEEN_A | SEEN_S0;
973+ emit_load_imm(r_s0, k, ctx);
974+ emit_div(r_A, r_s0, ctx);
975+ break;
976+ case BPF_S_ALU_MOD_K:
977+ /* A %= k */
978+ if (k == 1 || optimize_div(&k)) {
979+ ctx->flags |= SEEN_A;
980+ emit_jit_reg_move(r_A, r_zero, ctx);
981+ } else {
982+ ctx->flags |= SEEN_A | SEEN_S0;
983+ emit_load_imm(r_s0, k, ctx);
984+ emit_mod(r_A, r_s0, ctx);
985+ }
986+ break;
987+ case BPF_S_ALU_DIV_X:
988+ /* A /= X */
989+ update_on_xread(ctx);
990+ ctx->flags |= SEEN_X | SEEN_A;
991+ /* Check if r_X is zero */
992+ emit_bcond(MIPS_COND_EQ, r_X, r_zero,
993+ b_imm(prog->len, ctx), ctx);
994+ emit_load_imm(r_val, 0, ctx); /* delay slot */
995+ emit_div(r_A, r_X, ctx);
996+ break;
997+ case BPF_S_ALU_MOD_X:
998+ /* A %= X */
999+ update_on_xread(ctx);
1000+ ctx->flags |= SEEN_X | SEEN_A;
1001+ /* Check if r_X is zero */
1002+ emit_bcond(MIPS_COND_EQ, r_X, r_zero,
1003+ b_imm(prog->len, ctx), ctx);
1004+ emit_load_imm(r_val, 0, ctx); /* delay slot */
1005+ emit_mod(r_A, r_X, ctx);
1006+ break;
1007+ case BPF_S_ALU_OR_K:
1008+ /* A |= K */
1009+ ctx->flags |= SEEN_A;
1010+ emit_ori(r_A, r_A, k, ctx);
1011+ break;
1012+ case BPF_S_ALU_OR_X:
1013+ /* A |= X */
1014+ update_on_xread(ctx);
1015+ ctx->flags |= SEEN_A;
1016+ emit_ori(r_A, r_A, r_X, ctx);
1017+ break;
1018+ case BPF_S_ALU_XOR_K:
1019+ /* A ^= k */
1020+ ctx->flags |= SEEN_A;
1021+ emit_xori(r_A, r_A, k, ctx);
1022+ break;
1023+ case BPF_S_ANC_ALU_XOR_X:
1024+ case BPF_S_ALU_XOR_X:
1025+ /* A ^= X */
1026+ update_on_xread(ctx);
1027+ ctx->flags |= SEEN_A;
1028+ emit_xor(r_A, r_A, r_X, ctx);
1029+ break;
1030+ case BPF_S_ALU_AND_K:
1031+ /* A &= K */
1032+ ctx->flags |= SEEN_A;
1033+ emit_andi(r_A, r_A, k, ctx);
1034+ break;
1035+ case BPF_S_ALU_AND_X:
1036+ /* A &= X */
1037+ update_on_xread(ctx);
1038+ ctx->flags |= SEEN_A | SEEN_X;
1039+ emit_and(r_A, r_A, r_X, ctx);
1040+ break;
1041+ case BPF_S_ALU_LSH_K:
1042+ /* A <<= K */
1043+ ctx->flags |= SEEN_A;
1044+ emit_sll(r_A, r_A, k, ctx);
1045+ break;
1046+ case BPF_S_ALU_LSH_X:
1047+ /* A <<= X */
1048+ ctx->flags |= SEEN_A | SEEN_X;
1049+ update_on_xread(ctx);
1050+ emit_sllv(r_A, r_A, r_X, ctx);
1051+ break;
1052+ case BPF_S_ALU_RSH_K:
1053+ /* A >>= K */
1054+ ctx->flags |= SEEN_A;
1055+ emit_srl(r_A, r_A, k, ctx);
1056+ break;
1057+ case BPF_S_ALU_RSH_X:
1058+ ctx->flags |= SEEN_A | SEEN_X;
1059+ update_on_xread(ctx);
1060+ emit_srlv(r_A, r_A, r_X, ctx);
1061+ break;
1062+ case BPF_S_ALU_NEG:
1063+ /* A = -A */
1064+ ctx->flags |= SEEN_A;
1065+ emit_neg(r_A, ctx);
1066+ break;
1067+ case BPF_S_JMP_JA:
1068+ /* pc += K */
1069+ emit_b(b_imm(i + k + 1, ctx), ctx);
1070+ emit_nop(ctx);
1071+ break;
1072+ case BPF_S_JMP_JEQ_K:
1073+ /* pc += ( A == K ) ? pc->jt : pc->jf */
1074+ condt = MIPS_COND_EQ | MIPS_COND_K;
1075+ goto jmp_cmp;
1076+ case BPF_S_JMP_JEQ_X:
1077+ ctx->flags |= SEEN_X;
1078+ /* pc += ( A == X ) ? pc->jt : pc->jf */
1079+ condt = MIPS_COND_EQ | MIPS_COND_X;
1080+ goto jmp_cmp;
1081+ case BPF_S_JMP_JGE_K:
1082+ /* pc += ( A >= K ) ? pc->jt : pc->jf */
1083+ condt = MIPS_COND_GE | MIPS_COND_K;
1084+ goto jmp_cmp;
1085+ case BPF_S_JMP_JGE_X:
1086+ ctx->flags |= SEEN_X;
1087+ /* pc += ( A >= X ) ? pc->jt : pc->jf */
1088+ condt = MIPS_COND_GE | MIPS_COND_X;
1089+ goto jmp_cmp;
1090+ case BPF_S_JMP_JGT_K:
1091+ /* pc += ( A > K ) ? pc->jt : pc->jf */
1092+ condt = MIPS_COND_GT | MIPS_COND_K;
1093+ goto jmp_cmp;
1094+ case BPF_S_JMP_JGT_X:
1095+ ctx->flags |= SEEN_X;
1096+ /* pc += ( A > X ) ? pc->jt : pc->jf */
1097+ condt = MIPS_COND_GT | MIPS_COND_X;
1098+jmp_cmp:
1099+ /* Greater or Equal */
1100+ if ((condt & MIPS_COND_GE) ||
1101+ (condt & MIPS_COND_GT)) {
1102+ if (condt & MIPS_COND_K) { /* K */
1103+ ctx->flags |= SEEN_S0 | SEEN_A;
1104+ emit_sltiu(r_s0, r_A, k, ctx);
1105+ } else { /* X */
1106+ ctx->flags |= SEEN_S0 | SEEN_A |
1107+ SEEN_X;
1108+ emit_sltu(r_s0, r_A, r_X, ctx);
1109+ }
1110+ /* A < (K|X) ? r_scrach = 1 */
1111+ b_off = b_imm(i + inst->jf + 1, ctx);
1112+ emit_bcond(MIPS_COND_GT, r_s0, r_zero, b_off,
1113+ ctx);
1114+ emit_nop(ctx);
1115+ /* A > (K|X) ? scratch = 0 */
1116+ if (condt & MIPS_COND_GT) {
1117+ /* Checking for equality */
1118+ ctx->flags |= SEEN_S0 | SEEN_A | SEEN_X;
1119+ if (condt & MIPS_COND_K)
1120+ emit_load_imm(r_s0, k, ctx);
1121+ else
1122+ emit_jit_reg_move(r_s0, r_X,
1123+ ctx);
1124+ b_off = b_imm(i + inst->jf + 1, ctx);
1125+ emit_bcond(MIPS_COND_EQ, r_A, r_s0,
1126+ b_off, ctx);
1127+ emit_nop(ctx);
1128+ /* Finally, A > K|X */
1129+ b_off = b_imm(i + inst->jt + 1, ctx);
1130+ emit_b(b_off, ctx);
1131+ emit_nop(ctx);
1132+ } else {
1133+ /* A >= (K|X) so jump */
1134+ b_off = b_imm(i + inst->jt + 1, ctx);
1135+ emit_b(b_off, ctx);
1136+ emit_nop(ctx);
1137+ }
1138+ } else {
1139+ /* A == K|X */
1140+ if (condt & MIPS_COND_K) { /* K */
1141+ ctx->flags |= SEEN_S0 | SEEN_A;
1142+ emit_load_imm(r_s0, k, ctx);
1143+ /* jump true */
1144+ b_off = b_imm(i + inst->jt + 1, ctx);
1145+ emit_bcond(MIPS_COND_EQ, r_A, r_s0,
1146+ b_off, ctx);
1147+ emit_nop(ctx);
1148+ /* jump false */
1149+ b_off = b_imm(i + inst->jf + 1,
1150+ ctx);
1151+ emit_bcond(MIPS_COND_NE, r_A, r_s0,
1152+ b_off, ctx);
1153+ emit_nop(ctx);
1154+ } else { /* X */
1155+ /* jump true */
1156+ ctx->flags |= SEEN_A | SEEN_X;
1157+ b_off = b_imm(i + inst->jt + 1,
1158+ ctx);
1159+ emit_bcond(MIPS_COND_EQ, r_A, r_X,
1160+ b_off, ctx);
1161+ emit_nop(ctx);
1162+ /* jump false */
1163+ b_off = b_imm(i + inst->jf + 1, ctx);
1164+ emit_bcond(MIPS_COND_NE, r_A, r_X,
1165+ b_off, ctx);
1166+ emit_nop(ctx);
1167+ }
1168+ }
1169+ break;
1170+ case BPF_S_JMP_JSET_K:
1171+ ctx->flags |= SEEN_S0 | SEEN_S1 | SEEN_A;
1172+ /* pc += (A & K) ? pc -> jt : pc -> jf */
1173+ emit_load_imm(r_s1, k, ctx);
1174+ emit_and(r_s0, r_A, r_s1, ctx);
1175+ /* jump true */
1176+ b_off = b_imm(i + inst->jt + 1, ctx);
1177+ emit_bcond(MIPS_COND_NE, r_s0, r_zero, b_off, ctx);
1178+ emit_nop(ctx);
1179+ /* jump false */
1180+ b_off = b_imm(i + inst->jf + 1, ctx);
1181+ emit_b(b_off, ctx);
1182+ emit_nop(ctx);
1183+ break;
1184+ case BPF_S_JMP_JSET_X:
1185+ ctx->flags |= SEEN_S0 | SEEN_X | SEEN_A;
1186+ /* pc += (A & X) ? pc -> jt : pc -> jf */
1187+ emit_and(r_s0, r_A, r_X, ctx);
1188+ /* jump true */
1189+ b_off = b_imm(i + inst->jt + 1, ctx);
1190+ emit_bcond(MIPS_COND_NE, r_s0, r_zero, b_off, ctx);
1191+ emit_nop(ctx);
1192+ /* jump false */
1193+ b_off = b_imm(i + inst->jf + 1, ctx);
1194+ emit_b(b_off, ctx);
1195+ emit_nop(ctx);
1196+ break;
1197+ case BPF_S_RET_A:
1198+ ctx->flags |= SEEN_A;
1199+ if (i != prog->len - 1)
1200+ /*
1201+ * If this is not the last instruction
1202+ * then jump to the epilogue
1203+ */
1204+ emit_b(b_imm(prog->len, ctx), ctx);
1205+ emit_reg_move(r_ret, r_A, ctx); /* delay slot */
1206+ break;
1207+ case BPF_S_RET_K:
1208+ /*
1209+ * It can emit two instructions so it does not fit on
1210+ * the delay slot.
1211+ */
1212+ emit_load_imm(r_ret, k, ctx);
1213+ if (i != prog->len - 1) {
1214+ /*
1215+ * If this is not the last instruction
1216+ * then jump to the epilogue
1217+ */
1218+ emit_b(b_imm(prog->len, ctx), ctx);
1219+ emit_nop(ctx);
1220+ }
1221+ break;
1222+ case BPF_S_MISC_TAX:
1223+ /* X = A */
1224+ ctx->flags |= SEEN_X | SEEN_A;
1225+ emit_jit_reg_move(r_X, r_A, ctx);
1226+ break;
1227+ case BPF_S_MISC_TXA:
1228+ /* A = X */
1229+ ctx->flags |= SEEN_A | SEEN_X;
1230+ update_on_xread(ctx);
1231+ emit_jit_reg_move(r_A, r_X, ctx);
1232+ break;
1233+ /* AUX */
1234+ case BPF_S_ANC_PROTOCOL:
1235+ /* A = ntohs(skb->protocol */
1236+ ctx->flags |= SEEN_SKB | SEEN_OFF | SEEN_A;
1237+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
1238+ protocol) != 2);
1239+ off = offsetof(struct sk_buff, protocol);
1240+ emit_half_load(r_A, r_skb, off, ctx);
1241+#ifdef CONFIG_CPU_LITTLE_ENDIAN
1242+ /* This needs little endian fixup */
1243+ if (cpu_has_mips_r2) {
1244+ /* R2 and later have the wsbh instruction */
1245+ emit_wsbh(r_A, r_A, ctx);
1246+ } else {
1247+ /* Get first byte */
1248+ emit_andi(r_tmp_imm, r_A, 0xff, ctx);
1249+ /* Shift it */
1250+ emit_sll(r_tmp, r_tmp_imm, 8, ctx);
1251+ /* Get second byte */
1252+ emit_srl(r_tmp_imm, r_A, 8, ctx);
1253+ emit_andi(r_tmp_imm, r_tmp_imm, 0xff, ctx);
1254+ /* Put everyting together in r_A */
1255+ emit_or(r_A, r_tmp, r_tmp_imm, ctx);
1256+ }
1257+#endif
1258+ break;
1259+ case BPF_S_ANC_CPU:
1260+ ctx->flags |= SEEN_A | SEEN_OFF;
1261+ /* A = current_thread_info()->cpu */
1262+ BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info,
1263+ cpu) != 4);
1264+ off = offsetof(struct thread_info, cpu);
1265+ /* $28/gp points to the thread_info struct */
1266+ emit_load(r_A, 28, off, ctx);
1267+ break;
1268+ case BPF_S_ANC_IFINDEX:
1269+ /* A = skb->dev->ifindex */
1270+ ctx->flags |= SEEN_SKB | SEEN_A | SEEN_S0;
1271+ off = offsetof(struct sk_buff, dev);
1272+ emit_load(r_s0, r_skb, off, ctx);
1273+ /* error (0) in the delay slot */
1274+ emit_bcond(MIPS_COND_EQ, r_s0, r_zero,
1275+ b_imm(prog->len, ctx), ctx);
1276+ emit_reg_move(r_ret, r_zero, ctx);
1277+ BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
1278+ ifindex) != 4);
1279+ off = offsetof(struct net_device, ifindex);
1280+ emit_load(r_A, r_s0, off, ctx);
1281+ break;
1282+ case BPF_S_ANC_MARK:
1283+ ctx->flags |= SEEN_SKB | SEEN_A;
1284+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
1285+ off = offsetof(struct sk_buff, mark);
1286+ emit_load(r_A, r_skb, off, ctx);
1287+ break;
1288+ case BPF_S_ANC_RXHASH:
1289+ ctx->flags |= SEEN_SKB | SEEN_A;
1290+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4);
1291+ off = offsetof(struct sk_buff, hash);
1292+ emit_load(r_A, r_skb, off, ctx);
1293+ break;
1294+ case BPF_S_ANC_VLAN_TAG:
1295+ case BPF_S_ANC_VLAN_TAG_PRESENT:
1296+ ctx->flags |= SEEN_SKB | SEEN_S0 | SEEN_A;
1297+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
1298+ vlan_tci) != 2);
1299+ off = offsetof(struct sk_buff, vlan_tci);
1300+ emit_half_load(r_s0, r_skb, off, ctx);
1301+ if (inst->code == BPF_S_ANC_VLAN_TAG)
1302+ emit_and(r_A, r_s0, VLAN_VID_MASK, ctx);
1303+ else
1304+ emit_and(r_A, r_s0, VLAN_TAG_PRESENT, ctx);
1305+ break;
1306+ case BPF_S_ANC_PKTTYPE:
1307+ off = pkt_type_offset();
1308+
1309+ if (off < 0)
1310+ return -1;
1311+ emit_load_byte(r_tmp, r_skb, off, ctx);
1312+ /* Keep only the last 3 bits */
1313+ emit_andi(r_A, r_tmp, PKT_TYPE_MAX, ctx);
1314+ break;
1315+ case BPF_S_ANC_QUEUE:
1316+ ctx->flags |= SEEN_SKB | SEEN_A;
1317+ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
1318+ queue_mapping) != 2);
1319+ BUILD_BUG_ON(offsetof(struct sk_buff,
1320+ queue_mapping) > 0xff);
1321+ off = offsetof(struct sk_buff, queue_mapping);
1322+ emit_half_load(r_A, r_skb, off, ctx);
1323+ break;
1324+ default:
1325+ pr_warn("%s: Unhandled opcode: 0x%02x\n", __FILE__,
1326+ inst->code);
1327+ return -1;
1328+ }
1329+ }
1330+
1331+ /* compute offsets only during the first pass */
1332+ if (ctx->target == NULL)
1333+ ctx->offsets[i] = ctx->idx * 4;
1334+
1335+ return 0;
1336+}
1337+
1338+int bpf_jit_enable __read_mostly;
1339+
1340+void bpf_jit_compile(struct sk_filter *fp)
1341+{
1342+ struct jit_ctx ctx;
1343+ unsigned int alloc_size, tmp_idx;
1344+
1345+ if (!bpf_jit_enable)
1346+ return;
1347+
1348+ memset(&ctx, 0, sizeof(ctx));
1349+
1350+ ctx.offsets = kcalloc(fp->len, sizeof(*ctx.offsets), GFP_KERNEL);
1351+ if (ctx.offsets == NULL)
1352+ return;
1353+
1354+ ctx.skf = fp;
1355+
1356+ if (build_body(&ctx))
1357+ goto out;
1358+
1359+ tmp_idx = ctx.idx;
1360+ build_prologue(&ctx);
1361+ ctx.prologue_bytes = (ctx.idx - tmp_idx) * 4;
1362+ /* just to complete the ctx.idx count */
1363+ build_epilogue(&ctx);
1364+
1365+ alloc_size = 4 * ctx.idx;
1366+ ctx.target = module_alloc(alloc_size);
1367+ if (ctx.target == NULL)
1368+ goto out;
1369+
1370+ /* Clean it */
1371+ memset(ctx.target, 0, alloc_size);
1372+
1373+ ctx.idx = 0;
1374+
1375+ /* Generate the actual JIT code */
1376+ build_prologue(&ctx);
1377+ build_body(&ctx);
1378+ build_epilogue(&ctx);
1379+
1380+ /* Update the icache */
1381+ flush_icache_range((ptr)ctx.target, (ptr)(ctx.target + ctx.idx));
1382+
1383+ if (bpf_jit_enable > 1)
1384+ /* Dump JIT code */
1385+ bpf_jit_dump(fp->len, alloc_size, 2, ctx.target);
1386+
1387+ fp->bpf_func = (void *)ctx.target;
1388+ fp->jited = 1;
1389+
1390+out:
1391+ kfree(ctx.offsets);
1392+}
1393+
1394+void bpf_jit_free(struct sk_filter *fp)
1395+{
1396+ if (fp->jited)
1397+ module_free(NULL, fp->bpf_func);
1398+ kfree(fp);
1399+}
arch/mips/net/bpf_jit.h+44−0
@@ -0,0 +1,44 @@
1+/*
2+ * Just-In-Time compiler for BPF filters on MIPS
3+ *
4+ * Copyright (c) 2014 Imagination Technologies Ltd.
5+ * Author: Markos Chandras <markos.chandras@imgtec.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify it
8+ * under the terms of the GNU General Public License as published by the
9+ * Free Software Foundation; version 2 of the License.
10+ */
11+
12+#ifndef BPF_JIT_MIPS_OP_H
13+#define BPF_JIT_MIPS_OP_H
14+
15+/* Registers used by JIT */
16+#define MIPS_R_ZERO 0
17+#define MIPS_R_V0 2
18+#define MIPS_R_V1 3
19+#define MIPS_R_A0 4
20+#define MIPS_R_A1 5
21+#define MIPS_R_T6 14
22+#define MIPS_R_T7 15
23+#define MIPS_R_S0 16
24+#define MIPS_R_S1 17
25+#define MIPS_R_S2 18
26+#define MIPS_R_S3 19
27+#define MIPS_R_S4 20
28+#define MIPS_R_S5 21
29+#define MIPS_R_S6 22
30+#define MIPS_R_S7 23
31+#define MIPS_R_SP 29
32+#define MIPS_R_RA 31
33+
34+/* Conditional codes */
35+#define MIPS_COND_EQ 0x1
36+#define MIPS_COND_GE (0x1 << 1)
37+#define MIPS_COND_GT (0x1 << 2)
38+#define MIPS_COND_NE (0x1 << 3)
39+#define MIPS_COND_ALL (0x1 << 4)
40+/* Conditionals on X register or K immediate */
41+#define MIPS_COND_X (0x1 << 5)
42+#define MIPS_COND_K (0x1 << 6)
43+
44+#endif /* BPF_JIT_MIPS_OP_H */
arch/mips/netlogic/common/irq.c+2−0
@@ -203,6 +203,8 @@ void nlm_set_pic_extra_ack(int node, int irq, void (*xack)(struct irq_data *)) · 202 unmodified lines
203203
204204 xirq = nlm_irq_to_xirq(node, irq);
205205 pic_data = irq_get_handler_data(xirq);
206+ if (WARN_ON(!pic_data))
207+ return;
206208 pic_data->extra_ack = xack;
207209 }
208210
arch/mips/netlogic/common/reset.S+30−9
@@ -35,6 +35,7 @@ · 34 unmodified lines
3535
3636 #include <asm/asm.h>
3737 #include <asm/asm-offsets.h>
38+#include <asm/cpu.h>
3839 #include <asm/cacheops.h>
3940 #include <asm/regdef.h>
4041 #include <asm/mipsregs.h>
@@ -73,6 +74,18 @@ · 32 unmodified lines
7374 mtcr t1, t0
7475 .endm
7576
77+/*
78+ * Allow access to physical mem >64G by enabling ELPA in PAGEGRAIN
79+ * register. This is needed before going to C code since the SP can
80+ * in this region. Called from all HW threads.
81+ */
82+.macro xlp_early_mmu_init
83+ mfc0 t0, CP0_PAGEMASK, 1
84+ li t1, (1 << 29) /* ELPA bit */
85+ or t0, t1
86+ mtc0 t0, CP0_PAGEMASK, 1
87+.endm
88+
7689 /*
7790 * L1D cache has to be flushed before enabling threads in XLP.
7891 * On XLP8xx/XLP3xx, we do a low level flush using processor control
@@ -80,7 +93,7 @@ · 1 unmodified line
8093 */
8194 .macro xlp_flush_l1_dcache
8295 mfc0 t0, CP0_EBASE, 0
83− andi t0, t0, 0xff00
96+ andi t0, t0, PRID_IMP_MASK
8497 slt t1, t0, 0x1200
8598 beqz t1, 15f
8699 nop
@@ -159,11 +172,15 @@ FEXPORT(nlm_reset_entry) · 72 unmodified lines
159172
160173 1: /* Entry point on core wakeup */
161174 mfc0 t0, CP0_EBASE, 0 /* processor ID */
162− andi t0, 0xff00
175+ andi t0, PRID_IMP_MASK
163176 li t1, 0x1500 /* XLP 9xx */
164177 beq t0, t1, 2f /* does not need to set coherent */
165178 nop
166179
180+ li t1, 0x1300 /* XLP 5xx */
181+ beq t0, t1, 2f /* does not need to set coherent */
182+ nop
183+
167184 /* set bit in SYS coherent register for the core */
168185 mfc0 t0, CP0_EBASE, 1
169186 mfc0 t1, CP0_EBASE, 1
@@ -197,6 +214,9 @@ FEXPORT(nlm_reset_entry) · 27 unmodified lines
197214 EXPORT(nlm_boot_siblings)
198215 /* core L1D flush before enable threads */
199216 xlp_flush_l1_dcache
217+ /* save ra and sp, will be used later (only for boot cpu) */
218+ dmtc0 ra, $22, 6
219+ dmtc0 sp, $22, 7
200220 /* Enable hw threads by writing to MAP_THREADMODE of the core */
201221 li t0, CKSEG1ADDR(RESET_DATA_PHYS)
202222 lw t1, BOOT_THREAD_MODE(t0) /* t1 <- thread mode */
@@ -225,6 +245,8 @@ EXPORT(nlm_boot_siblings) · 22 unmodified lines
225245 #endif
226246 mtc0 t1, CP0_STATUS
227247
248+ xlp_early_mmu_init
249+
228250 /* mark CPU ready */
229251 li t3, CKSEG1ADDR(RESET_DATA_PHYS)
230252 ADDIU t1, t3, BOOT_CPU_READY
@@ -238,14 +260,12 @@ EXPORT(nlm_boot_siblings) · 7 unmodified lines
238260 nop
239261
240262 /*
241− * For the boot CPU, we have to restore registers and
242− * return
263+ * For the boot CPU, we have to restore ra and sp and return, rest
264+ * of the registers will be restored by the caller
243265 */
244−4: dmfc0 t0, $4, 2 /* restore SP from UserLocal */
245− li t1, 0xfadebeef
246− dmtc0 t1, $4, 2 /* restore SP from UserLocal */
247− PTR_SUBU sp, t0, PT_SIZE
248− RESTORE_ALL
266+4:
267+ dmfc0 ra, $22, 6
268+ dmfc0 sp, $22, 7
249269 jr ra
250270 nop
251271 EXPORT(nlm_reset_entry_end)
@@ -253,6 +273,7 @@ EXPORT(nlm_reset_entry_end) · 1 unmodified line
253273 LEAF(nlm_init_boot_cpu)
254274 #ifdef CONFIG_CPU_XLP
255275 xlp_config_lsu
276+ xlp_early_mmu_init
256277 #endif
257278 jr ra
258279 nop
arch/mips/netlogic/common/smp.c+4−8
@@ -135,10 +135,6 @@ void nlm_smp_finish(void) · 134 unmodified lines
135135 local_irq_enable();
136136 }
137137
138−void nlm_cpus_done(void)
139−{
140−}
141−
142138 /*
143139 * Boot all other cpus in the system, initialize them, and bring them into
144140 * the boot function
@@ -198,7 +194,7 @@ void __init nlm_smp_setup(void) · 53 unmodified lines
198194 cpumask_scnprintf(buf, ARRAY_SIZE(buf), cpu_possible_mask);
199195 pr_info("Possible CPU mask: %s\n", buf);
200196
201− /* check with the cores we have worken up */
197+ /* check with the cores we have woken up */
202198 for (ncore = 0, i = 0; i < NLM_NR_NODES; i++)
203199 ncore += hweight32(nlm_get_node(i)->coremask);
204200
@@ -213,6 +209,7 @@ static int nlm_parse_cpumask(cpumask_t *wakeup_mask) · 8 unmodified lines
213209 {
214210 uint32_t core0_thr_mask, core_thr_mask;
215211 int threadmode, i, j;
212+ char buf[64];
216213
217214 core0_thr_mask = 0;
218215 for (i = 0; i < NLM_THREADS_PER_CORE; i++)
@@ -247,8 +244,8 @@ static int nlm_parse_cpumask(cpumask_t *wakeup_mask) · 28 unmodified lines
247244 return threadmode;
248245
249246 unsupp:
250− panic("Unsupported CPU mask %lx",
251− (unsigned long)cpumask_bits(wakeup_mask)[0]);
247+ cpumask_scnprintf(buf, ARRAY_SIZE(buf), wakeup_mask);
248+ panic("Unsupported CPU mask %s", buf);
252249 return 0;
253250 }
254251
@@ -277,7 +274,6 @@ struct plat_smp_ops nlm_smp_ops = { · 22 unmodified lines
277274 .send_ipi_mask = nlm_send_ipi_mask,
278275 .init_secondary = nlm_init_secondary,
279276 .smp_finish = nlm_smp_finish,
280− .cpus_done = nlm_cpus_done,
281277 .boot_secondary = nlm_boot_secondary,
282278 .smp_setup = nlm_smp_setup,
283279 .prepare_cpus = nlm_prepare_cpus,
arch/mips/netlogic/common/smpboot.S+8−4
@@ -54,8 +54,9 @@ · 53 unmodified lines
5454 .set noat
5555 .set arch=xlr /* for mfcr/mtcr, XLR is sufficient */
5656
57−FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */
58− dmtc0 sp, $4, 2 /* SP saved in UserLocal */
57+/* Called by the boot cpu to wake up its sibling threads */
58+NESTED(xlp_boot_core0_siblings, PT_SIZE, sp)
59+ /* CPU register contents lost when enabling threads, save them first */
5960 SAVE_ALL
6061 sync
6162 /* find the location to which nlm_boot_siblings was relocated */
@@ -65,9 +66,12 @@ FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */ · 3 unmodified lines
6566 dsubu t2, t1
6667 daddu t2, t0
6768 /* call it */
68− jr t2
69+ jalr t2
6970 nop
70− /* not reached */
71+ RESTORE_ALL
72+ jr ra
73+ nop
74+END(xlp_boot_core0_siblings)
7175
7276 NESTED(nlm_boot_secondary_cpus, 16, sp)
7377 /* Initialize CP0 Status */
arch/mips/netlogic/common/time.c+4−1
@@ -82,6 +82,7 @@ static struct clocksource csrc_pic = { · 81 unmodified lines
8282 static void nlm_init_pic_timer(void)
8383 {
8484 uint64_t picbase = nlm_get_node(0)->picbase;
85+ u32 picfreq;
8586
8687 nlm_pic_set_timer(picbase, PIC_CLOCK_TIMER, ~0ULL, 0, 0);
8788 if (current_cpu_data.cputype == CPU_XLR) {
@@ -92,7 +93,9 @@ static void nlm_init_pic_timer(void) · 4 unmodified lines
9293 csrc_pic.read = nlm_get_pic_timer;
9394 }
9495 csrc_pic.rating = 1000;
95− clocksource_register_hz(&csrc_pic, pic_timer_freq());
96+ picfreq = pic_timer_freq();
97+ clocksource_register_hz(&csrc_pic, picfreq);
98+ pr_info("PIC clock source added, frequency %d\n", picfreq);
9699 }
97100
98101 void __init plat_time_init(void)
arch/mips/netlogic/dts/xlp_gvp.dts+3−2
@@ -26,11 +26,12 @@ · 25 unmodified lines
2626 interrupt-parent = <&pic>;
2727 interrupts = <17>;
2828 };
29− pic: pic@4000 {
30− interrupt-controller;
29+ pic: pic@110000 {
30+ compatible = "netlogic,xlp-pic";
3131 #address-cells = <0>;
3232 #interrupt-cells = <1>;
3333 reg = <0 0x110000 0x200>;
34+ interrupt-controller;
3435 };
3536
3637 nor_flash@1,0 {
arch/mips/netlogic/xlp/Makefile+2−0
@@ -2,3 +2,5 @@ obj-y += setup.o nlm_hal.o cop2-ex.o dt.o · 1 unmodified line
22 obj-$(CONFIG_SMP) += wakeup.o
33 obj-$(CONFIG_USB) += usb-init.o
44 obj-$(CONFIG_USB) += usb-init-xlp2.o
5+obj-$(CONFIG_SATA_AHCI) += ahci-init.o
6+obj-$(CONFIG_SATA_AHCI) += ahci-init-xlp2.o
arch/mips/netlogic/xlp/ahci-init-xlp2.c+377−0
@@ -0,0 +1,377 @@
1+/*
2+ * Copyright (c) 2003-2014 Broadcom Corporation
3+ * All Rights Reserved
4+ *
5+ * This software is available to you under a choice of one of two
6+ * licenses. You may choose to be licensed under the terms of the GNU
7+ * General Public License (GPL) Version 2, available from the file
8+ * COPYING in the main directory of this source tree, or the Broadcom
9+ * license below:
10+ *
11+ * Redistribution and use in source and binary forms, with or without
12+ * modification, are permitted provided that the following conditions
13+ * are met:
14+ *
15+ * 1. Redistributions of source code must retain the above copyright
16+ * notice, this list of conditions and the following disclaimer.
17+ * 2. Redistributions in binary form must reproduce the above copyright
18+ * notice, this list of conditions and the following disclaimer in
19+ * the documentation and/or other materials provided with the
20+ * distribution.
21+ *
22+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
23+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25+ * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
26+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
32+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33+ */
34+
35+#include <linux/dma-mapping.h>
36+#include <linux/kernel.h>
37+#include <linux/delay.h>
38+#include <linux/init.h>
39+#include <linux/pci.h>
40+#include <linux/irq.h>
41+#include <linux/bitops.h>
42+#include <linux/pci_ids.h>
43+#include <linux/nodemask.h>
44+
45+#include <asm/cpu.h>
46+#include <asm/mipsregs.h>
47+
48+#include <asm/netlogic/common.h>
49+#include <asm/netlogic/haldefs.h>
50+#include <asm/netlogic/mips-extns.h>
51+#include <asm/netlogic/xlp-hal/xlp.h>
52+#include <asm/netlogic/xlp-hal/iomap.h>
53+
54+#define SATA_CTL 0x0
55+#define SATA_STATUS 0x1 /* Status Reg */
56+#define SATA_INT 0x2 /* Interrupt Reg */
57+#define SATA_INT_MASK 0x3 /* Interrupt Mask Reg */
58+#define SATA_BIU_TIMEOUT 0x4
59+#define AXIWRSPERRLOG 0x5
60+#define AXIRDSPERRLOG 0x6
61+#define BiuTimeoutLow 0x7
62+#define BiuTimeoutHi 0x8
63+#define BiuSlvErLow 0x9
64+#define BiuSlvErHi 0xa
65+#define IO_CONFIG_SWAP_DIS 0xb
66+#define CR_REG_TIMER 0xc
67+#define CORE_ID 0xd
68+#define AXI_SLAVE_OPT1 0xe
69+#define PHY_MEM_ACCESS 0xf
70+#define PHY0_CNTRL 0x10
71+#define PHY0_STAT 0x11
72+#define PHY0_RX_ALIGN 0x12
73+#define PHY0_RX_EQ_LO 0x13
74+#define PHY0_RX_EQ_HI 0x14
75+#define PHY0_BIST_LOOP 0x15
76+#define PHY1_CNTRL 0x16
77+#define PHY1_STAT 0x17
78+#define PHY1_RX_ALIGN 0x18
79+#define PHY1_RX_EQ_LO 0x19
80+#define PHY1_RX_EQ_HI 0x1a
81+#define PHY1_BIST_LOOP 0x1b
82+#define RdExBase 0x1c
83+#define RdExLimit 0x1d
84+#define CacheAllocBase 0x1e
85+#define CacheAllocLimit 0x1f
86+#define BiuSlaveCmdGstNum 0x20
87+
88+/*SATA_CTL Bits */
89+#define SATA_RST_N BIT(0) /* Active low reset sata_core phy */
90+#define SataCtlReserve0 BIT(1)
91+#define M_CSYSREQ BIT(2) /* AXI master low power, not used */
92+#define S_CSYSREQ BIT(3) /* AXI slave low power, not used */
93+#define P0_CP_DET BIT(8) /* Reserved, bring in from pad */
94+#define P0_MP_SW BIT(9) /* Mech Switch */
95+#define P0_DISABLE BIT(10) /* disable p0 */
96+#define P0_ACT_LED_EN BIT(11) /* Active LED enable */
97+#define P0_IRST_HARD_SYNTH BIT(12) /* PHY hard synth reset */
98+#define P0_IRST_HARD_TXRX BIT(13) /* PHY lane hard reset */
99+#define P0_IRST_POR BIT(14) /* PHY power on reset*/
100+#define P0_IPDTXL BIT(15) /* PHY Tx lane dis/power down */
101+#define P0_IPDRXL BIT(16) /* PHY Rx lane dis/power down */
102+#define P0_IPDIPDMSYNTH BIT(17) /* PHY synthesizer dis/porwer down */
103+#define P0_CP_POD_EN BIT(18) /* CP_POD enable */
104+#define P0_AT_BYPASS BIT(19) /* P0 address translation by pass */
105+#define P1_CP_DET BIT(20) /* Reserved,Cold Detect */
106+#define P1_MP_SW BIT(21) /* Mech Switch */
107+#define P1_DISABLE BIT(22) /* disable p1 */
108+#define P1_ACT_LED_EN BIT(23) /* Active LED enable */
109+#define P1_IRST_HARD_SYNTH BIT(24) /* PHY hard synth reset */
110+#define P1_IRST_HARD_TXRX BIT(25) /* PHY lane hard reset */
111+#define P1_IRST_POR BIT(26) /* PHY power on reset*/
112+#define P1_IPDTXL BIT(27) /* PHY Tx lane dis/porwer down */
113+#define P1_IPDRXL BIT(28) /* PHY Rx lane dis/porwer down */
114+#define P1_IPDIPDMSYNTH BIT(29) /* PHY synthesizer dis/porwer down */
115+#define P1_CP_POD_EN BIT(30)
116+#define P1_AT_BYPASS BIT(31) /* P1 address translation by pass */
117+
118+/* Status register */
119+#define M_CACTIVE BIT(0) /* m_cactive, not used */
120+#define S_CACTIVE BIT(1) /* s_cactive, not used */
121+#define P0_PHY_READY BIT(8) /* phy is ready */
122+#define P0_CP_POD BIT(9) /* Cold PowerOn */
123+#define P0_SLUMBER BIT(10) /* power mode slumber */
124+#define P0_PATIAL BIT(11) /* power mode patial */
125+#define P0_PHY_SIG_DET BIT(12) /* phy dignal detect */
126+#define P0_PHY_CALI BIT(13) /* phy calibration done */
127+#define P1_PHY_READY BIT(16) /* phy is ready */
128+#define P1_CP_POD BIT(17) /* Cold PowerOn */
129+#define P1_SLUMBER BIT(18) /* power mode slumber */
130+#define P1_PATIAL BIT(19) /* power mode patial */
131+#define P1_PHY_SIG_DET BIT(20) /* phy dignal detect */
132+#define P1_PHY_CALI BIT(21) /* phy calibration done */
133+
134+/* SATA CR_REG_TIMER bits */
135+#define CR_TIME_SCALE (0x1000 << 0)
136+
137+/* SATA PHY specific registers start and end address */
138+#define RXCDRCALFOSC0 0x0065
139+#define CALDUTY 0x006e
140+#define RXDPIF 0x8065
141+#define PPMDRIFTMAX_HI 0x80A4
142+
143+#define nlm_read_sata_reg(b, r) nlm_read_reg(b, r)
144+#define nlm_write_sata_reg(b, r, v) nlm_write_reg(b, r, v)
145+#define nlm_get_sata_pcibase(node) \
146+ nlm_pcicfg_base(XLP9XX_IO_SATA_OFFSET(node))
147+#define nlm_get_sata_regbase(node) \
148+ (nlm_get_sata_pcibase(node) + 0x100)
149+
150+/* SATA PHY config for register block 1 0x0065 .. 0x006e */
151+static const u8 sata_phy_config1[] = {
152+ 0xC9, 0xC9, 0x07, 0x07, 0x18, 0x18, 0x01, 0x01, 0x22, 0x00
153+};
154+
155+/* SATA PHY config for register block 2 0x0x8065 .. 0x0x80A4 */
156+static const u8 sata_phy_config2[] = {
157+ 0xAA, 0x00, 0x4C, 0xC9, 0xC9, 0x07, 0x07, 0x18,
158+ 0x18, 0x05, 0x0C, 0x10, 0x00, 0x10, 0x00, 0xFF,
159+ 0xCF, 0xF7, 0xE1, 0xF5, 0xFD, 0xFD, 0xFF, 0xFF,
160+ 0xFF, 0xFF, 0xE3, 0xE7, 0xDB, 0xF5, 0xFD, 0xFD,
161+ 0xF5, 0xF5, 0xFF, 0xFF, 0xE3, 0xE7, 0xDB, 0xF5,
162+ 0xFD, 0xFD, 0xF5, 0xF5, 0xFF, 0xFF, 0xFF, 0xF5,
163+ 0x3F, 0x00, 0x32, 0x00, 0x03, 0x01, 0x05, 0x05,
164+ 0x04, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x04,
165+};
166+
167+const int sata_phy_debug = 0; /* set to verify PHY writes */
168+
169+static void sata_clear_glue_reg(u64 regbase, u32 off, u32 bit)
170+{
171+ u32 reg_val;
172+
173+ reg_val = nlm_read_sata_reg(regbase, off);
174+ nlm_write_sata_reg(regbase, off, (reg_val & ~bit));
175+}
176+
177+static void sata_set_glue_reg(u64 regbase, u32 off, u32 bit)
178+{
179+ u32 reg_val;
180+
181+ reg_val = nlm_read_sata_reg(regbase, off);
182+ nlm_write_sata_reg(regbase, off, (reg_val | bit));
183+}
184+
185+static void write_phy_reg(u64 regbase, u32 addr, u32 physel, u8 data)
186+{
187+ nlm_write_sata_reg(regbase, PHY_MEM_ACCESS,
188+ (1u << 31) | (physel << 24) | (data << 16) | addr);
189+ udelay(850);
190+}

187 more lines aren’t shown here.

arch/mips/netlogic/xlp/ahci-init.c+209−0

This diff is large: its 210 lines aren’t shown here.

arch/mips/netlogic/xlp/dt.c+2−1

This diff is large: its 12 lines aren’t shown here.

arch/mips/netlogic/xlp/nlm_hal.c+204−79

This diff is large: its 372 lines aren’t shown here.

arch/mips/netlogic/xlp/setup.c+2−1

This diff is large: its 11 lines aren’t shown here.

arch/mips/netlogic/xlp/wakeup.c+10−6

This diff is large: its 33 lines aren’t shown here.

arch/mips/paravirt/Kconfig+6−0

This diff is large: its 7 lines aren’t shown here.

arch/mips/paravirt/Makefile+14−0

This diff is large: its 15 lines aren’t shown here.

arch/mips/paravirt/Platform+8−0

This diff is large: its 9 lines aren’t shown here.

arch/mips/paravirt/paravirt-irq.c+368−0

This diff is large: its 369 lines aren’t shown here.

arch/mips/paravirt/paravirt-smp.c+143−0

This diff is large: its 144 lines aren’t shown here.

arch/mips/paravirt/serial.c+40−0

This diff is large: its 41 lines aren’t shown here.

arch/mips/paravirt/setup.c+67−0

This diff is large: its 68 lines aren’t shown here.

arch/mips/pci/Makefile+1−1

This diff is large: its 9 lines aren’t shown here.

arch/mips/pci/fixup-malta.c+6−0

This diff is large: its 20 lines aren’t shown here.

arch/mips/pci/msi-octeon.c+6−0

This diff is large: its 20 lines aren’t shown here.

arch/mips/pci/msi-xlp.c+135−49

This diff is large: its 336 lines aren’t shown here.

arch/mips/pci/ops-pmcmsp.c+1−1

This diff is large: its 9 lines aren’t shown here.

arch/mips/pci/ops-tx3927.c+1−1

This diff is large: its 9 lines aren’t shown here.

arch/mips/pci/ops-tx4927.c+6−3

This diff is large: its 24 lines aren’t shown here.

arch/mips/pci/pci-virtio-guest.c+131−0

This diff is large: its 132 lines aren’t shown here.

arch/mips/pmcs-msp71xx/Makefile+0−1

This diff is large: its 5 lines aren’t shown here.

arch/mips/pmcs-msp71xx/msp_eth.c+0−76

This diff is large: its 97 lines aren’t shown here.

arch/mips/pmcs-msp71xx/msp_irq.c+5−11

This diff is large: its 37 lines aren’t shown here.

arch/mips/pmcs-msp71xx/msp_irq_cic.c+1−6

This diff is large: its 23 lines aren’t shown here.

arch/mips/pmcs-msp71xx/msp_irq_per.c+0−3

This diff is large: its 10 lines aren’t shown here.

arch/mips/pmcs-msp71xx/msp_setup.c+1−16

This diff is large: its 36 lines aren’t shown here.

arch/mips/pmcs-msp71xx/msp_smtc.c+0−104

This diff is large: its 105 lines aren’t shown here.

arch/mips/pmcs-msp71xx/msp_usb.c+0−90

This diff is large: its 118 lines aren’t shown here.

arch/mips/pnx833x/common/platform.c+0−73

This diff is large: its 94 lines aren’t shown here.

arch/mips/sgi-ip22/ip22-gio.c+28−14

This diff is large: its 85 lines aren’t shown here.

arch/mips/sgi-ip22/ip22-int.c+6−1

This diff is large: its 16 lines aren’t shown here.

arch/mips/sgi-ip27/ip27-smp.c+0−5

This diff is large: its 19 lines aren’t shown here.

arch/mips/sibyte/bcm1480/irq.c+0−11

This diff is large: its 20 lines aren’t shown here.

arch/mips/sibyte/bcm1480/smp.c+0−8

This diff is large: its 22 lines aren’t shown here.

arch/mips/sibyte/sb1250/smp.c+0−8

This diff is large: its 22 lines aren’t shown here.

arch/mips/txx9/generic/setup.c+2−2

This diff is large: its 11 lines aren’t shown here.

drivers/cpuidle/Kconfig+5−0

This diff is large: its 12 lines aren’t shown here.

drivers/cpuidle/Kconfig.mips+17−0

This diff is large: its 18 lines aren’t shown here.

drivers/cpuidle/Makefile+4−0

This diff is large: its 11 lines aren’t shown here.

drivers/cpuidle/cpuidle-cps.c+186−0

This diff is large: its 187 lines aren’t shown here.

drivers/usb/host/ehci-pmcmsp.c+0−40

This diff is large: its 76 lines aren’t shown here.

include/linux/cpuidle.h+1−0

This diff is large: its 8 lines aren’t shown here.

include/uapi/linux/kvm_para.h+3−0

This diff is large: its 10 lines aren’t shown here.