summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/nvram.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/powerpc/ppcn_60x/nvram/nvram.c')
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/nvram/nvram.c515
1 files changed, 515 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/nvram.c b/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/nvram.c
new file mode 100644
index 0000000000..bf085c968b
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/nvram/nvram.c
@@ -0,0 +1,515 @@
+/*
+ * This file contains the NvRAM driver for the PPCn_60x
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ */
+
+#include <bsp.h>
+#include "ds1385.h"
+#include "mk48t18.h"
+#include "stk11c68.h"
+
+/*
+ * Private types
+ */
+typedef
+void
+(*PNVRAMWRITE)
+(
+ unsigned32 ulOffset,
+ unsigned8 ucByte
+);
+
+typedef
+unsigned8
+(*PNVRAMREAD)
+(
+ unsigned32 ulOffset
+);
+
+typedef
+void
+(*PNVRAMCOMMIT)
+(
+);
+
+typedef struct _NVRAM_ENTRY_TABLE
+{
+ PNVRAMWRITE nvramWrite;
+ PNVRAMREAD nvramRead;
+ PNVRAMCOMMIT nvramCommit;
+ unsigned32 nvramSize;
+} NVRAM_ENTRY_TABLE, *PNVRAM_ENTRY_TABLE;
+
+/*
+ * Private routines
+ */
+
+/*
+ * This routine provides a stub for NvRAM devices which
+ * do not require a commit operation
+ */
+static void nvramCommitStub();
+
+/*
+ * DS1385 specific routines
+ */
+static void nvramDsWrite(unsigned32 ulOffset, unsigned8 ucByte);
+static unsigned8 nvramDsRead(unsigned32 ulOffset);
+
+/*
+ * MK48T18 specific routines
+ */
+static void nvramMkWrite(unsigned32 ulOffset, unsigned8 ucByte);
+static unsigned8 nvramMkRead(unsigned32 ulOffset);
+
+/*
+ * STK11C68 specific routines
+ */
+static void nvramStk11C68Commit();
+/*
+ * STK11C88 specific routines
+ */
+static void nvramStk11C88Commit();
+
+/*
+ * NvRAM hook tables
+ */
+NVRAM_ENTRY_TABLE nvramDsTable =
+{
+ nvramDsWrite,
+ nvramDsRead,
+ nvramCommitStub,
+ DS1385_NVSIZE
+};
+
+NVRAM_ENTRY_TABLE nvramMkTable =
+{
+ nvramMkWrite,
+ nvramMkRead,
+ nvramCommitStub,
+ MK48T18_NVSIZE
+};
+
+/*
+ * As the STK devicxe is at the same address as the MK device,
+ * the MK read/write routines may be used
+ */
+NVRAM_ENTRY_TABLE nvramStkTable =
+{
+ nvramMkWrite,
+ nvramMkRead,
+ nvramStk11C68Commit,
+ STK11C68_NVSIZE
+};
+
+NVRAM_ENTRY_TABLE nvramStk88Table =
+{
+ nvramMkWrite,
+ nvramMkRead,
+ nvramStk11C88Commit,
+ STK11C88_NVSIZE
+};
+
+/*
+ * Private variables
+ */
+static PNVRAM_ENTRY_TABLE pNvRAMFunc;
+static boolean bNvRAMChanged=FALSE;
+static unsigned32 ulPRePOSAreaLength;
+static unsigned32 ulPRePOSAreaOffset;
+
+/*
+ * Mutual-exclusion semaphore
+ */
+static rtems_id semNvRAM;
+
+/*
+ * These routines support the ds1385
+ */
+static unsigned8 nvramDsRead(unsigned32 ulOffset)
+{
+ unsigned8 ucTemp;
+
+ ucTemp = ulOffset & 0xff;
+ outport_byte(DS1385_PORT_BASE, ucTemp);
+
+ ucTemp = (ulOffset >> 8) & 0xf;
+ outport_byte((DS1385_PORT_BASE + 1) , ucTemp);
+
+ inport_byte(DS1385_PORT_BASE+3, ucTemp);
+ return(ucTemp);
+}
+
+static void nvramDsWrite(unsigned32 ulOffset, unsigned8 ucData)
+{
+ unsigned8 ucTemp;
+
+ ucTemp = (unsigned8)(ulOffset & 0xff);
+ outport_byte(DS1385_PORT_BASE, (unsigned8) ucTemp);
+
+ ucTemp = (unsigned8)((ulOffset >> 8) & 0xf);
+ outport_byte((DS1385_PORT_BASE + 1) , (unsigned8)ucTemp);
+
+ outport_byte((DS1385_PORT_BASE+3), ucData);
+}
+
+/*
+ * These routines support the MK48T18 and STK11C68
+ */
+static unsigned8 nvramMkRead(unsigned32 ulOffset)
+{
+ unsigned8 *pNvRAM = (unsigned8 *)MK48T18_BASE;
+
+ return(pNvRAM[ulOffset]);
+}
+
+static void nvramMkWrite(unsigned32 ulOffset, unsigned8 ucData)
+{
+ unsigned8 *pNvRAM = (unsigned8 *)MK48T18_BASE;
+
+ pNvRAM[ulOffset]=ucData;
+}
+
+/*
+ * This routine provides a stub for NvRAM devices which
+ * do not require a commit operation
+ */
+static void nvramCommitStub()
+{
+}
+
+/*
+ * This routine triggers a transfer from the NvRAM to the
+ * EE array in the STK11C68 device
+ */
+static void nvramStk11C68Commit()
+{
+#if 0
+ rtems_interval ticks_per_second;
+ rtems_status_code status;
+#endif
+
+ rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ /*
+ * Issue Store command
+ */
+ EIEIO;
+ (void)pNvRAMFunc->nvramRead(0x0000);
+ EIEIO;
+ (void)pNvRAMFunc->nvramRead(0x1555);
+ EIEIO;
+ (void)pNvRAMFunc->nvramRead(0x0aaa);
+ EIEIO;
+ (void)pNvRAMFunc->nvramRead(0x1fff);
+ EIEIO;
+ (void)pNvRAMFunc->nvramRead(0x10f0);
+ EIEIO;
+ (void)pNvRAMFunc->nvramRead(0x0f0f);
+ EIEIO;
+ /*
+ * Delay for 10mS to allow store to
+ * complete
+ */
+#if 0
+ status = rtems_clock_get(
+ RTEMS_CLOCK_GET_TICKS_PER_SECOND,
+ &ticks_per_second
+ );
+
+ status = rtems_task_wake_after(ticks_per_second/100);
+#endif
+ bNvRAMChanged=FALSE;
+
+ rtems_semaphore_release(semNvRAM);
+}
+
+/*
+ * This routine triggers a transfer from the NvRAM to the
+ * EE array in the STK11C88 device
+ */
+static void nvramStk11C88Commit()
+{
+#if 0
+ rtems_interval ticks_per_second;
+ rtems_status_code status;
+#endif
+
+ rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ /*
+ * Issue Store command
+ */
+ EIEIO;
+ (void)pNvRAMFunc->nvramRead(0x0e38);
+ EIEIO;
+ (void)pNvRAMFunc->nvramRead(0x31c7);
+ EIEIO;
+ (void)pNvRAMFunc->nvramRead(0x03e0);
+ EIEIO;
+ (void)pNvRAMFunc->nvramRead(0x3c1f);
+ EIEIO;
+ (void)pNvRAMFunc->nvramRead(0x303f);
+ EIEIO;
+ (void)pNvRAMFunc->nvramRead(0x0fc0);
+ EIEIO;
+ /*
+ * Delay for 10mS to allow store to
+ * complete
+ */
+#if 0
+ status = rtems_clock_get(
+ RTEMS_CLOCK_GET_TICKS_PER_SECOND,
+ &ticks_per_second
+ );
+
+ status = rtems_task_wake_after(ticks_per_second/100);
+#endif
+ bNvRAMChanged=FALSE;
+
+ rtems_semaphore_release(semNvRAM);
+}
+
+/*
+ * These are the publically accessable routines
+ */
+/*
+ * This routine returns the size of the NvRAM
+ */
+unsigned32 SizeNvRAM()
+{
+ return(ulPRePOSAreaLength);
+}
+
+/*
+ * This routine commits changes to the NvRAM
+ */
+void CommitNvRAM()
+{
+ if(bNvRAMChanged)
+ {
+ (pNvRAMFunc->nvramCommit)();
+ }
+}
+
+/*
+ * This routine reads a byte from the NvRAM
+ */
+rtems_status_code ReadNvRAM8(unsigned32 ulOffset, unsigned8 *pucData)
+{
+ if(ulOffset>ulPRePOSAreaLength)
+ {
+ return RTEMS_INVALID_ADDRESS;
+ }
+ rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ *pucData=pNvRAMFunc->nvramRead(ulPRePOSAreaOffset+ulOffset);
+ rtems_semaphore_release(semNvRAM);
+ return(RTEMS_SUCCESSFUL);
+}
+
+/*
+ * This routine writes a byte to the NvRAM
+ */
+rtems_status_code WriteNvRAM8(unsigned32 ulOffset, unsigned8 ucValue)
+{
+ if(ulOffset>ulPRePOSAreaLength)
+ {
+ return RTEMS_INVALID_ADDRESS;
+ }
+ rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ pNvRAMFunc->nvramWrite(ulPRePOSAreaOffset+ulOffset, ucValue);
+ bNvRAMChanged=TRUE;
+ rtems_semaphore_release(semNvRAM);
+ return(RTEMS_SUCCESSFUL);
+}
+
+/*
+ * This routine reads a block of bytes from the NvRAM
+ */
+rtems_status_code ReadNvRAMBlock(
+ unsigned32 ulOffset, unsigned8 *pucData, unsigned32 length)
+{
+ unsigned32 i;
+
+ if((ulOffset + length) > ulPRePOSAreaLength)
+ {
+ return RTEMS_INVALID_ADDRESS;
+ }
+ rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ for ( i=0 ; i<length ; i++ )
+ pucData[i] =
+ pNvRAMFunc->nvramRead(ulPRePOSAreaOffset+ulOffset+i);
+ rtems_semaphore_release(semNvRAM);
+ return(RTEMS_SUCCESSFUL);
+}
+
+/*
+ * This routine writes a block of bytes to the NvRAM
+ */
+rtems_status_code WriteNvRAMBlock(
+ unsigned32 ulOffset, unsigned8 *ucValue, unsigned32 length)
+{
+ unsigned32 i;
+
+ if((ulOffset + length) > ulPRePOSAreaLength)
+ {
+ return RTEMS_INVALID_ADDRESS;
+ }
+ rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+
+ for ( i=0 ; i<length ; i++ )
+ pNvRAMFunc->nvramWrite(
+ ulPRePOSAreaOffset+ulOffset+i, ucValue[i]);
+ bNvRAMChanged=TRUE;
+ rtems_semaphore_release(semNvRAM);
+ return(RTEMS_SUCCESSFUL);
+}
+
+/*
+ * The NVRAM holds data in Big-Endian format
+ */
+rtems_status_code ReadNvRAM16 (unsigned32 ulOffset, unsigned16 *pusData)
+{
+ unsigned32 ulTrueOffset=ulPRePOSAreaOffset+ulOffset;
+
+ if(ulOffset>ulPRePOSAreaLength)
+ {
+ return RTEMS_INVALID_ADDRESS;
+ }
+ rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ *pusData=(pNvRAMFunc->nvramRead(ulTrueOffset) << 8) +
+ (pNvRAMFunc->nvramRead(ulTrueOffset + 1));
+ rtems_semaphore_release(semNvRAM);
+ return(RTEMS_SUCCESSFUL);
+}
+
+rtems_status_code WriteNvRAM16 (unsigned32 ulOffset, unsigned16 usValue)
+{
+ unsigned32 ulTrueOffset=ulPRePOSAreaOffset+ulOffset;
+
+ if(ulOffset>ulPRePOSAreaLength)
+ {
+ return RTEMS_INVALID_ADDRESS;
+ }
+ rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ pNvRAMFunc->nvramWrite(ulTrueOffset, (unsigned8) (usValue >> 8));
+ pNvRAMFunc->nvramWrite(ulTrueOffset + 1, (unsigned8) usValue);
+ bNvRAMChanged=TRUE;
+ rtems_semaphore_release(semNvRAM);
+ return(RTEMS_SUCCESSFUL);
+}
+
+rtems_status_code ReadNvRAM32 (unsigned32 ulOffset, unsigned32 *pulData)
+{
+ unsigned32 ulTrueOffset=ulPRePOSAreaOffset+ulOffset;
+
+ if(ulOffset>ulPRePOSAreaLength)
+ {
+ return RTEMS_INVALID_ADDRESS;
+ }
+ rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ *pulData=(pNvRAMFunc->nvramRead(ulTrueOffset) << 24) +
+ (pNvRAMFunc->nvramRead(ulTrueOffset + 1) << 16) +
+ (pNvRAMFunc->nvramRead(ulTrueOffset + 2) << 8) +
+ (pNvRAMFunc->nvramRead(ulTrueOffset + 3));
+ rtems_semaphore_release(semNvRAM);
+ return(RTEMS_SUCCESSFUL);
+}
+
+rtems_status_code WriteNvRAM32 (unsigned32 ulOffset, unsigned32 ulValue)
+{
+ unsigned32 ulTrueOffset=ulPRePOSAreaOffset+ulOffset;
+
+ if(ulOffset>ulPRePOSAreaLength)
+ {
+ return RTEMS_INVALID_ADDRESS;
+ }
+ rtems_semaphore_obtain(semNvRAM, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ pNvRAMFunc->nvramWrite(ulTrueOffset, (unsigned8) (ulValue >> 24));
+ pNvRAMFunc->nvramWrite(ulTrueOffset + 1, (unsigned8) (ulValue >> 16));
+ pNvRAMFunc->nvramWrite(ulTrueOffset + 2, (unsigned8) (ulValue >> 8));
+ pNvRAMFunc->nvramWrite(ulTrueOffset + 3, (unsigned8) ulValue);
+ bNvRAMChanged=TRUE;
+ rtems_semaphore_release(semNvRAM);
+ return(RTEMS_SUCCESSFUL);
+}
+
+void
+InitializeNvRAM(void)
+{
+ PHEADER pNvHeader = (PHEADER)0;
+ rtems_status_code sc;
+ unsigned32 ulLength, ulOffset;
+
+ if(ucSystemType==SYS_TYPE_PPC1)
+ {
+ if(ucBoardRevMaj<5)
+ {
+ pNvRAMFunc=&nvramDsTable;
+ }
+ else
+ {
+ pNvRAMFunc=&nvramMkTable;
+ }
+ }
+ else if(ucSystemType==SYS_TYPE_PPC1a)
+ {
+ pNvRAMFunc=&nvramMkTable;
+ }
+ else if(ucSystemType==SYS_TYPE_PPC4)
+ {
+ pNvRAMFunc=&nvramStk88Table;
+ }
+ else
+ {
+ pNvRAMFunc=&nvramStkTable;
+ }
+
+ /*
+ * Set up mutex semaphore
+ */
+ sc = rtems_semaphore_create (
+ rtems_build_name ('N', 'V', 'R', 's'),
+ 1,
+ RTEMS_BINARY_SEMAPHORE |
+ RTEMS_INHERIT_PRIORITY |
+ RTEMS_PRIORITY,
+ RTEMS_NO_PRIORITY,
+ &semNvRAM);
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+ rtems_fatal_error_occurred (sc);
+ }
+
+ /*
+ * Initially access the whole of NvRAM until we determine where the
+ * OS Area is located.
+ */
+ ulPRePOSAreaLength=0xffffffff;
+ ulPRePOSAreaOffset=0;
+
+ /*
+ * Access the header at the start of NvRAM
+ */
+ ReadNvRAM32((unsigned32)(&pNvHeader->OSAreaLength), &ulLength);
+ ReadNvRAM32((unsigned32)(&pNvHeader->OSAreaAddress), &ulOffset);
+
+ /*
+ * Now set limits for future accesses
+ */
+ ulPRePOSAreaLength=ulLength;
+ ulPRePOSAreaOffset=ulOffset;
+}
+
+