public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* x86 BIOS interface for partitioning and system serial number on SGI UV
@ 2008-07-31 19:57 Russ Anderson
  2008-08-01 17:34 ` H. Peter Anvin
  0 siblings, 1 reply; 15+ messages in thread
From: Russ Anderson @ 2008-07-31 19:57 UTC (permalink / raw)
  To: mingo, tglx; +Cc: linux-kernel, Jack Steiner, Russ Anderson

x86 BIOS interface for partitioning and system serial number on SGI UV

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

---
 arch/x86/kernel/Makefile         |    2 
 arch/x86/kernel/bios_uv.c        |   87 +++++++++++++++++++++++++-
 arch/x86/kernel/genx2apic_uv_x.c |    8 +-
 arch/x86/kernel/tlb_uv.c         |    5 +
 arch/x86/kernel/uv_proc_fs.c     |  122 +++++++++++++++++++++++++++++++++++++
 include/asm-x86/uv/bios.h        |  127 ++++++++++++++++++++++++++++++++++-----
 6 files changed, 326 insertions(+), 25 deletions(-)

Index: linux/arch/x86/kernel/tlb_uv.c
===================================================================
--- linux.orig/arch/x86/kernel/tlb_uv.c	2008-07-31 14:37:40.000000000 -0500
+++ linux/arch/x86/kernel/tlb_uv.c	2008-07-31 14:44:17.000000000 -0500
@@ -14,6 +14,7 @@
 #include <asm/uv/uv_mmrs.h>
 #include <asm/uv/uv_hub.h>
 #include <asm/uv/uv_bau.h>
+#include <asm/uv/bios.h>
 #include <asm/genapic.h>
 #include <asm/idle.h>
 #include <asm/tsc.h>
@@ -565,7 +566,9 @@ static int __init uv_ptc_init(void)
 	if (!is_uv_system())
 		return 0;
 
-	if (!proc_mkdir("sgi_uv", NULL))
+	if (!sgi_uv_dir)
+		sgi_uv_dir = proc_mkdir("sgi_uv", NULL);
+	if (!sgi_uv_dir)
 		return -EINVAL;
 
 	proc_uv_ptc = create_proc_entry(UV_PTC_BASENAME, 0444, NULL);
Index: linux/arch/x86/kernel/uv_proc_fs.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/x86/kernel/uv_proc_fs.c	2008-07-31 14:44:17.000000000 -0500
@@ -0,0 +1,122 @@
+/*
+ * This file supports the /proc/sgi_uv interfaces for SGI UV.
+ *
+ *  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
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  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/proc_fs.h>
+#include <linux/seq_file.h>
+#include <asm/genapic.h>
+#include <asm/uv/bios.h>
+
+struct proc_dir_entry *sgi_uv_dir;
+
+static int partition_id_show(struct seq_file *s, void *p)
+{
+	seq_printf(s, "%d\n", sn_partition_id);
+	return 0;
+}
+
+static int partition_id_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, partition_id_show, NULL);
+}
+
+static int system_serial_number_show(struct seq_file *s, void *p)
+{
+	seq_printf(s, "%s\n", sn_system_serial_number());
+	return 0;
+}
+
+static int system_serial_number_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, system_serial_number_show, NULL);
+}
+
+static int licenseID_show(struct seq_file *s, void *p)
+{
+	seq_printf(s, "0x%llx\n", sn_partition_serial_number_val());
+	return 0;
+}
+
+static int licenseID_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, licenseID_show, NULL);
+}
+
+static int coherence_id_show(struct seq_file *s, void *p)
+{
+	seq_printf(s, "%d\n", partition_coherence_id());
+
+	return 0;
+}
+
+static int coherence_id_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, coherence_id_show, NULL);
+}
+
+static const struct file_operations proc_partition_id_fops = {
+	.open		= partition_id_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations proc_system_sn_fops = {
+	.open		= system_serial_number_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations proc_license_id_fops = {
+	.open		= licenseID_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations proc_coherence_id_fops = {
+	.open		= coherence_id_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init register_uv_procfs(void)
+{
+	if (!sgi_uv_dir)
+		sgi_uv_dir = proc_mkdir("sgi_uv", NULL);
+	if (!sgi_uv_dir) {
+		printk(KERN_WARNING "proc_mkdir sgi_uv failed \n");
+		return -EINVAL;
+	}
+
+	proc_create("partition_id", 0444, sgi_uv_dir,
+		    &proc_partition_id_fops);
+	proc_create("system_serial_number", 0444, sgi_uv_dir,
+		    &proc_system_sn_fops);
+	proc_create("licenseID", 0444, sgi_uv_dir, &proc_license_id_fops);
+	proc_create("coherence_id", 0444, sgi_uv_dir,
+		    &proc_coherence_id_fops);
+
+	return 0;
+}
+
+__initcall(register_uv_procfs);
Index: linux/arch/x86/kernel/Makefile
===================================================================
--- linux.orig/arch/x86/kernel/Makefile	2008-07-31 14:37:39.000000000 -0500
+++ linux/arch/x86/kernel/Makefile	2008-07-31 14:44:17.000000000 -0500
@@ -104,7 +104,7 @@ obj-$(CONFIG_OLPC)		+= olpc.o
 # 64 bit specific files
 ifeq ($(CONFIG_X86_64),y)
         obj-y				+= genapic_64.o genapic_flat_64.o genx2apic_uv_x.o tlb_uv.o
-	obj-y				+= bios_uv.o
+	obj-y				+= bios_uv.o uv_proc_fs.o
         obj-y				+= genx2apic_cluster.o
         obj-y				+= genx2apic_phys.o
         obj-$(CONFIG_X86_PM_TIMER)	+= pmtimer_64.o
Index: linux/arch/x86/kernel/bios_uv.c
===================================================================
--- linux.orig/arch/x86/kernel/bios_uv.c	2008-07-31 14:37:39.000000000 -0500
+++ linux/arch/x86/kernel/bios_uv.c	2008-07-31 14:44:17.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,12 +14,37 @@
  *  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 <asm/uv/bios.h>
 
+char sn_system_serial_number_string[128];
+EXPORT_SYMBOL(sn_system_serial_number_string);
+u64 sn_partition_serial_number;
+EXPORT_SYMBOL(sn_partition_serial_number);
+u8 sn_partition_id;
+EXPORT_SYMBOL(sn_partition_id);
+u8 uv_type;
+EXPORT_SYMBOL(uv_type);
+u16 uv_nasid_bitmask;
+EXPORT_SYMBOL(uv_nasid_bitmask);
+u8 uv_nasid_shift;
+EXPORT_SYMBOL(uv_nasid_shift);
+u8 uv_system_size;
+EXPORT_SYMBOL(uv_system_size);
+u8 uv_sharing_domain_size;
+EXPORT_SYMBOL(uv_sharing_domain_size);
+u8 uv_coherency_id;
+EXPORT_SYMBOL(uv_coherency_id);
+u8 uv_region_size;
+EXPORT_SYMBOL(uv_region_size);
+
+
 const char *
-x86_bios_strerror(long status)
+uv_bios_strerror(long status)
 {
 	const char *str;
 	switch (status) {
@@ -35,7 +58,7 @@ x86_bios_strerror(long status)
 }
 
 long
-x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
+uv_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
 		   unsigned long *drift_info)
 {
 	struct uv_bios_retval isrv;
@@ -45,4 +68,58 @@ x86_bios_freq_base(unsigned long which, 
 	*drift_info = isrv.v1;
 	return isrv.status;
 }
-EXPORT_SYMBOL_GPL(x86_bios_freq_base);
+EXPORT_SYMBOL_GPL(uv_bios_freq_base);
+
+/*
+ * Returns information about the UV HUB.
+ *  In:
+ *      arg0 - BIOS_GET_SN_INFO
+ *      arg1 - 0 (other values reserved for future use)
+ *  Out:
+ *      v0
+ *		[7:0]   - uv hub version (0=hub1, 1=hub2)
+ *		[15:8]  - Log2 max number of nodes in entire system
+ *		[23:16] - Log2 of nodes per sharing domain
+ *		[31:24] - partition ID
+ *		[39:32] - coherency_id
+ *		[47:40] - regionsize
+ *      v1
+ *		[15:0]  - nasid mask (ex., 0x7ff for 11 bit nasid)
+ *		[23:15] - bit position of low nasid bit
+ */
+u64
+uv_bios_get_sn_info(int fc, u8 *uvtype, u16 *nasid_bitmask, u8 *nasid_shift,
+		    u8 *systemsize, u8 *sharing_domain_size, u8 *partid,
+		    u8 *coher, u8 *reg)
+{
+	struct uv_bios_retval ret_stuff;
+
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	BIOS_CALL_NOLOCK(ret_stuff, BIOS_GET_SN_INFO, fc, 0, 0, 0, 0, 0, 0);
+
+	if (ret_stuff.status < 0)
+		return ret_stuff.status;
+
+	if (uvtype)
+		*uvtype = ret_stuff.v0 & 0xff;
+	if (systemsize)
+		*systemsize = (ret_stuff.v0 >> 8) & 0xff;
+	if (sharing_domain_size)
+		*sharing_domain_size = (ret_stuff.v0 >> 16) & 0xff;
+	if (partid)
+		*partid = (ret_stuff.v0 >> 24) & 0xff;
+	if (coher)
+		*coher = (ret_stuff.v0 >> 32) & 0xff;
+	if (reg)
+		*reg = (ret_stuff.v0 >> 40) & 0xff;
+	if (nasid_bitmask)
+		*nasid_bitmask = (ret_stuff.v1 & 0xffff);
+	if (nasid_shift)
+		*nasid_shift = (ret_stuff.v1 >> 16) & 0xff;
+	return 0;
+}
+
+
Index: linux/arch/x86/kernel/genx2apic_uv_x.c
===================================================================
--- linux.orig/arch/x86/kernel/genx2apic_uv_x.c	2008-07-31 14:42:44.000000000 -0500
+++ linux/arch/x86/kernel/genx2apic_uv_x.c	2008-07-31 14:44:17.000000000 -0500
@@ -344,7 +344,7 @@ static __init void uv_rtc_init(void)
 	long status, ticks_per_sec, drift;
 
 	status =
-	    x86_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
+	    uv_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
 					&drift);
 	if (status != 0 || ticks_per_sec < 100000) {
 		printk(KERN_WARNING
@@ -410,6 +410,10 @@ static __init void uv_system_init(void)
 	gnode_upper = (((unsigned long)node_id.s.node_id) &
 		       ~((1 << n_val) - 1)) << m_val;
 
+	uv_bios_get_sn_info(0, &uv_type, &uv_nasid_bitmask,
+			    &uv_nasid_shift, &uv_system_size,
+			    &uv_sharing_domain_size, &sn_partition_id,
+			    &uv_coherency_id, &uv_region_size);
 	uv_rtc_init();
 
 	for_each_present_cpu(cpu) {
@@ -431,7 +435,7 @@ static __init void uv_system_init(void)
 		uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1;
 		uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper;
 		uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
-		uv_cpu_hub_info(cpu)->coherency_domain_number = 0;/* ZZZ */
+		uv_cpu_hub_info(cpu)->coherency_domain_number = uv_coherency_id;
 		uv_node_to_blade[nid] = blade;
 		uv_cpu_to_blade[cpu] = blade;
 		max_pnode = max(pnode, max_pnode);
Index: linux/include/asm-x86/uv/bios.h
===================================================================
--- linux.orig/include/asm-x86/uv/bios.h	2008-07-31 14:37:42.000000000 -0500
+++ linux/include/asm-x86/uv/bios.h	2008-07-31 14:44:17.000000000 -0500
@@ -1,11 +1,9 @@
-#ifndef _ASM_X86_BIOS_H
-#define _ASM_X86_BIOS_H
+#ifndef _ASM_UV_BIOS_H
+#define _ASM_UV_BIOS_H
 
 /*
  * BIOS layer definitions.
  *
- *  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
@@ -19,11 +17,17 @@
  *  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>
 
-#define BIOS_FREQ_BASE			0x01000001
+#define BIOS_FREQ_BASE			0x01
+#define BIOS_GET_SN_INFO		0x02
+#define BIOS_SYS_SERIAL_GET		0x03
+#define BIOS_PARTITION_SERIAL_GET	0x04
 
 enum {
 	BIOS_FREQ_BASE_PLATFORM = 0,
@@ -31,14 +35,6 @@ 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)
-
 enum {
 	BIOS_STATUS_SUCCESS		=  0,
 	BIOS_STATUS_UNIMPLEMENTED	= -1,
@@ -60,9 +56,108 @@ struct uv_bios_retval {
 	u64 v2;
 };
 
+
+# define BIOS_CALL(result, a0, a1, a2, a3, a4, a5, a6, a7)		\
+	do {								\
+		/* XXX - the real call goes here */			\
+		result.status = BIOS_STATUS_UNIMPLEMENTED;		\
+		result.v0 = 0;						\
+		result.v1 = 0;						\
+	} while (0)
+
+# define BIOS_CALL_NOLOCK(result, a0, a1, a2, a3, a4, a5, a6, a7)	\
+	do {								\
+		unsigned long __bios_flags;				\
+		local_irq_save(__bios_flags);				\
+		/* XXX - the real call goes here */			\
+		local_irq_restore(__bios_flags);			\
+		result.status = BIOS_STATUS_UNIMPLEMENTED;		\
+		result.v0 = 0;						\
+		result.v1 = 0;						\
+	} while (0)
+
+# define BIOS_CALL_REENTRANT(result, a0, a1, a2, a3, a4, a5, a6, a7)	\
+	do {								\
+		preempt_disable();					\
+		/* XXX - the real call goes here */			\
+		preempt_enable();					\
+		result.status = BIOS_STATUS_UNIMPLEMENTED;		\
+		result.v0 = 0;						\
+		result.v1 = 0;						\
+	} while (0)
+
+/*
+ * Retrieve the system serial number as an ASCII string.
+ */
+static inline u64
+uv_bios_sys_serial_get(char *buf)
+{
+	struct uv_bios_retval ret_stuff;
+
+	BIOS_CALL(ret_stuff, BIOS_SYS_SERIAL_GET, buf, 0, 0, 0, 0, 0, 0);
+
+	return ret_stuff.status;
+}
+
+
+extern char sn_system_serial_number_string[];
+extern u64 sn_partition_serial_number;
+
+static inline char *
+sn_system_serial_number(void)
+{
+	if (unlikely(!sn_system_serial_number_string[0]))
+		uv_bios_sys_serial_get(sn_system_serial_number_string);
+
+	return sn_system_serial_number_string;
+}
+/*
+ * Returns a unique id number for this system and partition (suitable for
+ * use with license managers), based in part on the system serial number.
+ */
+static inline u64
+bios_partition_serial_get(void)
+{
+	struct uv_bios_retval ret_stuff;
+	BIOS_CALL_REENTRANT(ret_stuff, BIOS_PARTITION_SERIAL_GET, 0,
+				0, 0, 0, 0, 0, 0);
+	if (ret_stuff.status != 0)
+		return 0;
+	return ret_stuff.v0;
+}
+
+static inline u64
+sn_partition_serial_number_val(void)
+{
+	if (unlikely(sn_partition_serial_number == 0))
+		sn_partition_serial_number = bios_partition_serial_get();
+
+	return sn_partition_serial_number;
+}
+
+
+extern struct proc_dir_entry *sgi_uv_dir;
+/* extern void __init register_uv_procfs(void); */
+
+extern u8 uv_type;
+extern u16 uv_nasid_bitmask;
+extern u8 uv_nasid_shift;
+extern u8 sn_partition_id;
+extern u8 uv_system_size;
+extern u8 uv_sharing_domain_size;
+extern u8 uv_coherency_id;
+extern u8 uv_region_size;
+extern u8 uv_coherency_id;
+#define partition_coherence_id()	(uv_coherency_id)
+
 extern long
-x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
+uv_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
 		   unsigned long *drift_info);
-extern const char *x86_bios_strerror(long status);
+extern u64
+uv_bios_get_sn_info(int fc, u8 *uvtype, u16 *nasid_bitmask, u8 *nasid_shift,
+		    u8 *systemsize, u8 *sharing_domain_size, u8 *partid,
+		    u8 *coher, u8 *reg);
+
+extern const char *uv_bios_strerror(long status);
 
-#endif /* _ASM_X86_BIOS_H */
+#endif /* _ASM_UV_BIOS_H */
-- 
Russ Anderson, OS RAS/Partitioning Project Lead  
SGI - Silicon Graphics Inc          rja@sgi.com

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

* Re: x86 BIOS interface for partitioning and system serial number on SGI UV
  2008-07-31 19:57 x86 BIOS interface for partitioning and system serial number on SGI UV Russ Anderson
@ 2008-08-01 17:34 ` H. Peter Anvin
  2008-08-04 22:19   ` Russ Anderson
  0 siblings, 1 reply; 15+ messages in thread
From: H. Peter Anvin @ 2008-08-01 17:34 UTC (permalink / raw)
  To: Russ Anderson; +Cc: mingo, tglx, linux-kernel, Jack Steiner

Russ Anderson wrote:
> x86 BIOS interface for partitioning and system serial number on SGI UV

> -	if (!proc_mkdir("sgi_uv", NULL))
> +	if (!sgi_uv_dir)
> +		sgi_uv_dir = proc_mkdir("sgi_uv", NULL);
> +	if (!sgi_uv_dir)
>  		return -EINVAL;

This really seems more that it should belong in sysfs -- 
/sys/class/firmware presumably.

> +# define BIOS_CALL(result, a0, a1, a2, a3, a4, a5, a6, a7)		\
> +	do {								\
> +		/* XXX - the real call goes here */			\
> +		result.status = BIOS_STATUS_UNIMPLEMENTED;		\
> +		result.v0 = 0;						\
> +		result.v1 = 0;						\
> +	} while (0)

I have more than a little problem with submitting patches like this.  We 
have no way to judge the suitability of the coding or the interface with 
the "meat" of the driver stubbed out!

	-hpa

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

* Re: x86 BIOS interface for partitioning and system serial number on SGI UV
  2008-08-01 17:34 ` H. Peter Anvin
