LKML Archive mirror
 help / color / mirror / Atom feed
* [PATCH 2/4] x86: Add UV bios call infrastructure
@ 2008-08-22 21:53 Russ Anderson
  0 siblings, 0 replies; 6+ messages in thread
From: Russ Anderson @ 2008-08-22 21:53 UTC (permalink / raw
  To: linux-kernel, mingo, tglx; +Cc: Russ Anderson, Jack Steiner

[PATCH 2/4] x86: Add UV bios call infrastructure

Add the EFI callback function and associated wrapper code.
Initialize SAL system table entry info at boot time.

Signed-off-by: Russ Anderson <rja@sgi.com>
Signed-off-by: Paul Jackson <pj@sgi.com>

---
 arch/x86/kernel/bios_uv.c        |  106 +++++++++++++++++++++++++++++++--------
 arch/x86/kernel/genx2apic_uv_x.c |    1 
 include/asm-x86/uv/bios.h        |   58 +++++++++++----------
 3 files changed, 117 insertions(+), 48 deletions(-)

Index: linux/arch/x86/kernel/bios_uv.c
===================================================================
--- linux.orig/arch/x86/kernel/bios_uv.c	2008-08-22 14:51:54.000000000 -0500
+++ linux/arch/x86/kernel/bios_uv.c	2008-08-22 14:52:00.000000000 -0500
@@ -1,8 +1,6 @@
 /*
  * BIOS run time interface routines.
  *
- *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
- *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 2 of the License, or
@@ -16,33 +14,99 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ *  Copyright (c) Russ Anderson
  */
 
+#include <linux/efi.h>
+#include <linux/io.h>
 #include <asm/uv/bios.h>
 
-const char *
-x86_bios_strerror(long status)
+struct sal_systab sal_systab;
+
+s64 uv_bios_call(int which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5)
 {
-	const char *str;
-	switch (status) {
-	case  0: str = "Call completed without error"; break;
-	case -1: str = "Not implemented"; break;
-	case -2: str = "Invalid argument"; break;
-	case -3: str = "Call completed with error"; break;
-	default: str = "Unknown BIOS status code"; break;
-	}
-	return str;
+	struct sal_systab *tab = &sal_systab;
+
+	if (tab->function == (unsigned long)NULL)
+		/*
+		 * BIOS does not support SAL systab
+		 */
+		return BIOS_STATUS_UNIMPLEMENTED;
+
+	return efi_call6((void *)__va(tab->function),
+					which, a1, a2, a3, a4, a5);
 }
 
-long
-x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
-		   unsigned long *drift_info)
+s64 uv_bios_call_irqsave(int which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5)
 {
-	struct uv_bios_retval isrv;
+	unsigned long bios_flags;
+	s64 ret;
 
-	BIOS_CALL(isrv, BIOS_FREQ_BASE, which, 0, 0, 0, 0, 0, 0);
-	*ticks_per_second = isrv.v0;
-	*drift_info = isrv.v1;
-	return isrv.status;
+	local_irq_save(bios_flags);
+	ret = uv_bios_call(which, a1, a2, a3, a4, a5);
+	local_irq_restore(bios_flags);
+
+	return ret;
+}
+
+s64 uv_bios_call_reentrant(int which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5)
+{
+	s64 ret;
+
+	preempt_disable();
+	ret = uv_bios_call(which, a1, a2, a3, a4, a5);
+	preempt_enable();
+
+	return ret;
+}
+
+long
+x86_bios_freq_base(unsigned long clock_type, unsigned long *ticks_per_second,
+					unsigned long *drift_info)
+{
+	return uv_bios_call(BIOS_FREQ_BASE, clock_type,
+				(u64)ticks_per_second, 0, 0, 0);
 }
 EXPORT_SYMBOL_GPL(x86_bios_freq_base);
