summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Muhle <armuhle@us.ibm.com>2012-06-25 07:50:23 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-07-09 12:23:40 -0500
commita87cb9ce7a0322f9fd6c6e015894f12a2975e10f (patch)
tree036b9f7d634493154723b3d1c4171fbed1938aa3
parentdfff59856617139f7776d473fdc226a91761128e (diff)
downloadtalos-hostboot-a87cb9ce7a0322f9fd6c6e015894f12a2975e10f.tar.gz
talos-hostboot-a87cb9ce7a0322f9fd6c6e015894f12a2975e10f.zip
Update PNOR RP to parse FFS Partition Table
This function allows us to support varied PNOR layouts in Hostboot. Change-Id: I7294999d3619692aaab424dca1ae608a0a84fa81 RTC: 35057 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1274 Tested-by: Jenkins Server Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rwxr-xr-xsrc/build/buildpnor/buildpnor.pl16
-rw-r--r--src/build/buildpnor/pnorLayout.xml27
-rw-r--r--src/include/usr/pnor/pnorif.H51
-rw-r--r--src/usr/hwas/deconfigGard.C47
-rwxr-xr-xsrc/usr/mvpd/mvpd.C2
-rw-r--r--src/usr/pnor/ffs.h136
-rw-r--r--src/usr/pnor/pnordd.C48
-rw-r--r--src/usr/pnor/pnordd.H58
-rw-r--r--src/usr/pnor/pnorrp.C369
-rw-r--r--src/usr/pnor/pnorrp.H96
-rw-r--r--src/usr/pnor/test/pnorrptest.H109
-rwxr-xr-xsrc/usr/spd/spd.C4
-rw-r--r--src/usr/targeting/attrrp.C48
-rw-r--r--src/usr/vfs/vfsrp.C49
14 files changed, 637 insertions, 423 deletions
diff --git a/src/build/buildpnor/buildpnor.pl b/src/build/buildpnor/buildpnor.pl
index ed0f8472d..b582822ba 100755
--- a/src/build/buildpnor/buildpnor.pl
+++ b/src/build/buildpnor/buildpnor.pl
@@ -207,6 +207,7 @@ sub loadPnorLayout
$imageSize = getNumber($imageSize);
$blockSize = getNumber($blockSize);
+ $partTableSize = getNumber($partTableSize);
$$i_pnorLayoutRef{metadata}{imageSize} = $imageSize;
$$i_pnorLayoutRef{metadata}{blockSize} = $blockSize;
@@ -223,6 +224,7 @@ sub loadPnorLayout
my $physicalRegionSize = $sectionEl->{physicalRegionSize}[0];
my $ecc = $sectionEl->{ecc}[0];
my $source = $sectionEl->{source}[0];
+ my $sideless = $sectionEl->{sideless}[0];
my $actualRegionSize = 0;
if(exists($sectionEl->{actualRegionSize}[0]))
@@ -245,6 +247,7 @@ sub loadPnorLayout
$$i_pnorLayoutRef{sections}{$physicalOffset}{actualRegionSize} = $actualRegionSize;
$$i_pnorLayoutRef{sections}{$physicalOffset}{ecc} = $ecc;
$$i_pnorLayoutRef{sections}{$physicalOffset}{source} = $source;
+ $$i_pnorLayoutRef{sections}{$physicalOffset}{sideless} = $sideless;
}
@@ -431,9 +434,16 @@ sub genToc
insertPadBytes($FILEHANDLE, 4);
}
- #FFS User Word 2-3: Miscellaneous information. Not currently implemented
- insertPadBytes($FILEHANDLE, 8);
-
+ #FFS User Word 2-3: Miscellaneous information.
+ #User Word 2, bit 18 indicates sideless.
+ my $miscInfo = 0x00000000;
+ if($sectionHash{$key}{sideless} =~ "yes")
+ {
+ $miscInfo = $miscInfo | 0x00004000;
+ }
+ print $FILEHANDLE pack('N', $miscInfo);
+ #User Word 3 Not currently implemented.
+ insertPadBytes($FILEHANDLE, 4);
#FFS User Word 4-16: Free space User Data
insertPadBytes($FILEHANDLE, 52);
diff --git a/src/build/buildpnor/pnorLayout.xml b/src/build/buildpnor/pnorLayout.xml
index da1df2139..d6adc9289 100644
--- a/src/build/buildpnor/pnorLayout.xml
+++ b/src/build/buildpnor/pnorLayout.xml
@@ -22,50 +22,55 @@
IBM_PROLOG_END_TAG -->
<pnor>
<metadata>
- <imageSize>0x400000</imageSize>
- <blockSize>0x1000</blockSize>
- <partTableSize>0x1</partTableSize>
+ <imageSize>0x400000</imageSize>
+ <blockSize>0x1000</blockSize>
+ <partTableSize>0x1</partTableSize>
</metadata>
<section>
- <description>Table of Contents (2K)</description>
+ <description>Table of Contents (2K)</description>
<eyeCatch>part</eyeCatch>
<physicalOffset>0</physicalOffset>
<physicalRegionSize>0x1000</physicalRegionSize>
<ecc>no</ecc>
<source>Generate</source>
+ <sideless>no</sideless>
</section>
<section>
- <description>Hostboot Extended image (2MB)</description>
+ <description>Hostboot Extended image (2MB)</description>
<eyeCatch>HBI</eyeCatch>
<physicalOffset>0x1000</physicalOffset>
<physicalRegionSize>0x200000</physicalRegionSize>
<ecc>no</ecc>
<source>File</source>
+ <sideless>no</sideless>
</section>
<section>
- <description>Attribute Data (512K)</description>
+ <description>Attribute Data (512K)</description>
<eyeCatch>HBD</eyeCatch>
<physicalOffset>0x201000</physicalOffset>
<physicalRegionSize>0x80000</physicalRegionSize>
<ecc>no</ecc>
<source>File</source>
- </section>
+ <sideless>no</sideless>
+ </section>
<section>
- <description>Module VPD</description>
+ <description>Module VPD</description>
<eyeCatch>MVPD</eyeCatch>
<physicalOffset>0x281000</physicalOffset>
<physicalRegionSize>0x80000</physicalRegionSize>
- <actualRegionSize>0x80000</actualRegionSize>
+ <actualRegionSize>0x80000</actualRegionSize>
<ecc>no</ecc>
<source>Blank</source>
+ <sideless>yes</sideless>
</section>
<section>
- <description>DIMM JEDEC</description>
+ <description>DIMM JEDEC</description>
<eyeCatch>DJVPD</eyeCatch>
<physicalOffset>0x301000</physicalOffset>
<physicalRegionSize>0x40000</physicalRegionSize>
- <actualRegionSize>0x40000</actualRegionSize>
+ <actualRegionSize>0x40000</actualRegionSize>
<ecc>no</ecc>
<source>Blank</source>
+ <sideless>yes</sideless>
</section>
</pnor>
diff --git a/src/include/usr/pnor/pnorif.H b/src/include/usr/pnor/pnorif.H
index 86dbdebc5..c3440c1a5 100644
--- a/src/include/usr/pnor/pnorif.H
+++ b/src/include/usr/pnor/pnorif.H
@@ -1,25 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/include/usr/pnor/pnorif.H $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/include/usr/pnor/pnorif.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2011-2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
#ifndef __PNOR_PNORIF_H
#define __PNOR_PNORIF_H
@@ -60,9 +61,9 @@ enum SectionId
*/
enum SideSelect
{
- SIDE_A, /**< A-side of flash */
- SIDE_B, /**< B-side of flash */
- SIDELESS, /**< Sideless data */
+ SIDE_A, /**< A-side of flash */
+ SIDE_B, /**< B-side of flash */
+ CURRENT_SIDE, /**< Use the currently selected side */
};
/**
diff --git a/src/usr/hwas/deconfigGard.C b/src/usr/hwas/deconfigGard.C
index 28a7b917d..549c5e09d 100644
--- a/src/usr/hwas/deconfigGard.C
+++ b/src/usr/hwas/deconfigGard.C
@@ -1,25 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/hwas/deconfigGard.C $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwas/deconfigGard.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2011-2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
/**
* @file deconfigGard.C
*
@@ -736,7 +737,7 @@ errlHndl_t DeconfigGard::_ensureGardRecordDataSetup()
PNOR::SectionInfo_t l_section;
// TODO Update when PNOR for GARD Records available (change HB_DATA)
- l_pErr = PNOR::getSectionInfo(PNOR::HB_DATA, PNOR::SIDE_A, l_section);
+ l_pErr = PNOR::getSectionInfo(PNOR::HB_DATA, PNOR::CURRENT_SIDE, l_section);
if(l_pErr)
{
diff --git a/src/usr/mvpd/mvpd.C b/src/usr/mvpd/mvpd.C
index 07c98560e..6fe4276ff 100755
--- a/src/usr/mvpd/mvpd.C
+++ b/src/usr/mvpd/mvpd.C
@@ -744,7 +744,7 @@ errlHndl_t mvpdFetchData ( uint64_t i_byteAddr,
info.segmentSize = MVPD_SECTION_SIZE;
info.maxSegments = MVPD_MAX_SECTIONS;
info.pnorSection = PNOR::MODULE_VPD;
- info.pnorSide = PNOR::SIDELESS;
+ info.pnorSide = PNOR::CURRENT_SIDE;
err = SPD::readPNOR( i_byteAddr,
i_numBytes,
o_data,
diff --git a/src/usr/pnor/ffs.h b/src/usr/pnor/ffs.h
new file mode 100644
index 000000000..e640c1e79
--- /dev/null
+++ b/src/usr/pnor/ffs.h
@@ -0,0 +1,136 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/pnor/ffs.h $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+/*
+ * Copyright (c) International Business Machines Corp., 2012
+ *
+ * FSP Flash Structure
+ *
+ * This header defines the layout for the FSP Flash Structure.
+ */
+
+#ifndef __FFS_H__
+#define __FFS_H__
+
+#include <stdint.h>
+
+/* The version of this partition implementation */
+#define FFS_VERSION_1 1
+
+/* Magic number for the partition header (ASCII 'PART') */
+#define FFS_MAGIC 0x50415254
+
+/* The maximum length of the partition name */
+#define PART_NAME_MAX 15
+
+/*
+ * Sizes of the data structures
+ */
+#define FFS_HDR_SIZE sizeof(struct ffs_hdr)
+#define FFS_ENTRY_SIZE sizeof(struct ffs_entry)
+
+/*
+ * Sizes of the data structures w/o checksum
+ */
+#define FFS_HDR_SIZE_CSUM (FFS_HDR_SIZE - sizeof(uint32_t))
+#define FFS_ENTRY_SIZE_CSUM (FFS_ENTRY_SIZE - sizeof(uint32_t))
+
+/* pid of logical partitions/containers */
+#define FFS_PID_TOPLEVEL 0xFFFFFFFF
+
+/*
+ * Type of image contained w/in partition
+ */
+enum type {
+ FFS_TYPE_DATA = 1,
+ FFS_TYPE_LOGICAL = 2,
+ FFS_TYPE_PARTITION = 3,
+};
+
+/*
+ * Flag bit definitions
+ */
+#define FFS_FLAGS_PROTECTED 0x0001
+
+/*
+ * Number of user data words
+ */
+#define FFS_USER_WORDS 16
+
+/**
+ * struct ffs_entry - Partition entry
+ *
+ * @name: Opaque null terminated string
+ * @base: Starting offset of partition in flash (in hdr.block_size)
+ * @size: Partition size (in hdr.block_size)
+ * @pid: Parent partition entry (FFS_PID_TOPLEVEL for toplevel)
+ * @id: Partition entry ID [1..65536]
+ * @type: Describe type of partition
+ * @flags: Partition attributes (optional)
+ * @resvd: Reserved words for future use
+ * @user: User data (optional)
+ * @checksum: Partition entry checksum (includes all above)
+ */
+struct ffs_entry {
+ char name[PART_NAME_MAX + 1];
+ uint32_t base;
+ uint32_t size;
+ uint32_t pid;
+ uint32_t id;
+ uint32_t type;
+ uint32_t flags;
+ uint32_t resvd[5];
+ struct {
+ uint32_t data[FFS_USER_WORDS];
+ } user;
+ uint32_t checksum;
+} __attribute__ ((packed));
+
+/**
+ * struct ffs_hdr - FSP Flash Structure header
+ *
+ * @magic: Eye catcher/corruption detector
+ * @version: Version of the structure
+ * @size: Size of partition table (in block_size)
+ * @entry_size: Size of struct ffs_entry element (in bytes)
+ * @entry_count: Number of struct ffs_entry elements in @entries array
+ * @block_size: Size of block on device (in bytes)
+ * @block_count: Number of blocks on device
+ * @resvd: Reserved words for future use
+ * @checksum: Header checksum
+ * @entries: Pointer to array of partition entries
+ */
+struct ffs_hdr {
+ uint32_t magic;
+ uint32_t version;
+ uint32_t size;
+ uint32_t entry_size;
+ uint32_t entry_count;
+ uint32_t block_size;
+ uint32_t block_count;
+ uint32_t resvd[4];
+ uint32_t checksum;
+ struct ffs_entry entries[];
+} __attribute__ ((packed));
+
+#endif /* __FFS_H__ */
diff --git a/src/usr/pnor/pnordd.C b/src/usr/pnor/pnordd.C
index a62bc59f0..2468b470d 100644
--- a/src/usr/pnor/pnordd.C
+++ b/src/usr/pnor/pnordd.C
@@ -275,13 +275,6 @@ errlHndl_t PnorDD::readFlash(void* o_buffer,
//multiple fake chips eventually
uint64_t l_address = i_address & 0x00000000FFFFFFFF;
- l_err = verifyFlashAddressRange(l_address, io_buflen);
- if(l_err)
- {
- io_buflen = 0;
- break;
- }
-
// skip everything in MEMCPY mode
if( MODEL_MEMCPY == iv_mode )
{
@@ -318,10 +311,6 @@ errlHndl_t PnorDD::writeFlash(void* i_buffer,
//multiple fake chips eventually
uint64_t l_address = i_address & 0x00000000FFFFFFFF;
- // make sure this is a valid address
- l_err = verifyFlashAddressRange(l_address, io_buflen);
- if(l_err) { break; }
-
// skip everything in MEMCPY mode
if( MODEL_MEMCPY == iv_mode )
{
@@ -571,43 +560,6 @@ void PnorDD::sfcInit( )
}
/**
- * @brief Verify flash request is in appropriate address range
- */
-errlHndl_t PnorDD::verifyFlashAddressRange(uint64_t i_address,
- size_t& i_length)
-{
- errlHndl_t l_err = NULL;
-
- do{
- //@todo - Do we really need any checking here?
- // if so we should be getting the size told to us by the PNOR RP
- // based on the TOC or global data
-
- if((i_address+i_length) > PNORSIZE)
- {
- TRACFCOMP( g_trac_pnor, "PnorDD::verifyAddressRange> Invalid Address Requested : i_address=%d", i_address );
- /*@
- * @errortype
- * @moduleid PNOR::MOD_PNORDD_VERIFYADDRESSRANGE
- * @reasoncode PNOR::RC_INVALID_ADDRESS
- * @userdata1 Requested Address
- * @userdata2 Requested Length
- * @devdesc PnorDD::verifyAddressRange> Invalid Address requested
- */
- l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- PNOR::MOD_PNORDD_VERIFYADDRESSRANGE,
- PNOR::RC_INVALID_ADDRESS,
- TO_UINT64(i_address),
- TO_UINT64(i_length));
- break;
- }
-
- }while(0);
-
- return l_err;
-}
-
-/**
* @brief Write a SFC Register
*/
errlHndl_t PnorDD::writeRegSfc(SfcRange i_range,
diff --git a/src/usr/pnor/pnordd.H b/src/usr/pnor/pnordd.H
index ed88695af..acb8be1a6 100644
--- a/src/usr/pnor/pnordd.H
+++ b/src/usr/pnor/pnordd.H
@@ -1,25 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/pnor/pnordd.H $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/pnor/pnordd.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2011-2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
#ifndef __PNOR_PNORDD_H
#define __PNOR_PNORDD_H
@@ -95,17 +96,6 @@ class PnorDD
/**
- * @brief Verify flash request is in appropriate address range
- *
- * @i_address Flash address being operated on
- * @i_length Length of chunk being operated on
- *
- * @return Error if requested address range is invalid
- */
- errlHndl_t verifyFlashAddressRange(uint64_t i_address,
- size_t& i_length);
-
- /**
* @brief LPC HC Registers
* These are offsets within the LPC Host Controller Register Space
*/
@@ -370,7 +360,7 @@ class PnorDD
LPC_STAT_REG_ERROR_MASK = 0xFC0000000007F700, /**< Error Bits */
- PNORSIZE = 4 * MEGABYTE, //@fixme - read from TOC instead
+ PNORSIZE = 16 * MEGABYTE, //@fixme - read from TOC instead (RTC: 42252)
ERASESIZE_BYTES_DEFAULT = 4 * KILOBYTE, /**< Minimum Erase Block (bytes) */
ECCB_POLL_TIME_NS = 400000, /**< max time from Manfred Walz is 400ms */
ECCB_POLL_INCR_NS = 10, /**< minimum increment during poll */
diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C
index 9545475e5..e24c54f44 100644
--- a/src/usr/pnor/pnorrp.C
+++ b/src/usr/pnor/pnorrp.C
@@ -1,25 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/pnor/pnorrp.C $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/pnor/pnorrp.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2011-2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
#include "pnorrp.H"
#include <pnor/pnor_reasoncodes.H>
#include <initservice/taskargs.H>
@@ -47,7 +48,7 @@ TRAC_INIT(&g_trac_pnor, "PNOR", 4096); //4K
* Eyecatcher strings for PNOR TOC entries
*/
const char* cv_EYECATCHER[] = { //@todo - convert there to uint64_t
- "TOC", /**< PNOR::TOC : Table of Contents */
+ "part", /**< PNOR::TOC : Table of Contents */
"HBI", /**< PNOR::HB_EXT_CODE : Hostboot Extended Image */
"HBD", /**< PNOR::HB_DATA : Hostboot Data */
"DJVPD", /**< PNOR::DIMM_JEDEC_VPD: Dimm JEDEC VPD */
@@ -146,6 +147,10 @@ PnorRP::PnorRP()
{
TRACFCOMP(g_trac_pnor, "PnorRP::PnorRP> " );
+ //Default to PNOR Side A for now.
+ //TODO: Determine proper side (RTC: 34764)
+ iv_curSide = PNOR::SIDE_A;
+
// setup everything in a separate function
initDaemon();
@@ -246,9 +251,15 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section,
//TRACDCOMP(g_trac_pnor, "PnorRP::getSectionInfo> i_section=%d, i_side=%X", i_section, i_side );
errlHndl_t l_errhdl = NULL;
PNOR::SectionId id = i_section;
+ PNOR::SideSelect side = i_side;
do
{
+ if(side == PNOR::CURRENT_SIDE)
+ {
+ side = iv_curSide;
+ }
+
// Abort this operation if we had a startup failure
uint64_t rc = 0;
if( didStartupFail(rc) )
@@ -274,10 +285,10 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section,
}
// Zero-length means the section is invalid
- if( 0 == iv_TOC[i_side][id].size )
+ if( 0 == iv_TOC[side][id].size )
{
- TRACFCOMP( g_trac_pnor, "PnorRP::getSectionInfo> Invalid Section Requested : i_section=%d, i_side=%d", i_section, i_side );
- TRACFCOMP(g_trac_pnor, "o_info={ id=%d, size=%d }", iv_TOC[i_side][i_section].id, iv_TOC[i_side][i_section].size );
+ TRACFCOMP( g_trac_pnor, "PnorRP::getSectionInfo> Invalid Section Requested : i_section=%d, side=%d", i_section, side );
+ TRACFCOMP(g_trac_pnor, "o_info={ id=%d, size=%d }", iv_TOC[side][i_section].id, iv_TOC[side][i_section].size );
/*@
* @errortype
* @moduleid PNOR::MOD_PNORRP_GETSECTIONINFO
@@ -290,7 +301,7 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section,
PNOR::MOD_PNORRP_GETSECTIONINFO,
PNOR::RC_INVALID_SECTION,
TO_UINT64(i_section),
- TO_UINT64(i_side));
+ TO_UINT64(side));
// set the return section to our invalid data
id = PNOR::INVALID_SECTION;
@@ -298,21 +309,20 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section,
}
} while(0);
- TRACFCOMP( g_trac_pnor, "i_section=%d, i_side=%d : id=%d", i_section, i_side, iv_TOC[i_side][i_section].id );
+ TRACDCOMP( g_trac_pnor, "PnorRP::getSectionInfo: i_section=%d, side=%d : id=%d", i_section, side, iv_TOC[side][i_section].id );
// copy my data into the external format
- o_info.id = iv_TOC[i_side][id].id;
- o_info.side = iv_TOC[i_side][id].side;
+ o_info.id = iv_TOC[side][id].id;
+ o_info.side = iv_TOC[side][id].side;
o_info.name = cv_EYECATCHER[id];
- o_info.vaddr = iv_TOC[i_side][id].virtAddr;
- o_info.size = iv_TOC[i_side][id].size;
- o_info.eccProtected = iv_TOC[i_side][id].eccProtected;
+ o_info.vaddr = iv_TOC[side][id].virtAddr;
+ o_info.size = iv_TOC[side][id].size;
+ o_info.eccProtected = (bool)(iv_TOC[side][id].miscFlags & MISC_ECC_PROTECT);
return l_errhdl;
}
-
/**
* @brief Read the TOC and store section information
*/
@@ -320,63 +330,172 @@ errlHndl_t PnorRP::readTOC()
{
TRACUCOMP(g_trac_pnor, "PnorRP::readTOC>" );
errlHndl_t l_errhdl = NULL;
+ uint8_t* tocBuffer = NULL;
+#define SIDELESS_VADDR_INDEX 2
+ uint64_t nextVAddr[] = {SIDEA_VADDR, SIDEB_VADDR, SIDELESS_VADDR};
- // Zero out my table
- for( uint64_t side = 0; side < NUM_SIDES; side++ )
- {
- for( PNOR::SectionId id = PNOR::FIRST_SECTION;
- id <= PNOR::NUM_SECTIONS; //include extra entry for error paths
- id = (PNOR::SectionId) (id + 1) )
+ do{
+ // Zero out my table
+ for( uint64_t side = 0; side < NUM_SIDES; side++ )
{
- iv_TOC[side][id].id = id;
- iv_TOC[side][id].side = (PNOR::SideSelect)side;
- iv_TOC[side][id].chip = 0;
- iv_TOC[side][id].flashAddr = 0;
- iv_TOC[side][id].virtAddr = 0;
- iv_TOC[side][id].size = 0;
- iv_TOC[side][id].eccProtected = 0;
+ for( PNOR::SectionId id = PNOR::FIRST_SECTION;
+ id <= PNOR::NUM_SECTIONS; //include extra entry for error paths
+ id = (PNOR::SectionId) (id + 1) )
+ {
+ iv_TOC[side][id].id = id;
+ iv_TOC[side][id].side = (PNOR::SideSelect)side;
+ iv_TOC[side][id].chip = 0;
+ iv_TOC[side][id].flashAddr = 0;
+ iv_TOC[side][id].virtAddr = 0;
+ iv_TOC[side][id].size = 0;
+ iv_TOC[side][id].miscFlags = 0;
+ }
}
- }
- //@todo - Add in some dummy values for now
- // Will update under Story 3871
-
- // assume 1 chip with only 1 side for now, no sideless
- // TOC starts at offset zero
-
- // put some random sizes in here
- //sizes and offsets taken from pnorLayout.xml
- iv_TOC[PNOR::SIDE_A][PNOR::TOC].size = 0x1000;
- iv_TOC[PNOR::SIDE_A][PNOR::HB_EXT_CODE].size = 0x200000; //1MB
- iv_TOC[PNOR::SIDE_A][PNOR::HB_DATA].size = 0x80000; //512K
- iv_TOC[PNOR::SIDELESS][PNOR::MODULE_VPD].size = 0x80000; //512K
- iv_TOC[PNOR::SIDELESS][PNOR::DIMM_JEDEC_VPD].size = 0x40000; //256K
-
- // fake PNOR will look like this: TOC::HB_EXT_CODE:HB_DATA:MODULE_VPD:DIMM_JEDEC_VPD
- // virtual addresses
- iv_TOC[PNOR::SIDE_A][PNOR::TOC].virtAddr = BASE_VADDR + 0;
- iv_TOC[PNOR::SIDE_A][PNOR::HB_EXT_CODE].virtAddr = BASE_VADDR + 0x1000;
- iv_TOC[PNOR::SIDE_A][PNOR::HB_DATA].virtAddr = BASE_VADDR + 0x201000;
- iv_TOC[PNOR::SIDELESS][PNOR::MODULE_VPD].virtAddr = SIDELESS_VADDR + 0x281000;
- iv_TOC[PNOR::SIDELESS][PNOR::DIMM_JEDEC_VPD].virtAddr = SIDELESS_VADDR + 0x301000;
- // flash
- iv_TOC[PNOR::SIDE_A][PNOR::TOC].flashAddr = 0;
- iv_TOC[PNOR::SIDE_A][PNOR::HB_EXT_CODE].flashAddr = 0x1000;
- iv_TOC[PNOR::SIDE_A][PNOR::HB_DATA].flashAddr = 0x201000;
- iv_TOC[PNOR::SIDELESS][PNOR::MODULE_VPD].flashAddr = 0x281000;
- iv_TOC[PNOR::SIDELESS][PNOR::DIMM_JEDEC_VPD].flashAddr = 0x301000;
-
- //@todo - end fake data
-
- //keep these traces here until PNOR is rock-solid
- TRACFCOMP(g_trac_pnor, "TOC: size=0x%.8X flash=0x%.8X virt=0x%.16X", iv_TOC[PNOR::SIDE_A][PNOR::TOC].size, iv_TOC[PNOR::SIDE_A][PNOR::TOC].flashAddr, iv_TOC[PNOR::SIDE_A][PNOR::TOC].virtAddr );
- TRACFCOMP(g_trac_pnor, "EXT: size=0x%.8X flash=0x%.8X virt=0x%.16X", iv_TOC[PNOR::SIDE_A][PNOR::HB_EXT_CODE].size, iv_TOC[PNOR::SIDE_A][PNOR::HB_EXT_CODE].flashAddr, iv_TOC[PNOR::SIDE_A][PNOR::HB_EXT_CODE].virtAddr );
- TRACFCOMP(g_trac_pnor, "DATA: size=0x%.8X flash=0x%.8X virt=0x%.16X", iv_TOC[PNOR::SIDE_A][PNOR::HB_DATA].size, iv_TOC[PNOR::SIDE_A][PNOR::HB_DATA].flashAddr, iv_TOC[PNOR::SIDE_A][PNOR::HB_DATA].virtAddr );
- TRACFCOMP(g_trac_pnor, "MVPD: size=0x%.8X flash=0x%.8X virt=0x%.16X", iv_TOC[PNOR::SIDELESS][PNOR::MODULE_VPD].size, iv_TOC[PNOR::SIDELESS][PNOR::MODULE_VPD].flashAddr, iv_TOC[PNOR::SIDELESS][PNOR::MODULE_VPD].virtAddr );
- TRACFCOMP(g_trac_pnor, "DJVPD: size=0x%.8X flash=0x%.8X virt=0x%.16X", iv_TOC[PNOR::SIDELESS][PNOR::DIMM_JEDEC_VPD].size, iv_TOC[PNOR::SIDELESS][PNOR::DIMM_JEDEC_VPD].flashAddr, iv_TOC[PNOR::SIDELESS][PNOR::DIMM_JEDEC_VPD].virtAddr );
-
- //@todo - load flash layout (how many chips)
- //@todo - read TOC on each chip/bank/whatever
+ // Read TOC information
+ // assume 1 chip with only 1 side for now, no sideless
+ const uint32_t cur_side = PNOR::SIDE_A;
+
+ // TOC starts at offset zero
+
+ tocBuffer = new uint8_t[PAGESIZE];
+ l_errhdl = readFromDevice( FFS_TABLE_BASE_ADDR, 0, false, tocBuffer );
+ if( l_errhdl ) { break; }
+
+ ffs_hdr* l_ffs_hdr = (ffs_hdr*) tocBuffer;
+
+ //TODO: verify checksum of header RTC: 44147
+
+ TRACFCOMP(g_trac_pnor, "PnorRp::readTOC: FFS Block size = 0x%.8X, Partition Table Size = 0x%.8x, entry_count=%d", l_ffs_hdr->block_size, l_ffs_hdr->size, l_ffs_hdr->entry_count);
+
+ /* Checking FFS Header to make sure it looks valid */
+ //TODO: Leave FFDC Breadcrumbs before issuing critical assert in the checks below.. RTC: 44146.
+ if(l_ffs_hdr->magic != FFS_MAGIC)
+ {
+ TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Invalid magic number in FFS header: 0x%.4X", l_ffs_hdr->magic);
+ crit_assert(0);
+ }
+
+ if(l_ffs_hdr->version != SUPPORTED_FFS_VERSION)
+ {
+ TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Unsupported FFS Header version: 0x%.4X", l_ffs_hdr->version);
+ crit_assert(0);
+ }
+
+ if(l_ffs_hdr->entry_size != sizeof(ffs_entry))
+ {
+ TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Unexpected entry_size(0x%.8x) in FFS header: 0x%.4X", l_ffs_hdr->entry_size);
+ crit_assert(0);
+ }
+
+ if(l_ffs_hdr->entries == NULL)
+ {
+ TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: FFS Header pointer to entries is NULL.");
+ crit_assert(0);
+ }
+
+ if(l_ffs_hdr->block_size != PAGESIZE)
+ {
+ TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Unsupported Block Size(0x%.4X). PNOR Blocks must be 4k", l_ffs_hdr->block_size);
+ crit_assert(0);
+ }
+
+ if(l_ffs_hdr->block_count == 0)
+ {
+ TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Unsupported BLock COunt(0x%.4X). Device cannot be zero blocks in length.", l_ffs_hdr->block_count);
+ crit_assert(0);
+ }
+
+ //Make sure all the entries fit in specified partition table size.
+ uint64_t spaceUsed = (sizeof(ffs_entry))*l_ffs_hdr->entry_count;
+ if(spaceUsed > ((l_ffs_hdr->block_size * l_ffs_hdr->size) - sizeof(ffs_hdr)))
+ {
+ TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: FFS Entries (0x%.16X) go past end of FFS Table.", spaceUsed);
+ crit_assert(0);
+ }
+
+ ffs_hb_user_t* ffsUserData = NULL;
+
+ //Walk through all the entries in the table and parse the data.
+ ffs_entry* cur_entry = (l_ffs_hdr->entries);
+ for(uint32_t i=0; i<l_ffs_hdr->entry_count; i++)
+ {
+ TRACUCOMP(g_trac_pnor, "PnorRp::readTOC: Entry %d, name=%s, pointer=0x%X", i, cur_entry->name, (uint64_t)cur_entry);
+
+ //TODO: verify checksum of entry RTC: 44147
+
+ uint32_t secId = PNOR::INVALID_SECTION;
+
+ //Figure out section enum
+ for(uint32_t eyeIndex=PNOR::TOC; eyeIndex < PNOR::NUM_SECTIONS; eyeIndex++)
+ {
+ if(strcmp(cv_EYECATCHER[eyeIndex], cur_entry->name) == 0)
+ {
+ secId = eyeIndex;
+ TRACUCOMP(g_trac_pnor, "PnorRp::readTOC: sectionId=%d", secId);
+ break;
+ }
+ }
+
+ if(secId == PNOR::INVALID_SECTION)
+ {
+ TRACFCOMP(g_trac_pnor, "PnorRp::readTOC: Unrecognized Section name(%s), skipping", cur_entry->name);
+ continue;
+ }
+
+ ffsUserData = (ffs_hb_user_t*)&cur_entry->user;
+
+ //size
+ iv_TOC[cur_side][secId].size = ((uint64_t)cur_entry->size)*PAGESIZE;
+
+
+ //virtAddr
+ //The PNOR data is broken up into 3 blocks of Virtual Addresses, A, B, and Sideless.
+ //For Sections found to be sideless, both PNOR sides will map to the same virtual address.
+ if(!(ffsUserData->miscFlags & MISC_SIDELESS))
+ {
+ iv_TOC[cur_side][secId].virtAddr = nextVAddr[cur_side];
+ nextVAddr[cur_side] += iv_TOC[cur_side][secId].size;
+ }
+ else
+ {
+ //TODO: Map both sides of PNOR to the same VADDR for Sideless (RTC: 34764)
+ iv_TOC[cur_side][secId].virtAddr = nextVAddr[SIDELESS_VADDR_INDEX];
+ nextVAddr[SIDELESS_VADDR_INDEX] += iv_TOC[cur_side][secId].size;
+ }
+
+ //flashAddr
+ iv_TOC[cur_side][secId].flashAddr = ((uint64_t)cur_entry->base)*PAGESIZE;
+
+ //chipSelect
+ iv_TOC[cur_side][secId].chip = ffsUserData->chip;
+
+ //mics flags
+ iv_TOC[cur_side][secId].miscFlags = ffsUserData->miscFlags;
+
+ if((iv_TOC[cur_side][secId].flashAddr + iv_TOC[cur_side][secId].size) > (l_ffs_hdr->block_count*PAGESIZE))
+ {
+ TRACFCOMP(g_trac_pnor, "E>PnorRp::readTOC: Partition(%s) at base address (0x%.8x) extends past end of flash device", cur_entry->name, iv_TOC[cur_side][secId].flashAddr);
+ crit_assert(0);
+ }
+
+ cur_entry++;
+ }
+
+ //keep these traces here until PNOR is rock-solid
+ TRACFCOMP(g_trac_pnor, "TOC: size=0x%.8X flash=0x%.8X virt=0x%.16X", iv_TOC[PNOR::SIDE_A][PNOR::TOC].size, iv_TOC[PNOR::SIDE_A][PNOR::TOC].flashAddr, iv_TOC[PNOR::SIDE_A][PNOR::TOC].virtAddr );
+ TRACFCOMP(g_trac_pnor, "EXT: size=0x%.8X flash=0x%.8X virt=0x%.16X", iv_TOC[PNOR::SIDE_A][PNOR::HB_EXT_CODE].size, iv_TOC[PNOR::SIDE_A][PNOR::HB_EXT_CODE].flashAddr, iv_TOC[PNOR::SIDE_A][PNOR::HB_EXT_CODE].virtAddr );
+ TRACFCOMP(g_trac_pnor, "DATA: size=0x%.8X flash=0x%.8X virt=0x%.16X", iv_TOC[PNOR::SIDE_A][PNOR::HB_DATA].size, iv_TOC[PNOR::SIDE_A][PNOR::HB_DATA].flashAddr, iv_TOC[PNOR::SIDE_A][PNOR::HB_DATA].virtAddr );
+ TRACFCOMP(g_trac_pnor, "MVPD: size=0x%.8X flash=0x%.8X virt=0x%.16X", iv_TOC[PNOR::SIDE_A][PNOR::MODULE_VPD].size, iv_TOC[PNOR::SIDE_A][PNOR::MODULE_VPD].flashAddr, iv_TOC[PNOR::SIDE_A][PNOR::MODULE_VPD].virtAddr );
+ TRACFCOMP(g_trac_pnor, "DJVPD: size=0x%.8X flash=0x%.8X virt=0x%.16X", iv_TOC[PNOR::SIDE_A][PNOR::DIMM_JEDEC_VPD].size, iv_TOC[PNOR::SIDE_A][PNOR::DIMM_JEDEC_VPD].flashAddr, iv_TOC[PNOR::SIDE_A][PNOR::DIMM_JEDEC_VPD].virtAddr );
+
+ }while(0);
+
+ if(tocBuffer != NULL)
+ {
+ TRACUCOMP(g_trac_pnor, "Deleting tocBuffer");
+ delete tocBuffer;
+ }
TRACUCOMP(g_trac_pnor, "< PnorRP::readTOC" );
return l_errhdl;
@@ -656,7 +775,7 @@ errlHndl_t PnorRP::computeDeviceAddr( void* i_vaddr,
// pull out the information we need to return from our global copy
o_chip = iv_TOC[side][id].chip;
- o_ecc = iv_TOC[side][id].eccProtected;
+ o_ecc = (bool)(iv_TOC[side][id].miscFlags & MISC_ECC_PROTECT);
o_offset = l_vaddr - iv_TOC[side][id].virtAddr; //offset into pnor
o_offset += iv_TOC[side][id].flashAddr;
@@ -673,7 +792,7 @@ void PnorRP::applyECC( void* i_orig,
{
TRACFCOMP(g_trac_pnor, "> PnorRP::applyECC" );
- //@todo - fill this in (Story 3548)
+ //@todo - fill this in (Story 34763)
memcpy( o_ecc, i_orig, PAGESIZE );
TRACFCOMP(g_trac_pnor, "< PnorRP::applyECC" );
@@ -687,7 +806,7 @@ errlHndl_t PnorRP::stripECC( void* i_orig,
{
TRACFCOMP(g_trac_pnor, "> PnorRP::stripECC" );
- //@todo - fill this in (Story 3548)
+ //@todo - fill this in (Story 34763)
memcpy( o_data, i_orig, PAGESIZE );
TRACFCOMP(g_trac_pnor, "< PnorRP::stripECC" );
@@ -713,24 +832,46 @@ errlHndl_t PnorRP::computeSection( uint64_t i_vaddr,
o_id = PNOR::INVALID_SECTION;
- // first figure out which side it is on (slight performance boost)
- if( (i_vaddr >= SIDEA_VADDR)
- && (i_vaddr < (SIDEA_VADDR + SIDE_SIZE)) )
- {
- o_side = PNOR::SIDE_A;
- }
- else if( (i_vaddr >= SIDEB_VADDR)
- && (i_vaddr < (SIDEB_VADDR + SIDE_SIZE)) )
- {
- o_side = PNOR::SIDE_B;
- }
- else if( (i_vaddr >= SIDELESS_VADDR)
- && (i_vaddr < (SIDELESS_VADDR + SIDE_SIZE)) )
- {
- o_side = PNOR::SIDELESS;
- }
- else
- {
+ do {
+ // first figure out which side it is on (slight performance boost)
+ if( (i_vaddr >= SIDEA_VADDR)
+ && (i_vaddr < (SIDEA_VADDR + SIDE_SIZE)) )
+ {
+ o_side = PNOR::SIDE_A;
+ }
+ else if( (i_vaddr >= SIDEB_VADDR)
+ && (i_vaddr < (SIDEB_VADDR + SIDE_SIZE)) )
+ {
+ o_side = PNOR::SIDE_B;
+ }
+ else if( (i_vaddr >= SIDELESS_VADDR)
+ && (i_vaddr < (SIDELESS_VADDR + SIDE_SIZE)) )
+ {
+ o_side = iv_curSide;
+ }
+ else
+ {
+ //break to send down error path
+ break;
+ }
+
+ // loop through all sections to find a matching id
+ for( PNOR::SectionId id = PNOR::FIRST_SECTION;
+ id < PNOR::NUM_SECTIONS;
+ id = (PNOR::SectionId) (id + 1) )
+ {
+ if( (i_vaddr >= iv_TOC[o_side][id].virtAddr)
+ && (i_vaddr < (iv_TOC[o_side][id].virtAddr + iv_TOC[o_side][id].size)) )
+ {
+ o_id = iv_TOC[o_side][id].id;
+ break;
+ }
+ }
+
+ }while(0);
+
+ if(o_id == PNOR::INVALID_SECTION)
+ {
TRACFCOMP( g_trac_pnor, "PnorRP::computeSection> Invalid virtual address : i_vaddr=%X", i_vaddr );
/*@
* @errortype
@@ -748,18 +889,6 @@ errlHndl_t PnorRP::computeSection( uint64_t i_vaddr,
return errhdl;
}
- // loop through all sections to find a matching id
- for( PNOR::SectionId id = PNOR::FIRST_SECTION;
- id < PNOR::NUM_SECTIONS;
- id = (PNOR::SectionId) (id + 1) )
- {
- if( (i_vaddr >= iv_TOC[o_side][id].virtAddr)
- && (i_vaddr < (iv_TOC[o_side][id].virtAddr + iv_TOC[o_side][id].size)) )
- {
- o_id = iv_TOC[o_side][id].id;
- break;
- }
- }
return errhdl;
}
diff --git a/src/usr/pnor/pnorrp.H b/src/usr/pnor/pnorrp.H
index 07e020034..61f230916 100644
--- a/src/usr/pnor/pnorrp.H
+++ b/src/usr/pnor/pnorrp.H
@@ -1,25 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/pnor/pnorrp.H $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/pnor/pnorrp.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2011-2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
#ifndef __PNOR_PNORRP_H
#define __PNOR_PNORRP_H
@@ -29,6 +30,7 @@
#include <builtins.h>
#include <errl/errlentry.H>
#include <vmmconst.h>
+#include "ffs.h" //Common header file with BuildingBlock.
/**
* PNOR Resource Provider
@@ -77,50 +79,61 @@ class PnorRP
{
BASE_VADDR = VMM_VADDR_PNOR_RP, /**< 2GB = 0x80000000*/
- NUM_SIDES = 3, /**< A, B, Sideless */
+ NUM_SIDES = 2, /**< A, B */
SIDE_SIZE = 32*MEGABYTE, /**< Allocate 32 MB (0x2000000) of VA per side */
+ NUM_VADDR_BLOCKS = NUM_SIDES+1, /**< Number of VADDR blocks. */
SIDEA_VADDR = BASE_VADDR, /**< Base address of Side A */
SIDEB_VADDR = SIDEA_VADDR + SIDE_SIZE, /**< Base address of Side B */
- SIDELESS_VADDR = SIDEB_VADDR + SIDE_SIZE, /**< Base address of Sideless data */
+ SIDELESS_VADDR = SIDEB_VADDR + SIDE_SIZE, /**< Sideless data Base Addr */
- TOTAL_SIZE = SIDE_SIZE*NUM_SIDES, /**< Size of PNOR VA region */
+ TOTAL_SIZE = SIDE_SIZE*NUM_VADDR_BLOCKS, /**< Size of PNOR VA region */
LAST_VADDR = BASE_VADDR + TOTAL_SIZE, /**< End of our VA range */
/** Real number of bytes required to read 1 logical page */
PAGESIZE_PLUS_ECC = PAGESIZE * (9/8), // 8 bytes of data + 1 byte of ECC
+
+ SUPPORTED_FFS_VERSION = 0x1, /**< Supported FFS Version */
+ FFS_TABLE_BASE_ADDR = 0x0, /**< Currently only have FFS table */
};
/**
- * Table of Contents entry
- * This matches the PNOR binary layout @todo this will change
+ * FFS Misc information flags
*/
- struct TOCEntry_t
+ enum
{
- char name[8]; /**< Null terminated ascii string */
- uint64_t offset; /**< Offset to region from zero (relative to chip) */
- uint64_t size; /**< Size of region in bytes (with or without ECC?) */
- uint64_t size_act; /**< Actual size of content in bytes */
- uint64_t misc; /**< Miscellaneious Info */
- char fuse_tbd[89]; /**< Free Space */
- //@todo - need a chip select here I think?
+ MISC_ECC_PROTECT = 0x80, /**< ECC protected */
+ MISC_SIDELESS = 0x40, /**< Preserved across code updates (sideless) =1 */
+ MISC_CRC_PROTECTED = 0x20, /**< CRC protected */
+ MISC_UNUSED = 0x1F, /**< Unused MISC Flags */
+ };
+
+ /**
+ * FFS entry
+ * This matches the PNOR binary layout
+ */
+ struct ffs_hb_user_t{
+ uint32_t sizeAct; /**< Actual Size of the image */
+ uint8_t chip; /**< Chip Select (0,1) */
+ uint8_t compressType; /**< Compression Indication/alg (0=not compressed) */
+ uint8_t miscFlags; /**< Misc Partition related Flags */
+ uint8_t freeMisc[5]; /**< Unused Miscellaneious Info */
+ uint32_t freeUser[13]; /**< Unused User Data */
} PACKED;
+
/**
* Internal information to deal with the sections of PNOR
*/
struct SectionData_t {
PNOR::SectionId id; /**< Identifier for this section */
PNOR::SideSelect side; /** Side Select */
-
uint64_t virtAddr; /**< Virtual address for the start of the section */
-
uint32_t flashAddr; /**< Address in flash */
-
uint32_t size; /**< Actual size of content in bytes (not including ECC) */
uint8_t chip; /**< Chip Select */
- uint8_t eccProtected; /**< Section is ECC protected */
+ uint8_t miscFlags; /**<chip select, ECC Protect, sideless flags */
} PACKED;
/**
@@ -129,6 +142,11 @@ class PnorRP
SectionData_t iv_TOC[NUM_SIDES][PNOR::NUM_SECTIONS+1];
/**
+ * Currently selected PNOR Side
+ */
+ PNOR::SideSelect iv_curSide;
+
+ /**
* Pointer to the message queue where we receive messages
*/
msg_q_t iv_msgQ;
diff --git a/src/usr/pnor/test/pnorrptest.H b/src/usr/pnor/test/pnorrptest.H
index 06fce7db1..f1791f8ba 100644
--- a/src/usr/pnor/test/pnorrptest.H
+++ b/src/usr/pnor/test/pnorrptest.H
@@ -1,25 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/pnor/test/pnorrptest.H $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/pnor/test/pnorrptest.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2011-2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
#ifndef __PNORRPTEST_H
#define __PNORRPTEST_H
@@ -47,81 +48,51 @@ class PnorRpTest : public CxxTest::TestSuite
/**
* @brief PNOR RP test - Section Info
- * Look for mismatches in section information from expected
+ * Check that the section info at least appears somewhat valid.
*/
- void test_getSectionInfo(void)
+ void test_sectionInfo(void)
{
- TRACFCOMP(g_trac_pnor, "PnorRpTest::test_getSectionInfo> Start" );
+ TRACFCOMP(g_trac_pnor, "PnorRpTest::test_sectionInfo> Start" );
uint64_t fails = 0;
uint64_t total = 0;
PNOR::SectionInfo_t info;
errlHndl_t errhdl = NULL;
- struct ExpVals_t {
- uint64_t size;
- uint64_t vaddr;
- PNOR::SideSelect side;
- };
- const ExpVals_t exp_data[] = {
- /* TOC */ { 0x1000, 0x80000000, PNOR::SIDE_A },
- /* HB_EXT_CODE */ { 0x200000, 0x80001000, PNOR::SIDE_A },
- /* HB_DATA */ { 0x80000, 0x80201000, PNOR::SIDE_A },
- /* DIMM_JEDEC_VPD */ { 0x40000, 0x84301000, PNOR::SIDELESS },
- /* MODULE_VPD */ { 0x80000, 0x84281000, PNOR::SIDELESS },
- /* GLOBAL_DATA { 0, 0 },*/
- /* SBE_IPL { 0, 0 },*/
- /* HB_ERRLOGS { 0, 0 },*/
- /* HB_BASE_CODE { 0, 0 },*/
- /* HB_RUNTIME { 0, 0 },*/
- /* PAYLOAD { 0, 0 },*/
- /* PFW_LITE_CODE { 0, 0 },*/
- /* OCC_CODE { 0, 0 },*/
- /* KVM_PART_INFO { 0, 0 },*/
- /* CODE_UPDATE { 0, 0 },*/
- };
-
for( PNOR::SectionId id = PNOR::FIRST_SECTION;
id < PNOR::NUM_SECTIONS;
id = (PNOR::SectionId) (id + 1) )
{
total++;
- errhdl = PNOR::getSectionInfo( id, exp_data[id].side, info );
+ errhdl = PNOR::getSectionInfo( id, PNOR::CURRENT_SIDE, info );
if( errhdl )
{
- if( exp_data[id].size != 0 )
- {
- TRACFCOMP(g_trac_pnor, "PnorRpTest::test_getSectionInfo> ERROR : getSectionInfo returned error for %d : RC=%X", id, errhdl->reasonCode() );
- TS_FAIL( "PnorRpTest::test_getSectionInfo> ERROR : Unexpected error log" );
- fails++;
- errlCommit(errhdl,PNOR_COMP_ID);
- }
- else
- {
- delete errhdl;
- }
+ TRACFCOMP(g_trac_pnor, "PnorRpTest::test_sectionInfo> ERROR : getSectionInfo returned error for %d : RC=%X", id, errhdl->reasonCode() );
+ TS_FAIL( "PnorRpTest::test_getSectionInfo> ERROR : Unexpected error log" );
+ fails++;
+ errlCommit(errhdl,PNOR_COMP_ID);
}
- // Look for expected size
+ // Look for non-zero size
total++;
- if( info.size != exp_data[id].size )
+ if( info.size == 0 )
{
- TRACFCOMP(g_trac_pnor, "PnorRpTest::test_getSectionInfo> ERROR : Mismatched size for section %d : id=%d, exp=%d, actual=%d", id, info.id, exp_data[id].size, info.size );
- TS_FAIL( "PnorRpTest::test_getSectionInfo> ERROR : Mismatched Size" );
+ TRACFCOMP(g_trac_pnor, "PnorRpTest::test_sectionInfo> ERROR : zero size for section %d : id=%d, actual=%d", id, info.id, info.size );
+ TS_FAIL( "PnorRpTest::test_getSectionInfo> ERROR : Zero Size" );
fails++;
}
- // Look for expected vaddr
+ // Look for vaddr in appropriate section of virtual memory
total++;
- if( info.vaddr != exp_data[id].vaddr )
+ if( info.vaddr < PnorRP::BASE_VADDR )
{
- TRACFCOMP(g_trac_pnor, "PnorRpTest::test_getSectionInfo> ERROR : Mismatched vaddr for section %d : id=%d, exp=%d, actual=%d", id, info.id, exp_data[id].vaddr, info.vaddr );
- TS_FAIL( "PnorRpTest::test_getSectionInfo> ERROR : Mismatched vaddr" );
+ TRACFCOMP(g_trac_pnor, "PnorRpTest::test_sectionInfo> ERROR : Virtual Addr section %d Not in appropriate range: id=%d, actual=%d", id, info.id, info.vaddr );
+ TS_FAIL( "PnorRpTest::test_getSectionInfo> ERROR : Invalid vaddr" );
fails++;
}
}
- TRACFCOMP(g_trac_pnor, "PnorRpTest::test_getSectionInfo> %d/%d fails", fails, total );
+ TRACFCOMP(g_trac_pnor, "PnorRpTest::test_sectionInfo> %d/%d fails", fails, total );
};
/**
diff --git a/src/usr/spd/spd.C b/src/usr/spd/spd.C
index ff75cc83c..bd3371e5c 100755
--- a/src/usr/spd/spd.C
+++ b/src/usr/spd/spd.C
@@ -323,7 +323,7 @@ errlHndl_t spdFetchData ( uint64_t i_byteAddr,
info.segmentSize = DIMM_SPD_SECTION_SIZE;
info.maxSegments = DIMM_SPD_MAX_SECTIONS;
info.pnorSection = PNOR::DIMM_JEDEC_VPD;
- info.pnorSide = PNOR::SIDELESS;
+ info.pnorSide = PNOR::CURRENT_SIDE;
err = readPNOR( i_byteAddr,
i_numBytes,
o_data,
@@ -379,7 +379,7 @@ errlHndl_t spdWriteData ( uint64_t i_offset,
info.segmentSize = DIMM_SPD_SECTION_SIZE;
info.maxSegments = DIMM_SPD_MAX_SECTIONS;
info.pnorSection = PNOR::DIMM_JEDEC_VPD;
- info.pnorSide = PNOR::SIDELESS;
+ info.pnorSide = PNOR::CURRENT_SIDE;
err = writePNOR( i_offset,
i_numBytes,
i_data,
diff --git a/src/usr/targeting/attrrp.C b/src/usr/targeting/attrrp.C
index c250ec4d5..aae2f3915 100644
--- a/src/usr/targeting/attrrp.C
+++ b/src/usr/targeting/attrrp.C
@@ -1,26 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/targeting/attrrp.C $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
-
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/targeting/attrrp.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2011-2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
/**
* @file targeting/attrrp.C
*
@@ -290,7 +290,7 @@ namespace TARGETING
// Locate attribute section in PNOR.
PNOR::SectionInfo_t l_pnorSectionInfo;
l_errl = PNOR::getSectionInfo(PNOR::HB_DATA,
- PNOR::SIDE_A,
+ PNOR::CURRENT_SIDE,
l_pnorSectionInfo);
if (l_errl) break;
diff --git a/src/usr/vfs/vfsrp.C b/src/usr/vfs/vfsrp.C
index 42a63ea86..b7a897f96 100644
--- a/src/usr/vfs/vfsrp.C
+++ b/src/usr/vfs/vfsrp.C
@@ -1,25 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/vfs/vfsrp.C $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/vfs/vfsrp.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2011-2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
/**
* @file vfsrp.C
* @brief Virtual File system Extended image support
@@ -116,8 +117,8 @@ errlHndl_t VfsRp::_init()
// Discover PNOR virtual address of extended image
PNOR::SectionInfo_t l_pnor_info;
- // How will SIDE eventually be determined? TODO
- err = PNOR::getSectionInfo(PNOR::HB_EXT_CODE, PNOR::SIDE_A, l_pnor_info);
+ // Always use CURRENT_SIDE. PNOR RP will know if that is A or B.
+ err = PNOR::getSectionInfo(PNOR::HB_EXT_CODE, PNOR::CURRENT_SIDE, l_pnor_info);
if(!err)
{
iv_pnor_vaddr = l_pnor_info.vaddr;
OpenPOWER on IntegriCloud