@ 2008-08-04 22:19   ` Russ Anderson
  2008-08-05  0:50     ` H. Peter Anvin
                       ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Russ Anderson @ 2008-08-04 22:19 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: mingo, tglx, linux-kernel, Jack Steiner

On Fri, Aug 01, 2008 at 10:34:30AM -0700, H. Peter Anvin wrote:
> Russ Anderson wrote:
> >x86 BIOS interface for partitioning and system serial number on SGI UV
> 
> >-	if (!proc_mkdir("sgi_uv", NULL))
> >+	if (!sgi_uv_dir)
> >+		sgi_uv_dir = proc_mkdir("sgi_uv", NULL);
> >+	if (!sgi_uv_dir)
> > 		return -EINVAL;
> 
> This really seems more that it should belong in sysfs -- 
> /sys/class/firmware presumably.

/proc/sgi_uv already exists, similar to /proc/sgi_sn on Itanium systems.

Would it be /sys/class/firmware?  Reading Documentation/sysfs-rules.txt
seems to indicate somewhere under /sys/devices, such as /sys/devices/system/,
but I may be wrong.

> >+# define BIOS_CALL(result, a0, a1, a2, a3, a4, a5, a6, a7)		\
> >+	do {								\
> >+		/* XXX - the real call goes here */			\
> >+		result.status = BIOS_STATUS_UNIMPLEMENTED;		\
> >+		result.v0 = 0;						\
> >+		result.v1 = 0;						\
> >+	} while (0)
> 
> I have more than a little problem with submitting patches like this.  We 
> have no way to judge the suitability of the coding or the interface with 
> the "meat" of the driver stubbed out!

