linux-parisc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] add TOC support
@ 2021-10-09 21:38 Sven Schnelle
  2021-10-09 21:38 ` [PATCH 1/2] parisc/firmware: add functions to retrieve TOC data Sven Schnelle
  2021-10-09 21:38 ` [PATCH 2/2] parisc: add support for TOC (transfer of control) Sven Schnelle
  0 siblings, 2 replies; 10+ messages in thread
From: Sven Schnelle @ 2021-10-09 21:38 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-parisc

This adds support for the TOC switches found on most PA-RISC
machines. I tested this on my c8000 and a HP 16702A, which is
basically a B160L with some logic analyzer hardware.

Sven Schnelle (2):
  parisc/firmware: add functions to retrieve TOC data
  parisc: add support for TOC (transfer of control)

 arch/parisc/include/asm/pdc.h       |  2 +
 arch/parisc/include/asm/processor.h |  4 ++
 arch/parisc/include/uapi/asm/pdc.h  | 28 +++++++++-
 arch/parisc/kernel/entry.S          | 69 +++++++++++++++++++++++++
 arch/parisc/kernel/firmware.c       | 32 ++++++++++++
 arch/parisc/kernel/processor.c      | 21 ++++++++
 arch/parisc/kernel/traps.c          | 79 +++++++++++++++++++++++++++++
 7 files changed, 233 insertions(+), 2 deletions(-)

-- 
2.33.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/2] parisc/firmware: add functions to retrieve TOC data
  2021-10-09 21:38 [PATCH 0/2] add TOC support Sven Schnelle
@ 2021-10-09 21:38 ` Sven Schnelle
  2021-10-09 21:38 ` [PATCH 2/2] parisc: add support for TOC (transfer of control) Sven Schnelle
  1 sibling, 0 replies; 10+ messages in thread
From: Sven Schnelle @ 2021-10-09 21:38 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-parisc

Add functions to retrieve TOC data from firmware both
for 1.1 and 2.0 PDC.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
 arch/parisc/include/asm/pdc.h      |  2 ++
 arch/parisc/include/uapi/asm/pdc.h | 22 ++++++++++++++++++++
 arch/parisc/kernel/firmware.c      | 32 ++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)

diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h
index b388d8176588..18b957a8630d 100644
--- a/arch/parisc/include/asm/pdc.h
+++ b/arch/parisc/include/asm/pdc.h
@@ -51,6 +51,8 @@ int pdc_spaceid_bits(unsigned long *space_bits);
 int pdc_btlb_info(struct pdc_btlb_info *btlb);
 int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path);
 #endif /* !CONFIG_PA20 */
+int pdc_pim_toc11(struct pdc_toc_pim_11 *ret);
+int pdc_pim_toc20(struct pdc_toc_pim_20 *ret);
 int pdc_lan_station_id(char *lan_addr, unsigned long net_hpa);
 
 int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count);
diff --git a/arch/parisc/include/uapi/asm/pdc.h b/arch/parisc/include/uapi/asm/pdc.h
index 15211723ebf5..ad51df8ba952 100644
--- a/arch/parisc/include/uapi/asm/pdc.h
+++ b/arch/parisc/include/uapi/asm/pdc.h
@@ -689,6 +689,28 @@ struct pdc_hpmc_pim_20 { /* PDC_PIM */
 	unsigned long long fr[32];
 };
 
+struct pdc_toc_pim_11 {
+	unsigned int gr[32];
+	unsigned int cr[32];
+	unsigned int sr[8];
+	unsigned int iasq_back;
+	unsigned int iaoq_back;
+	unsigned int check_type;
+	unsigned int hversion;
+	unsigned int cpu_state;
+};
+
+struct pdc_toc_pim_20 {
+	unsigned long long gr[32];
+	unsigned long long cr[32];
+	unsigned long long sr[8];
+	unsigned long long iasq_back;
+	unsigned long long iaoq_back;
+	unsigned int check_type;
+	unsigned int hversion;
+	unsigned int cpu_state;
+};
+
 #endif /* !defined(__ASSEMBLY__) */
 
 #endif /* _UAPI_PARISC_PDC_H */
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index 7034227dbdf3..9179b4409b63 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -1061,6 +1061,38 @@ int pdc_mem_pdt_read_entries(struct pdc_mem_read_pdt *pret,
 	return retval;
 }
 
