diff options
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.c | 515 |
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; +} + + |