This is also code for hardware that does not exist.  In order for the
code to be in distro releases in time for the hardware to ship, we
must push it _before_ we have hardware.  The main concern is getting in
interfaces now, because the interfaces cannot change in a minor release.
Providing more "meat" is on the ToDo list.  

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

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

* Re: x86 BIOS interface for partitioning and system serial number on SGI UV
  2008-08-04 22:19   ` Russ Anderson
@ 2008-08-05  0:50     ` H. Peter Anvin
  2008-08-05  0:59     ` H. Peter Anvin
  2008-08-05  5:21     ` Kyle Moffett
  2 siblings, 0 replies; 15+ messages in thread
From: H. Peter Anvin @ 2008-08-05  0:50 UTC (permalink / raw)
  To: Russ Anderson; +Cc: mingo, tglx, linux-kernel, Jack Steiner

Russ Anderson wrote:
> 
> /proc/sgi_uv already exists, similar to /proc/sgi_sn on Itanium systems.
> 

Both those to be really awful.

> Would it be /sys/class/firmware?  Reading Documentation/sysfs-rules.txt
> seems to indicate somewhere under /sys/devices, such as /sys/devices/system/,
> but I may be wrong.
> 
>>> +# define BIOS_CALL(result, a0, a1, a2, a3, a4, a5, a6, a7)		\
>>> +	do {								\
>>> +		/* XXX - the real call goes here */			\
>>> +		result.status = BIOS_STATUS_UNIMPLEMENTED;		\
>>> +		result.v0 = 0;						\
>>> +		result.v1 = 0;						\
>>> +	} while (0)
>> I have more than a little problem with submitting patches like this.  We 
>> have no way to judge the suitability of the coding or the interface with 
>> the "meat" of the driver stubbed out!
> 
> This is also code for hardware that does not exist.  In order for the
> code to be in distro releases in time for the hardware to ship, we
> must push it _before_ we have hardware.  The main concern is getting in
> interfaces now, because the interfaces cannot change in a minor release.
> Providing more "meat" is on the ToDo list.  

You could still document the intended interface so we know how it is 
supposed to work.  At this point, you're basically saying "trust us", 
which really isn't how the Linux community is supposed to work.

	-hpa

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

* Re: x86 BIOS interface for partitioning and system serial number on SGI UV
  2008-08-04 22:19   ` Russ Anderson
  2008-08-05  0:50     ` H. Peter Anvin
@ 2008-08-05  0:59     ` H. Peter Anvin
  2008-08-05  3:54       ` Greg KH
  2008-08-05  5:21     ` Kyle Moffett
  2 siblings, 1 reply; 15+ messages in thread
From: H. Peter Anvin @ 2008-08-05  0:59 UTC (permalink / raw)
  To: Russ Anderson; +Cc: mingo, tglx, linux-kernel, Jack Steiner, Greg KH

Russ Anderson wrote:
>> This really seems more that it should belong in sysfs -- 
>> /sys/class/firmware presumably.
> 
> /proc/sgi_uv already exists, similar to /proc/sgi_sn on Itanium systems.
> 
> Would it be /sys/class/firmware?  Reading Documentation/sysfs-rules.txt
> seems to indicate somewhere under /sys/devices, such as /sys/devices/system/,
> but I may be wrong.

/sys/class/firmware is usually where firmware-related things end up, but 
gregkh is the authority on sysfs organization.

	-hpa

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

* Re: x86 BIOS interface for partitioning and system serial number on SGI UV
  2008-08-05  0:59     ` H. Peter Anvin
@ 2008-08-05  3:54       ` Greg KH
  2008-08-05 16:32         ` Russ Anderson
  2008-08-05 23:06         ` Russ Anderson
  0 siblings, 2 replies; 15+ messages in thread
From: Greg KH @ 2008-08-05  3:54 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: Russ Anderson, mingo, tglx, linux-kernel, Jack Steiner

On Mon, Aug 04, 2008 at 05:59:42PM -0700, H. Peter Anvin wrote:
> Russ Anderson wrote:
>>> This really seems more that it should belong in sysfs -- 
>>> /sys/class/firmware presumably.
>> /proc/sgi_uv already exists, similar to /proc/sgi_sn on Itanium systems.
>> Would it be /sys/class/firmware?  Reading Documentation/sysfs-rules.txt
>> seems to indicate somewhere under /sys/devices, such as 
>> /sys/devices/system/,
>> but I may be wrong.
>
> /sys/class/firmware is usually where firmware-related things end up, but 
> gregkh is the authority on sysfs organization.

/sys/class/firmware has a few users, but perhaps you are thinking of
/sys/firmware instead?  That's probably the better place for something
that is not using the firmware class itself.

thanks,

greg k-h

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

* Re: x86 BIOS interface for partitioning and system serial number on SGI UV
  2008-08-04 22:19   ` Russ Anderson
  2008-08-05  0:50     ` H. Peter Anvin
  2008-08-05  0:59     ` H. Peter Anvin
@ 2008-08-05  5:21     ` Kyle Moffett
  2008-08-05 14:35       ` Mike Travis
  2 siblings, 1 reply; 15+ messages in thread
From: Kyle Moffett @ 2008-08-05  5:21 UTC (permalink / raw)
  To: Russ Anderson; +Cc: H. Peter Anvin, mingo, tglx, linux-kernel, Jack Steiner

On Mon, Aug 4, 2008 at 6:19 PM, Russ Anderson <rja@sgi.com> wrote:
> On Fri, Aug 01, 2008 at 10:34:30AM -0700, H. Peter Anvin wrote:
>>Russ Anderson wrote:
>>>+# define BIOS_CALL(result, a0, a1, a2, a3, a4, a5, a6, a7)          \
>>>+    do {                                                            \
>>>+            /* XXX - the real call goes here */                     \
>>>+            result.status = BIOS_STATUS_UNIMPLEMENTED;              \
>>>+            result.v0 = 0;                                          \
>>>+            result.v1 = 0;                                          \
>>>+    } while (0)
>>
>> I have more than a little problem with submitting patches like this.  We
>> have no way to judge the suitability of the coding or the interface with
>> the "meat" of the driver stubbed out!
>
> This is also code for hardware that does not exist.  In order for the
> code to be in distro releases in time for the hardware to ship, we
> must push it _before_ we have hardware.  The main concern is getting in
> interfaces now, because the interfaces cannot change in a minor release.
> Providing more "meat" is on the ToDo list.

These kinds of statements are not the way to get things done on LKML.
Quite a number of people have gotten flamed/ignored/etc lately by
making statements "We need this (unfinished code) in the kernel by
2.6.27 because RHEL6 is going to use 2.6.27 and otherwise we won't be
supported in RHEL6".

Cheers,
Kyle Moffett

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

* Re: x86 BIOS interface for partitioning and system serial number on SGI UV
  2008-08-05  5:21     ` Kyle Moffett
@ 2008-08-05 14:35       ` Mike Travis
  2008-08-05 15:40         ` H. Peter Anvin
  0 siblings, 1 reply; 15+ messages in thread
From: Mike Travis @ 2008-08-05 14:35 UTC (permalink / raw)
  To: Kyle Moffett
  Cc: Russ Anderson, H. Peter Anvin, mingo, tglx, linux-kernel,
	Jack Steiner

Kyle Moffett wrote:
> On Mon, Aug 4, 2008 at 6:19 PM, Russ Anderson <rja@sgi.com> wrote:
>> On Fri, Aug 01, 2008 at 10:34:30AM -0700, H. Peter Anvin wrote:
>>> Russ Anderson wrote:
>>>> +# define BIOS_CALL(result, a0, a1, a2, a3, a4, a5, a6, a7)          \
>>>> +    do {                                                            \
>>>> +            /* XXX - the real call goes here */                     \
>>>> +            result.status = BIOS_STATUS_UNIMPLEMENTED;              \
>>>> +            result.v0 = 0;                                          \
>>>> +            result.v1 = 0;                                          \
>>>> +    } while (0)
>>> I have more than a little problem with submitting patches like this.  We
>>> have no way to judge the suitability of the coding or the interface with
>>> the "meat" of the driver stubbed out!
>> This is also code for hardware that does not exist.  In order for the
>> code to be in distro releases in time for the hardware to ship, we
>> must push it _before_ we have hardware.  The main concern is getting in
>> interfaces now, because the interfaces cannot change in a minor release.
>> Providing more "meat" is on the ToDo list.
> 
> These kinds of statements are not the way to get things done on LKML.
> Quite a number of people have gotten flamed/ignored/etc lately by
> making statements "We need this (unfinished code) in the kernel by
> 2.6.27 because RHEL6 is going to use 2.6.27 and otherwise we won't be
> supported in RHEL6".
> 
> Cheers,
> Kyle Moffett

Hi Kyle,

As I'm very new to this development arena, could you explain a bit more
on why this is considered "bad manners"?

I'm not speaking of any particular change, but there are some realities in
bringing a new product to market that depends heavily on new "features"
being accepted into a specific kernel release.  I certainly do not want
to "taint" any kernel code (and I'm always amazed at the dedication of
so many individuals to insure this doesn't happen), but the line between
acceptability (and not) seems to waver all over the place... ;-)

Thanks,
Mike


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

* Re: x86 BIOS interface for partitioning and system serial number on SGI UV
  2008-08-05 14:35       ` Mike Travis
