All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tim Hockin <thockin@sun.com>
To: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: [PATCH] nvram - add Cobalt support
Date: Mon, 05 Aug 2002 19:50:10 -0700	[thread overview]
Message-ID: <3D4F3962.3050303@sun.com> (raw)

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

This patch adds support for Cobalt systems to the nvram driver.  In the 
process, the nvram symbols were exported, and a few other minor cleanup 
went in.  This iwll soon be available through bk, but I thought I'd 
solicit any gripes before I push it up. :)

This is another in a series of patches trying desperately to get our 
tree synced :).  If it all looks ok, I'll ask Marcelo and Linus to pull it.

Tim

-- 
Tim Hockin
Systems Software Engineer
Sun Microsystems, Cobalt Server Appliances
thockin@sun.com

[-- Attachment #2: bk-rev-1.582.2.81.patch --]
[-- Type: text/plain, Size: 26379 bytes --]

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.582.2.80 -> 1.582.2.81
#	include/linux/nvram.h	1.1     -> 1.3    
#	drivers/char/nvram.c	1.9     -> 1.11   
#	drivers/char/Makefile	1.18    -> 1.19   
#	Documentation/Configure.help	1.110   -> 1.111  
#	               (new)	        -> 1.2     include/linux/cobalt-nvram.h
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/08/02	th122948@scl3.sfbay.sun.com	1.582.2.81
# Add Cobalt Networks support to nvram driver
# export nvram interfaces
# general cleanup of nvram driver
# protect nvram state with a lock
# fix nvram O_EXCL hack to actually work
# --------------------------------------------
#
diff -Nru a/Documentation/Configure.help b/Documentation/Configure.help
--- a/Documentation/Configure.help	Mon Aug  5 18:55:26 2002
+++ b/Documentation/Configure.help	Mon Aug  5 18:55:26 2002
@@ -18187,9 +18187,10 @@
 CONFIG_NVRAM
   If you say Y here and create a character special file /dev/nvram
   with major number 10 and minor number 144 using mknod ("man mknod"),
-  you get read and write access to the 50 bytes of non-volatile memory
-  in the real time clock (RTC), which is contained in every PC and
-  most Ataris.
+  you get read and write access to the extra bytes of non-volatile
+  memory in the real time clock (RTC), which is contained in every PC
+  and most Ataris.  The actual number of bytes varies, depending on the
+  nvram in the system, but is usually 114 (128-14 for the RTC).
 
   This memory is conventionally called "CMOS RAM" on PCs and "NVRAM"
   on Ataris. /dev/nvram may be used to view settings there, or to
diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile
--- a/drivers/char/Makefile	Mon Aug  5 18:55:26 2002
+++ b/drivers/char/Makefile	Mon Aug  5 18:55:26 2002
@@ -24,7 +24,7 @@
 export-objs     :=	busmouse.o console.o keyboard.o sysrq.o \
 			misc.o pty.o random.o selection.o serial.o \
 			sonypi.o tty_io.o tty_ioctl.o generic_serial.o \
-			au1000_gpio.o
+			au1000_gpio.o nvram.o
 
 mod-subdirs	:=	joystick ftape drm drm-4.0 pcmcia
 
diff -Nru a/drivers/char/nvram.c b/drivers/char/nvram.c
--- a/drivers/char/nvram.c	Mon Aug  5 18:55:26 2002
+++ b/drivers/char/nvram.c	Mon Aug  5 18:55:26 2002
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 1997 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
  * idea by and with help from Richard Jelinek <rj@suse.de>
+ * Portions copyright (c) 2001,2002 Sun Microsystems (thockin@sun.com)
  *
  * This driver allows you to access the contents of the non-volatile memory in
  * the mc146818rtc.h real-time clock. This chip is built into all PCs and into
@@ -10,9 +11,10 @@
  * "NVRAM" (NV stands for non-volatile).
  *
  * The data are supplied as a (seekable) character device, /dev/nvram. The
- * size of this file is 50, the number of freely available bytes in the memory
- * (i.e., not used by the RTC itself).
- * 
+ * size of this file is dependant on the controller.  The usual size is 114,
+ * the number of freely available bytes in the memory (i.e., not used by the
+ * RTC itself).
+ *
  * Checksums over the NVRAM contents are managed by this driver. In case of a
  * bad checksum, reads and writes return -EIO. The checksum can be initialized
  * to a sane state either by ioctl(NVRAM_INIT) (clear whole NVRAM) or
@@ -28,25 +30,35 @@
  *
  * 	1.1	Cesar Barros: SMP locking fixes
  * 		added changelog
+ * 	1.2	Erik Gilling: Cobalt Networks support
+ * 		Tim Hockin: general cleanup, Cobalt support
  */
 
-#define NVRAM_VERSION		"1.1"
+#define NVRAM_VERSION	"1.2"
 
 #include <linux/module.h>
 #include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
+#include <linux/nvram.h>
 
 #define PC		1
 #define ATARI		2
+#define COBALT		3
 
 /* select machine configuration */
 #if defined(CONFIG_ATARI)
-#define MACH ATARI
+#  define MACH ATARI
 #elif defined(__i386__) || defined(__x86_64__) || defined(__arm__)  /* and others?? */
 #define MACH PC
+#  if defined(CONFIG_COBALT)
+#    include <linux/cobalt-nvram.h>
+#    define MACH COBALT
+#  else
+#    define MACH PC
+#  endif
 #else
-#error Cannot build nvram driver for this machine configuration.
+#  error Cannot build nvram driver for this machine configuration.
 #endif
 
 #if MACH == PC
@@ -58,10 +70,23 @@
 #define PC_CKS_RANGE_START	2
 #define PC_CKS_RANGE_END	31
 #define PC_CKS_LOC		32
+#define NVRAM_BYTES		(128-NVRAM_FIRST_BYTE)
+
+#define mach_check_checksum	pc_check_checksum
+#define mach_set_checksum	pc_set_checksum
+#define mach_proc_infos		pc_proc_infos
+
+#endif
+
+#if MACH == COBALT
+
+#define CHECK_DRIVER_INIT()     1
+
+#define NVRAM_BYTES		(128-NVRAM_FIRST_BYTE)
 
-#define	mach_check_checksum	pc_check_checksum
-#define	mach_set_checksum	pc_set_checksum
-#define	mach_proc_infos		pc_proc_infos
+#define mach_check_checksum	cobalt_check_checksum
+#define mach_set_checksum	cobalt_set_checksum
+#define mach_proc_infos		cobalt_proc_infos
 
 #endif
 
@@ -79,9 +104,9 @@
 #define ATARI_CKS_RANGE_END	47
 #define ATARI_CKS_LOC		48
 
-#define	mach_check_checksum	atari_check_checksum
-#define	mach_set_checksum	atari_set_checksum
-#define	mach_proc_infos		atari_proc_infos
+#define mach_check_checksum	atari_check_checksum
+#define mach_set_checksum	atari_set_checksum
+#define mach_proc_infos		atari_proc_infos
 
 #endif
 
@@ -98,7 +123,6 @@
 #include <linux/ioport.h>
 #include <linux/fcntl.h>
 #include <linux/mc146818rtc.h>
-#include <linux/nvram.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #include <linux/spinlock.h>
@@ -107,15 +131,11 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
+static spinlock_t nvram_state_lock = SPIN_LOCK_UNLOCKED;
 static int nvram_open_cnt;	/* #times opened */
 static int nvram_open_mode;	/* special open modes */
-
-#define	NVRAM_WRITE		1	/* opened for writing (exclusive) */
-#define	NVRAM_EXCL		2	/* opened with O_EXCL */
-
-#define	RTC_FIRST_BYTE		14	/* RTC register number of first
-					 * NVRAM byte */
-#define	NVRAM_BYTES		128-RTC_FIRST_BYTE /* number of NVRAM bytes */
+#define NVRAM_WRITE		1 /* opened for writing (exclusive) */
+#define NVRAM_EXCL		2 /* opened with O_EXCL */
 
 static int mach_check_checksum(void);
 static void mach_set_checksum(void);
@@ -126,95 +146,85 @@
 #endif
 
 /*
- * These are the internal NVRAM access functions, which do NOT disable
- * interrupts and do not check the checksum. Both tasks are left to higher
- * level function, so they need to be done only once per syscall.
- */
-
-static __inline__ unsigned char
-nvram_read_int(int i)
-{
-	return CMOS_READ(RTC_FIRST_BYTE + i);
-}
-
-static __inline__ void
-nvram_write_int(unsigned char c, int i)
-{
-	CMOS_WRITE(c, RTC_FIRST_BYTE + i);
-}
-
-static __inline__ int
-nvram_check_checksum_int(void)
-{
-	return mach_check_checksum();
-}
-
-static __inline__ void
-nvram_set_checksum_int(void)
-{
-	mach_set_checksum();
-}
-
-#if MACH == ATARI
-
-/*
- * These non-internal functions are provided to be called by other parts of
+ * These functions are provided to be called internally or by other parts of
  * the kernel. It's up to the caller to ensure correct checksum before reading
  * or after writing (needs to be done only once).
  *
- * They're only built if CONFIG_ATARI is defined, because Atari drivers use
- * them. For other configurations (PC), the rest of the kernel can't rely on
- * them being present (this driver may not be configured at all, or as a
- * module), so they access config information themselves.
+ * It is worth noting that these functions all access bytes of general
+ * purpose memory in the NVRAM - that is to say, they all add the
+ * NVRAM_FIRST_BYTE offset.  Pass them offsets into NVRAM as if you did not 
+ * know about the RTC cruft.
  */
 
 unsigned char
+__nvram_read_byte(int i)
+{
+	return CMOS_READ(NVRAM_FIRST_BYTE + i);
+}
+
+unsigned char
 nvram_read_byte(int i)
 {
 	unsigned long flags;
 	unsigned char c;
 
 	spin_lock_irqsave(&rtc_lock, flags);
-	c = nvram_read_int(i);
+	c = __nvram_read_byte(i);
 	spin_unlock_irqrestore(&rtc_lock, flags);
 	return c;
 }
 
 /* This races nicely with trying to read with checksum checking (nvram_read) */
 void
+__nvram_write_byte(unsigned char c, int i)
+{
+	CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
+}
+
+void
 nvram_write_byte(unsigned char c, int i)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&rtc_lock, flags);