+/**
+ * pdc_pim_toc11 - Fetch TOC PIM 1.1 data from firmware.
+ * @ret: pointer to return buffer
+ */
+int pdc_pim_toc11(struct pdc_toc_pim_11 *ret)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PIM, PDC_PIM_TOC, __pa(pdc_result),
+			      __pa(ret), sizeof(struct pdc_toc_pim_11));
+	spin_unlock_irqrestore(&pdc_lock, flags);
+	return retval;
+}
+
+/**
+ * pdc_pim_toc20 - Fetch TOC PIM 2.0 data from firmware.
+ * @ret: pointer to return buffer
+ */
+int pdc_pim_toc20(struct pdc_toc_pim_20 *ret)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PIM, PDC_PIM_TOC, __pa(pdc_result),
+			      __pa(ret), sizeof(struct pdc_toc_pim_20));
+	spin_unlock_irqrestore(&pdc_lock, flags);
+	return retval;
+}
+
 /**
  * pdc_tod_set - Set the Time-Of-Day clock.
  * @sec: The number of seconds since epoch.
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/2] parisc: add support for TOC (transfer of control)
  2021-10-09 21:38 [PATCH 0/2] add TOC support Sven Schnelle
  2021-10-09 21:38 ` [PATCH 1/2] parisc/firmware: add functions to retrieve TOC data Sven Schnelle
@ 2021-10-09 21:38 ` Sven Schnelle
  2021-10-10  9:13   ` Helge Deller
  1 sibling, 1 reply; 10+ messages in thread
From: Sven Schnelle @ 2021-10-09 21:38 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-parisc

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@stackframe.org>
---
 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
+
+	/* setup pt_regs on stack and save the
+	 * floating point registers. PIM_TOC doesn't
+	 * save fp registers, so we're doing it here.
+	 */
+	copy	%sp,%arg0
+	ldo	PT_SZ_ALGN(%sp), %sp
+
+	/* clear pt_regs */
+	copy	%arg0,%r1
+0:	cmpb,<<,n %r1,%sp,0b
+	stw,ma	%r0,4(%r1)
+
+	ldo	PT_FR0(%arg0),%r25
+	save_fp	%r25
+
+	/* go virtual */
+	load32	PA(swapper_pg_dir),%r4
+	mtctl	%r4,%cr24
+	mtctl	%r4,%cr25
+
+	/* Clear sr4-sr7 */
+	mtsp	%r0, %sr4
+	mtsp	%r0, %sr5
+	mtsp	%r0, %sr6
+	mtsp	%r0, %sr7
+
+	tovirt_r1 %sp
+	tovirt_r1 %arg0
+	virt_map
+
+	loadgp
+#ifdef CONFIG_64BIT
+	ldo	-16(%sp),%r29
+#endif
+	b,l	toc_intr,%r2
+	nop
+0:	b	0b
+ENDPROC_CFI(toc_handler)
+
+SYM_DATA(toc_handler_csum, .long 0)
+SYM_DATA(toc_handler_size, .long . - toc_handler)
+SYM_DATA(toc_lock, .long 1)
+
+	__PAGE_ALIGNED_BSS
+	.align 16384*NR_CPUS
+toc_stack:
+	.block 16384*NR_CPUS
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index 1b6129e7d776..582caf99d952 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -28,6 +28,7 @@
 #include <asm/pdcpat.h>
 #include <asm/irq.h>		/* for struct irq_region */
 #include <asm/parisc-device.h>
+#include <asm/sections.h>
 
 struct system_cpuinfo_parisc boot_cpu_data __ro_after_init;
 EXPORT_SYMBOL(boot_cpu_data);
@@ -453,6 +454,25 @@ static struct parisc_driver cpu_driver __refdata = {
 	.probe		= processor_probe
 };
 