@ 2008-08-05 15:40         ` H. Peter Anvin
  2008-08-05 15:56           ` Mike Travis
  0 siblings, 1 reply; 15+ messages in thread
From: H. Peter Anvin @ 2008-08-05 15:40 UTC (permalink / raw)
  To: Mike Travis
  Cc: Kyle Moffett, Russ Anderson, mingo, tglx, linux-kernel,
	Jack Steiner

Mike Travis wrote:
> 
> Hi Kyle,
> 
> As I'm very new to this development arena, could you explain a bit more
> on why this is considered "bad manners"?
> 
> I'm not speaking of any particular change, but there are some realities in
> bringing a new product to market that depends heavily on new "features"
> being accepted into a specific kernel release.  I certainly do not want
> to "taint" any kernel code (and I'm always amazed at the dedication of
> so many individuals to insure this doesn't happen), but the line between
> acceptability (and not) seems to waver all over the place... ;-)
> 

It's because it's your responsibility to get the code in by whenever you 
need it to, but trying to push unfinished code with the motivation "we 
need it in by <release>" violates the development model *and* is just 
plain rude.

This comes down to the old saying "lack of planning on your part does 
not constitute an emergency on my part."

In other words, if you want to push code in by a specific release, the 
code needs to be *done* and properly submitted.  Submitting code that 
has a big "real code goes here" comment, is ridiculous.

Unfortunately we have seen a *lot* of that from several people at SGI 
over the last year.

	-hpa


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

* Re: x86 BIOS interface for partitioning and system serial number on SGI UV
  2008-08-05 15:40         ` H. Peter Anvin
@ 2008-08-05 15:56           ` Mike Travis
  0 siblings, 0 replies; 15+ messages in thread
From: Mike Travis @ 2008-08-05 15:56 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Kyle Moffett, Russ Anderson, mingo, tglx, linux-kernel,
	Jack Steiner

H. Peter Anvin wrote:
> Mike Travis wrote:
>>
>> Hi Kyle,
>>
>> As I'm very new to this development arena, could you explain a bit more
>> on why this is considered "bad manners"?
>>
>> I'm not speaking of any particular change, but there are some
>> realities in
>> bringing a new product to market that depends heavily on new "features"
>> being accepted into a specific kernel release.  I certainly do not want
>> to "taint" any kernel code (and I'm always amazed at the dedication of
>> so many individuals to insure this doesn't happen), but the line between
>> acceptability (and not) seems to waver all over the place... ;-)
>>
> 
> It's because it's your responsibility to get the code in by whenever you
> need it to, but trying to push unfinished code with the motivation "we
> need it in by <release>" violates the development model *and* is just
> plain rude.
> 
> This comes down to the old saying "lack of planning on your part does
> not constitute an emergency on my part."
> 
> In other words, if you want to push code in by a specific release, the
> code needs to be *done* and properly submitted.  Submitting code that
> has a big "real code goes here" comment, is ridiculous.
> 
> Unfortunately we have seen a *lot* of that from several people at SGI
> over the last year.
> 
>     -hpa

Hi Peter,

Ok, thanks, I do see your point (very clearly), as I prepare yet another
"we really, really need this" patch... ;-)

[ok, it's only a led driver and the world won't stop if it doesn't show up
in the kernel... ;-)]

Cheers,
Mike

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

* Re: x86 BIOS interface for partitioning and system serial number on SGI UV
  2008-08-05  3:54       ` Greg KH
@ 2008-08-05 16:32         ` Russ Anderson
  2008-08-05 16:53           ` Greg KH
  2008-08-05 23:06         ` Russ Anderson
  1 sibling, 1 reply; 15+ messages in thread
From: Russ Anderson @ 2008-08-05 16:32 UTC (permalink / raw)
  To: Greg KH; +Cc: H. Peter Anvin, mingo, tglx, linux-kernel, Jack Steiner

On Mon, Aug 04, 2008 at 08:54:50PM -0700, Greg KH wrote:
> On Mon, Aug 04, 2008 at 05:59:42PM -0700, H. Peter Anvin wrote:
> > Russ Anderson wrote:
> >>> This really seems more that it should belong in sysfs -- 
> >>> /sys/class/firmware presumably.
> >> /proc/sgi_uv already exists, similar to /proc/sgi_sn on Itanium systems.
> >> Would it be /sys/class/firmware?  Reading Documentation/sysfs-rules.txt
> >> seems to indicate somewhere under /sys/devices, such as 
> >> /sys/devices/system/,
> >> but I may be wrong.
> >
> > /sys/class/firmware is usually where firmware-related things end up, but 
> > gregkh is the authority on sysfs organization.
> 
> /sys/class/firmware has a few users, but perhaps you are thinking of
> /sys/firmware instead?  That's probably the better place for something
> that is not using the firmware class itself.

Hi Greg,

If /sys/firmware is the right place, that is where I will put it.

Are the rules for /sys/firmware documented?  Documentation/sysfs-rules.txt
does not mention /sys/firmware.  It seems to indicate that /sys/class
should only contain symlinks:

  There are currently three places for classification of devices:
  /sys/block, /sys/class and /sys/bus. It is planned that these will
  not contain any device directories themselves, but only flat lists of
  symlinks pointing to the unified /sys/devices tree.

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

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

* Re: x86 BIOS interface for partitioning and system serial number on SGI UV
  2008-08-05 16:32         ` Russ Anderson
@ 2008-08-05 16:53           ` Greg KH
  2008-08-05 19:22             ` Russ Anderson
  0 siblings, 1 reply; 15+ messages in thread
From: Greg KH @ 2008-08-05 16:53 UTC (permalink / raw)
  To: Russ Anderson; +Cc: H. Peter Anvin, mingo, tglx, linux-kernel, Jack Steiner

On Tue, Aug 05, 2008 at 11:32:30AM -0500, Russ Anderson wrote:
> On Mon, Aug 04, 2008 at 08:54:50PM -0700, Greg KH wrote:
> > On Mon, Aug 04, 2008 at 05:59:42PM -0700, H. Peter Anvin wrote:
> > > Russ Anderson wrote:
> > >>> This really seems more that it should belong in sysfs -- 
> > >>> /sys/class/firmware presumably.
> > >> /proc/sgi_uv already exists, similar to /proc/sgi_sn on Itanium systems.
> > >> Would it be /sys/class/firmware?  Reading Documentation/sysfs-rules.txt
> > >> seems to indicate somewhere under /sys/devices, such as 
> > >> /sys/devices/system/,
> > >> but I may be wrong.
> > >
> > > /sys/class/firmware is usually where firmware-related things end up, but 
> > > gregkh is the authority on sysfs organization.
> > 
> > /sys/class/firmware has a few users, but perhaps you are thinking of
> > /sys/firmware instead?  That's probably the better place for something
> > that is not using the firmware class itself.
> 
> Hi Greg,
> 
> If /sys/firmware is the right place, that is where I will put it.
> 
> Are the rules for /sys/firmware documented?  Documentation/sysfs-rules.txt
> does not mention /sys/firmware.  It seems to indicate that /sys/class
> should only contain symlinks:

Yes, using /sys/class is when using a 'struct device', is that what you
are using, or are you stuck with "raw" kobjects?

What exactly are you wanting to place in sysfs?  That will make it
easier to determine where to put it :)

Do you have a patch showing what you are proposing?

thanks,

greg k-h

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

* RE: x86 BIOS interface for partitioning and system serial number on SGI UV
@ 2008-08-05 17:24 H. Peter Anvin
  0 siblings, 0 replies; 15+ messages in thread
From: H. Peter Anvin @ 2008-08-05 17:24 UTC (permalink / raw)
  To: Mike Travis
  Cc: Kyle Moffett, Russ Anderson, mingo, tglx, linux-kernel,
	Jack Steiner

For code that is ready you should of course have a reasonable expectation that the code should go in in a timely manner.  Anything other than that would be blatantly unfair.  What I have reacted to is (a) the pushing of code which is obviously not even complete, and (b) demanding that *other* people prioritize you particular problems.  Both of these are blatantly abusive.

-- 
Sent from my mobile phone (pardon any lack of formatting)


-----Original Message-----
From: Mike Travis <travis@sgi.com>
Sent: Tuesday, August 05, 2008 8:56
To: H. Peter Anvin <hpa@zytor.com>
Cc: Kyle Moffett <kyle@moffetthome.net>; Russ Anderson <rja@sgi.com>; mingo@elte.hu; tglx@linutronix.de; linux-kernel@vger.kernel.org; Jack Steiner <steiner@sgi.com>
Subject: Re: x86 BIOS interface for partitioning and system serial number on SGI UV

H. Peter Anvin wrote:
> Mike Travis wrote:
>>
>> Hi Kyle,
>>
>> As I'm very new to this development arena, could you explain a bit more
>> on why this is considered "bad manners"?
>>
>> I'm not speaking of any particular change, but there are some
>> realities in
>> bringing a new product to market that depends heavily on new "features"
>> being accepted into a specific kernel release.  I certainly do not want
>> to "taint" any kernel code (and I'm always amazed at the dedication of
>> so many individuals to insure this doesn't happen), but the line between
>> acceptability (and not) seems to waver all over the place... ;-)
>>
> 
> It's because it's your responsibility to get the code in by whenever you
> need it to, but trying to push unfinished code with the motivation "we
> need it in by <release>" violates the development model *and* is just
> plain rude.
> 
> This comes down to the old saying "lack of planning on your part does
> not constitute an emergency on my part."
> 
> In other words, if you want to push code in by a specific release, the
> code needs to be *done* and properly submitted.  Submitting code that
> has a big "real code goes here" comment, is ridiculous.
> 
> Unfortunately we have seen a *lot* of that from several people at SGI
> over the last year.
> 
>     -hpa

Hi Peter,

Ok, thanks, I do see your point (very clearly), as I prepare yet another
"we really, really need this" patch... ;-)

[ok, it's only a led driver and the world won't stop if it doesn't show up
in the kernel... ;-)]

Cheers,
Mike


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

* Re: x86 BIOS interface for partitioning and system serial number on SGI UV
  2008-08-05 16:53           ` Greg KH