-	nvram_write_int(c, i);
+	__nvram_write_byte(c, i);
 	spin_unlock_irqrestore(&rtc_lock, flags);
 }
 
 int
+__nvram_check_checksum(void)
+{
+	return mach_check_checksum();
+}
+
+int
 nvram_check_checksum(void)
 {
 	unsigned long flags;
 	int rv;
 
 	spin_lock_irqsave(&rtc_lock, flags);
-	rv = nvram_check_checksum_int();
+	rv = __nvram_check_checksum();
 	spin_unlock_irqrestore(&rtc_lock, flags);
 	return rv;
 }
 
 void
+__nvram_set_checksum(void)
+{
+	mach_set_checksum();
+}
+
+void
 nvram_set_checksum(void)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&rtc_lock, flags);
-	nvram_set_checksum_int();
+	__nvram_set_checksum();
 	spin_unlock_irqrestore(&rtc_lock, flags);
 }
 
-#endif /* MACH == ATARI */
-
 /*
  * The are the file operation function for user access to /dev/nvram
  */
@@ -239,17 +249,17 @@
 static ssize_t
 nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos)
 {
-	char contents[NVRAM_BYTES];
+	unsigned char contents[NVRAM_BYTES];
 	unsigned i = *ppos;
-	char *tmp;
+	unsigned char *tmp;
 
 	spin_lock_irq(&rtc_lock);
 
-	if (!nvram_check_checksum_int())
+	if (!__nvram_check_checksum())
 		goto checksum_err;
 
 	for (tmp = contents; count-- > 0 && i < NVRAM_BYTES; ++i, ++tmp)
-		*tmp = nvram_read_int(i);
+		*tmp = __nvram_read_byte(i);
 
 	spin_unlock_irq(&rtc_lock);
 
@@ -268,23 +278,24 @@
 static ssize_t
 nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
 {
-	char contents[NVRAM_BYTES];
+	unsigned char contents[NVRAM_BYTES];
 	unsigned i = *ppos;
-	char *tmp;
+	unsigned char *tmp;
+	int len;
 
-	if (copy_from_user(contents, buf, (NVRAM_BYTES - i) < count ?
-	    (NVRAM_BYTES - i) : count))
+	len = (NVRAM_BYTES - i) < count ? (NVRAM_BYTES - i) : count;
+	if (copy_from_user(contents, buf, len))
 		return -EFAULT;
 
 	spin_lock_irq(&rtc_lock);
 
-	if (!nvram_check_checksum_int())
+	if (!__nvram_check_checksum())
 		goto checksum_err;
 
 	for (tmp = contents; count-- > 0 && i < NVRAM_BYTES; ++i, ++tmp)
-		nvram_write_int(*tmp, i);
+		__nvram_write_byte(*tmp, i);
 
-	nvram_set_checksum_int();
+	__nvram_set_checksum();
 
 	spin_unlock_irq(&rtc_lock);
 
@@ -305,27 +316,28 @@
 
 	switch (cmd) {
 
-	case NVRAM_INIT:	/* initialize NVRAM contents and checksum */
+	case NVRAM_INIT:
+		/* initialize NVRAM contents and checksum */
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
 
 		spin_lock_irq(&rtc_lock);
 
 		for (i = 0; i < NVRAM_BYTES; ++i)
-			nvram_write_int(0, i);
-		nvram_set_checksum_int();
+			__nvram_write_byte(0, i);
+		__nvram_set_checksum();
 
 		spin_unlock_irq(&rtc_lock);
 		return 0;
 
-	case NVRAM_SETCKS:	/* just set checksum, contents unchanged
-				 * (maybe useful after checksum garbaged
-				 * somehow...) */
+	case NVRAM_SETCKS:
+		/* just set checksum, contents unchanged (maybe useful after 
+		 * checksum garbaged somehow...) */
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
 
 		spin_lock_irq(&rtc_lock);
-		nvram_set_checksum_int();
+		__nvram_set_checksum();
 		spin_unlock_irq(&rtc_lock);
 		return 0;
 
@@ -337,29 +349,40 @@
 static int
 nvram_open(struct inode *inode, struct file *file)
 {
+	spin_lock(&nvram_state_lock);
+
 	if ((nvram_open_cnt && (file->f_flags & O_EXCL)) ||
 	    (nvram_open_mode & NVRAM_EXCL) ||
-	    ((file->f_mode & 2) && (nvram_open_mode & NVRAM_WRITE)))
+	    ((file->f_mode & 2) && (nvram_open_mode & NVRAM_WRITE))) {
+		spin_unlock(&nvram_state_lock);
 		return -EBUSY;
+	}
 
 	if (file->f_flags & O_EXCL)
 		nvram_open_mode |= NVRAM_EXCL;
 	if (file->f_mode & 2)
 		nvram_open_mode |= NVRAM_WRITE;
 	nvram_open_cnt++;
+
+	spin_unlock(&nvram_state_lock);
+
 	return 0;
 }
 
 static int
 nvram_release(struct inode *inode, struct file *file)
 {
-	lock_kernel();
+	spin_lock(&nvram_state_lock);
+
 	nvram_open_cnt--;
-	if (file->f_flags & O_EXCL)
+
+	/* if only one instance is open, clear the EXCL bit */
+	if (nvram_open_mode & NVRAM_EXCL)
 		nvram_open_mode &= ~NVRAM_EXCL;
 	if (file->f_mode & 2)
 		nvram_open_mode &= ~NVRAM_WRITE;
-	unlock_kernel();
+
+	spin_unlock(&nvram_state_lock);
 
 	return 0;
 }
@@ -383,7 +406,7 @@
 
 	spin_lock_irq(&rtc_lock);
 	for (i = 0; i < NVRAM_BYTES; ++i)
-		contents[i] = nvram_read_int(i);
+		contents[i] = __nvram_read_byte(i);
 	spin_unlock_irq(&rtc_lock);
 
 	*eof = mach_proc_infos(contents, buffer, &len, &begin, offset, size);
@@ -397,7 +420,7 @@
 
 /* This macro frees the machine specific function from bounds checking and
  * this like that... */
-#define	PRINT_PROC(fmt,args...)					\
+#define PRINT_PROC(fmt,args...)					\
 	do {							\
 		*len += sprintf(buffer+*len, fmt, ##args);	\
 		if (*begin + *len > offset + size)		\
@@ -477,11 +500,13 @@
 {
 	int i;
 	unsigned short sum = 0;
+	unsigned short expect;
 
 	for (i = PC_CKS_RANGE_START; i <= PC_CKS_RANGE_END; ++i)
-		sum += nvram_read_int(i);
-	return ((sum & 0xffff) ==
-	    ((nvram_read_int(PC_CKS_LOC)<<8) | nvram_read_int(PC_CKS_LOC+1)));
+		sum += __nvram_read_byte(i);
+	expect = __nvram_read_byte(PC_CKS_LOC)<<8 |
+	    __nvram_read_byte(PC_CKS_LOC+1);
+	return ((sum & 0xffff) == expect);
 }
 
 static void
@@ -491,9 +516,9 @@
 	unsigned short sum = 0;
 
 	for (i = PC_CKS_RANGE_START; i <= PC_CKS_RANGE_END; ++i)
-		sum += nvram_read_int(i);
-	nvram_write_int(sum >> 8, PC_CKS_LOC);
-	nvram_write_int(sum & 0xff, PC_CKS_LOC + 1);
+		sum += __nvram_read_byte(i);
+	__nvram_write_byte(sum >> 8, PC_CKS_LOC);
+	__nvram_write_byte(sum & 0xff, PC_CKS_LOC + 1);
 }
 
 #ifdef CONFIG_PROC_FS
@@ -518,7 +543,7 @@
 	int type;
 
 	spin_lock_irq(&rtc_lock);
-	checksum = nvram_check_checksum_int();
+	checksum = __nvram_check_checksum();
 	spin_unlock_irq(&rtc_lock);
 
 	PRINT_PROC("Checksum status: %svalid\n", checksum ? "" : "not ");
@@ -576,6 +601,177 @@
 
 #endif /* MACH == PC */
 
+#if MACH == COBALT
+
+/* the cobalt CMOS has a wider range of it's checksum */
+static int cobalt_check_checksum(void)
+{
+	int i;
+	unsigned short sum = 0;
+	unsigned short expect;
+
+	for (i = COBT_CMOS_CKS_START; i <= COBT_CMOS_CKS_END; ++i) {
+		if ((i == COBT_CMOS_CHECKSUM) || (i == (COBT_CMOS_CHECKSUM+1)))
+			continue;
+
+		sum += __nvram_read_byte(i);
+	}
+	expect = __nvram_read_byte(COBT_CMOS_CHECKSUM) << 8 |
+	    __nvram_read_byte(COBT_CMOS_CHECKSUM+1);
+	return ((sum & 0xffff) == expect);
+}
+
+static void cobalt_set_checksum(void)
+{
+	int i;
+	unsigned short sum = 0;
+
+	for (i = COBT_CMOS_CKS_START; i <= COBT_CMOS_CKS_END; ++i) {
+		if ((i == COBT_CMOS_CHECKSUM) || (i == (COBT_CMOS_CHECKSUM+1)))
+			continue;
+
+		sum += __nvram_read_byte(i);
+	}
+
+	__nvram_write_byte(sum >> 8, COBT_CMOS_CHECKSUM);
+	__nvram_write_byte(sum & 0xff, COBT_CMOS_CHECKSUM+1);
+}
+
+#ifdef CONFIG_PROC_FS
+
+static int cobalt_proc_infos(unsigned char *nvram, char *buffer, int *len,
+	off_t *begin, off_t offset, int size)
+{
+	int i;
+	unsigned int checksum;
+	unsigned int flags;
+	char sernum[14];
+	char *key = "cNoEbTaWlOtR!";
+	unsigned char bto_csum;
+
+	spin_lock_irq(&rtc_lock);
+	checksum = __nvram_check_checksum();
+	spin_unlock_irq(&rtc_lock);
+
+	PRINT_PROC("Checksum status: %svalid\n", checksum ? "" : "not ");
+
+	flags = nvram[COBT_CMOS_FLAG_BYTE_0] << 8 
+	    | nvram[COBT_CMOS_FLAG_BYTE_1];
+
+	PRINT_PROC("Console: %s\n",
+		flags & COBT_CMOS_CONSOLE_FLAG ?  "on": "off");
+
+	PRINT_PROC("Firmware Debug Messages: %s\n",
+		flags & COBT_CMOS_DEBUG_FLAG ? "on": "off");
+
+	PRINT_PROC("Auto Prompt: %s\n",
+		flags & COBT_CMOS_AUTO_PROMPT_FLAG ? "on": "off");
+
+	PRINT_PROC("Shutdown Status: %s\n",
+		flags & COBT_CMOS_CLEAN_BOOT_FLAG ? "clean": "dirty");
+
+	PRINT_PROC("Hardware Probe: %s\n",
+		flags & COBT_CMOS_HW_NOPROBE_FLAG ? "partial": "full");
+
+	PRINT_PROC("System Fault: %sdetected\n",
+		flags & COBT_CMOS_SYSFAULT_FLAG ? "": "not ");
+
+	PRINT_PROC("Panic on OOPS: %s\n",
+		flags & COBT_CMOS_OOPSPANIC_FLAG ? "yes": "no");
+
+	PRINT_PROC("Delayed Cache Initialization: %s\n",
+		flags & COBT_CMOS_DELAY_CACHE_FLAG ? "yes": "no");
+
+	PRINT_PROC("Show Logo at Boot: %s\n",
+		flags & COBT_CMOS_NOLOGO_FLAG ? "no": "yes");
+
+	PRINT_PROC("Boot Method: ");
+	switch (nvram[COBT_CMOS_BOOT_METHOD]) {
+	case COBT_CMOS_BOOT_METHOD_DISK:
+		PRINT_PROC("disk\n");
+		break;
+
+	case COBT_CMOS_BOOT_METHOD_ROM:
+		PRINT_PROC("rom\n");
+		break;
+
+	case COBT_CMOS_BOOT_METHOD_NET:
+		PRINT_PROC("net\n");
+		break;
+
+	default:
+		PRINT_PROC("unknown\n");
+		break;
+	}
+
+	PRINT_PROC("Primary Boot Device: %d:%d\n",
+		nvram[COBT_CMOS_BOOT_DEV0_MAJ],
+		nvram[COBT_CMOS_BOOT_DEV0_MIN] );
+	PRINT_PROC("Secondary Boot Device: %d:%d\n",
+		nvram[COBT_CMOS_BOOT_DEV1_MAJ],
+		nvram[COBT_CMOS_BOOT_DEV1_MIN] );
+	PRINT_PROC("Tertiary Boot Device: %d:%d\n",
+		nvram[COBT_CMOS_BOOT_DEV2_MAJ],
+		nvram[COBT_CMOS_BOOT_DEV2_MIN] );
+
+	PRINT_PROC("Uptime: %d\n",
+		nvram[COBT_CMOS_UPTIME_0] << 24 |
+		nvram[COBT_CMOS_UPTIME_1] << 16 |
+		nvram[COBT_CMOS_UPTIME_2] << 8  |
+		nvram[COBT_CMOS_UPTIME_3]);
+
+	PRINT_PROC("Boot Count: %d\n",
+		nvram[COBT_CMOS_BOOTCOUNT_0] << 24 |
+		nvram[COBT_CMOS_BOOTCOUNT_1] << 16 |
+		nvram[COBT_CMOS_BOOTCOUNT_2] << 8  |
+		nvram[COBT_CMOS_BOOTCOUNT_3]);
+
+	/* 13 bytes of serial num */
+	for (i=0 ; i<13 ; i++) {
+		sernum[i] = nvram[COBT_CMOS_SYS_SERNUM_0 + i];
+	}
+	sernum[13] = '\0';
+
+	checksum = 0;
+	for (i=0 ; i<13 ; i++) {
+		checksum += sernum[i] ^ key[i];
+	}
+	checksum = ((checksum & 0x7f) ^ (0xd6)) & 0xff;
+
+	PRINT_PROC("Serial Number: %s", sernum);
+	if (checksum != nvram[COBT_CMOS_SYS_SERNUM_CSUM]) {
+		PRINT_PROC(" (invalid checksum)");
+	}
+	PRINT_PROC("\n");
+
+	PRINT_PROC("Rom Revison: %d.%d.%d\n", nvram[COBT_CMOS_ROM_REV_MAJ],
+		nvram[COBT_CMOS_ROM_REV_MIN], nvram[COBT_CMOS_ROM_REV_REV]);
+
+	PRINT_PROC("BTO Server: %d.%d.%d.%d", nvram[COBT_CMOS_BTO_IP_0],
+		nvram[COBT_CMOS_BTO_IP_1], nvram[COBT_CMOS_BTO_IP_2],
+		nvram[COBT_CMOS_BTO_IP_3]);
+	bto_csum = nvram[COBT_CMOS_BTO_IP_0] + nvram[COBT_CMOS_BTO_IP_1]
+		+ nvram[COBT_CMOS_BTO_IP_2] + nvram[COBT_CMOS_BTO_IP_3];
+	if (bto_csum != nvram[COBT_CMOS_BTO_IP_CSUM]) {
+		PRINT_PROC(" (invalid checksum)");
+	}
+	PRINT_PROC("\n");
+
+	if (flags & COBT_CMOS_VERSION_FLAG
+	 && nvram[COBT_CMOS_VERSION] >= COBT_CMOS_VER_BTOCODE) {
+		PRINT_PROC("BTO Code: 0x%x\n",
+			nvram[COBT_CMOS_BTO_CODE_0] << 24 |
+			nvram[COBT_CMOS_BTO_CODE_1] << 16 |
+			nvram[COBT_CMOS_BTO_CODE_2] << 8 |
+			nvram[COBT_CMOS_BTO_CODE_3]);
+	}
+
+	return 1;
+}
+#endif /* CONFIG_PROC_FS */
+
+#endif /* MACH == COBALT */
+
 #if MACH == ATARI
 
 static int
@@ -585,9 +781,9 @@
 	unsigned char sum = 0;
 
 	for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i)
-		sum += nvram_read_int(i);
-	return (nvram_read_int(ATARI_CKS_LOC) == (~sum & 0xff) &&
-	    nvram_read_int(ATARI_CKS_LOC + 1) == (sum & 0xff));
+		sum += __nvram_read_byte(i);
+	return (__nvram_read_byte(ATARI_CKS_LOC) == (~sum & 0xff) &&
+	    __nvram_read_byte(ATARI_CKS_LOC + 1) == (sum & 0xff));
 }
 
 static void
@@ -597,9 +793,9 @@
 	unsigned char sum = 0;
 
 	for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i)
