aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/Kconfig8
-rw-r--r--arch/powerpc/configs/ppc64_defconfig1
-rw-r--r--arch/powerpc/configs/pseries_defconfig1
-rw-r--r--arch/powerpc/include/asm/ppc-opcode.h3
-rw-r--r--arch/powerpc/include/asm/reg.h1
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S123
6 files changed, 137 insertions, 0 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 98e513b62709..748ccaa3b4b3 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -560,6 +560,14 @@ config SCHED_SMT
560 when dealing with POWER5 cpus at a cost of slightly increased 560 when dealing with POWER5 cpus at a cost of slightly increased
561 overhead in some places. If unsure say N here. 561 overhead in some places. If unsure say N here.
562 562
563config PPC_DENORMALISATION
564 bool "PowerPC denormalisation exception handling"
565 depends on PPC_BOOK3S_64
566 default "n"
567 ---help---
568 Add support for handling denormalisation of single precision
569 values. Useful for bare metal only. If unsure say Y here.
570
563config CMDLINE_BOOL 571config CMDLINE_BOOL
564 bool "Default bootloader kernel arguments" 572 bool "Default bootloader kernel arguments"
565 573
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index db27c82e0542..e263e6a5aca1 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -51,6 +51,7 @@ CONFIG_KEXEC=y
51CONFIG_IRQ_ALL_CPUS=y 51CONFIG_IRQ_ALL_CPUS=y
52CONFIG_MEMORY_HOTREMOVE=y 52CONFIG_MEMORY_HOTREMOVE=y
53CONFIG_SCHED_SMT=y 53CONFIG_SCHED_SMT=y
54CONFIG_PPC_DENORMALISATION=y
54CONFIG_PCCARD=y 55CONFIG_PCCARD=y
55CONFIG_ELECTRA_CF=y 56CONFIG_ELECTRA_CF=y
56CONFIG_HOTPLUG_PCI=m 57CONFIG_HOTPLUG_PCI=m
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index 1f65b3c9b59a..c169dfb3e42d 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -48,6 +48,7 @@ CONFIG_MEMORY_HOTREMOVE=y
48CONFIG_PPC_64K_PAGES=y 48CONFIG_PPC_64K_PAGES=y
49CONFIG_PPC_SUBPAGE_PROT=y 49CONFIG_PPC_SUBPAGE_PROT=y
50CONFIG_SCHED_SMT=y 50CONFIG_SCHED_SMT=y
51CONFIG_PPC_DENORMALISATION=y
51CONFIG_HOTPLUG_PCI=m 52CONFIG_HOTPLUG_PCI=m
52CONFIG_HOTPLUG_PCI_RPA=m 53CONFIG_HOTPLUG_PCI_RPA=m
53CONFIG_HOTPLUG_PCI_RPA_DLPAR=m 54CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index 4c25319f2fbc..5f73ce63fcae 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -126,6 +126,7 @@
126#define PPC_INST_TLBIVAX 0x7c000624 126#define PPC_INST_TLBIVAX 0x7c000624
127#define PPC_INST_TLBSRX_DOT 0x7c0006a5 127#define PPC_INST_TLBSRX_DOT 0x7c0006a5
128#define PPC_INST_XXLOR 0xf0000510 128#define PPC_INST_XXLOR 0xf0000510
129#define PPC_INST_XVCPSGNDP 0xf0000780
129 130
130#define PPC_INST_NAP 0x4c000364 131#define PPC_INST_NAP 0x4c000364
131#define PPC_INST_SLEEP 0x4c0003a4 132#define PPC_INST_SLEEP 0x4c0003a4
@@ -277,6 +278,8 @@
277 VSX_XX1((s), a, b)) 278 VSX_XX1((s), a, b))
278#define XXLOR(t, a, b) stringify_in_c(.long PPC_INST_XXLOR | \ 279#define XXLOR(t, a, b) stringify_in_c(.long PPC_INST_XXLOR | \
279 VSX_XX3((t), a, b)) 280 VSX_XX3((t), a, b))
281#define XVCPSGNDP(t, a, b) stringify_in_c(.long (PPC_INST_XVCPSGNDP | \
282 VSX_XX3((t), (a), (b))))
280 283
281#define PPC_NAP stringify_in_c(.long PPC_INST_NAP) 284#define PPC_NAP stringify_in_c(.long PPC_INST_NAP)
282#define PPC_SLEEP stringify_in_c(.long PPC_INST_SLEEP) 285#define PPC_SLEEP stringify_in_c(.long PPC_INST_SLEEP)
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 121a90bbf778..a1096fb62816 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -524,6 +524,7 @@
524 524
525#define SPRN_HSRR0 0x13A /* Save/Restore Register 0 */ 525#define SPRN_HSRR0 0x13A /* Save/Restore Register 0 */
526#define SPRN_HSRR1 0x13B /* Save/Restore Register 1 */ 526#define SPRN_HSRR1 0x13B /* Save/Restore Register 1 */
527#define HSRR1_DENORM 0x00100000 /* Denorm exception */
527 528
528#define SPRN_TBCTL 0x35f /* PA6T Timebase control register */ 529#define SPRN_TBCTL 0x35f /* PA6T Timebase control register */
529#define TBCTL_FREEZE 0x0000000000000000ull /* Freeze all tbs */ 530#define TBCTL_FREEZE 0x0000000000000000ull /* Freeze all tbs */
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 39aa97d3ff88..5eb00569199f 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -275,6 +275,31 @@ vsx_unavailable_pSeries_1:
275 STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint) 275 STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint)
276 KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_STD, 0x1300) 276 KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_STD, 0x1300)
277 277
278 . = 0x1500
279 .global denorm_Hypervisor
280denorm_exception_hv:
281 HMT_MEDIUM
282 mtspr SPRN_SPRG_HSCRATCH0,r13
283 mfspr r13,SPRN_SPRG_HPACA
284 std r9,PACA_EXGEN+EX_R9(r13)
285 std r10,PACA_EXGEN+EX_R10(r13)
286 std r11,PACA_EXGEN+EX_R11(r13)
287 std r12,PACA_EXGEN+EX_R12(r13)
288 mfspr r9,SPRN_SPRG_HSCRATCH0
289 std r9,PACA_EXGEN+EX_R13(r13)
290 mfcr r9
291
292#ifdef CONFIG_PPC_DENORMALISATION
293 mfspr r10,SPRN_HSRR1
294 mfspr r11,SPRN_HSRR0 /* save HSRR0 */
295 andis. r10,r10,(HSRR1_DENORM)@h /* denorm? */
296 addi r11,r11,-4 /* HSRR0 is next instruction */
297 bne+ denorm_assist
298#endif
299
300 EXCEPTION_PROLOG_PSERIES_1(denorm_common, EXC_HV)
301 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x1500)
302
278#ifdef CONFIG_CBE_RAS 303#ifdef CONFIG_CBE_RAS
279 STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance) 304 STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance)
280 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1602) 305 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1602)
@@ -336,6 +361,103 @@ do_stab_bolted_pSeries:
336 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x900) 361 KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x900)
337 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x982) 362 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x982)
338 363
364#ifdef CONFIG_PPC_DENORMALISATION
365denorm_assist:
366BEGIN_FTR_SECTION
367/*
368 * To denormalise we need to move a copy of the register to itself.
369 * For POWER6 do that here for all FP regs.
370 */
371 mfmsr r10
372 ori r10,r10,(MSR_FP|MSR_FE0|MSR_FE1)
373 xori r10,r10,(MSR_FE0|MSR_FE1)
374 mtmsrd r10
375 sync
376 fmr 0,0
377 fmr 1,1
378 fmr 2,2
379 fmr 3,3
380 fmr 4,4
381 fmr 5,5
382 fmr 6,6
383 fmr 7,7
384 fmr 8,8
385 fmr 9,9
386 fmr 10,10
387 fmr 11,11
388 fmr 12,12
389 fmr 13,13
390 fmr 14,14
391 fmr 15,15
392 fmr 16,16
393 fmr 17,17
394 fmr 18,18
395 fmr 19,19
396 fmr 20,20
397 fmr 21,21
398 fmr 22,22
399 fmr 23,23
400 fmr 24,24
401 fmr 25,25
402 fmr 26,26
403 fmr 27,27
404 fmr 28,28
405 fmr 29,29
406 fmr 30,30
407 fmr 31,31
408FTR_SECTION_ELSE
409/*
410 * To denormalise we need to move a copy of the register to itself.
411 * For POWER7 do that here for the first 32 VSX registers only.
412 */
413 mfmsr r10
414 oris r10,r10,MSR_VSX@h
415 mtmsrd r10
416 sync
417 XVCPSGNDP(0,0,0)
418 XVCPSGNDP(1,1,1)
419 XVCPSGNDP(2,2,2)
420 XVCPSGNDP(3,3,3)
421 XVCPSGNDP(4,4,4)
422 XVCPSGNDP(5,5,5)
423 XVCPSGNDP(6,6,6)
424 XVCPSGNDP(7,7,7)
425 XVCPSGNDP(8,8,8)
426 XVCPSGNDP(9,9,9)
427 XVCPSGNDP(10,10,10)
428 XVCPSGNDP(11,11,11)
429 XVCPSGNDP(12,12,12)
430 XVCPSGNDP(13,13,13)
431 XVCPSGNDP(14,14,14)
432 XVCPSGNDP(15,15,15)
433 XVCPSGNDP(16,16,16)
434 XVCPSGNDP(17,17,17)
435 XVCPSGNDP(18,18,18)
436 XVCPSGNDP(19,19,19)
437 XVCPSGNDP(20,20,20)
438 XVCPSGNDP(21,21,21)
439 XVCPSGNDP(22,22,22)
440 XVCPSGNDP(23,23,23)
441 XVCPSGNDP(24,24,24)
442 XVCPSGNDP(25,25,25)
443 XVCPSGNDP(26,26,26)
444 XVCPSGNDP(27,27,27)
445 XVCPSGNDP(28,28,28)
446 XVCPSGNDP(29,29,29)
447 XVCPSGNDP(30,30,30)
448 XVCPSGNDP(31,31,31)
449ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206)
450 mtspr SPRN_HSRR0,r11
451 mtcrf 0x80,r9
452 ld r9,PACA_EXGEN+EX_R9(r13)
453 ld r10,PACA_EXGEN+EX_R10(r13)
454 ld r11,PACA_EXGEN+EX_R11(r13)
455 ld r12,PACA_EXGEN+EX_R12(r13)
456 ld r13,PACA_EXGEN+EX_R13(r13)
457 HRFID
458 b .
459#endif
460
339 .align 7 461 .align 7
340 /* moved from 0xe00 */ 462 /* moved from 0xe00 */
341 STD_EXCEPTION_HV(., 0xe02, h_data_storage) 463 STD_EXCEPTION_HV(., 0xe02, h_data_storage)
@@ -495,6 +617,7 @@ machine_check_common:
495 STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception) 617 STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
496 STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, .performance_monitor_exception) 618 STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, .performance_monitor_exception)
497 STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) 619 STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
620 STD_EXCEPTION_COMMON(0x1502, denorm, .unknown_exception)
498#ifdef CONFIG_ALTIVEC 621#ifdef CONFIG_ALTIVEC
499 STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception) 622 STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
500#else 623#else