@ 2008-08-05 19:22             ` Russ Anderson
  0 siblings, 0 replies; 15+ messages in thread
From: Russ Anderson @ 2008-08-05 19:22 UTC (permalink / raw)
  To: Greg KH; +Cc: H. Peter Anvin, mingo, tglx, linux-kernel, Jack Steiner

On Tue, Aug 05, 2008 at 09:53:45AM -0700, Greg KH wrote:
> On Tue, Aug 05, 2008 at 11:32:30AM -0500, Russ Anderson wrote:
> > 
> > Hi Greg,
> > 
> > If /sys/firmware is the right place, that is where I will put it.
> > 
> > Are the rules for /sys/firmware documented?  Documentation/sysfs-rules.txt
> > does not mention /sys/firmware.  It seems to indicate that /sys/class
> > should only contain symlinks:
> 
> Yes, using /sys/class is when using a 'struct device', is that what you
> are using, or are you stuck with "raw" kobjects?

Whatever makes the most sense.

> What exactly are you wanting to place in sysfs?  That will make it
> easier to determine where to put it :)

This patch has four entries: partition_id, coherence_id, system_serial_number, 
and licenseID.  Each of the values comes from bios.  The values are either
u64 or char string.  The values are read only in sysfs.

On ia64, this functionality is in /proc/sgi_sn/ for SGI Altix.  The intent
is to provide similar functionality for SGI UV on x86.  ia64 linux uses 
SAL calls to get the information.  For x86, the intent is to have comparable 
bios calls to get the data.

> Do you have a patch showing what you are proposing?

This is the patch using /proc/.

-----------------------------------------------------------------
SGI UV support for partitioning and system serial number.

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

---
 arch/x86/kernel/Makefile         |    2 
 arch/x86/kernel/bios_uv.c        |   87 +++++++++++++++++++++++++-
 arch/x86/kernel/genx2apic_uv_x.c |    8 +-
 arch/x86/kernel/tlb_uv.c         |    5 +
 arch/x86/kernel/uv_proc_fs.c     |  122 +++++++++++++++++++++++++++++++++++++
 include/asm-x86/uv/bios.h        |  127 ++++++++++++++++++++++++++++++++++-----
 6 files changed, 326 insertions(+), 25 deletions(-)

Index: linux/arch/x86/kernel/tlb_uv.c
===================================================================
--- linux.orig/arch/x86/kernel/tlb_uv.c	2008-07-31 14:37:40.000000000 -0500
+++ linux/arch/x86/kernel/tlb_uv.c	2008-07-31 14:44:17.000000000 -0500
@@ -14,6 +14,7 @@
 #include <asm/uv/uv_mmrs.h>
 #include <asm/uv/uv_hub.h>
 #include <asm/uv/uv_bau.h>
+#include <asm/uv/bios.h>
 #include <asm/genapic.h>
 #include <asm/idle.h>
 #include <asm/tsc.h>
@@ -565,7 +566,9 @@ static int __init uv_ptc_init(void)
 	if (!is_uv_system())
 		return 0;
 
-	if (!proc_mkdir("sgi_uv", NULL))
+	if (!sgi_uv_dir)
+		sgi_uv_dir = proc_mkdir("sgi_uv", NULL);
+	if (!sgi_uv_dir)
 		return -EINVAL;
 
 	proc_uv_ptc = create_proc_entry(UV_PTC_BASENAME, 0444, NULL);
Index: linux/arch/x86/kernel/uv_proc_fs.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/x86/kernel/uv_proc_fs.c	2008-07-31 14:44:17.000000000 -0500
@@ -0,0 +1,122 @@
+/*
+ * This file supports the /proc/sgi_uv interfaces for SGI UV.
+ *
+ *  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
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  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/proc_fs.h>
+#include <linux/seq_file.h>
+#include <asm/genapic.h>
+#include <asm/uv/bios.h>
+
+struct proc_dir_entry *sgi_uv_dir;
+
+static int partition_id_show(struct seq_file *s, void *p)
+{
+	seq_printf(s, "%d\n", sn_partition_id);
+	return 0;
+}
+
+static int partition_id_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, partition_id_show, NULL);
+}
+
+static int system_serial_number_show(struct seq_file *s, void *p)
+{
+	seq_printf(s, "%s\n", sn_system_serial_number());
+	return 0;
+}
+
+static int system_serial_number_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, system_serial_number_show, NULL);
+}
+
+static int licenseID_show(struct seq_file *s, void *p)
+{
+	seq_printf(s, "0x%llx\n", sn_partition_serial_number_val());
+	return 0;
+}
+
+static int licenseID_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, licenseID_show, NULL);
+}
+
+static int coherence_id_show(struct seq_file *s, void *p)
+{
+	seq_printf(s, "%d\n", partition_coherence_id());
+
+	return 0;
+}
+
+static int coherence_id_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, coherence_id_show, NULL);
+}
+
+static const struct file_operations proc_partition_id_fops = {
+	.open		= partition_id_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations proc_system_sn_fops = {
+	.open		= system_serial_number_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations proc_license_id_fops = {
+	.open		= licenseID_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations proc_coherence_id_fops = {
+	.open		= coherence_id_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init register_uv_procfs(void)
+{
+	if (!sgi_uv_dir)
+		sgi_uv_dir = proc_mkdir("sgi_uv", NULL);
+	if (!sgi_uv_dir) {
+		printk(KERN_WARNING "proc_mkdir sgi_uv failed \n");
+		return -EINVAL;
+	}
+
+	proc_create("partition_id", 0444, sgi_uv_dir,
+		    &proc_partition_id_fops);
+	proc_create("system_serial_number", 0444, sgi_uv_dir,
+		    &proc_system_sn_fops);
+	proc_create("licenseID", 0444, sgi_uv_dir, &proc_license_id_fops);
+	proc_create("coherence_id", 0444, sgi_uv_dir,
+		    &proc_coherence_id_fops);
+
+	return 0;
+}
+
+__initcall(register_uv_procfs);
Index: linux/arch/x86/kernel/Makefile
===================================================================
--- linux.orig/arch/x86/kernel/Makefile	2008-07-31 14:37:39.000000000 -0500
+++ linux/arch/x86/kernel/Makefile	2008-07-31 14:44:17.000000000 -0500
@@ -104,7 +104,7 @@ obj-$(CONFIG_OLPC)		+= olpc.o
 # 64 bit specific files
 ifeq ($(CONFIG_X86_64),y)
         obj-y				+= genapic_64.o genapic_flat_64.o genx2apic_uv_x.o tlb_uv.o
-	obj-y				+= bios_uv.o
+	obj-y				+= bios_uv.o uv_proc_fs.o
         obj-y				+= genx2apic_cluster.o
         obj-y				+= genx2apic_phys.o
         obj-$(CONFIG_X86_PM_TIMER)	+= pmtimer_64.o
Index: linux/arch/x86/kernel/bios_uv.c
===================================================================
--- linux.orig/arch/x86/kernel/bios_uv.c	2008-07-31 14:37:39.000000000 -0500
+++ linux/arch/x86/kernel/bios_uv.c	2008-07-31 14:44:17.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,12 +14,37 @@
  *  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 <asm/uv/bios.h>
 
+char sn_system_serial_number_string[128];
+EXPORT_SYMBOL(sn_system_serial_number_string);
+u64 sn_partition_serial_number;
+EXPORT_SYMBOL(sn_partition_serial_number);
+u8 sn_partition_id;
+EXPORT_SYMBOL(sn_partition_id);
+u8 uv_type;
+EXPORT_SYMBOL(uv_type);
+u16 uv_nasid_bitmask;
+EXPORT_SYMBOL(uv_nasid_bitmask);
+u8 uv_nasid_shift;
+EXPORT_SYMBOL(uv_nasid_shift);
+u8 uv_system_size;
+EXPORT_SYMBOL(uv_system_size);
+u8 uv_sharing_domain_size;
+EXPORT_SYMBOL(uv_sharing_domain_size);
+u8 uv_coherency_id;
+EXPORT_SYMBOL(uv_coherency_id);
+u8 uv_region_size;
+EXPORT_SYMBOL(uv_region_size);
+
+
 const char *
-x86_bios_strerror(long status)
+uv_bios_strerror(long status)
 {
 	const char *str;
 	switch (status) {
@@ -35,7 +58,7 @@ x86_bios_strerror(long status)
 }
 
 long
-x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
+uv_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
 		   unsigned long *drift_info)
 {
 	struct uv_bios_retval isrv;
@@ -45,4 +68,58 @@ x86_bios_freq_base(unsigned long which, 
 	*drift_info = isrv.v1;
 	return isrv.status;
 }
-EXPORT_SYMBOL_GPL(x86_bios_freq_base);
+EXPORT_SYMBOL_GPL(uv_bios_freq_base);
+
+/*
+ * Returns information about the UV HUB.
+ *  In:
+ *      arg0 - BIOS_GET_SN_INFO
+ *      arg1 - 0 (other values reserved for future use)
+ *  Out:
+ *      v0
+ *		[7:0]   - uv hub version (0=hub1, 1=hub2)
+ *		[15:8]  - Log2 max number of nodes in entire system
+ *		[23:16] - Log2 of nodes per sharing domain
+ *		[31:24] - partition ID
+ *		[39:32] - coherency_id
+ *		[47:40] - regionsize
+ *      v1
+ *		[15:0]  - nasid mask (ex., 0x7ff for 11 bit nasid)
+ *		[23:15] - bit position of low nasid bit
+ */
+u64
+uv_bios_get_sn_info(int fc, u8 *uvtype, u16 *nasid_bitmask, u8 *nasid_shift,
+		    u8 *systemsize, u8 *sharing_domain_size, u8 *partid,
+		    u8 *coher, u8 *reg)
+{
+	struct uv_bios_retval ret_stuff;
+
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	BIOS_CALL_NOLOCK(ret_stuff, BIOS_GET_SN_INFO, fc, 0, 0, 0, 0, 0, 0);
+
+	if (ret_stuff.status < 0)
+		return ret_stuff.status;
+
+	if (uvtype)
+		*uvtype = ret_stuff.v0 & 0xff;
+	if (systemsize)
+		*systemsize = (ret_stuff.v0 >> 8) & 0xff;
+	if (sharing_domain_size)
+		*sharing_domain_size = (ret_stuff.v0 >> 16) & 0xff;
+	if (partid)
+		*partid = (ret_stuff.v0 >> 24) & 0xff;
+	if (coher)
+		*coher = (ret_stuff.v0 >> 32) & 0xff;
+	if (reg)
+		*reg = (ret_stuff.v0 >> 40) & 0xff;
+	if (nasid_bitmask)
+		*nasid_bitmask = (ret_stuff.v1 & 0xffff);
+	if (nasid_shift)
+		*nasid_shift = (ret_stuff.v1 >> 16) & 0xff;
+	return 0;
+}
+
+
Index: linux/arch/x86/kernel/genx2apic_uv_x.c
===================================================================
--- linux.orig/arch/x86/kernel/genx2apic_uv_x.c	2008-07-31 14:42:44.000000000 -0500
+++ linux/arch/x86/kernel/genx2apic_uv_x.c	2008-07-31 14:44:17.000000000 -0500
@@ -344,7 +344,7 @@ static __init void uv_rtc_init(void)
 	long status, ticks_per_sec, drift;
 
 	status =
-	    x86_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
+	    uv_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
 					&drift);
 	if (status != 0 || ticks_per_sec < 100000) {
 		printk(KERN_WARNING
@@ -410,6 +410,10 @@ static __init void uv_system_init(void)
 	gnode_upper = (((unsigned long)node_id.s.node_id) &
 		       ~((1 << n_val) - 1)) << m_val;
 
+	uv_bios_get_sn_info(0, &uv_type, &uv_nasid_bitmask,
+			    &uv_nasid_shift, &uv_system_size,
+			    &uv_sharing_domain_size, &sn_partition_id,
+			    &uv_coherency_id, &uv_region_size);
 	uv_rtc_init();
 
 	for_each_present_cpu(cpu) {
@@ -431,7 +435,7 @@ static __init void uv_system_init(void)
 		uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1;
 		uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper;
 		uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
-		uv_cpu_hub_info(cpu)->coherency_domain_number = 0;/* ZZZ */
+		uv_cpu_hub_info(cpu)->coherency_domain_number = uv_coherency_id;
 		uv_node_to_blade[nid] = blade;
 		uv_cpu_to_blade[cpu] = blade;
 		max_pnode = max(pnode, max_pnode);
Index: linux/include/asm-x86/uv/bios.h
===================================================================
--- linux.orig/include/asm-x86/uv/bios.h	2008-07-31 14:37:42.000000000 -0500
+++ linux/include/asm-x86/uv/bios.h	2008-07-31 14:44:17.000000000 -0500
@@ -1,11 +1,9 @@
-#ifndef _ASM_X86_BIOS_H
-#define _ASM_X86_BIOS_H
+#ifndef _ASM_UV_BIOS_H
+#define _ASM_UV_BIOS_H
 
 /*
  * BIOS layer definitions.
  *
- *  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
@@ -19,11 +17,17 @@
  *  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>
 
-#define BIOS_FREQ_BASE			0x01000001
+#define BIOS_FREQ_BASE			0x01
+#define BIOS_GET_SN_INFO		0x02
+#define BIOS_SYS_SERIAL_GET		0x03
+#define BIOS_PARTITION_SERIAL_GET	0x04
 
 enum {
 	BIOS_FREQ_BASE_PLATFORM = 0,
@@ -31,14 +35,6 @@ 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)
-
 enum {
 	BIOS_STATUS_SUCCESS		=  0,
 	BIOS_STATUS_UNIMPLEMENTED	= -1,
@@ -60,9 +56,108 @@ struct uv_bios_retval {
 	u64 v2;
 };
 
+
+# define BIOS_CALL(result, a0, a1, a2, a3, a4, a5, a6, a7)		\
+	do {								\
+		/* XXX - the real call goes here */			\
+		result.status = BIOS_STATUS_UNIMPLEMENTED;		\
+		result.v0 = 0;						\
+		result.v1 = 0;						\
+	} while (0)
+
+# define BIOS_CALL_NOLOCK(result, a0, a1, a2, a3, a4, a5, a6, a7)	\
+	do {								\
+		unsigned long __bios_flags;				\
+		local_irq_save(__bios_flags);				\
+		/* XXX - the real call goes here */			\
+		local_irq_restore(__bios_flags);			\
+		result.status = BIOS_STATUS_UNIMPLEMENTED;		\
+		result.v0 = 0;						\
+		result.v1 = 0;						\
+	} while (0)
+
+# define BIOS_CALL_REENTRANT(result, a0, a1, a2, a3, a4, a5, a6, a7)	\
+	do {								\
+		preempt_disable();					\
+		/* XXX - the real call goes here */			\
+		preempt_enable();					\
+		result.status = BIOS_STATUS_UNIMPLEMENTED;		\
+		result.v0 = 0;						\
+		result.v1 = 0;						\
+	} while (0)
+
+/*
+ * Retrieve the system serial number as an ASCII string.
+ */
+static inline u64
+uv_bios_sys_serial_get(char *buf)
+{
+	struct uv_bios_retval ret_stuff;
+
+	BIOS_CALL(ret_stuff, BIOS_SYS_SERIAL_GET, buf, 0, 0, 0, 0, 0, 0);
+
+	return ret_stuff.status;
+}
+
+
+extern char sn_system_serial_number_string[];
+extern u64 sn_partition_serial_number;
+
+static inline char *
+sn_system_serial_number(void)
+{
+	if (unlikely(!sn_system_serial_number_string[0]))
+		uv_bios_sys_serial_get(sn_system_serial_number_string);
+
+	return sn_system_serial_number_string;
+}
+/*
+ * Returns a unique id number for this system and partition (suitable for
+ * use with license managers), based in part on the system serial number.
+ */
+static inline u64
+bios_partition_serial_get(void)
+{
+	struct uv_bios_retval ret_stuff;
+	BIOS_CALL_REENTRANT(ret_stuff, BIOS_PARTITION_SERIAL_GET, 0,
+				0, 0, 0, 0, 0, 0);
+	if (ret_stuff.status != 0)
+		return 0;
+	return ret_stuff.v0;
+}
+
+static inline u64
+sn_partition_serial_number_val(void)
+{
+	if (unlikely(sn_partition_serial_number == 0))
+		sn_partition_serial_number = bios_partition_serial_get();
+
+	return sn_partition_serial_number;
+}
+
+
+extern struct proc_dir_entry *sgi_uv_dir;
+/* extern void __init register_uv_procfs(void); */
+
+extern u8 uv_type;
+extern u16 uv_nasid_bitmask;
+extern u8 uv_nasid_shift;
+extern u8 sn_partition_id;
+extern u8 uv_system_size;
+extern u8 uv_sharing_domain_size;
+extern u8 uv_coherency_id;
+extern u8 uv_region_size;
+extern u8 uv_coherency_id;
+#define partition_coherence_id()	(uv_coherency_id)
+
 extern long
-x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
+uv_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
 		   unsigned long *drift_info);
-extern const char *x86_bios_strerror(long status);
+extern u64
+uv_bios_get_sn_info(int fc, u8 *uvtype, u16 *nasid_bitmask, u8 *nasid_shift,
+		    u8 *systemsize, u8 *sharing_domain_size, u8 *partid,
+		    u8 *coher, u8 *reg);
+
+extern const char *uv_bios_strerror(long status);
 
-#endif /* _ASM_X86_BIOS_H */
+#endif /* _ASM_UV_BIOS_H */

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

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

* Re: x86 BIOS interface for partitioning and system serial number on SGI UV
  2008-08-05  3:54       ` Greg KH
  2008-08-05 16:32         ` Russ Anderson
@ 2008-08-05 23:06         ` Russ Anderson
  1 sibling, 0 replies; 15+ messages in thread
