On 10/9/21 23:38, Sven Schnelle wrote: > Almost all PA-RISC machines have either a button that > is labeled with 'TOC' or a BMC function to trigger a TOC. > TOC is a non-maskable interrupt that is sent to the processor. > This can be used for diagnostic purposes like obtaining a > stack trace/register dump or to enter KDB/KGDB. > > As an example, on my c8000, TOC can be used with: > > CONFIG_KGDB=y > CONFIG_KGDB_KDB=y > > and the 'kgdboc=ttyS0,115200' appended to the command line. > > Press ^( on serial console, which will enter the BMC command line, > and enter 'TOC s': > > root@(none):/# ( > cli>TOC s > Sending TOC/INIT. > <Cpu3> 2800035d03e00000 0000000040c21ac8 CC_ERR_CHECK_TOC > <Cpu0> 2800035d00e00000 0000000040c21ad0 CC_ERR_CHECK_TOC > <Cpu2> 2800035d02e00000 0000000040c21ac8 CC_ERR_CHECK_TOC > <Cpu1> 2800035d01e00000 0000000040c21ad0 CC_ERR_CHECK_TOC > <Cpu3> 37000f7303e00000 2000000000000000 CC_ERR_CPU_CHECK_SUMMARY > <Cpu0> 37000f7300e00000 2000000000000000 CC_ERR_CPU_CHECK_SUMMARY > <Cpu2> 37000f7302e00000 2000000000000000 CC_ERR_CPU_CHECK_SUMMARY > <Cpu1> 37000f7301e00000 2000000000000000 CC_ERR_CPU_CHECK_SUMMARY > <Cpu3> 4300100803e00000 c0000000001d26cc CC_MC_BR_TO_OS_TOC > <Cpu0> 4300100800e00000 c0000000001d26cc CC_MC_BR_TO_OS_TOC > <Cpu2> 4300100802e00000 c0000000001d26cc CC_MC_BR_TO_OS_TOC > <Cpu1> 4300100801e00000 c0000000001d26cc CC_MC_BR_TO_OS_TOC > > Entering kdb (current=0x00000000411cef80, pid 0) on processor 0 due to NonMaskable Interrupt @ 0x40c21ad0 > [0]kdb> > > Signed-off-by: Sven Schnelle <svens@xxxxxxxxxxxxxx> > --- > arch/parisc/include/asm/processor.h | 4 ++ > arch/parisc/include/uapi/asm/pdc.h | 6 ++- > arch/parisc/kernel/entry.S | 69 +++++++++++++++++++++++++ > arch/parisc/kernel/processor.c | 21 ++++++++ > arch/parisc/kernel/traps.c | 79 +++++++++++++++++++++++++++++ > 5 files changed, 177 insertions(+), 2 deletions(-) > > diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h > index eeb7da064289..1e9a4c986921 100644 > --- a/arch/parisc/include/asm/processor.h > +++ b/arch/parisc/include/asm/processor.h > @@ -294,6 +294,10 @@ extern int _parisc_requires_coherency; > > extern int running_on_qemu; > > +extern void toc_handler(void); > +extern unsigned int toc_handler_size; > +extern unsigned int toc_handler_csum; > + > #endif /* __ASSEMBLY__ */ > > #endif /* __ASM_PARISC_PROCESSOR_H */ > diff --git a/arch/parisc/include/uapi/asm/pdc.h b/arch/parisc/include/uapi/asm/pdc.h > index ad51df8ba952..acc633c15722 100644 > --- a/arch/parisc/include/uapi/asm/pdc.h > +++ b/arch/parisc/include/uapi/asm/pdc.h > @@ -398,8 +398,10 @@ struct zeropage { > /* int (*vec_rendz)(void); */ > unsigned int vec_rendz; > int vec_pow_fail_flen; > - int vec_pad[10]; > - > + int vec_pad0[3]; > + unsigned int vec_toc_hi; > + int vec_pad1[6]; > + > /* [0x040] reserved processor dependent */ > int pad0[112]; > > diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S > index 9f939afe6b88..f486f3b51075 100644 > --- a/arch/parisc/kernel/entry.S > +++ b/arch/parisc/kernel/entry.S > @@ -28,6 +28,7 @@ > > #include <linux/linkage.h> > #include <linux/pgtable.h> > +#include <linux/threads.h> > > #ifdef CONFIG_64BIT > .level 2.0w > @@ -2414,3 +2415,71 @@ ENTRY_CFI(set_register) > copy %r1,%r31 > ENDPROC_CFI(set_register) > > + .import toc_intr,code > + ENTRY_CFI(toc_handler) > + /* > + * synchronize CPUs and obtain offset > + * for stack setup. > + */ > + load32 PA(toc_lock),%r1 > +0: ldcw,co 0(%r1),%r2 > + cmpib,= 0,%r2,0b > + nop > + addi 1,%r2,%r4 > + stw %r4,0(%r1) > + addi -1,%r2,%r4 > + > + load32 PA(toc_stack),sp > + /* > + * deposit CPU number into stack address, > + * so every CPU will have its own stack. > + */ > + depw %r4,18,2,%sp Shouldn't this be 5 instead of 2, otherwise it limits it to 4 CPUs, while we currently can have up to 32 (see arch/parisc/Kconfig). e.g.: depw %r4,18,5,%sp > + > ... > +SYM_DATA(toc_handler_size, .long . - toc_handler) > +SYM_DATA(toc_lock, .long 1) > + > + __PAGE_ALIGNED_BSS > + .align 16384*NR_CPUS ^ This align is too big, esp. since NR_CPUS can be 32. At minimum a stack needs to be 64-byte aligned. I think a simple .align 64 here, and changing the multiplication above with adding the offset is better. > +toc_stack: > + .block 16384*NR_CPUS all other seems ok. Thanks! Helge