-		sum += nvram_read_int(i);
-	nvram_write_int(~sum, ATARI_CKS_LOC);
-	nvram_write_int(sum, ATARI_CKS_LOC + 1);
+		sum += __nvram_read_byte(i);
+	__nvram_write_byte(~sum, ATARI_CKS_LOC);
+	__nvram_write_byte(sum, ATARI_CKS_LOC + 1);
 }
 
 #ifdef CONFIG_PROC_FS
@@ -716,4 +912,11 @@
 
 MODULE_LICENSE("GPL");
 
-EXPORT_NO_SYMBOLS;
+EXPORT_SYMBOL(__nvram_read_byte);
+EXPORT_SYMBOL(nvram_read_byte);
+EXPORT_SYMBOL(__nvram_write_byte);
+EXPORT_SYMBOL(nvram_write_byte);
+EXPORT_SYMBOL(__nvram_check_checksum);
+EXPORT_SYMBOL(nvram_check_checksum);
+EXPORT_SYMBOL(__nvram_set_checksum);
+EXPORT_SYMBOL(nvram_set_checksum);
diff -Nru a/include/linux/cobalt-nvram.h b/include/linux/cobalt-nvram.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/cobalt-nvram.h	Mon Aug  5 18:55:26 2002
@@ -0,0 +1,109 @@
+/*
+ * $Id: cobalt-nvram.h,v 1.20 2001/10/17 23:16:55 thockin Exp $
+ * cobalt-nvram.h : defines for the various fields in the cobalt NVRAM
+ *
+ * Copyright 2001,2002 Sun Microsystems, Inc.
+ */
+
+#ifndef COBALT_NVRAM_H
+#define COBALT_NVRAM_H
+
+#include <linux/nvram.h>
+
+#define COBT_CMOS_INFO_MAX		0x7f	/* top address allowed */
+#define COBT_CMOS_BIOS_DRIVE_INFO	0x12	/* drive info would go here */
+
+#define COBT_CMOS_CKS_START		NVRAM_OFFSET(0x0e)
+#define COBT_CMOS_CKS_END		NVRAM_OFFSET(0x7f)
+
+/* flag bytes - 16 flags for now, leave room for more */
+#define COBT_CMOS_FLAG_BYTE_0		NVRAM_OFFSET(0x10)
+#define COBT_CMOS_FLAG_BYTE_1		NVRAM_OFFSET(0x11)
+
+/* flags in flag bytes - up to 16 */
+#define COBT_CMOS_FLAG_MIN		0x0001
+#define COBT_CMOS_CONSOLE_FLAG		0x0001 /* console on/off */
+#define COBT_CMOS_DEBUG_FLAG		0x0002 /* ROM debug messages */
+#define COBT_CMOS_AUTO_PROMPT_FLAG	0x0004 /* boot to ROM prompt? */
+#define COBT_CMOS_CLEAN_BOOT_FLAG	0x0008 /* set by a clean shutdown */
+#define COBT_CMOS_HW_NOPROBE_FLAG	0x0010 /* go easy on the probing */
+#define COBT_CMOS_SYSFAULT_FLAG		0x0020 /* system fault detected */
+#define COBT_CMOS_OOPSPANIC_FLAG	0x0040 /* panic on oops */
+#define COBT_CMOS_DELAY_CACHE_FLAG	0x0080 /* delay cache initialization */
+#define COBT_CMOS_NOLOGO_FLAG		0x0100 /* hide "C" logo @ boot */
+#define COBT_CMOS_VERSION_FLAG		0x0200 /* the version field is valid */
+#define COBT_CMOS_FLAG_MAX		0x0200
+
+/* leave byte 0x12 blank - Linux looks for drive info here */
+
+/* CMOS structure version, valid if COBT_CMOS_VERSION_FLAG is true */
+#define COBT_CMOS_VERSION		NVRAM_OFFSET(0x13)
+#define COBT_CMOS_VER_BTOCODE		1 /* min. version needed for btocode */
+
+/* index of default boot method */
+#define COBT_CMOS_BOOT_METHOD		NVRAM_OFFSET(0x20)
+#define COBT_CMOS_BOOT_METHOD_DISK	0
+#define COBT_CMOS_BOOT_METHOD_ROM	1
+#define COBT_CMOS_BOOT_METHOD_NET	2
+
+#define COBT_CMOS_BOOT_DEV_MIN		NVRAM_OFFSET(0x21)
+/* major #, minor # of first through fourth boot device */
+#define COBT_CMOS_BOOT_DEV0_MAJ		NVRAM_OFFSET(0x21)
+#define COBT_CMOS_BOOT_DEV0_MIN		NVRAM_OFFSET(0x22)
+#define COBT_CMOS_BOOT_DEV1_MAJ		NVRAM_OFFSET(0x23)
+#define COBT_CMOS_BOOT_DEV1_MIN		NVRAM_OFFSET(0x24)
+#define COBT_CMOS_BOOT_DEV2_MAJ		NVRAM_OFFSET(0x25)
+#define COBT_CMOS_BOOT_DEV2_MIN		NVRAM_OFFSET(0x26)
+#define COBT_CMOS_BOOT_DEV3_MAJ		NVRAM_OFFSET(0x27)
+#define COBT_CMOS_BOOT_DEV3_MIN		NVRAM_OFFSET(0x28)
+#define COBT_CMOS_BOOT_DEV_MAX		NVRAM_OFFSET(0x28)
+
+/* checksum of bytes 0xe-0x7f */
+#define COBT_CMOS_CHECKSUM		NVRAM_OFFSET(0x2e)
+
+/* running uptime counter, units of 5 minutes (32 bits =~ 41000 years) */
+#define COBT_CMOS_UPTIME_0		NVRAM_OFFSET(0x30)
+#define COBT_CMOS_UPTIME_1		NVRAM_OFFSET(0x31)
+#define COBT_CMOS_UPTIME_2		NVRAM_OFFSET(0x32)
+#define COBT_CMOS_UPTIME_3		NVRAM_OFFSET(0x33)
+
+/* count of successful boots (32 bits) */
+#define COBT_CMOS_BOOTCOUNT_0		NVRAM_OFFSET(0x38)
+#define COBT_CMOS_BOOTCOUNT_1		NVRAM_OFFSET(0x39)
+#define COBT_CMOS_BOOTCOUNT_2		NVRAM_OFFSET(0x3a)
+#define COBT_CMOS_BOOTCOUNT_3		NVRAM_OFFSET(0x3b)
+
+/* 13 bytes: system serial number, same as on the back of the system */
+#define COBT_CMOS_SYS_SERNUM_LEN	13
+#define COBT_CMOS_SYS_SERNUM_0		NVRAM_OFFSET(0x40)
+#define COBT_CMOS_SYS_SERNUM_1		NVRAM_OFFSET(0x41)
+#define COBT_CMOS_SYS_SERNUM_2		NVRAM_OFFSET(0x42)
+#define COBT_CMOS_SYS_SERNUM_3		NVRAM_OFFSET(0x43)
+#define COBT_CMOS_SYS_SERNUM_4		NVRAM_OFFSET(0x44)
+#define COBT_CMOS_SYS_SERNUM_5		NVRAM_OFFSET(0x45)
+#define COBT_CMOS_SYS_SERNUM_6		NVRAM_OFFSET(0x46)
+#define COBT_CMOS_SYS_SERNUM_7		NVRAM_OFFSET(0x47)
+#define COBT_CMOS_SYS_SERNUM_8		NVRAM_OFFSET(0x48)
+#define COBT_CMOS_SYS_SERNUM_9		NVRAM_OFFSET(0x49)
+#define COBT_CMOS_SYS_SERNUM_10		NVRAM_OFFSET(0x4a)
+#define COBT_CMOS_SYS_SERNUM_11		NVRAM_OFFSET(0x4b)
+#define COBT_CMOS_SYS_SERNUM_12		NVRAM_OFFSET(0x4c)
+/* checksum for serial num - 1 byte */
+#define COBT_CMOS_SYS_SERNUM_CSUM	NVRAM_OFFSET(0x4f)
+
+#define COBT_CMOS_ROM_REV_MAJ		NVRAM_OFFSET(0x50)
+#define COBT_CMOS_ROM_REV_MIN		NVRAM_OFFSET(0x51)
+#define COBT_CMOS_ROM_REV_REV		NVRAM_OFFSET(0x52)
+
+#define COBT_CMOS_BTO_CODE_0		NVRAM_OFFSET(0x53)
+#define COBT_CMOS_BTO_CODE_1		NVRAM_OFFSET(0x54)
+#define COBT_CMOS_BTO_CODE_2		NVRAM_OFFSET(0x55)
+#define COBT_CMOS_BTO_CODE_3		NVRAM_OFFSET(0x56)
+
+#define COBT_CMOS_BTO_IP_CSUM		NVRAM_OFFSET(0x57)
+#define COBT_CMOS_BTO_IP_0		NVRAM_OFFSET(0x58)
+#define COBT_CMOS_BTO_IP_1		NVRAM_OFFSET(0x59)
+#define COBT_CMOS_BTO_IP_2		NVRAM_OFFSET(0x5a)
+#define COBT_CMOS_BTO_IP_3		NVRAM_OFFSET(0x5b)
+
+#endif /* COBALT_NVRAM_H */
diff -Nru a/include/linux/nvram.h b/include/linux/nvram.h
--- a/include/linux/nvram.h	Mon Aug  5 18:55:26 2002
+++ b/include/linux/nvram.h	Mon Aug  5 18:55:26 2002
@@ -4,14 +4,24 @@
 #include <linux/ioctl.h>
 
 /* /dev/nvram ioctls */