From: Russ Anderson @ 2008-08-05 23:06 UTC (permalink / raw)
  To: Greg KH
  Cc: H. Peter Anvin, mingo, tglx, linux-kernel, Jack Steiner,
	Russ Anderson

On Mon, Aug 04, 2008 at 08:54:50PM -0700, Greg KH wrote:
> On Mon, Aug 04, 2008 at 05:59:42PM -0700, H. Peter Anvin wrote:
> > Russ Anderson wrote:
> >>> This really seems more that it should belong in sysfs -- 
> >>> /sys/class/firmware presumably.
> >> /proc/sgi_uv already exists, similar to /proc/sgi_sn on Itanium systems.
> >> Would it be /sys/class/firmware?  Reading Documentation/sysfs-rules.txt
> >> seems to indicate somewhere under /sys/devices, such as 
> >> /sys/devices/system/,
> >> but I may be wrong.
> >
> > /sys/class/firmware is usually where firmware-related things end up, but 
> > gregkh is the authority on sysfs organization.
> 
> /sys/class/firmware has a few users, but perhaps you are thinking of
> /sys/firmware instead?  That's probably the better place for something
> that is not using the firmware class itself.
> 
> thanks,
> 
> greg k-h

Here is an updated patch using /sys/firmware/sgi_uv/, to see 
if it resolves concerns in that area.  This patch does not
address the stubs issue.  Still working that.