+static __init void setup_toc(void)
+{
+	unsigned int csum = 0;
+	unsigned long toc_code = (unsigned long)dereference_function_descriptor(toc_handler);
+	int i;
+
+	PAGE0->vec_toc = __pa(toc_code) & 0xffffffff;
+#ifdef CONFIG_64BIT
+	PAGE0->vec_toc_hi = __pa(toc_code) >> 32;
+#else
+	PAGE0->vec_toc_hi = 0;
+#endif
+	PAGE0->vec_toclen = toc_handler_size;
+
+	for (i = 0; i < toc_handler_size/4; i++)
+		csum += ((u32 *)toc_code)[i];
+	toc_handler_csum = -csum;
+}
+
 /**
  * processor_init - Processor initialization procedure.
  *
@@ -460,5 +480,6 @@ static struct parisc_driver cpu_driver __refdata = {
  */
 void __init processor_init(void)
 {
+	setup_toc();
 	register_parisc_driver(&cpu_driver);
 }
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index 747c328fb886..e847d37eda3a 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -30,6 +30,8 @@
 #include <linux/ratelimit.h>
 #include <linux/uaccess.h>
 #include <linux/kdebug.h>
+#include <linux/kdb.h>
+#include <linux/reboot.h>
 
 #include <asm/assembly.h>
 #include <asm/io.h>
@@ -472,6 +474,83 @@ void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long o
 	panic(msg);
 }
 
+static void toc20_to_pt_regs(struct pt_regs *regs, struct pdc_toc_pim_20 *toc)
+{
+	int i;
+
+	regs->gr[0] = (unsigned long)toc->cr[22];
+
+	for (i = 1; i < 32; i++)
+		regs->gr[i] = (unsigned long)toc->gr[i];
+
+	for (i = 0; i < 8; i++)
+		regs->sr[i] = (unsigned long)toc->sr[i];
+
+	regs->iasq[0] = (unsigned long)toc->cr[17];
+	regs->iasq[1] = (unsigned long)toc->iasq_back;
+	regs->iaoq[0] = (unsigned long)toc->cr[18];
+	regs->iaoq[1] = (unsigned long)toc->iaoq_back;
+
+	regs->sar = (unsigned long)toc->cr[11];
+	regs->iir = (unsigned long)toc->cr[19];
+	regs->isr = (unsigned long)toc->cr[20];
+	regs->ior = (unsigned long)toc->cr[21];
+}
+
+static void toc11_to_pt_regs(struct pt_regs *regs, struct pdc_toc_pim_11 *toc)
+{
+	int i;
+
+	regs->gr[0] = toc->cr[22];
+
+	for (i = 1; i < 32; i++)
+		regs->gr[i] = toc->gr[i];
+
+	for (i = 0; i < 8; i++)
+		regs->sr[i] = toc->sr[i];
+
+	regs->iasq[0] = toc->cr[17];
+	regs->iasq[1] = toc->iasq_back;
+	regs->iaoq[0] = toc->cr[18];
+	regs->iaoq[1] = toc->iaoq_back;
+
+	regs->sar  = toc->cr[11];
+	regs->iir  = toc->cr[19];
+	regs->isr  = toc->cr[20];
+	regs->ior  = toc->cr[21];
+}
+
+void notrace toc_intr(struct pt_regs *regs)
+{
+	struct pdc_toc_pim_20 pim_data20;
+	struct pdc_toc_pim_11 pim_data11;
+
+	nmi_enter();
+
+	if (boot_cpu_data.cpu_type >= pcxu) {
+		if (pdc_pim_toc20(&pim_data20))
+			panic("Failed to get PIM data");
+		toc20_to_pt_regs(regs, &pim_data20);
+	} else {
+		if (pdc_pim_toc11(&pim_data11))
+			panic("Failed to get PIM data");
+		toc11_to_pt_regs(regs, &pim_data11);
+	}
+
+#ifdef CONFIG_KGDB
+	if (atomic_read(&kgdb_active) != -1)
+		kgdb_nmicallback(raw_smp_processor_id(), regs);
+	kgdb_handle_exception(KDB_REASON_SYSTEM_NMI, SIGTRAP, 0, regs);
+#endif
+	show_regs(regs);
+
+	/* give other CPUs time to show their backtrace */
+	mdelay(2000);
+	machine_restart("TOC");
+
+	nmi_exit();
+}
+
 void notrace handle_interruption(int code, struct pt_regs *regs)
 {
 	unsigned long fault_address = 0;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/2] parisc: add support for TOC (transfer of control)
  2021-10-09 21:38 ` [PATCH 2/2] parisc: add support for TOC (transfer of control) Sven Schnelle
@ 2021-10-10  9:13   ` Helge Deller
  2021-10-10 11:42     ` Sven Schnelle
  0 siblings, 1 reply; 10+ messages in thread
From: Helge Deller @ 2021-10-10  9:13 UTC (permalink / raw)
  To: Sven Schnelle; +Cc: linux-parisc

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@stackframe.org>
> ---
>  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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/2] parisc: add support for TOC (transfer of control)
  2021-10-10  9:13   ` Helge Deller