+
+
+#ifdef CONFIG_EFI
+void uv_bios_init(void)
+{
+	struct sal_systab *tab;
+
+	if ((efi.sal_systab == EFI_INVALID_TABLE_ADDR) ||
+	    (efi.sal_systab == (unsigned long)NULL)) {
+		printk(KERN_CRIT "No EFI SAL System Table.\n");
+		sal_systab.function = (unsigned long)NULL;
+		return;
+	}
+
+	tab = (struct sal_systab *)ioremap(efi.sal_systab,
+					sizeof(struct sal_systab));
+	if (strncmp(tab->signature, "SST_", 4) != 0)
+		printk(KERN_ERR "bad signature in SAL system table!");
+
+	/*
+	 * Copy table to permanent spot for later use.
+	 */
+	memcpy(&sal_systab, tab, sizeof(struct sal_systab));
+	iounmap(tab);
+
+	printk(KERN_INFO "EFI SAL System Table Revision %d\n", tab->revision);
+}
+#else	/* !CONFIG_EFI */
+/*
+ * IF EFI is not configured, have the EFI calls return unimplemented.
+ */
+u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3,
+			u64 arg4, u64 arg5, u64 arg6)
+{
+	return  BIOS_STATUS_UNIMPLEMENTED;
+}
+
+void uv_bios_init(void) { }
+#endif
+
Index: linux/arch/x86/kernel/genx2apic_uv_x.c
===================================================================
--- linux.orig/arch/x86/kernel/genx2apic_uv_x.c	2008-08-22 14:51:54.000000000 -0500
+++ linux/arch/x86/kernel/genx2apic_uv_x.c	2008-08-22 14:52:00.000000000 -0500
@@ -411,6 +411,7 @@ static __init void uv_system_init(void)
 	gnode_upper = (((unsigned long)node_id.s.node_id) &
 		       ~((1 << n_val) - 1)) << m_val;
 
+	uv_bios_init();
 	uv_rtc_init();
 
 	for_each_present_cpu(cpu) {
Index: linux/include/asm-x86/uv/bios.h
===================================================================
--- linux.orig/include/asm-x86/uv/bios.h	2008-08-22 14:51:54.000000000 -0500
+++ linux/include/asm-x86/uv/bios.h	2008-08-22 14:52:00.000000000 -0500
@@ -2,9 +2,7 @@
 #define ASM_X86__UV__BIOS_H
 
 /*
- * BIOS layer definitions.
- *
- *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ * UV BIOS layer definitions.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -19,6 +17,9 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ *  Copyright (c) Russ Anderson
  */
 
 #include <linux/rtc.h>
@@ -31,38 +32,41 @@ enum {
 	BIOS_FREQ_BASE_REALTIME_CLOCK = 2
 };
 
-# define BIOS_CALL(result, a0, a1, a2, a3, a4, a5, a6, a7)		\
-	do {								\
-		/* XXX - the real call goes here */			\
-		result.status = BIOS_STATUS_UNIMPLEMENTED;		\
-		isrv.v0 = 0;						\
-		isrv.v1 = 0;						\
-	} while (0)
-
+/*
+ * Status values returned from a BIOS call.
+ */
 enum {
 	BIOS_STATUS_SUCCESS		=  0,
-	BIOS_STATUS_UNIMPLEMENTED	= -1,
-	BIOS_STATUS_EINVAL		= -2,
-	BIOS_STATUS_ERROR		= -3
+	BIOS_STATUS_UNIMPLEMENTED	= -ENOSYS,
+	BIOS_STATUS_EINVAL		= -EINVAL,
+	BIOS_STATUS_UNAVAIL		= -EBUSY
 };
 
-struct uv_bios_retval {
-	/*
-	 * A zero status value indicates call completed without error.
-	 * A negative status value indicates reason of call failure.
-	 * A positive status value indicates success but an
-	 * informational value should be printed (e.g., "reboot for
-	 * change to take effect").
-	 */
-	s64 status;
-	u64 v0;
-	u64 v1;
-	u64 v2;
+/*
+ * The SAL system table describes specific firmware
+ * capabilities available to the Linux kernel at runtime.
+ */
+struct sal_systab {
+	char signature[4];	/* must be "SST_" */
+	u32 revision;		/* distinguish different firmware revs */
+	u64 function; 		/* BIOS runtime callback function ptr */
 };
 
+/*
+ * bios calls have 6 parameters
+ */
+extern s64 uv_bios_call(int, u64, u64, u64, u64, u64);
+extern s64 uv_bios_call_irqsave(int, u64, u64, u64, u64, u64);
+extern s64 uv_bios_call_reentrant(int which, u64, u64, u64, u64, u64);
+
+extern void uv_bios_init(void);
+
 extern long
 x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
 		   unsigned long *drift_info);
-extern const char *x86_bios_strerror(long status);
+
+#ifndef CONFIG_EFI
+extern u64 efi_call6(void *, u64, u64, u64, u64, u64, u64);
+#endif
 
 #endif /* ASM_X86__UV__BIOS_H */
-- 
Russ Anderson, OS RAS/Partitioning Project Lead  
SGI - Silicon Graphics Inc          rja@sgi.com

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

* [PATCH 2/4] x86: Add UV bios call infrastructure
@ 2008-09-22 21:09 Russ Anderson
  2008-09-22 22:07 ` H. Peter Anvin
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Russ Anderson @ 2008-09-22 21:09 UTC (permalink / raw
  To: linux-kernel, mingo, tglx; +Cc: H. Peter Anvin, Jack Steiner, Russ Anderson

[PATCH 2/4] Add UV bios call infrastructure

Add the EFI callback function and associated wrapper code.
Initialize SAL system table entry info at boot time.

Signed-off-by: Russ Anderson <rja@sgi.com>
Signed-off-by: Paul Jackson <pj@sgi.com>

---
 arch/x86/kernel/bios_uv.c        |  106 +++++++++++++++++++++++++++++++--------
 arch/x86/kernel/genx2apic_uv_x.c |    1 
 include/asm-x86/uv/bios.h        |   58 +++++++++++----------
 3 files changed, 117 insertions(+), 48 deletions(-)

Index: linux/arch/x86/kernel/bios_uv.c
===================================================================
--- linux.orig/arch/x86/kernel/bios_uv.c	2008-09-22 16:01:00.000000000 -0500
+++ linux/arch/x86/kernel/bios_uv.c	2008-09-22 16:01:11.000000000 -0500
@@ -1,8 +1,6 @@
 /*
  * BIOS run time interface routines.
  *
- *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
- *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 2 of the License, or
@@ -16,33 +14,99 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ *  Copyright (c) Russ Anderson
  */
 
+#include <linux/efi.h>
+#include <linux/io.h>
 #include <asm/uv/bios.h>
 
-const char *
-x86_bios_strerror(long status)
+struct sal_systab sal_systab;
+
+s64 uv_bios_call(int which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5)
 {
-	const char *str;
-	switch (status) {
-	case  0: str = "Call completed without error";	break;
-	case -1: str = "Not implemented";		break;
-	case -2: str = "Invalid argument";		break;
-	case -3: str = "Call completed with error";	break;
-	default: str = "Unknown BIOS status code";	break;
-	}
-	return str;
+	struct sal_systab *tab = &sal_systab;
+
+	if (tab->function == (unsigned long)NULL)
+		/*
+		 * BIOS does not support SAL systab
+		 */
+		return BIOS_STATUS_UNIMPLEMENTED;
+
+	return efi_call6((void *)__va(tab->function),
+					which, a1, a2, a3, a4, a5);
 }
 
-long
-x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
-		   unsigned long *drift_info)
+s64 uv_bios_call_irqsave(int which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5)
 {
-	struct uv_bios_retval isrv;
+	unsigned long bios_flags;
+	s64 ret;
 
-	BIOS_CALL(isrv, BIOS_FREQ_BASE, which, 0, 0, 0, 0, 0, 0);
-	*ticks_per_second = isrv.v0;
-	*drift_info = isrv.v1;
-	return isrv.status;
+	local_irq_save(bios_flags);
+	ret = uv_bios_call(which, a1, a2, a3, a4, a5);
+	local_irq_restore(bios_flags);
+
+	return ret;
+}
+
+s64 uv_bios_call_reentrant(int which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5)
+{
+	s64 ret;
+
+	preempt_disable();
+	ret = uv_bios_call(which, a1, a2, a3, a4, a5);
+	preempt_enable();
+
+	return ret;
+}
+
+long
+x86_bios_freq_base(unsigned long clock_type, unsigned long *ticks_per_second,
+					unsigned long *drift_info)
+{
+	return uv_bios_call(BIOS_FREQ_BASE, clock_type,
+				(u64)ticks_per_second, 0, 0, 0);
 }
 EXPORT_SYMBOL_GPL(x86_bios_freq_base);
+
+
+#ifdef CONFIG_EFI
+void uv_bios_init(void)
+{
+	struct sal_systab *tab;
+
+	if ((efi.sal_systab == EFI_INVALID_TABLE_ADDR) ||
+	    (efi.sal_systab == (unsigned long)NULL)) {
+		printk(KERN_CRIT "No EFI SAL System Table.\n");
+		sal_systab.function = (unsigned long)NULL;
+		return;
+	}
+
+	tab = (struct sal_systab *)ioremap(efi.sal_systab,
+					sizeof(struct sal_systab));
+	if (strncmp(tab->signature, "SST_", 4) != 0)
+		printk(KERN_ERR "bad signature in SAL system table!");
+
+	/*
+	 * Copy table to permanent spot for later use.
+	 */
+	memcpy(&sal_systab, tab, sizeof(struct sal_systab));
+	iounmap(tab);
+
+	printk(KERN_INFO "EFI SAL System Table Revision %d\n", tab->revision);
+}
+#else	/* !CONFIG_EFI */
+/*
+ * IF EFI is not configured, have the EFI calls return unimplemented.
+ */
+u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3,
+			u64 arg4, u64 arg5, u64 arg6)
+{
+	return  BIOS_STATUS_UNIMPLEMENTED;
+}
+
+void uv_bios_init(void) { }
+#endif
+
Index: linux/arch/x86/kernel/genx2apic_uv_x.c
===================================================================
--- linux.orig/arch/x86/kernel/genx2apic_uv_x.c	2008-09-22 16:01:00.000000000 -0500
+++ linux/arch/x86/kernel/genx2apic_uv_x.c	2008-09-22 16:01:11.000000000 -0500
@@ -413,6 +413,7 @@ void __init uv_system_init(void)
 	gnode_upper = (((unsigned long)node_id.s.node_id) &
 		       ~((1 << n_val) - 1)) << m_val;
 
+	uv_bios_init();
 	uv_rtc_init();
 
 	for_each_present_cpu(cpu) {
Index: linux/include/asm-x86/uv/bios.h
===================================================================
--- linux.orig/include/asm-x86/uv/bios.h	2008-09-22 16:01:00.000000000 -0500
+++ linux/include/asm-x86/uv/bios.h	2008-09-22 16:01:11.000000000 -0500
@@ -2,9 +2,7 @@
 #define ASM_X86__UV__BIOS_H
 
 /*
- * BIOS layer definitions.
- *
- *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ * UV BIOS layer definitions.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -19,6 +17,9 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ *  Copyright (c) Russ Anderson
  */
 
 #include <linux/rtc.h>
@@ -31,38 +32,41 @@ enum {
 	BIOS_FREQ_BASE_REALTIME_CLOCK = 2
 };
 
-# define BIOS_CALL(result, a0, a1, a2, a3, a4, a5, a6, a7)		\
-	do {								\
-		/* XXX - the real call goes here */			\
-		result.status = BIOS_STATUS_UNIMPLEMENTED;		\
-		isrv.v0 = 0;						\
-		isrv.v1 = 0;						\
-	} while (0)
-
+/*
+ * Status values returned from a BIOS call.
+ */
 enum {
 	BIOS_STATUS_SUCCESS		=  0,
-	BIOS_STATUS_UNIMPLEMENTED	= -1,
-	BIOS_STATUS_EINVAL		= -2,
-	BIOS_STATUS_ERROR		= -3
+	BIOS_STATUS_UNIMPLEMENTED	= -ENOSYS,
+	BIOS_STATUS_EINVAL		= -EINVAL,
+	BIOS_STATUS_UNAVAIL		= -EBUSY
 };
 
-struct uv_bios_retval {
-	/*
-	 * A zero status value indicates call completed without error.
-	 * A negative status value indicates reason of call failure.
-	 * A positive status value indicates success but an
-	 * informational value should be printed (e.g., "reboot for
-	 * change to take effect").
-	 */
-	s64 status;
-	u64 v0;
-	u64 v1;
-	u64 v2;
+/*
+ * The SAL system table describes specific firmware
+ * capabilities available to the Linux kernel at runtime.
+ */
+struct sal_systab {
+	char signature[4];	/* must be "SST_" */
+	u32 revision;		/* distinguish different firmware revs */
+	u64 function; 		/* BIOS runtime callback function ptr */
 };
 
+/*
+ * bios calls have 6 parameters
+ */
+extern s64 uv_bios_call(int, u64, u64, u64, u64, u64);
+extern s64 uv_bios_call_irqsave(int, u64, u64, u64, u64, u64);
+extern s64 uv_bios_call_reentrant(int which, u64, u64, u64, u64, u64);
+
+extern void uv_bios_init(void);
+
 extern long
 x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
 		   unsigned long *drift_info);
-extern const char *x86_bios_strerror(long status);
+
+#ifndef CONFIG_EFI
+extern u64 efi_call6(void *, u64, u64, u64, u64, u64, u64);
+#endif
 
 #endif /* ASM_X86__UV__BIOS_H */
-- 
Russ Anderson, OS RAS/Partitioning Project Lead  
SGI - Silicon Graphics Inc          rja@sgi.com

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

* Re: [PATCH 2/4] x86: Add UV bios call infrastructure
  2008-09-22 21:09 [PATCH 2/4] x86: Add UV bios call infrastructure Russ Anderson
@ 2008-09-22 22:07 ` H. Peter Anvin
  2008-09-22 22:18   ` Russ Anderson
  2008-09-23 11:07 ` Ingo Molnar
  2008-09-24  3:20 ` Huang Ying
  2 siblings, 1 reply; 6+ messages in thread
From: H. Peter Anvin @ 2008-09-22 22:07 UTC (permalink / raw
  To: Russ Anderson; +Cc: linux-kernel, mingo, tglx, Jack Steiner

Russ Anderson wrote:
> +	if (tab->function == (unsigned long)NULL)

Preferred style is:

	if (!tab->function)

	-hpa

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

* Re: [PATCH 2/4] x86: Add UV bios call infrastructure
  2008-09-22 22:07 ` H. Peter Anvin
@ 2008-09-22 22:18   ` Russ Anderson
  0 siblings, 0 replies; 6+ messages in thread
From: Russ Anderson @ 2008-09-22 22:18 UTC (permalink / raw
  To: H. Peter Anvin; +Cc: linux-kernel, mingo, tglx, Jack Steiner

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

On Mon, Sep 22, 2008 at 03:07:01PM -0700, H. Peter Anvin wrote:
> Russ Anderson wrote:
> >+	if (tab->function == (unsigned long)NULL)
> 
> Preferred style is:
> 
> 	if (!tab->function)
> 
> 	-hpa

Attached is an updated patch.


-- 
Russ Anderson, OS RAS/Partitioning Project Lead  
SGI - Silicon Graphics Inc          rja@sgi.com

[-- Attachment #2: uv_bios_common --]
[-- Type: text/plain, Size: 7465 bytes --]

[PATCH 2/4] Add UV bios call infrastructure

Add the EFI callback function and associated wrapper code.
Initialize SAL system table entry info at boot time.

Signed-off-by: Russ Anderson <rja@sgi.com>
Signed-off-by: Paul Jackson <pj@sgi.com>

---
 arch/x86/kernel/bios_uv.c        |  106 +++++++++++++++++++++++++++++++--------
 arch/x86/kernel/genx2apic_uv_x.c |    1 
 include/asm-x86/uv/bios.h        |   58 +++++++++++----------
 3 files changed, 117 insertions(+), 48 deletions(-)

Index: linux/arch/x86/kernel/bios_uv.c
===================================================================
--- linux.orig/arch/x86/kernel/bios_uv.c	2008-09-22 17:14:08.000000000 -0500
+++ linux/arch/x86/kernel/bios_uv.c	2008-09-22 17:14:39.000000000 -0500
@@ -1,8 +1,6 @@
 /*
  * BIOS run time interface routines.
  *
- *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
- *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 2 of the License, or
@@ -16,33 +14,99 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ *  Copyright (c) Russ Anderson
  */
 
+#include <linux/efi.h>
+#include <linux/io.h>
 #include <asm/uv/bios.h>
 
-const char *
-x86_bios_strerror(long status)
+struct sal_systab sal_systab;
+
+s64 uv_bios_call(int which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5)
 {
-	const char *str;
-	switch (status) {
-	case  0: str = "Call completed without error";	break;
-	case -1: str = "Not implemented";		break;
-	case -2: str = "Invalid argument";		break;
-	case -3: str = "Call completed with error";	break;
-	default: str = "Unknown BIOS status code";	break;
-	}
-	return str;
+	struct sal_systab *tab = &sal_systab;
+
+	if (!tab->function)
+		/*
+		 * BIOS does not support SAL systab
+		 */
+		return BIOS_STATUS_UNIMPLEMENTED;
+
+	return efi_call6((void *)__va(tab->function),
+					which, a1, a2, a3, a4, a5);
 }
 
-long
-x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
-		   unsigned long *drift_info)
+s64 uv_bios_call_irqsave(int which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5)
 {
-	struct uv_bios_retval isrv;
+	unsigned long bios_flags;
+	s64 ret;
 
-	BIOS_CALL(isrv, BIOS_FREQ_BASE, which, 0, 0, 0, 0, 0, 0);
-	*ticks_per_second = isrv.v0;
-	*drift_info = isrv.v1;
-	return isrv.status;
+	local_irq_save(bios_flags);
+	ret = uv_bios_call(which, a1, a2, a3, a4, a5);
+	local_irq_restore(bios_flags);
+
+	return ret;
+}
+
+s64 uv_bios_call_reentrant(int which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5)
+{
+	s64 ret;
+
+	preempt_disable();
+	ret = uv_bios_call(which, a1, a2, a3, a4, a5);
+	preempt_enable();
+
+	return ret;
+}
+
+long
+x86_bios_freq_base(unsigned long clock_type, unsigned long *ticks_per_second,
+					unsigned long *drift_info)
+{
+	return uv_bios_call(BIOS_FREQ_BASE, clock_type,
+				(u64)ticks_per_second, 0, 0, 0);
 }
 EXPORT_SYMBOL_GPL(x86_bios_freq_base);
+
+
+#ifdef CONFIG_EFI
+void uv_bios_init(void)
+{
+	struct sal_systab *tab;
+
+	if ((efi.sal_systab == EFI_INVALID_TABLE_ADDR) ||
+	    (efi.sal_systab == (unsigned long)NULL)) {
+		printk(KERN_CRIT "No EFI SAL System Table.\n");
+		sal_systab.function = (unsigned long)NULL;
+		return;
+	}
+
+	tab = (struct sal_systab *)ioremap(efi.sal_systab,
+					sizeof(struct sal_systab));
+	if (strncmp(tab->signature, "SST_", 4) != 0)
+		printk(KERN_ERR "bad signature in SAL system table!");
+
+	/*
+	 * Copy table to permanent spot for later use.
+	 */
+	memcpy(&sal_systab, tab, sizeof(struct sal_systab));
+	iounmap(tab);
+
+	printk(KERN_INFO "EFI SAL System Table Revision %d\n", tab->revision);
+}
+#else	/* !CONFIG_EFI */
+/*
+ * IF EFI is not configured, have the EFI calls return unimplemented.
+ */
+u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3,
+			u64 arg4, u64 arg5, u64 arg6)
+{
+	return  BIOS_STATUS_UNIMPLEMENTED;
+}
+
+void uv_bios_init(void) { }
+#endif
+
Index: linux/arch/x86/kernel/genx2apic_uv_x.c
===================================================================
--- linux.orig/arch/x86/kernel/genx2apic_uv_x.c	2008-09-22 17:14:08.000000000 -0500
+++ linux/arch/x86/kernel/genx2apic_uv_x.c	2008-09-22 17:14:18.000000000 -0500
@@ -413,6 +413,7 @@ void __init uv_system_init(void)
 	gnode_upper = (((unsigned long)node_id.s.node_id) &
 		       ~((1 << n_val) - 1)) << m_val;
 
+	uv_bios_init();
 	uv_rtc_init();
 
 	for_each_present_cpu(cpu) {
Index: linux/include/asm-x86/uv/bios.h
===================================================================
--- linux.orig/include/asm-x86/uv/bios.h	2008-09-22 17:14:08.000000000 -0500
+++ linux/include/asm-x86/uv/bios.h	2008-09-22 17:14:18.000000000 -0500
@@ -2,9 +2,7 @@
 #define ASM_X86__UV__BIOS_H
 
 /*
- * BIOS layer definitions.
- *
- *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ * UV BIOS layer definitions.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -19,6 +17,9 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ *  Copyright (c) Russ Anderson
  */
 
 #include <linux/rtc.h>
@@ -31,38 +32,41 @@ enum {
 	BIOS_FREQ_BASE_REALTIME_CLOCK = 2
 };
 
-# define BIOS_CALL(result, a0, a1, a2, a3, a4, a5, a6, a7)		\
-	do {								\
-		/* XXX - the real call goes here */			\
-		result.status = BIOS_STATUS_UNIMPLEMENTED;		\
-		isrv.v0 = 0;						\
-		isrv.v1 = 0;						\
-	} while (0)
-
+/*
+ * Status values returned from a BIOS call.
+ */
 enum {
 	BIOS_STATUS_SUCCESS		=  0,
-	BIOS_STATUS_UNIMPLEMENTED	= -1,
-	BIOS_STATUS_EINVAL		= -2,
-	BIOS_STATUS_ERROR		= -3
+	BIOS_STATUS_UNIMPLEMENTED	= -ENOSYS,
+	BIOS_STATUS_EINVAL		= -EINVAL,
+	BIOS_STATUS_UNAVAIL		= -EBUSY
 };
 
-struct uv_bios_retval {
-	/*
-	 * A zero status value indicates call completed without error.
-	 * A negative status value indicates reason of call failure.
-	 * A positive status value indicates success but an
-	 * informational value should be printed (e.g., "reboot for
-	 * change to take effect").
-	 */
-	s64 status;
-	u64 v0;
-	u64 v1;
-	u64 v2;
+/*
+ * The SAL system table describes specific firmware
+ * capabilities available to the Linux kernel at runtime.
+ */
+struct sal_systab {
+	char signature[4];	/* must be "SST_" */
+	u32 revision;		/* distinguish different firmware revs */
+	u64 function; 		/* BIOS runtime callback function ptr */
 };
 
+/*
+ * bios calls have 6 parameters
+ */
+extern s64 uv_bios_call(int, u64, u64, u64, u64, u64);
+extern s64 uv_bios_call_irqsave(int, u64, u64, u64, u64, u64);
+extern s64 uv_bios_call_reentrant(int which, u64, u64, u64, u64, u64);
+
+extern void uv_bios_init(void);
+
 extern long
 x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
 		   unsigned long *drift_info);
-extern const char *x86_bios_strerror(long status);
+
+#ifndef CONFIG_EFI
+extern u64 efi_call6(void *, u64, u64, u64, u64, u64, u64);
+#endif
 
 #endif /* ASM_X86__UV__BIOS_H */

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

* Re: [PATCH 2/4] x86: Add UV bios call infrastructure
  2008-09-22 21:09 [PATCH 2/4] x86: Add UV bios call infrastructure Russ Anderson
  2008-09-22 22:07 ` H. Peter Anvin
@ 2008-09-23 11:07 ` Ingo Molnar
  2008-09-24  3:20 ` Huang Ying
  2 siblings, 0 replies; 6+ messages in thread
From: Ingo Molnar @ 2008-09-23 11:07 UTC (permalink / raw
  To: Russ Anderson, Huang, Ying
  Cc: linux-kernel, tglx, H. Peter Anvin, Jack Steiner


* Russ Anderson <rja@sgi.com> wrote:

> +/*
> + * IF EFI is not configured, have the EFI calls return unimplemented.
> + */
> +u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3,
> +			u64 arg4, u64 arg5, u64 arg6)
> +{
> +	return  BIOS_STATUS_UNIMPLEMENTED;
> +}

> +#ifndef CONFIG_EFI
> +extern u64 efi_call6(void *, u64, u64, u64, u64, u64, u64);
> +#endif

shouldnt this be done in include/asm-x86/efi.h and 
arch/x86/kernel/efi_stub_64.S instead?

	Ingo

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

* Re: [PATCH 2/4] x86: Add UV bios call infrastructure
  2008-09-22 21:09 [PATCH 2/4] x86: Add UV bios call infrastructure Russ Anderson
  2008-09-22 22:07 ` H. Peter Anvin
  2008-09-23 11:07 ` Ingo Molnar
@ 2008-09-24  3:20 ` Huang Ying
  2 siblings, 0 replies; 6+ messages in thread
From: Huang Ying @ 2008-09-24  3:20 UTC (permalink / raw
  To: Russ Anderson; +Cc: linux-kernel, mingo, tglx, H. Peter Anvin, Jack Steiner

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

Hi, Russ,

On Mon, 2008-09-22 at 16:09 -0500, Russ Anderson wrote:
> +
> +s64 uv_bios_call(int which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5)
>  {
> -	const char *str;
> -	switch (status) {
> -	case  0: str = "Call completed without error";	break;
> -	case -1: str = "Not implemented";		break;
> -	case -2: str = "Invalid argument";		break;
> -	case -3: str = "Call completed with error";	break;
> -	default: str = "Unknown BIOS status code";	break;
> -	}
> -	return str;
> +	struct sal_systab *tab = &sal_systab;
> +
> +	if (tab->function == (unsigned long)NULL)
> +		/*
> +		 * BIOS does not support SAL systab
> +		 */
> +		return BIOS_STATUS_UNIMPLEMENTED;
> +
> +	return efi_call6((void *)__va(tab->function),
> +					which, a1, a2, a3, a4, a5);
>  }
[...]
> +#else	/* !CONFIG_EFI */
> +/*
> + * IF EFI is not configured, have the EFI calls return unimplemented.
> + */
> +u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3,
> +			u64 arg4, u64 arg5, u64 arg6)
> +{
> +	return  BIOS_STATUS_UNIMPLEMENTED;
> +}
> +
> +void uv_bios_init(void) { }
> +#endif
> +
[...]
> +
> +#ifndef CONFIG_EFI
> +extern u64 efi_call6(void *, u64, u64, u64, u64, u64, u64);
> +#endif

Either wrap efi_call6() in uv_bios_call() inside #ifdef CONFIG_EFI, or
add efi_call<x>() implementation when CONFIG_EFI is undefined into
include/asm-x86/efi.h.

Best Regards,
Huang Ying


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

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

end of thread, other threads:[~2008-09-24  3:21 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-22 21:09 [PATCH 2/4] x86: Add UV bios call infrastructure Russ Anderson
2008-09-22 22:07 ` H. Peter Anvin
2008-09-22 22:18   ` Russ Anderson
2008-09-23 11:07 ` Ingo Molnar
2008-09-24  3:20 ` Huang Ying
  -- strict thread matches above, loose matches on Subject: below --
2008-08-22 21:53 Russ Anderson

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 read-only IMAP folder(s) and NNTP newsgroup(s).