Thanks,
Russ

---------------------------------------------------------------------

SGI UV support for partitioning and system serial number.

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

---
 arch/x86/kernel/Makefile         |    2 
 arch/x86/kernel/bios_uv.c        |   87 +++++++++++++++++++++++++-
 arch/x86/kernel/genx2apic_uv_x.c |    8 +-
 arch/x86/kernel/uv_sysfs.c       |   84 ++++++++++++++++++++++++++
 include/asm-x86/uv/bios.h        |  126 ++++++++++++++++++++++++++++++++++-----
 5 files changed, 283 insertions(+), 24 deletions(-)

Index: linux/arch/x86/kernel/uv_sysfs.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/x86/kernel/uv_sysfs.c	2008-08-05 17:07:16.000000000 -0500
@@ -0,0 +1,84 @@
+/*
+ * This file supports the /sys/firmware/sgi_uv interfaces for SGI UV.
+ *
+ *  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
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  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/sysdev.h>
+/* #include <linux/seq_file.h> */
+/* #include <asm/genapic.h> */
+#include <asm/uv/bios.h>
+
+struct kobject *sgi_uv_kobj;
+
+static ssize_t partition_id_show(struct kobject *kobj,
+			struct kobj_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", sn_partition_id);
+}
+
+static ssize_t system_serial_number_show(struct kobject *kobj,
+			struct kobj_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", sn_system_serial_number());
+}
+
+static ssize_t licenseID_show(struct kobject *kobj,
+			struct kobj_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "0x%llx\n",
+			sn_partition_serial_number_val());
+}
+
+static ssize_t coherence_id_show(struct kobject *kobj,
+			struct kobj_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", partition_coherence_id());
+}
+
+static struct kobj_attribute partition_id_attr =
+	__ATTR(partition_id, S_IRUGO, partition_id_show, NULL);
+
+static struct kobj_attribute system_sn_attr =
+	__ATTR(system_serial_number, S_IRUGO, system_serial_number_show, NULL);
+
+static struct kobj_attribute license_id_attr =
+	__ATTR(licenseID, S_IRUGO, licenseID_show, NULL);
+
+static struct kobj_attribute coherence_id_attr =
+	__ATTR(coherence_id, S_IRUGO, coherence_id_show, NULL);
+
+
+static int __init sgi_uv_sysfs_init(void)
+{
+	if (!sgi_uv_kobj)
+		sgi_uv_kobj = kobject_create_and_add("sgi_uv", firmware_kobj);
+	if (!sgi_uv_kobj) {
+		printk(KERN_WARNING "kobject_create_and_add sgi_uv failed \n");
+		return -EINVAL;
+	}
+
+	sysfs_create_file(sgi_uv_kobj, &partition_id_attr.attr);
+	sysfs_create_file(sgi_uv_kobj, &system_sn_attr.attr);
+	sysfs_create_file(sgi_uv_kobj, &license_id_attr.attr);
+	sysfs_create_file(sgi_uv_kobj, &coherence_id_attr.attr);
+
+	return 0;
+}
+
+device_initcall(sgi_uv_sysfs_init);
Index: linux/arch/x86/kernel/Makefile
===================================================================
--- linux.orig/arch/x86/kernel/Makefile	2008-08-05 17:07:01.000000000 -0500
+++ linux/arch/x86/kernel/Makefile	2008-08-05 17:07:16.000000000 -0500
@@ -104,7 +104,7 @@ obj-$(CONFIG_OLPC)		+= olpc.o
 # 64 bit specific files
 ifeq ($(CONFIG_X86_64),y)
         obj-y				+= genapic_64.o genapic_flat_64.o genx2apic_uv_x.o tlb_uv.o
-	obj-y				+= bios_uv.o
+	obj-y				+= bios_uv.o uv_sysfs.o
         obj-y				+= genx2apic_cluster.o
         obj-y				+= genx2apic_phys.o
         obj-$(CONFIG_X86_PM_TIMER)	+= pmtimer_64.o
Index: linux/arch/x86/kernel/bios_uv.c
===================================================================
--- linux.orig/arch/x86/kernel/bios_uv.c	2008-08-05 17:07:01.000000000 -0500
+++ linux/arch/x86/kernel/bios_uv.c	2008-08-05 17:07:16.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,12 +14,37 @@
  *  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 <asm/uv/bios.h>
 
+char sn_system_serial_number_string[128];
+EXPORT_SYMBOL(sn_system_serial_number_string);
+u64 sn_partition_serial_number;
+EXPORT_SYMBOL(sn_partition_serial_number);
+u8 sn_partition_id;
+EXPORT_SYMBOL(sn_partition_id);
+u8 uv_type;
+EXPORT_SYMBOL(uv_type);
+u16 uv_nasid_bitmask;
+EXPORT_SYMBOL(uv_nasid_bitmask);
+u8 uv_nasid_shift;
+EXPORT_SYMBOL(uv_nasid_shift);
+u8 uv_system_size;
+EXPORT_SYMBOL(uv_system_size);
+u8 uv_sharing_domain_size;
+EXPORT_SYMBOL(uv_sharing_domain_size);
+u8 uv_coherency_id;
+EXPORT_SYMBOL(uv_coherency_id);
+u8 uv_region_size;
+EXPORT_SYMBOL(uv_region_size);
+
+
 const char *