@ 2021-10-10 11:42     ` Sven Schnelle
  0 siblings, 0 replies; 10+ messages in thread
From: Sven Schnelle @ 2021-10-10 11:42 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-parisc

Helge Deller <deller@gmx.de> writes:

> On 10/9/21 23:38, Sven Schnelle wrote:
>> +	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.

The .align was a quick way to test the stack offset, but i agree that
doing a regular add is the better way. Also i missed to align toc_lock
at a 16 byte boundary.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] parisc/firmware: add functions to retrieve TOC data
  2021-10-12 20:33       ` Sven Schnelle
@ 2021-10-12 20:52         ` Helge Deller
  0 siblings, 0 replies; 10+ messages in thread
From: Helge Deller @ 2021-10-12 20:52 UTC (permalink / raw)
  To: Sven Schnelle; +Cc: Rolf Eike Beer, linux-parisc

On 10/12/21 22:33, Sven Schnelle wrote:
> Helge Deller <deller@gmx.de> writes:
>
>> On 10/11/21 17:05, Rolf Eike Beer wrote:
>>>> --- a/arch/parisc/include/uapi/asm/pdc.h
>>>> +++ b/arch/parisc/include/uapi/asm/pdc.h
>>>> @@ -689,6 +689,28 @@ struct pdc_hpmc_pim_20 { /* PDC_PIM */
>>>>  	unsigned long long fr[32];
>>>>  };
>>>>
>>>> +struct pdc_toc_pim_11 {
>>>> +	unsigned int gr[32];
>>>> +	unsigned int cr[32];
>>>> +	unsigned int sr[8];
>>>> +	unsigned int iasq_back;
>>>> +	unsigned int iaoq_back;
>>>> +	unsigned int check_type;
>>>> +	unsigned int hversion;
>>>> +	unsigned int cpu_state;
>>>> +};
>>>> +
>>>> +struct pdc_toc_pim_20 {
>>>> +	unsigned long long gr[32];
>>>> +	unsigned long long cr[32];
>>>> +	unsigned long long sr[8];
>>>> +	unsigned long long iasq_back;
>>>> +	unsigned long long iaoq_back;
>>>> +	unsigned int check_type;
>>>> +	unsigned int hversion;
>>>> +	unsigned int cpu_state;
>>>> +};
>>>> +
>>>>  #endif /* !defined(__ASSEMBLY__) */
>>>
>>> Since these are defined by the hardware and have a well defined size I suggest
>>> using u32 and u64 to cover this.
>>
>> You're right.
>> But in the whole file we use "unsigned int" for 32bit, and "unsigned long long"
>> for 64bit, so this change is consistent with the other contents.
>
> Yes, especially the 'unsigned long long' catched my eye. However, i kept
> it that way so it is consistent with the other structs. I'm happy to
> change the types with a cleanup patch, but i'm wondering: why is that
> all uapi? IMHO this should go to include/asm? Any objections against
> moving it? I don't see how userspace could use that given that only the
> kernel should be able to call into firmware.

I think for the palo bootloader and the qemu sources they were put in include/uapi.
Both projects have copies though, so I think it can go to include/asm.
If you send a patch I can take it.

Helge

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] parisc/firmware: add functions to retrieve TOC data
  2021-10-11 20:13     ` Helge Deller
@ 2021-10-12 20:33       ` Sven Schnelle
  2021-10-12 20:52         ` Helge Deller
  0 siblings, 1 reply; 10+ messages in thread
From: Sven Schnelle @ 2021-10-12 20:33 UTC (permalink / raw)
  To: Helge Deller; +Cc: Rolf Eike Beer, linux-parisc

Helge Deller <deller@gmx.de> writes:

> On 10/11/21 17:05, Rolf Eike Beer wrote:
>>> --- a/arch/parisc/include/uapi/asm/pdc.h
>>> +++ b/arch/parisc/include/uapi/asm/pdc.h
>>> @@ -689,6 +689,28 @@ struct pdc_hpmc_pim_20 { /* PDC_PIM */
>>>  	unsigned long long fr[32];
>>>  };
>>>
>>> +struct pdc_toc_pim_11 {
>>> +	unsigned int gr[32];
>>> +	unsigned int cr[32];
>>> +	unsigned int sr[8];
>>> +	unsigned int iasq_back;
>>> +	unsigned int iaoq_back;
>>> +	unsigned int check_type;
>>> +	unsigned int hversion;
>>> +	unsigned int cpu_state;
>>> +};
>>> +
>>> +struct pdc_toc_pim_20 {
>>> +	unsigned long long gr[32];
>>> +	unsigned long long cr[32];
>>> +	unsigned long long sr[8];
>>> +	unsigned long long iasq_back;
>>> +	unsigned long long iaoq_back;
>>> +	unsigned int check_type;
>>> +	unsigned int hversion;
>>> +	unsigned int cpu_state;
>>> +};
>>> +
>>>  #endif /* !defined(__ASSEMBLY__) */
>>
>> Since these are defined by the hardware and have a well defined size I suggest
>> using u32 and u64 to cover this.
>
> You're right.
> But in the whole file we use "unsigned int" for 32bit, and "unsigned long long"
> for 64bit, so this change is consistent with the other contents.

Yes, especially the 'unsigned long long' catched my eye. However, i kept
it that way so it is consistent with the other structs. I'm happy to
change the types with a cleanup patch, but i'm wondering: why is that
all uapi? IMHO this should go to include/asm? Any objections against
moving it? I don't see how userspace could use that given that only the
kernel should be able to call into firmware.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] parisc/firmware: add functions to retrieve TOC data
  2021-10-11 15:05   ` Rolf Eike Beer
@ 2021-10-11 20:13     ` Helge Deller
  2021-10-12 20:33       ` Sven Schnelle
  0 siblings, 1 reply; 10+ messages in thread
From: Helge Deller @ 2021-10-11 20:13 UTC (permalink / raw)
  To: Rolf Eike Beer, Sven Schnelle; +Cc: linux-parisc

On 10/11/21 17:05, Rolf Eike Beer wrote:
>> --- a/arch/parisc/include/uapi/asm/pdc.h
>> +++ b/arch/parisc/include/uapi/asm/pdc.h
>> @@ -689,6 +689,28 @@ struct pdc_hpmc_pim_20 { /* PDC_PIM */
>>  	unsigned long long fr[32];
>>  };
>>
>> +struct pdc_toc_pim_11 {
>> +	unsigned int gr[32];
>> +	unsigned int cr[32];
>> +	unsigned int sr[8];
>> +	unsigned int iasq_back;
>> +	unsigned int iaoq_back;
>> +	unsigned int check_type;
>> +	unsigned int hversion;
>> +	unsigned int cpu_state;
>> +};
>> +
>> +struct pdc_toc_pim_20 {
>> +	unsigned long long gr[32];
>> +	unsigned long long cr[32];
>> +	unsigned long long sr[8];
>> +	unsigned long long iasq_back;
>> +	unsigned long long iaoq_back;
>> +	unsigned int check_type;
>> +	unsigned int hversion;
>> +	unsigned int cpu_state;
>> +};
>> +
>>  #endif /* !defined(__ASSEMBLY__) */
>
> Since these are defined by the hardware and have a well defined size I suggest
> using u32 and u64 to cover this.

You're right.
But in the whole file we use "unsigned int" for 32bit, and "unsigned long long"
for 64bit, so this change is consistent with the other contents.

Helge

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] parisc/firmware: add functions to retrieve TOC data
  2021-10-10 18:38 ` [PATCH 1/2] parisc/firmware: add functions to retrieve TOC data Sven Schnelle
@ 2021-10-11 15:05   ` Rolf Eike Beer
  2021-10-11 20:13     ` Helge Deller
  0 siblings, 1 reply; 10+ messages in thread
From: Rolf Eike Beer @ 2021-10-11 15:05 UTC (permalink / raw)
  To: Helge Deller, Sven Schnelle; +Cc: linux-parisc

[-- Attachment #1: Type: text/plain, Size: 2203 bytes --]

> --- a/arch/parisc/include/uapi/asm/pdc.h
> +++ b/arch/parisc/include/uapi/asm/pdc.h
> @@ -689,6 +689,28 @@ struct pdc_hpmc_pim_20 { /* PDC_PIM */
>  	unsigned long long fr[32];
>  };
> 
> +struct pdc_toc_pim_11 {
> +	unsigned int gr[32];
> +	unsigned int cr[32];
> +	unsigned int sr[8];
> +	unsigned int iasq_back;
> +	unsigned int iaoq_back;
> +	unsigned int check_type;
> +	unsigned int hversion;
> +	unsigned int cpu_state;
> +};
> +
> +struct pdc_toc_pim_20 {
> +	unsigned long long gr[32];
> +	unsigned long long cr[32];
> +	unsigned long long sr[8];
> +	unsigned long long iasq_back;
> +	unsigned long long iaoq_back;
> +	unsigned int check_type;
> +	unsigned int hversion;
> +	unsigned int cpu_state;
> +};
> +
>  #endif /* !defined(__ASSEMBLY__) */

Since these are defined by the hardware and have a well defined size I suggest 
using u32 and u64 to cover this.

> diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
> index 7034227dbdf3..9179b4409b63 100644
> --- a/arch/parisc/kernel/firmware.c
> +++ b/arch/parisc/kernel/firmware.c
> @@ -1061,6 +1061,38 @@ int pdc_mem_pdt_read_entries(struct pdc_mem_read_pdt
> *pret, return retval;
>  }
> 
> +/**
> + * pdc_pim_toc11 - Fetch TOC PIM 1.1 data from firmware.
> + * @ret: pointer to return buffer
> + */
> +int pdc_pim_toc11(struct pdc_toc_pim_11 *ret)
> +{
> +	int retval;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&pdc_lock, flags);
> +	retval = mem_pdc_call(PDC_PIM, PDC_PIM_TOC, __pa(pdc_result),
> +			      __pa(ret), sizeof(struct 
pdc_toc_pim_11));
sizeof(*ret)

> +	spin_unlock_irqrestore(&pdc_lock, flags);
> +	return retval;
> +}
> +
> +/**
> + * pdc_pim_toc20 - Fetch TOC PIM 2.0 data from firmware.
> + * @ret: pointer to return buffer
> + */
> +int pdc_pim_toc20(struct pdc_toc_pim_20 *ret)
> +{
> +	int retval;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&pdc_lock, flags);
> +	retval = mem_pdc_call(PDC_PIM, PDC_PIM_TOC, __pa(pdc_result),
> +			      __pa(ret), sizeof(struct 
pdc_toc_pim_20));
sizeof(*ret)

> +	spin_unlock_irqrestore(&pdc_lock, flags);
> +	return retval;
> +}
> +
>  /**
>   * pdc_tod_set - Set the Time-Of-Day clock.
>   * @sec: The number of seconds since epoch.


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/2] parisc/firmware: add functions to retrieve TOC data
  2021-10-10 18:38 [PATCH v2 0/2] add TOC support Sven Schnelle
@ 2021-10-10 18:38 ` Sven Schnelle
  2021-10-11 15:05   ` Rolf Eike Beer
  0 siblings, 1 reply; 10+ messages in thread
From: Sven Schnelle @ 2021-10-10 18:38 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-parisc

Add functions to retrieve TOC data from firmware both
for 1.1 and 2.0 PDC.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
 arch/parisc/include/asm/pdc.h      |  2 ++
 arch/parisc/include/uapi/asm/pdc.h | 22 ++++++++++++++++++++
 arch/parisc/kernel/firmware.c      | 32 ++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)

diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h
index b388d8176588..18b957a8630d 100644
--- a/arch/parisc/include/asm/pdc.h
+++ b/arch/parisc/include/asm/pdc.h
@@ -51,6 +51,8 @@ int pdc_spaceid_bits(unsigned long *space_bits);
 int pdc_btlb_info(struct pdc_btlb_info *btlb);
 int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path);
 #endif /* !CONFIG_PA20 */
+int pdc_pim_toc11(struct pdc_toc_pim_11 *ret);
+int pdc_pim_toc20(struct pdc_toc_pim_20 *ret);
 int pdc_lan_station_id(char *lan_addr, unsigned long net_hpa);
 
 int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count);
diff --git a/arch/parisc/include/uapi/asm/pdc.h b/arch/parisc/include/uapi/asm/pdc.h
index 15211723ebf5..ad51df8ba952 100644
--- a/arch/parisc/include/uapi/asm/pdc.h
+++ b/arch/parisc/include/uapi/asm/pdc.h
@@ -689,6 +689,28 @@ struct pdc_hpmc_pim_20 { /* PDC_PIM */
 	unsigned long long fr[32];
 };
 
+struct pdc_toc_pim_11 {
+	unsigned int gr[32];
+	unsigned int cr[32];
+	unsigned int sr[8];
+	unsigned int iasq_back;
+	unsigned int iaoq_back;
+	unsigned int check_type;
+	unsigned int hversion;
+	unsigned int cpu_state;
+};
+
+struct pdc_toc_pim_20 {
+	unsigned long long gr[32];
+	unsigned long long cr[32];
+	unsigned long long sr[8];
+	unsigned long long iasq_back;
+	unsigned long long iaoq_back;
+	unsigned int check_type;
+	unsigned int hversion;
+	unsigned int cpu_state;
+};
+
 #endif /* !defined(__ASSEMBLY__) */
 
 #endif /* _UAPI_PARISC_PDC_H */
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index 7034227dbdf3..9179b4409b63 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -1061,6 +1061,38 @@ int pdc_mem_pdt_read_entries(struct pdc_mem_read_pdt *pret,
 	return retval;
 }
 
+/**
+ * pdc_pim_toc11 - Fetch TOC PIM 1.1 data from firmware.
+ * @ret: pointer to return buffer
+ */
+int pdc_pim_toc11(struct pdc_toc_pim_11 *ret)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PIM, PDC_PIM_TOC, __pa(pdc_result),
+			      __pa(ret), sizeof(struct pdc_toc_pim_11));
+	spin_unlock_irqrestore(&pdc_lock, flags);
+	return retval;
+}
+
+/**
+ * pdc_pim_toc20 - Fetch TOC PIM 2.0 data from firmware.
+ * @ret: pointer to return buffer
+ */
+int pdc_pim_toc20(struct pdc_toc_pim_20 *ret)
+{
+	int retval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	retval = mem_pdc_call(PDC_PIM, PDC_PIM_TOC, __pa(pdc_result),
+			      __pa(ret), sizeof(struct pdc_toc_pim_20));
+	spin_unlock_irqrestore(&pdc_lock, flags);
+	return retval;
+}
+
 /**
  * pdc_tod_set - Set the Time-Of-Day clock.
  * @sec: The number of seconds since epoch.
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-10-12 20:52 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-09 21:38 [PATCH 0/2] add TOC support Sven Schnelle
2021-10-09 21:38 ` [PATCH 1/2] parisc/firmware: add functions to retrieve TOC data Sven Schnelle
2021-10-09 21:38 ` [PATCH 2/2] parisc: add support for TOC (transfer of control) Sven Schnelle
2021-10-10  9:13   ` Helge Deller
2021-10-10 11:42     ` Sven Schnelle
2021-10-10 18:38 [PATCH v2 0/2] add TOC support Sven Schnelle
2021-10-10 18:38 ` [PATCH 1/2] parisc/firmware: add functions to retrieve TOC data Sven Schnelle
2021-10-11 15:05   ` Rolf Eike Beer
2021-10-11 20:13     ` Helge Deller
2021-10-12 20:33       ` Sven Schnelle
2021-10-12 20:52         ` Helge Deller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).