-#define NVRAM_INIT		_IO('p', 0x40) /* initialize NVRAM and set checksum */
-#define	NVRAM_SETCKS	_IO('p', 0x41) /* recalculate checksum */
+#define NVRAM_INIT	_IO('p', 0x40) /* initialize NVRAM and set checksum */
+#define NVRAM_SETCKS	_IO('p', 0x41) /* recalculate checksum */
+
+/* for all current systems, this is where NVRAM starts */
+#define NVRAM_FIRST_BYTE    14
+/* all these functions expect an NVRAM offset, not an absolute */
+#define NVRAM_OFFSET(x)   ((x)-NVRAM_FIRST_BYTE)
 
 #ifdef __KERNEL__
-extern unsigned char nvram_read_byte( int i );
-extern void nvram_write_byte( unsigned char c, int i );
-extern int nvram_check_checksum( void );
-extern void nvram_set_checksum( void );
+/* __foo is foo without grabbing the rtc_lock - get it yourself */
+extern unsigned char __nvram_read_byte(int i);
+extern unsigned char nvram_read_byte(int i);
+extern void __nvram_write_byte(unsigned char c, int i);
+extern void nvram_write_byte(unsigned char c, int i);
+extern int __nvram_check_checksum(void);
+extern int nvram_check_checksum(void);
+extern void __nvram_set_checksum(void);
+extern void nvram_set_checksum(void);
 #endif
 
 #endif  /* _LINUX_NVRAM_H */

                 reply	other threads:[~2002-08-06  2:46 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3D4F3962.3050303@sun.com \
    --to=thockin@sun.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.