-x86_bios_strerror(long status)
+uv_bios_strerror(long status)
 {
 	const char *str;
 	switch (status) {
@@ -35,7 +58,7 @@ x86_bios_strerror(long status)
 }
 
 long
-x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
+uv_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
 		   unsigned long *drift_info)
 {
 	struct uv_bios_retval isrv;
@@ -45,4 +68,58 @@ x86_bios_freq_base(unsigned long which, 
 	*drift_info = isrv.v1;
 	return isrv.status;
 }
-EXPORT_SYMBOL_GPL(x86_bios_freq_base);
+EXPORT_SYMBOL_GPL(uv_bios_freq_base);
+
+/*
+ * Returns information about the UV HUB.
+ *  In:
+ *      arg0 - BIOS_GET_SN_INFO
+ *      arg1 - 0 (other values reserved for future use)
+ *  Out:
+ *      v0
+ *		[7:0]   - uv hub version (0=hub1, 1=hub2)
+ *		[15:8]  - Log2 max number of nodes in entire system
+ *		[23:16] - Log2 of nodes per sharing domain
+ *		[31:24] - partition ID
+ *		[39:32] - coherency_id
+ *		[47:40] - regionsize
+ *      v1
+ *		[15:0]  - nasid mask (ex., 0x7ff for 11 bit nasid)
+ *		[23:15] - bit position of low nasid bit
+ */
+u64
+uv_bios_get_sn_info(int fc, u8 *uvtype, u16 *nasid_bitmask, u8 *nasid_shift,
+		    u8 *systemsize, u8 *sharing_domain_size, u8 *partid,
+		    u8 *coher, u8 *reg)
+{
+	struct uv_bios_retval ret_stuff;
+
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	BIOS_CALL_NOLOCK(ret_stuff, BIOS_GET_SN_INFO, fc, 0, 0, 0, 0, 0, 0);
+
+	if (ret_stuff.status < 0)
+		return ret_stuff.status;
+
+	if (uvtype)
+		*uvtype = ret_stuff.v0 & 0xff;
+	if (systemsize)
+		*systemsize = (ret_stuff.v0 >> 8) & 0xff;
+	if (sharing_domain_size)
+		*sharing_domain_size = (ret_stuff.v0 >> 16) & 0xff;
+	if (partid)
+		*partid = (ret_stuff.v0 >> 24) & 0xff;
+	if (coher)
+		*coher = (ret_stuff.v0 >> 32) & 0xff;
+	if (reg)
+		*reg = (ret_stuff.v0 >> 40) & 0xff;
+	if (nasid_bitmask)
+		*nasid_bitmask = (ret_stuff.v1 & 0xffff);
+	if (nasid_shift)
+		*nasid_shift = (ret_stuff.v1 >> 16) & 0xff;
+	return 0;
+}
+
+
Index: linux/arch/x86/kernel/genx2apic_uv_x.c
===================================================================
--- linux.orig/arch/x86/kernel/genx2apic_uv_x.c	2008-08-05 17:07:01.000000000 -0500
+++ linux/arch/x86/kernel/genx2apic_uv_x.c	2008-08-05 17:07:16.000000000 -0500
@@ -344,7 +344,7 @@ static __init void uv_rtc_init(void)
 	long status, ticks_per_sec, drift;
 
 	status =
-	    x86_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
+	    uv_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
 					&drift);
 	if (status != 0 || ticks_per_sec < 100000) {
 		printk(KERN_WARNING
@@ -410,6 +410,10 @@ static __init void uv_system_init(void)
 	gnode_upper = (((unsigned long)node_id.s.node_id) &
 		       ~((1 << n_val) - 1)) << m_val;
 
+	uv_bios_get_sn_info(0, &uv_type, &uv_nasid_bitmask,
+			    &uv_nasid_shift, &uv_system_size,
+			    &uv_sharing_domain_size, &sn_partition_id,
+			    &uv_coherency_id, &uv_region_size);
 	uv_rtc_init();
 
 	for_each_present_cpu(cpu) {
@@ -431,7 +435,7 @@ static __init void uv_system_init(void)
 		uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1;
 		uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper;
 		uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
-		uv_cpu_hub_info(cpu)->coherency_domain_number = 0;/* ZZZ */
+		uv_cpu_hub_info(cpu)->coherency_domain_number = uv_coherency_id;
 		uv_node_to_blade[nid] = blade;
 		uv_cpu_to_blade[cpu] = blade;
 		max_pnode = max(pnode, max_pnode);
Index: linux/include/asm-x86/uv/bios.h
===================================================================
--- linux.orig/include/asm-x86/uv/bios.h	2008-08-05 17:07:01.000000000 -0500
+++ linux/include/asm-x86/uv/bios.h	2008-08-05 17:07:16.000000000 -0500
@@ -1,11 +1,9 @@
-#ifndef _ASM_X86_BIOS_H
-#define _ASM_X86_BIOS_H
+#ifndef _ASM_UV_BIOS_H
+#define _ASM_UV_BIOS_H
 
 /*
  * BIOS layer definitions.
  *
- *  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
@@ -19,11 +17,17 @@
  *  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>
 
-#define BIOS_FREQ_BASE			0x01000001
+#define BIOS_FREQ_BASE			0x01
+#define BIOS_GET_SN_INFO		0x02
+#define BIOS_SYS_SERIAL_GET		0x03
+#define BIOS_PARTITION_SERIAL_GET	0x04
 
 enum {
 	BIOS_FREQ_BASE_PLATFORM = 0,
@@ -31,14 +35,6 @@ 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)
-
 enum {
 	BIOS_STATUS_SUCCESS		=  0,
 	BIOS_STATUS_UNIMPLEMENTED	= -1,
@@ -60,9 +56,107 @@ struct uv_bios_retval {
 	u64 v2;
 };
 
+
+# define BIOS_CALL(result, a0, a1, a2, a3, a4, a5, a6, a7)		\
+	do {								\
+		/* XXX - the real call goes here */			\
+		result.status = BIOS_STATUS_UNIMPLEMENTED;		\
+		result.v0 = 0;						\
+		result.v1 = 0;						\
+	} while (0)
+
+# define BIOS_CALL_NOLOCK(result, a0, a1, a2, a3, a4, a5, a6, a7)	\
+	do {								\
+		unsigned long __bios_flags;				\
+		local_irq_save(__bios_flags);				\
+		/* XXX - the real call goes here */			\
+		local_irq_restore(__bios_flags);			\
+		result.status = BIOS_STATUS_UNIMPLEMENTED;		\
+		result.v0 = 0;						\
+		result.v1 = 0;						\
+	} while (0)
+
+# define BIOS_CALL_REENTRANT(result, a0, a1, a2, a3, a4, a5, a6, a7)	\
+	do {								\
+		preempt_disable();					\
+		/* XXX - the real call goes here */			\
+		preempt_enable();					\
+		result.status = BIOS_STATUS_UNIMPLEMENTED;		\
+		result.v0 = 0;						\
+		result.v1 = 0;						\
+	} while (0)
+
+/*
+ * Retrieve the system serial number as an ASCII string.
+ */
+static inline u64
+uv_bios_sys_serial_get(char *buf)
+{
+	struct uv_bios_retval ret_stuff;
+
+	BIOS_CALL(ret_stuff, BIOS_SYS_SERIAL_GET, buf, 0, 0, 0, 0, 0, 0);
+
+	return ret_stuff.status;
+}
+
+
+extern char sn_system_serial_number_string[];
+extern u64 sn_partition_serial_number;
+
+static inline char *
+sn_system_serial_number(void)
+{
+	if (unlikely(!sn_system_serial_number_string[0]))
+		uv_bios_sys_serial_get(sn_system_serial_number_string);
+
+	return sn_system_serial_number_string;
+}
+/*
+ * Returns a unique id number for this system and partition (suitable for
+ * use with license managers), based in part on the system serial number.
+ */
+static inline u64
+bios_partition_serial_get(void)
+{
+	struct uv_bios_retval ret_stuff;
+	BIOS_CALL_REENTRANT(ret_stuff, BIOS_PARTITION_SERIAL_GET, 0,
+				0, 0, 0, 0, 0, 0);
+	if (ret_stuff.status != 0)
+		return 0;
+	return ret_stuff.v0;
+}
+
+static inline u64
+sn_partition_serial_number_val(void)
+{
+	if (unlikely(sn_partition_serial_number == 0))
+		sn_partition_serial_number = bios_partition_serial_get();
+
+	return sn_partition_serial_number;
+}
+
+
+extern struct kobject *sgi_uv_kobj;	/* /sys/firmware/sgi_uv */
+
+extern u8 uv_type;
+extern u16 uv_nasid_bitmask;
+extern u8 uv_nasid_shift;
+extern u8 sn_partition_id;
+extern u8 uv_system_size;
+extern u8 uv_sharing_domain_size;
+extern u8 uv_coherency_id;
+extern u8 uv_region_size;
+extern u8 uv_coherency_id;
+#define partition_coherence_id()	(uv_coherency_id)
+
 extern long
-x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
+uv_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
 		   unsigned long *drift_info);
-extern const char *x86_bios_strerror(long status);
+extern u64
+uv_bios_get_sn_info(int fc, u8 *uvtype, u16 *nasid_bitmask, u8 *nasid_shift,
+		    u8 *systemsize, u8 *sharing_domain_size, u8 *partid,
+		    u8 *coher, u8 *reg);
+
+extern const char *uv_bios_strerror(long status);
 
-#endif /* _ASM_X86_BIOS_H */
+#endif /* _ASM_UV_BIOS_H */
-- 
Russ Anderson, OS RAS/Partitioning Project Lead  
SGI - Silicon Graphics Inc          rja@sgi.com

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

end of thread, other threads:[~2008-08-05 23:07 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-31 19:57 x86 BIOS interface for partitioning and system serial number on SGI UV Russ Anderson
2008-08-01 17:34 ` H. Peter Anvin
2008-08-04 22:19   ` Russ Anderson
2008-08-05  0:50     ` H. Peter Anvin
2008-08-05  0:59     ` H. Peter Anvin
2008-08-05  3:54       ` Greg KH
2008-08-05 16:32         ` Russ Anderson
2008-08-05 16:53           ` Greg KH
2008-08-05 19:22             ` Russ Anderson
2008-08-05 23:06         ` Russ Anderson
2008-08-05  5:21     ` Kyle Moffett
2008-08-05 14:35       ` Mike Travis
2008-08-05 15:40         ` H. Peter Anvin
2008-08-05 15:56           ` Mike Travis
  -- strict thread matches above, loose matches on Subject: below --
2008-08-05 17:24 H. Peter Anvin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox