From 6a8e78667bd096e41a909273e4359bc62e444992 Mon Sep 17 00:00:00 2001 From: Missy Connell Date: Mon, 3 Dec 2012 12:13:25 -0600 Subject: Dump Collect code RTC:46996 Change-Id: I18863c91dcde353df6201c3c13e101626f24206b Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/3131 Tested-by: Jenkins Server Reviewed-by: Daniel M. Crowell Reviewed-by: A. Patrick Williams III --- src/include/usr/dump/dumpreasoncodes.H | 53 + src/include/usr/hbotcompid.H | 11 +- src/include/usr/runtime/runtime_reasoncodes.H | 4 +- src/include/usr/vmmconst.h | 37 + src/makefile | 6 +- src/usr/dump/dumpCollect.C | 681 ++++++++++++ src/usr/dump/dumpCollect.H | 109 ++ src/usr/dump/makefile | 30 + src/usr/dump/test/dumptest.H | 1198 ++++++++++++++++++++++ src/usr/dump/test/makefile | 28 + src/usr/initservice/extinitsvc/extinitsvctasks.H | 15 + src/usr/makefile | 2 +- src/usr/runtime/hdatservice.C | 48 +- src/usr/runtime/test/hdatservicetest.H | 151 +-- 14 files changed, 2291 insertions(+), 82 deletions(-) create mode 100644 src/include/usr/dump/dumpreasoncodes.H create mode 100644 src/usr/dump/dumpCollect.C create mode 100644 src/usr/dump/dumpCollect.H create mode 100644 src/usr/dump/makefile create mode 100644 src/usr/dump/test/dumptest.H create mode 100644 src/usr/dump/test/makefile diff --git a/src/include/usr/dump/dumpreasoncodes.H b/src/include/usr/dump/dumpreasoncodes.H new file mode 100644 index 000000000..9f1da4353 --- /dev/null +++ b/src/include/usr/dump/dumpreasoncodes.H @@ -0,0 +1,53 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/dump/dumpreasoncodes.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ +/* */ +/* 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 otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __DUMP_REASONCODES_H +#define __DUMP_REASONCODES_H + +#include + +namespace DUMP +{ + enum dumpModuleId + { + DUMP_COLLECT_INVALID = 0x00, + DUMP_COLLECT = 0x01, + }; + + enum dumpReasonCode + { + DUMP_INVALID_ADDR = DUMP_COMP_ID | 0x01, + DUMP_NO_HDAT_ADDR = DUMP_COMP_ID | 0x02, + DUMP_CANNOT_MAP = DUMP_COMP_ID | 0x03, + DUMP_CANNOT_UNMAP_SRC = DUMP_COMP_ID | 0x04, + DUMP_CANNOT_UNMAP_DEST = DUMP_COMP_ID | 0x05, + DUMP_CANNOT_UNMAP_RESULTS = DUMP_COMP_ID | 0x06, + DUMP_MDRT_INSUFFICIENT_SPACE = DUMP_COMP_ID | 0x07, + DUMP_MDST_INSUFFICIENT_SPACE = DUMP_COMP_ID | 0x08, + DUMP_MDDT_INSUFFICIENT_SPACE = DUMP_COMP_ID | 0x09, + DUMP_MDDT_INSUFFICIENT_ENTRIES = DUMP_COMP_ID | 0x0A, + DUMP_MDST_INVALID_TABLE_SIZE = DUMP_COMP_ID | 0x0B, + DUMP_MDDT_INVALID_TABLE_SIZE = DUMP_COMP_ID | 0x0C, + }; +}; + +#endif diff --git a/src/include/usr/hbotcompid.H b/src/include/usr/hbotcompid.H index 52ba02edf..662bb7982 100644 --- a/src/include/usr/hbotcompid.H +++ b/src/include/usr/hbotcompid.H @@ -180,7 +180,13 @@ const compId_t MBOX_COMP_ID = 0x1100; const char MBOX_COMP_NAME[] = "mbox"; //@} -// 0x1200 - open to reclaim +/** @name DUMP + * DUMP component + */ +//@{ +const compId_t DUMP_COMP_ID = 0x1200; +const char DUMP_COMP_NAME[] = "dump"; +//@} // 0x1300 - open to reclaim @@ -253,7 +259,7 @@ const char KERNEL_COMP_NAME[] = "kernel"; //@{ const compId_t IBSCOM_COMP_ID = 0x1C00; const char IBSCOM_COMP_NAME[] = "ibscom"; -//@} + /** @name VPD * Common VPD device driver component @@ -263,6 +269,7 @@ const compId_t VPD_COMP_ID = 0x1D00; const char VPD_COMP_NAME[] = "vpd"; //@} + /** @name HSVC * Host Services component * For the code running under PHYP diff --git a/src/include/usr/runtime/runtime_reasoncodes.H b/src/include/usr/runtime/runtime_reasoncodes.H index 0986d585b..4a8f8c0ae 100644 --- a/src/include/usr/runtime/runtime_reasoncodes.H +++ b/src/include/usr/runtime/runtime_reasoncodes.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ @@ -54,6 +54,8 @@ namespace RUNTIME RC_BAD_NACA = RUNTIME_COMP_ID | 0x0A, RC_INVALID_ADDRESS = RUNTIME_COMP_ID | 0x0B, RC_INVALID_SECTION = RUNTIME_COMP_ID | 0x0C, + RC_CANNOT_MAP_MEMORY3 = RUNTIME_COMP_ID | 0x0D, + }; }; diff --git a/src/include/usr/vmmconst.h b/src/include/usr/vmmconst.h index b6e7f9dd8..d3b29415e 100644 --- a/src/include/usr/vmmconst.h +++ b/src/include/usr/vmmconst.h @@ -129,5 +129,42 @@ enum BlockPriority #define HSVC_TEST_MEMORY_ADDR (VMM_MEMORY_SIZE + 32*MEGABYTE) #define HSVC_TEST_MEMORY_SIZE (2*MEGABYTE) +/* Chunk of physical memory used for Dump Source Table */ +//#define DUMP_TEST_SRC_MEM_ADDR (VMM_MEMORY_SIZE + 64*MEGABYTE) +#define DUMP_TEST_MEMORY_ADDR (HSVC_TEST_MEMORY_ADDR + HSVC_TEST_MEMORY_SIZE) +#define DUMP_TEST_MEMORY_SIZE (4*MEGABYTE) + + +// The rest of these #defines will be moved to dumpif.H. + +#define DUMP_TEST_SRC_MEM_ADDR (HSVC_TEST_MEMORY_ADDR + HSVC_TEST_MEMORY_SIZE) +#define DUMP_TEST_SRC_MEM_SIZE (MEGABYTE) + +/* Chunk of physical memory used for Dump Destination Table */ +#define DUMP_TEST_DST_MEM_ADDR (DUMP_TEST_SRC_MEM_ADDR + DUMP_TEST_SRC_MEM_SIZE) +#define DUMP_TEST_DST_MEM_SIZE (MEGABYTE) + +/* Chunk of physical memory used for Dump Results Table */ +#define DUMP_TEST_RESULTS_MEM_ADDR (DUMP_TEST_DST_MEM_ADDR + DUMP_TEST_DST_MEM_SIZE) +#define DUMP_TEST_RESULTS_MEM_SIZE (MEGABYTE) + +// Data location where the src, destination tables point to. +#define DUMP_TEST_SRC_DATA_AREA DUMP_TEST_RESULTS_MEM_ADDR + DUMP_TEST_RESULTS_MEM_SIZE +#define DUMP_TEST_DST_DATA_AREA DUMP_TEST_SRC_DATA_AREA + DUMP_TEST_DATA_SIZE +#define DUMP_TEST_DATA_SIZE MEGABYTE + +// default enums to point out the start and end of the DUMP Tables in memory +#define DUMP_TEST_TABLE_START DUMP_TEST_SRC_MEM_ADDR +#define DUMP_TEST_TABLE_SIZE DUMP_TEST_SRC_MEM_SIZE + DUMP_TEST_DST_MEM_SIZE + DUMP_TEST_RESULTS_MEM_SIZE +#define DUMP_TEST_TABLE_END DUMP_TEST_TABLE_START + DUMP_TEST_TABLE_SIZE + +// In addition to the dump table locations we have scratch data area that is used +// to put the SRC data that the MDST will point to. + +// This is the size of all the Data used for Dump testing +#define DUMP_TEST_ALL_SIZE = DUMP_TEST_TABLE_SIZE + (2*MEGABYTE) +// This is the ending address of test Data area +#define DUMP_TEST_ALL_END = DUMP_TEST_TABLE_START + DUMP_TEST_ALL_SIZE + #endif /* _VMMCONST_H */ diff --git a/src/makefile b/src/makefile index 40a428d03..014988e3d 100644 --- a/src/makefile +++ b/src/makefile @@ -46,7 +46,7 @@ DIRECT_BOOT_OBJECTS = start.o kernel.o taskmgr.o cpumgr.o syscall.o \ shutdown.o forceattn_p8.o terminate.o BASE_MODULES = trace errl devicefw scom xscom initservice \ - pnor vfs + pnor vfs EXTENDED_MODULES = targeting ecmddatabuffer fapi hwp plat \ extinitsvc istepdisp hwas fsi fsiscom i2c intr scan \ @@ -57,14 +57,14 @@ EXTENDED_MODULES = targeting ecmddatabuffer fapi hwp plat \ core_activate dram_initialization edi_ei_initialization \ establish_system_smp \ nest_chiplets start_payload thread_activate slave_sbe \ - attn runtime ibscom + attn runtime ibscom dump TESTCASE_MODULES = cxxtest testtrace testerrl testdevicefw testsyslib \ testscom testxscom testtargeting testinitservice testkernel \ testhwpf testecmddatabuffer initsvctesttask testcxxtest \ testpnor testi2c testfsi testvfs testhwas testintr testvpd \ testpore testutil testmbox testmdia testprdf testattn \ - testscan testruntime testibscom + testscan testruntime testibscom testdump RELOCATABLE_IMAGE_LDFLAGS = -pie --export-dynamic diff --git a/src/usr/dump/dumpCollect.C b/src/usr/dump/dumpCollect.C new file mode 100644 index 000000000..1a23a9757 --- /dev/null +++ b/src/usr/dump/dumpCollect.C @@ -0,0 +1,681 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/dump/dumpCollect.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ +/* */ +/* 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 otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/*****************************************************************************/ +// I n c l u d e s +/*****************************************************************************/ + +#include +#include "dumpCollect.H" +#include +#include +#include +#include +#include +#include +#include + + +// Trace definition +trace_desc_t* g_trac_dump = NULL; +TRAC_INIT(&g_trac_dump, "DUMP", 4*KILOBYTE); + + +namespace DUMP +{ + + + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + errlHndl_t doDumpCollect(void) + { + TRACFCOMP(g_trac_dump, "doDumpCollect - start "); + + errlHndl_t l_err = NULL; + + // Table Sizes + uint64_t srcTableSize = 0; + uint64_t destTableSize = 0; + uint64_t resultsTableSize = 0; + + // Dump table struct pointers + dumpEntry *srcTableEntry = NULL; + dumpEntry *destTableEntry = NULL; + resultsEntry *resultsTableEntry = NULL; + + do + { + // Get the Data pointers to the locations we need from HDAT + // MS_DUMP_SRC_TBL, < MDST: Memory Dump Source Table + // MS_DUMP_DST_TBL, < MDDT: Memory Dump Destination Table + // MS_DUMP_RESULTS_TBL, 3GB. + if (bytesLeftInSrc + srcOffset > THIRTYTWO_GB) + { + invalidSrcSize = true; + break; + } + else if ((bytesLeftInDest + destOffset > THIRTYTWO_GB)) + { + invalidDestSize = true; + break; + } + + vaMapSrcTableAddr = + (static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(curSrcTableAddr)), + THIRTYTWO_GB))); + + vaSrcTableAddr = vaMapSrcTableAddr; + + vaMapDestTableAddr = + (static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(curDestTableAddr)), + THIRTYTWO_GB))); + + vaDestTableAddr = vaMapDestTableAddr; + + // add the offset to the src and destination VAs, + vaSrcTableAddr += (srcOffset/(sizeof (uint64_t))); + + vaDestTableAddr += (destOffset/(sizeof (uint64_t))); + + // Current Source physical and Va address + TRACFCOMP(g_trac_dump, "copySrcToDest SrcTableIndex = %d, srcTableAddr = %.16X, VA = %.16X", curSourceIndex, curSrcTableAddr, vaSrcTableAddr); + + // Current Destination physical and Va address + TRACFCOMP(g_trac_dump, "HBDumpCopySrcToDest DestTableIndex = %d, DestTableAddr = %.16X, VA = %.16X", curDestIndex, curDestTableAddr, vaDestTableAddr); + + + while(1) + { + // If we have copied all the bytes in the src entry + if (bytesLeftInSrc == 0) + { + // unmap the previous src entry + rc = mmio_dev_unmap(reinterpret_cast(vaMapSrcTableAddr)); + + if (rc != 0) + { + /*@ + * @errortype + * @moduleid DUMP::DUMP_COLLECT + * @reasoncode DUMP::DUMP_CANNOT_UNMAP_SRC + * @userdata1 VA address of the MDST to unmap + * @userdata2 rc value from unmap + * @devdesc Cannot unmap the source table section + */ + l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + DUMP_COLLECT, + DUMP_CANNOT_UNMAP_SRC, + (uint64_t)vaMapSrcTableAddr, + rc); + + // commit the error and continue. Leave the devices unmapped for now. + errlCommit(l_err,DUMP_COMP_ID); + + l_err = NULL; + + } + + // increment to the next src entry + curSourceIndex++; + + // if we have reach all entries + if (curSourceIndex >= maxSrcEntries) + { + TRACFCOMP(g_trac_dump, "HBDumpCopySrcToDest - through all src entries"); + break; + } + + curSrcTableAddr = srcTableEntry[curSourceIndex].dataAddr; + bytesLeftInSrc = srcTableEntry[curSourceIndex].dataSize; + + // If the current Src table Address is 0 we are done + if (curSrcTableAddr == 0) + { + break; + } + + srcOffset = curSrcTableAddr - ALIGN_PAGE_DOWN(curSrcTableAddr); + + // If the data size is less then 32GB after page alignment + if (bytesLeftInSrc + srcOffset > THIRTYTWO_GB) + { + invalidSrcSize = true; + break; + } + + // map the MDST entry to a device such that we can read and write from that memory + // address + vaMapSrcTableAddr = + (static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(curSrcTableAddr)), + THIRTYTWO_GB))); + + vaSrcTableAddr = vaMapSrcTableAddr; + + vaSrcTableAddr += (srcOffset/(sizeof (uint64_t))); + + // Current Source physical and Va address + TRACFCOMP(g_trac_dump, "copySrcToDest SrcTableIndex = %d, srcTableAddr = %.16X, VA = %.16X", curSourceIndex, curSrcTableAddr, vaSrcTableAddr); + + } + + // If there is no more space in the destination area + if (bytesLeftInDest == 0) + { + // unmap the previous dest entry + rc = mmio_dev_unmap(reinterpret_cast(vaMapDestTableAddr)); + + if (rc != 0) + { + /*@ + * @errortype + * @moduleid DUMP::DUMP_COLLECT + * @reasoncode DUMP::DUMP_CANNOT_UNMAP_DEST + * @userdata1 VA address of the MDDT to unmap + * @userdata2 rc value from unmap + * @devdesc Cannot unmap the source table section + */ + l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + DUMP_COLLECT, + DUMP_CANNOT_UNMAP_DEST, + (uint64_t)vaMapDestTableAddr, + rc); + + // commit the error and continue. Leave the devices unmapped? + errlCommit(l_err,DUMP_COMP_ID); + + l_err = NULL; + } + + // increment to the next dest entry + curDestIndex++; + + // if made it through all dest entries. + if (curDestIndex >= maxDestEntries) + { + // need to check here to see if we still have SRC + // entries not copied. + if (bytesLeftInSrc != 0) + { + // Write an error because we have more src entries + // then destination space available. + TRACFCOMP(g_trac_dump, "HBDumpCopySrcToDest: not enough Destination table entries"); + + /*@ + * @errortype + * @moduleid DUMP::DUMP_COLLECT + * @reasoncode DUMP::DUMP_MDDT_INSUFFICIENT_ENTRIES + * @userdata1 Source Entires bytes left to copy + * @userdata2 Index into the MDST table + * @devdesc MDDT table is not big enough to hold all src entries + */ + l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + DUMP_COLLECT, + DUMP_MDDT_INSUFFICIENT_ENTRIES, + bytesLeftInSrc, + curSourceIndex); + + // do not commit this errorlog error as this is a + // real problem. + + // TODO: RTC: 64399 + // Need to add the src entries and sizes? that did + // not get copied to the destination. This error + // condition is such that the table entries are exceeded. + } + + break; + } + + curDestTableAddr = destTableEntry[curDestIndex].dataAddr; + bytesLeftInDest = destTableEntry[curDestIndex].dataSize; + + // If the current dest addr or the size to copy are zero. + if ((curDestTableAddr == 0) || (bytesLeftInDest == 0)) + { + + // If there are still SRC entries to copy with no + // destination send an error back. + if (bytesLeftInSrc != 0) + { + // Write an error because we have more src entries + // then destination space available. + TRACFCOMP(g_trac_dump, "HBDumpCopySrcToDest: not enough Destination table space"); + + /*@ + * @errortype + * @moduleid DUMP::DUMP_COLLECT + * @reasoncode DUMP::DUMP_MDDT_INSUFFICIENT_SPACE + * @userdata1 Source Entires bytes left to copy + * @userdata2 Index into the MDST table + * @devdesc MDDT table is not big enough to hold all src entries + */ + l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + DUMP_COLLECT, + DUMP_MDDT_INSUFFICIENT_SPACE, + bytesLeftInSrc, + curSourceIndex); + + // do not commit this errorlog error as this is a + // real problem. + + // TODO: RTC: 64399 + // Need to add the src entries and sizes? that did + // not get copied to the destination. This + // condition is such that we have a destination + // entry that either has a zero address or zero + // size.. Perhaps put the bad destination entry + // there as well + } + + break; + } + + destOffset = curDestTableAddr - ALIGN_PAGE_DOWN(curDestTableAddr); + + // If the data size is less then 32GB after page alignment + if (bytesLeftInDest + destOffset > THIRTYTWO_GB) + { + invalidDestSize = true; + break; + } + + // map the MDDT to a VA addresss + vaMapDestTableAddr = + (static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(curDestTableAddr)), + THIRTYTWO_GB))); + + vaDestTableAddr = vaMapDestTableAddr; + + vaDestTableAddr += (destOffset/(sizeof(uint64_t))); + + // Current Destination physical and Va address + TRACFCOMP(g_trac_dump, "HBDumpCopySrcToDest DestTableIndex = %d, DestTableAddr = %.16X, VA = %.16X", curDestIndex, curDestTableAddr, vaDestTableAddr); + + } + + + // Determine how much to copy.. + sizeToCopy = std::min(bytesLeftInSrc, bytesLeftInDest); + + // Do the copy of the data from the source to the destination + memcpy( vaDestTableAddr,vaSrcTableAddr, sizeToCopy); + + if (curResultIndex < maxResultEntries) + { + // Update the results table + resultsTableEntry->srcAddr = curSrcTableAddr; + resultsTableEntry->destAddr = curDestTableAddr; + resultsTableEntry->dataSize = sizeToCopy; + resultsTableEntry++; + curResultIndex++; + } + else + { + TRACFCOMP(g_trac_dump, "HBDumpCopySrcToDest: not enough result table space"); + + /*@ + * @errortype + * @moduleid DUMP::DUMP_COLLECT + * @reasoncode DUMP::DUMP_MDRT_INSUFFICIENT_SPACE + * @userdata1 Index into the MDRT + * @userdata2 max entries allowed given space allocated + * @devdesc MDRT table is not big enough to hold all entries + */ + l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + DUMP_COLLECT, + DUMP_MDRT_INSUFFICIENT_SPACE, + curResultIndex, + maxResultEntries); + + // commit the error and continue. + errlCommit(l_err,DUMP_COMP_ID); + + l_err = NULL; + } + + // decrement the amount copied from the source and destination + bytesLeftInSrc -= sizeToCopy; + bytesLeftInDest -= sizeToCopy; + + uint64_t addrOffset = sizeToCopy/(sizeof (uint64_t)); + + // increment the current src and dest addresses in both the + // physical and virtual addresses. + curSrcTableAddr += sizeToCopy; + curDestTableAddr += sizeToCopy; + vaSrcTableAddr += addrOffset; + vaDestTableAddr += addrOffset; + + } // end of while loop + + + if (invalidSrcSize) + { + // Write an error because we have more src entries + // then destination space available. + TRACFCOMP(g_trac_dump, "HBDumpCopySrcToDest: Source TableSize > 32GB"); + + /*@ + * @errortype + * @moduleid DUMP::DUMP_COLLECT + * @reasoncode DUMP::DUMP_MDST_INVALID_TABLE_SIZE + * @userdata1 Size of Source Table Entry + * @userdata2 Size of Page Aligned Source Table Entry + * @devdesc MDST table entry with page aligned is greater than 32GB + */ + l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + DUMP_COLLECT, + DUMP_MDST_INVALID_TABLE_SIZE, + bytesLeftInSrc, + bytesLeftInSrc + srcOffset); + break; + + } + if (invalidDestSize) + { + // Write an error because we have more src entries + // then destination space available. + TRACFCOMP(g_trac_dump, "HBDumpCopySrcToDest: Destination TableSize > 32GB"); + + /*@ + * @errortype + * @moduleid DUMP::DUMP_COLLECT + * @reasoncode DUMP::DUMP_MDDT_INVALID_TABLE_SIZE + * @userdata1 Size of Destination Table Entry + * @userdata2 Size of Page Aligned Destination Table Entry + * @devdesc MDDT table entry with page aligned is greater than 32GB + */ + l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + DUMP_COLLECT, + DUMP_MDDT_INVALID_TABLE_SIZE, + bytesLeftInDest, + bytesLeftInDest + destOffset); + + break; + } + + }while(0);// end of do-while loop + + // Got an errorlog back from get_host_data_sections + TRACFCOMP(g_trac_dump, "HBDumpCopySrcToDest - COMPLETE "); + + return l_err; + } + + + + /////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////// + + errlHndl_t getHostDataPtrs(dumpEntry *srcTableEntry, uint64_t &srcTableSize, + dumpEntry *destTableEntry, uint64_t &destTableSize, + resultsEntry *resultsTableEntry,uint64_t &resultsTableSize) + + { + + errlHndl_t l_err = NULL; + int rc = 0; + bool l_error = false; + uint64_t l_section = 0; + uint64_t l_addr = 0; + uint64_t srcTableAddr = 0; + uint64_t destTableAddr = 0; + uint64_t resultsTableAddr = 0; + + + do + { + + // Get the Src Table address (MDST) + l_err = RUNTIME::get_host_data_section(RUNTIME::MS_DUMP_SRC_TBL, + 0, + srcTableAddr, + srcTableSize); + + + if (l_err) + { + // Got an errorlog back from get_host_data_sections + TRACFCOMP(g_trac_dump, "HBDumpGetHostData get_host_data_sections for MDST failed rc=0x%X", rc); + + break; + } + + // If the address or size is zero - error out + if ((srcTableSize == 0) || (srcTableAddr == 0)) + { + // Invalid size or address + TRACFCOMP(g_trac_dump, "HBDumpGetHostData address or size invalie for MDST: addr =0x%X, size =0x%X," , srcTableAddr, srcTableSize); + + l_section = RUNTIME::MS_DUMP_SRC_TBL; + l_addr = srcTableAddr; + l_error = true; + // got back a bad address + break; + } + + srcTableEntry = reinterpret_cast(srcTableAddr); + + // Get the Destination Table Address (MDDT) + l_err = RUNTIME::get_host_data_section(RUNTIME::MS_DUMP_DST_TBL, + 0, + destTableAddr, + destTableSize); + + + if (l_err) + { + // Got an errorlog back from get_host_data_sections + TRACFCOMP(g_trac_dump, "HBDumpGetHostData get_host_data_sections for MDDT failed rc=0x%X", rc); + + break; + } + + // If the address or size is zero - error out + if ((destTableSize == 0) || (destTableAddr == 0)) + { + // Invalid size or address + TRACFCOMP(g_trac_dump, + "HBDumpGetHostData address or size invalie for MDDT: addr =0x%X, size =0x%X," , + destTableAddr, destTableSize); + + l_section = RUNTIME::MS_DUMP_DST_TBL; + l_addr = destTableAddr; + l_error = true; + + // got back a bad address + break; + } + + destTableEntry = reinterpret_cast(destTableAddr); + + // Get the Results Table Address + l_err = RUNTIME::get_host_data_section(RUNTIME::MS_DUMP_RESULTS_TBL, + 0, + resultsTableAddr, + resultsTableSize); + + + if (l_err) + { + // Got an errorlog back from get_host_data_sections + TRACFCOMP(g_trac_dump, "HBDumpGetHostData get_host_data_sections for MDDT failed rc=0x%X", rc); + + break; + } + + // If the address or size is zero - error out + if ((resultsTableSize == 0) || (resultsTableAddr == 0)) + { + // Invalid size or address + TRACFCOMP(g_trac_dump, + "HBDumpGetHostData address or size invalid for MDRT: addr =0x%X, size =0x%X," , + resultsTableAddr, resultsTableSize); + + l_section = RUNTIME::MS_DUMP_RESULTS_TBL; + l_addr = resultsTableAddr; + l_error = true; + // got back a bad address + break; + } + + // Each results table entry has the Source,Destination and Size for + // each copy that is done from source to destination + resultsTableEntry = reinterpret_cast(resultsTableAddr); + + TRACFCOMP(g_trac_dump, + "gethostDataPtrs SrcTableAddr = %.16x, DestTableAddr = %.16X, resultTableAddr = %.16X", + srcTableAddr, destTableAddr, resultsTableAddr); + + }while(0); + + if (l_error) + { + + /*@ + * @errortype + * @moduleid DUMP::DUMP_COLLECT + * @reasoncode DUMP::DUMP_NO_HDAT_ADDR + * @userdata1 Address returned + * @userdata2 Table type Requested + * @devdesc Invalid address and size returned from HDAT + */ + l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + DUMP_COLLECT, + DUMP_NO_HDAT_ADDR, + l_addr, + l_section); + + } + + return (l_err); + } + + +} diff --git a/src/usr/dump/dumpCollect.H b/src/usr/dump/dumpCollect.H new file mode 100644 index 000000000..282a13886 --- /dev/null +++ b/src/usr/dump/dumpCollect.H @@ -0,0 +1,109 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/dump/dumpCollect.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ +/* */ +/* 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 otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __DUMPCOLLECT_H +#define __DUMPCOLLECT_H + +#include + +/** @file dumpCollect.H + * @brief Provides the interfaces to copy dump data from src to destination + */ + +namespace DUMP +{ + + //These structures are defined in the HDAT spec + //The MDST and MDDT have this format. + struct dumpEntry + { + uint64_t dataAddr; + uint64_t dataSize; + }; + + + //The MDRT has this format. + struct resultsEntry + { + uint64_t srcAddr; + uint64_t destAddr; + uint64_t dataSize; + }; + + + /** + * @brief This function is a wrapper function that calls + * getHostDataPtrs to get the MDDT, MDST, MDRT pointers + * and then passes those values to the copySrcToDest + * routine that performs the copy + * + * @param[in] void + * + * @return errlHndl_t + */ + errlHndl_t doDumpCollect(void); + + /** + * @brief This function copies the data and sizes retrieved from the + * MDST(source table) to the addresses indicated by the MDDT(destination + * table). Each write is then logged in the MDRT (results table) with + * source addr, destination addr and size + * + * @param[in] srcTableEntry Ptr to the first MDST entry + * @param[in] srcTableSize Size of the entire MDST + * + * @param[in] destTableAddr Ptr to the first MDDT entry + * @param[in] destTableSize Size of the entire MDDT + * + * @param[in] resultsTableAddr Ptr to the first MDRT entry + * @param[in] resultsTableSize Size of the entire MDRT + * + * @return errlHndl_t + */ + errlHndl_t copySrcToDest(dumpEntry *srcTableEntry, uint64_t srcTableSize, + dumpEntry *destTableEntry, uint64_t destTableSize, + resultsEntry *resultsTableEntry, uint64_t resultsTableSize); + + /** + * @brief This routine retrieves first entry of the MDST, MDDT and + * MDRT and the size of each of those tables. + * + * @param[out] srcTableEntry Ptr to the first MDST entry + * @param[out] srcTableSize Size of the entire MDST + * + * @param[out] destTableAddr Ptr to the first MDDT entry + * @param[out] destTableSize Size of the entire MDDT + * + * @param[out] resultsTableAddr Ptr to the first MDRT entry + * @param[out] resultsTableSize Size of the entire MDRT + + * @return errlHndl_t + */ + errlHndl_t getHostDataPtrs(dumpEntry *srcTableEntry, uint64_t &srcTableSize, + dumpEntry *destTableEntry, uint64_t &destTableSize, + resultsEntry *resultsTableEntry,uint64_t &resultsTableSize); + + +} + + +#endif diff --git a/src/usr/dump/makefile b/src/usr/dump/makefile new file mode 100644 index 000000000..bc44d3a92 --- /dev/null +++ b/src/usr/dump/makefile @@ -0,0 +1,30 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/dump/makefile $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2012,2013 +# +# 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 otherwise +# divested of its trade secrets, irrespective of what has been +# deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END_TAG +ROOTPATH = ../../.. +MODULE = dump + +OBJS = dumpCollect.o + +SUBDIRS = test.d + +include ${ROOTPATH}/config.mk diff --git a/src/usr/dump/test/dumptest.H b/src/usr/dump/test/dumptest.H new file mode 100644 index 000000000..a0fa852d1 --- /dev/null +++ b/src/usr/dump/test/dumptest.H @@ -0,0 +1,1198 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/dump/test/dumptest.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ +/* */ +/* 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 otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __DUMPTEST_H +#define __DUMPTEST_H + +/** + * @file dumptest.H + * + * @brief Test case for dump code +*/ + +#include +#include +#include +#include +#include +#include "../dumpCollect.H" +#include +#include +#include +#include +#include + + +extern trace_desc_t* g_trac_dump; + +class DumpTest: public CxxTest::TestSuite +{ + public: + + + /** + * @brief Basic dump test that has sequential src addresses to + * equivalent destination locations and sizes. + * + */ + + void test_DumpCollect(void) + { + + TRACFCOMP( g_trac_dump, "DumpTest::test_dumpCollect START" ); + + errlHndl_t l_err = NULL; + + uint64_t srcTableAddr = 0; + uint64_t srcTableSize = 0; + + uint64_t dstTableAddr = 0; + uint64_t dstTableSize = 0; + + uint64_t resultsTableAddr = 0; + uint64_t resultsTableSize = 0; + + DUMP::dumpEntry *srcTableEntry = NULL; + DUMP::dumpEntry *destTableEntry = NULL; + DUMP::resultsEntry *resultsTableEntry = NULL; + + // For testing I am using my own data pointers and setting it up + // to look like PHYP would have to test the copy function. + srcTableAddr = DUMP_TEST_SRC_MEM_ADDR; + srcTableSize = DUMP_TEST_SRC_MEM_SIZE; + dstTableAddr = DUMP_TEST_DST_MEM_ADDR; + dstTableSize = DUMP_TEST_DST_MEM_SIZE; + resultsTableAddr = DUMP_TEST_RESULTS_MEM_ADDR; + resultsTableSize = DUMP_TEST_RESULTS_MEM_SIZE; + + + uint64_t src_data[8] = {DUMP_TEST_SRC_DATA_AREA, 64, // 450000 + DUMP_TEST_SRC_DATA_AREA + 64, 64, + DUMP_TEST_SRC_DATA_AREA + 128, 64, + DUMP_TEST_SRC_DATA_AREA + 192, 64}; + + + uint64_t dst_data[8] = {DUMP_TEST_DST_DATA_AREA, 64, // 460000 + DUMP_TEST_DST_DATA_AREA + 64, 64, + DUMP_TEST_DST_DATA_AREA + 128, 64, + DUMP_TEST_DST_DATA_AREA + 192, 64}; + + + // Point to the location of the src Data pointer. + uint64_t *srcTablePtr = reinterpret_cast(srcTableAddr); + + // Point to the location of the dest Data pointer. + uint64_t *dstTablePtr = reinterpret_cast(dstTableAddr); + + uint64_t *resultTablePtr = reinterpret_cast(resultsTableAddr); + + // Put the src addresses defined above into the MDST + memcpy(srcTablePtr, src_data, sizeof(src_data)); + + // Put the src addresses defined above into the MDDT + memcpy(dstTablePtr, dst_data, sizeof(dst_data)); + + // Need to memory map + uint64_t src_Inputdata[4][8] = { + {0x1111111111111111, 0x1111111111111111, + 0x1111111111111111, 0x1111111111111111, + 0x1111111111111111, 0x1111111111111111, + 0x1111111111111111, 0x1111111111111111}, + + {0x2222222222222222, 0x2222222222222222, + 0x2222222222222222, 0x2222222222222222, + 0x2222222222222222, 0x2222222222222222, + 0x2222222222222222, 0x2222222222222222}, + + {0x3333333333333333, 0x3333333333333333, + 0x3333333333333333, 0x3333333333333333, + 0x3333333333333333, 0x3333333333333333, + 0x3333333333333333,0x3333333333333333}, + + {0x4444444444444444, 0x4444444444444444, + 0x4444444444444444, 0x4444444444444444, + 0x4444444444444444, 0x4444444444444444, + 0x4444444444444444, 0x4444444444444444} + }; + + + // results output data expected + uint64_t result_data[12] = { + DUMP_TEST_SRC_DATA_AREA, DUMP_TEST_DST_DATA_AREA, 64, + DUMP_TEST_SRC_DATA_AREA+64, DUMP_TEST_DST_DATA_AREA+64, 64, + DUMP_TEST_SRC_DATA_AREA+128, DUMP_TEST_DST_DATA_AREA+128, 64, + DUMP_TEST_SRC_DATA_AREA+192, DUMP_TEST_DST_DATA_AREA+192, 64, + }; + + uint64_t *va_mapsrcTableAddr = 0; + uint64_t *va_srcTableAddr = 0; + uint64_t offset = 0; + int index = 0; + + for (int i = 0; i<4; i++) + { + + // Get the Va for the page aligned Physical address + va_mapsrcTableAddr = + static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(src_data[index])), + THIRTYTWO_GB)); + + // copy the mapped VA to a VA pointer we will + va_srcTableAddr = va_mapsrcTableAddr; + + // calculate offset based on page alignment. + offset = src_data[index] - ALIGN_PAGE_DOWN(src_data[index]); + + // increment the offset to correct VA offset. + va_srcTableAddr += (offset/(sizeof (uint64_t))); + + memcpy(va_srcTableAddr, src_Inputdata[i], sizeof(src_Inputdata[i])); + + // unmap the previous src entry + int rc = + mmio_dev_unmap(reinterpret_cast(va_mapsrcTableAddr)); + + if (rc != 0) + { + TRACFCOMP(g_trac_dump, "DumpTest:test_DumpCollect> got an error back from unmap : RC=%X",rc); + TS_FAIL( "DumpTest::CollectDump ERROR : BAD Rc from mmio_dev_unmap" ); + break; + } + index+=2; + } + + + srcTableEntry = reinterpret_cast(srcTableAddr); + destTableEntry = reinterpret_cast(dstTableAddr); + resultsTableEntry = reinterpret_cast(resultsTableAddr); + + + l_err = DUMP::copySrcToDest(srcTableEntry,srcTableSize, + destTableEntry,dstTableSize, + resultsTableEntry,resultsTableSize); + + if( l_err ) + { + TRACFCOMP(g_trac_dump, "DumpTest:test_DumpCollect> got an error back from dumpcollect : RC=%X",l_err->reasonCode() ); + TS_FAIL( "DumpTest::CollectDump ERROR : Unexpected error log from dumpcollect" ); + errlCommit(l_err,DUMP_COMP_ID); + } + + + // Verify that the data and the VA mapping is correct. + uint64_t *va_mapdestTableAddr = 0; + uint64_t *va_destTableAddr = 0; + offset = 0; + index = 0; + + for (int i = 0; i<4; i++) + { + // Get the Va for the page aligned Physical address + va_mapdestTableAddr = + static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(dst_data[index])), + THIRTYTWO_GB)); + + // copy the mapped VA to a VA pointer we will + va_destTableAddr = va_mapdestTableAddr; + + // calculate offset based on page alignment. + offset = dst_data[index] - ALIGN_PAGE_DOWN(dst_data[index]); + + // increment the offset to correct VA offset. + va_destTableAddr += (offset/(sizeof (uint64_t))); + + uint64_t paddr = mm_virt_to_phys(va_destTableAddr); + + if (paddr != dst_data[index]) + { + TRACFCOMP(g_trac_dump, + "DumpTest:test_DumpCollect:1> mapping mismatch actual paddr = %lx, expected paddr = %lx", paddr, dst_data[index]); + TS_FAIL( "DumpTest:test_DumpCollect:1 ERROR : Unexpected error physical address mismatch" ); + } + + + // Check the destination table. + int src_rc = memcmp(va_destTableAddr,src_Inputdata[i],sizeof(src_Inputdata[i])); + + if (src_rc!=0) + { + TRACFCOMP(g_trac_dump, "DumpTest::DumpCollect:1 : Results Data mismatch rc = %d", src_rc); + TS_FAIL( "DumpTest::DumpCollect ERROR : Unexpected error data mismatch in results table" ); + } + + + // unmap the previous src entry + int rc = + mmio_dev_unmap(reinterpret_cast(va_mapsrcTableAddr)); + + if (rc != 0) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollect got an error back from unmap : RC=%X",rc); + TS_FAIL( "DumpTest::DumpCollect ERROR : BAD Rc from mmio_dev_unmap" ); + break; + } + index+=2; + } + + + // Check the results table. + int result_rc = memcmp(resultTablePtr,result_data,sizeof (result_data)); + + if (result_rc!=0) + { + TRACFCOMP(g_trac_dump, "DumpTest::DumpCollect:1 : Results Data mismatch rc = %d", result_rc); + TS_FAIL( "DumpTest::DumpCollect ERROR : Unexpected error data mismatch in results table" ); + } + + TRACFCOMP( g_trac_dump, "DumpTest::DumpCollect COMPLETE" ); + + } + + /** + * @brief Basic dump test that has sequential src addresses to + * imbalanced destination locations and sizes. + * + */ + void test_DumpCollectUnevenDest(void) + { + + TRACFCOMP( g_trac_dump, "DumpTest::DumpCollectUnevenDest START" ); + errlHndl_t l_err = NULL; + uint64_t srcTableAddr = 0; + uint64_t srcTableSize = 0; + uint64_t dstTableAddr = 0; + uint64_t dstTableSize = 0; + uint64_t resultsTableAddr = 0; + uint64_t resultsTableSize = 0; + + DUMP::dumpEntry *srcTableEntry = NULL; + DUMP::dumpEntry *destTableEntry = NULL; + DUMP::resultsEntry *resultsTableEntry = NULL; + + // Setting up TESt version of the MDST, MDDT and MDRT. + srcTableAddr = DUMP_TEST_SRC_MEM_ADDR; + srcTableSize = DUMP_TEST_SRC_MEM_SIZE; + dstTableAddr = DUMP_TEST_DST_MEM_ADDR; + dstTableSize = DUMP_TEST_DST_MEM_SIZE; + resultsTableAddr = DUMP_TEST_RESULTS_MEM_ADDR; + resultsTableSize = DUMP_TEST_RESULTS_MEM_SIZE; + + + uint64_t src_data[8] = {DUMP_TEST_SRC_DATA_AREA+256, 64, // 4500100 + DUMP_TEST_SRC_DATA_AREA+256 + 64,64, // 4500140 + DUMP_TEST_SRC_DATA_AREA+256 + 128,64, // 4500180 + DUMP_TEST_SRC_DATA_AREA+256 + 192, 64}; // 45001C0 + + uint64_t dst_data[8] = {DUMP_TEST_DST_DATA_AREA+1024, 64, // 4600400 + DUMP_TEST_DST_DATA_AREA+1024 + 64, 32, // 4600440 + DUMP_TEST_DST_DATA_AREA+1024 + 96, 32, // 4600480 + DUMP_TEST_DST_DATA_AREA+1024+ 128, 128}; // 46004C0 + + uint64_t *srcTablePtr = reinterpret_cast(srcTableAddr); + uint64_t *dstTablePtr = reinterpret_cast(dstTableAddr); + uint64_t *resultTablePtr = reinterpret_cast(resultsTableAddr); + + memcpy(srcTablePtr, src_data, sizeof(src_data)); + memcpy(dstTablePtr, dst_data, sizeof(dst_data)); + + + // Need to memory map + uint64_t src_Inputdata[4][8] = { + {0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa, + 0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa, + 0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa, + 0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa}, + + {0xbbbbbbbbbbbbbbbb, 0xbbbbbbbbbbbbbbbb, + 0xbbbbbbbbbbbbbbbb, 0xbbbbbbbbbbbbbbbb, + 0xbbbbbbbbbbbbbbbb, 0xbbbbbbbbbbbbbbbb, + 0xbbbbbbbbbbbbbbbb, 0xbbbbbbbbbbbbbbbb}, + + {0xcccccccccccccccc, 0xcccccccccccccccc, + 0xcccccccccccccccc, 0xcccccccccccccccc, + 0xcccccccccccccccc, 0xcccccccccccccccc, + 0xcccccccccccccccc, 0xcccccccccccccccc}, + + {0xdddddddddddddddd, 0xdddddddddddddddd, + 0xdddddddddddddddd, 0xdddddddddddddddd, + 0xdddddddddddddddd, 0xdddddddddddddddd, + 0xdddddddddddddddd, 0xdddddddddddddddd}, + }; + + // results output data expected + uint64_t result_data[15] = { + DUMP_TEST_SRC_DATA_AREA+256, DUMP_TEST_DST_DATA_AREA+1024, 64, + DUMP_TEST_SRC_DATA_AREA+256+64, DUMP_TEST_DST_DATA_AREA+1024+64, 32, + DUMP_TEST_SRC_DATA_AREA+256+64+32, DUMP_TEST_DST_DATA_AREA+1024+64+32, 32, + DUMP_TEST_SRC_DATA_AREA+256+128,DUMP_TEST_DST_DATA_AREA+1024+128, 64, + DUMP_TEST_SRC_DATA_AREA+256+192, DUMP_TEST_DST_DATA_AREA+1024+128+64, 64, + }; + + uint64_t *va_mapsrcTableAddr = 0; + uint64_t *va_srcTableAddr = 0; + uint64_t offset = 0; + int index = 0; + + for (int i = 0; i<4; i++) + { + // Get the Va for the page aligned Physical address + va_mapsrcTableAddr = + static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(src_data[index])), + THIRTYTWO_GB)); + + // copy the mapped VA to a VA pointer + va_srcTableAddr = va_mapsrcTableAddr; + + // calculate offset based on page alignment. + offset = src_data[index] - ALIGN_PAGE_DOWN(src_data[index]); + + // increment the offset to correct VA offset. + va_srcTableAddr += (offset/(sizeof (uint64_t))); + + memcpy(va_srcTableAddr, src_Inputdata[i], sizeof(src_Inputdata[i])); + + // unmap the previous src entry + int rc = + mmio_dev_unmap(reinterpret_cast(va_mapsrcTableAddr)); + + if (rc != 0) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectUnevenDest> got an error back from unmap : RC=%X",rc); + TS_FAIL( "DumpTest::CollectDumpUnevenDest ERROR : BAD Rc from mmio_dev_unmap" ); + break; + } + index+=2; + } + + srcTableEntry = reinterpret_cast(srcTableAddr); + destTableEntry = reinterpret_cast(dstTableAddr); + resultsTableEntry = reinterpret_cast(resultsTableAddr); + + + l_err = DUMP::copySrcToDest(srcTableEntry,srcTableSize, + destTableEntry,dstTableSize, + resultsTableEntry,resultsTableSize); + + + if( l_err ) + { + TRACFCOMP(g_trac_dump, "DumpTest::DumpCollectUnevenDest got an error back from dumpcollect : RC=%X",l_err->reasonCode() ); + TS_FAIL( "DumpTest::CollectDumpUnevenDest ERROR : Unexpected error log from dumpcollect" ); + errlCommit(l_err,DUMP_COMP_ID); + } + + //---------------------------------------------------------------- + // !!!!! VERIFYING RESULTS + // Verify that the data and the VA mapping is correct. + //-------------------------------------------------------------- + do + { + + uint64_t *va_mapdestTableAddr = 0; + uint64_t *va_destTableAddr = 0; + offset = 0; + index = 0; + + int src_rc = 0; + uint64_t paddr = 0; + + // Looping throught the first 3 destinations + for (int i = 0; i<3; i++) + { + + // Get the Va for the page aligned Physical address + va_mapdestTableAddr = static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(dst_data[index])),THIRTYTWO_GB)); + + // copy the mapped VA to a VA pointer we will + va_destTableAddr = va_mapdestTableAddr; + + // calculate offset based on page alignment. + offset = dst_data[index] - ALIGN_PAGE_DOWN(dst_data[index]); + + // increment the offset to correct VA offset. + va_destTableAddr += (offset/(sizeof (uint64_t))); + + paddr = mm_virt_to_phys(va_destTableAddr); + + if (paddr != dst_data[index]) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectUnevenDest:1> mapping mismatch actual paddr = %lx, expected paddr = %lx", + paddr, dst_data[index]); + TS_FAIL( "DumpTest::DumpCollectUnevenDest ERROR : Unexpected error physical address mismatch" ); + } + + //if entry need to compare destination data to second portion of previous src + if (i == 2) + { + src_rc = memcmp(va_destTableAddr, &src_Inputdata[1][4], dst_data[index+1]); + } + else + { + // Check the destination table. + src_rc = memcmp(va_destTableAddr,src_Inputdata[i],dst_data[index+1]); + } + + // If got a memcmp fail + if (src_rc!=0) + { + TRACFCOMP(g_trac_dump, "DumpTest::DumpCollectUnevenDest:1 : Results Data mismatch rc = %d for index = %d", src_rc, i); + TS_FAIL( "DumpTest::DumpCollectUnevenDest ERROR : Unexpected error data mismatch in results table" ); + } + + + // unmap the previous src entry + int rc = + mmio_dev_unmap(reinterpret_cast(va_mapsrcTableAddr)); + + if (rc != 0) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectUnevenDest got an error back from unmap : RC=%X",rc); + TS_FAIL( "DumpTest::DumpCollectUnevenDest ERROR : BAD Rc from mmio_dev_unmap" ); + break; + } + index+=2; + } + + + // checking the 4th entry as it crosses through 2 source entries + + // Get the Va for the page aligned Physical address + va_mapdestTableAddr = static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(dst_data[index])),THIRTYTWO_GB)); + + // copy the mapped VA to a VA pointer we will + va_destTableAddr = va_mapdestTableAddr; + + // calculate offset based on page alignment. + offset = dst_data[index] - ALIGN_PAGE_DOWN(dst_data[index]); + + // increment the offset to correct VA offset. + va_destTableAddr += (offset/(sizeof (uint64_t))); + + paddr = mm_virt_to_phys(va_destTableAddr); + + if (paddr != dst_data[index]) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectUnevenDest:2> mapping mismatch actual paddr = %lx, expected paddr = %lx", + paddr, dst_data[index]); + TS_FAIL( "DumpTest::DumpCollectUnevenDest:2 ERROR : Unexpected error physical address mismatch" ); + } + + int dataentries = (dst_data[index+1]/16); + + // start with 3rd src index.. + int i = 2; + // Src Data input. + int dataIndex = 0; + + // Now loop through the data at this memory address and compare it to the data + for (int j = 0; j(va_mapdestTableAddr)); + + if (rc != 0) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectUnevenDest got an error back from unmap : RC=%X",rc); + TS_FAIL( "DumpTest::CollectDumpUnevenDest ERROR : BAD Rc from mmio_dev_unmap" ); + break; + } + index+=2; + + }while(0); + + // Check the results table. + int result_rc = memcmp(resultTablePtr,result_data,sizeof (result_data)); + + if (result_rc!=0) + { + TRACFCOMP(g_trac_dump, "DumpTest::DumpCollectUnevenDest : Results Data mismatch rc = %d", result_rc); + TS_FAIL( "DumpTest::DumpCollectUnevenDest ERROR : Unexpected error data mismatch in results table" ); + } + + + TRACFCOMP( g_trac_dump, "dumpTest::test_dumpCollectUnevenDest COMPLETE" ); + } + + + /** + * @brief Basic dump test that has non sequential src addresses with varying + * sizes to non sequential destination locations and uneven src + * + */ + + void test_DumpCollectUnevenSrc(void) + { + + TRACFCOMP( g_trac_dump, "dumpTest::test_dumpCollectUnevenSrc START" ); + + errlHndl_t l_err = NULL; + + uint64_t srcTableAddr = 0; + uint64_t srcTableSize = 0; + + uint64_t dstTableAddr = 0; + uint64_t dstTableSize = 0; + + uint64_t resultsTableAddr = 0; + uint64_t resultsTableSize = 0; + + uint64_t offset = 0; + + DUMP::dumpEntry *srcTableEntry = NULL; + DUMP::dumpEntry *destTableEntry = NULL; + DUMP::resultsEntry *resultsTableEntry = NULL; + + // Setting up TESt version of the MDST, MDDT and MDRT. + srcTableAddr = DUMP_TEST_SRC_MEM_ADDR; + srcTableSize = DUMP_TEST_SRC_MEM_SIZE; + dstTableAddr = DUMP_TEST_DST_MEM_ADDR; + dstTableSize = DUMP_TEST_DST_MEM_SIZE; + resultsTableAddr = DUMP_TEST_RESULTS_MEM_ADDR; + resultsTableSize = DUMP_TEST_RESULTS_MEM_SIZE; + + uint64_t src_data[8] = {DUMP_TEST_SRC_DATA_AREA+1024, 16, // 4500400 + DUMP_TEST_SRC_DATA_AREA+2048, 48, // 4500800 + DUMP_TEST_SRC_DATA_AREA+3072, 32, // 4500C00 + DUMP_TEST_SRC_DATA_AREA+4096, 160}; // 4501000 + + + uint64_t dst_data[8] = {DUMP_TEST_DST_DATA_AREA+2048, 64, // 4600800 + DUMP_TEST_DST_DATA_AREA+2048+128, 32, // 4600880 + DUMP_TEST_DST_DATA_AREA+3072, 32, // 4600C00 + DUMP_TEST_DST_DATA_AREA+3072+64, 128}; // 4600C40 + + + uint64_t *srcTablePtr = reinterpret_cast(srcTableAddr); + uint64_t *dstTablePtr = reinterpret_cast(dstTableAddr); + uint64_t *resultTablePtr = reinterpret_cast(resultsTableAddr); + + memcpy(srcTablePtr, src_data, sizeof(src_data)); + memcpy(dstTablePtr, dst_data, sizeof(dst_data)); + + + // Need to memory map + uint64_t src_data0[2] = {0x1212121212121212, 0x1212121212121212}; + + uint64_t src_data1[6] = {0x3434343434343434, 0x3434343434343434, + 0x3434343434343434, 0x3434343434343434, + 0x3434343434343434, 0x3434343434343434}; + + uint64_t src_data2[4] = {0x5656565656565656, 0x5656565656565656, + 0x5656565656565656, 0x5656565656565656}; + + uint64_t src_data3[20] = {0x7878787878787878, 0x7878787878787878, + 0x7878787878787878, 0x7878787878787878, + 0x7878787878787878, 0x7878787878787878, + 0x7878787878787878, 0x7878787878787878, + 0x7878787878787878, 0x7878787878787878, + 0x7878787878787878, 0x7878787878787878, + 0x7878787878787878, 0x7878787878787878, + 0x7878787878787878, 0x7878787878787878, + 0x7878787878787878, 0x7878787878787878, + 0x7878787878787878, 0x7878787878787878}; + + + // results output data expected + uint64_t result_data[15] = { + DUMP_TEST_SRC_DATA_AREA+1024, DUMP_TEST_DST_DATA_AREA+2048, 16, + DUMP_TEST_SRC_DATA_AREA+2048, DUMP_TEST_DST_DATA_AREA+2048+16, 48, + DUMP_TEST_SRC_DATA_AREA+3072, DUMP_TEST_DST_DATA_AREA+2048+128, 32, + DUMP_TEST_SRC_DATA_AREA+4096, DUMP_TEST_DST_DATA_AREA+3072, 32, + DUMP_TEST_SRC_DATA_AREA+4096+32, DUMP_TEST_DST_DATA_AREA+3072+64, 128, + }; + + do + { + uint64_t *va_mapsrcTableAddr = + static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(src_data[0])), + THIRTYTWO_GB)); + + uint64_t *va_srcTableAddr = va_mapsrcTableAddr; + + offset = src_data[0] - ALIGN_PAGE_DOWN(src_data[0]); + + // increment the offset to correct VA offset. + va_srcTableAddr += (offset/(sizeof (uint64_t))); + + memcpy(va_srcTableAddr, src_data0, sizeof(src_data0)); + + // unmap the previous src entry + int rc = mmio_dev_unmap(reinterpret_cast(va_mapsrcTableAddr)); + + if (rc != 0) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectUnevenSrc mmio_dev_map (1) bad RC=%X for addr %llx",rc, va_mapsrcTableAddr); + TS_FAIL( "DumpTest::DumpCollectUnevenSrc ERROR : BAD Rc from mmio_dev_unmap" ); + break; + + } + + va_mapsrcTableAddr = + static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(src_data[2])), + THIRTYTWO_GB)); + + va_srcTableAddr = va_mapsrcTableAddr; + + // calculate offset based on page alignment. + offset = src_data[2] - ALIGN_PAGE_DOWN(src_data[2]); + + // increment the offset to correct VA offset. + va_srcTableAddr += (offset/(sizeof (uint64_t))); + + memcpy(va_srcTableAddr, src_data1, sizeof(src_data1)); + + // unmap the previous src entry + rc = mmio_dev_unmap(reinterpret_cast(va_mapsrcTableAddr)); + + if (rc != 0) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectUnevenSrc mmio_dev_map (2) bad RC=%X for addr %llx",rc, va_mapsrcTableAddr); + TS_FAIL( "DumpTest::DumpCollectUnevenSrc ERROR : BAD Rc from mmio_dev_unmap" ); + break; + } + + + va_mapsrcTableAddr = + static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(src_data[4])), + THIRTYTWO_GB)); + + va_srcTableAddr = va_mapsrcTableAddr; + + // calculate offset based on page alignment. + offset = src_data[4] - ALIGN_PAGE_DOWN(src_data[4]); + + // increment the offset to correct VA offset. + va_srcTableAddr += (offset/(sizeof (uint64_t))); + + memcpy(va_srcTableAddr, src_data2, sizeof(src_data2)); + + // unmap the previous src entry + rc = mmio_dev_unmap(reinterpret_cast(va_mapsrcTableAddr)); + + if (rc != 0) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectUnevenSrc mmio_dev_map (3) bad RC=%X for addr %llx",rc, va_mapsrcTableAddr); + TS_FAIL( "DumpTest::DumpCollectUnevenSrc ERROR : BAD Rc from mmio_dev_unmap" ); + break; + + } + + va_mapsrcTableAddr = + static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(src_data[6])), + THIRTYTWO_GB)); + + va_srcTableAddr = va_mapsrcTableAddr; + + // calculate offset based on page alignment. + offset = src_data[6] - ALIGN_PAGE_DOWN(src_data[6]); + + // increment the offset to correct VA offset. + va_srcTableAddr += (offset/(sizeof (uint64_t))); + + memcpy(va_srcTableAddr, src_data3, sizeof(src_data3)); + + + // unmap the previous src entry + rc = mmio_dev_unmap(reinterpret_cast(va_mapsrcTableAddr)); + + if (rc != 0) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectUnevenSrc mmio_dev_map (4) bad RC=%X for addr %llx",rc, va_mapsrcTableAddr); + TS_FAIL( "DumpTest::DumpCollectUnevenSrc ERROR : BAD Rc from mmio_dev_unmap" ); + break; + } + }while(0); + + + srcTableEntry = reinterpret_cast(srcTableAddr); + destTableEntry = reinterpret_cast(dstTableAddr); + resultsTableEntry = reinterpret_cast(resultsTableAddr); + + + l_err = DUMP::copySrcToDest(srcTableEntry,srcTableSize, + destTableEntry,dstTableSize, + resultsTableEntry,resultsTableSize); + + if( l_err ) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectUnevenSrc got an error back from copySrcToDest : RC=%X", + l_err->reasonCode() ); + TS_FAIL( "DumpTest::DumpCollectUnevenSrc ERROR : Unexpected error log from copySrcToDest" ); + errlCommit(l_err,DUMP_COMP_ID); + } + + + //---------------------------------------------------------------- + // !!!!! VERIFYING RESULTS + // Verify that the data and the VA mapping is correct. + //---------------------------------------------------------------- + + do + { + + uint64_t *va_mapdestTableAddr = 0; + uint64_t *va_destTableAddr = 0; + offset = 0; + int index = 0; + int i = 0; + + + // FIRST Destination ENTRY source entires 0 and 1 !!!! + // Get the Va for the page aligned Physical address + va_mapdestTableAddr = + static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(dst_data[index])), + THIRTYTWO_GB)); + + // copy the mapped VA to a VA pointer we will + va_destTableAddr = va_mapdestTableAddr; + + // calculate offset based on page alignment. + offset = dst_data[index] - ALIGN_PAGE_DOWN(dst_data[index]); + + // increment the offset to correct VA offset. + va_destTableAddr += (offset/(sizeof (uint64_t))); + + uint64_t paddr = mm_virt_to_phys(va_destTableAddr); + + if (paddr != dst_data[index]) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectUnevenSrc:1 mapping mismatch actual paddr = %lx, expected paddr = %lx", + paddr, dst_data[index]); + TS_FAIL( "DumpTest::DumpCollectUnevenSrc ERROR : Unexpected error log from dumpcollect" ); + } + + int dataentries = (dst_data[index+1]/16); + + int curSrcEntry = 0; + + // Now loop through the data at this memory address and compare it to the data + for (int j = 0; j<2; j++) + { + if (va_destTableAddr[j] != src_data0[j]) + { + // error + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectUnevenSrc:1 : Data mismatch input data = %lX, outputdata = %lx", + src_data0[j], va_destTableAddr[j]); + TS_FAIL( "DumpTest::DumpCollectUnevenSrc ERROR : Unexpected error data mismatch" ); + break; + } + dataentries = dataentries-1; + curSrcEntry++; + } + + + // Now loop through the remainder of this destination to a new src data entry + for (int j = 0; j(va_mapdestTableAddr)); + + if (rc != 0) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectUnevenSrc:5 got an error back from unmap : RC=%X",rc); + TS_FAIL( "DumpTest::DumpCollectUnevenSrc:5 ERROR : BAD Rc from mmio_dev_unmap" ); + break; + } + index+=2; + + + // SECOND DEStination ENTRY third source entry!!!! + + // Get the Va for the page aligned Physical address + va_mapdestTableAddr = + static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(dst_data[index])), + THIRTYTWO_GB)); + + // copy the mapped VA to a VA pointer we will + va_destTableAddr = va_mapdestTableAddr; + + // calculate offset based on page alignment. + offset = dst_data[index] - ALIGN_PAGE_DOWN(dst_data[index]); + + // increment the offset to correct VA offset. + va_destTableAddr += (offset/(sizeof (uint64_t))); + + paddr = mm_virt_to_phys(va_destTableAddr); + + if (paddr != dst_data[index]) + { + TRACFCOMP(g_trac_dump, "DumpTest::DumpCollectUnevenSrc:2 mapping mismatch actual paddr = %lx, expected paddr = %lx", paddr, dst_data[index]); + TS_FAIL( "DumpTest::DumpCollectUnevenSrc:2 ERROR : Unexpected error log from dumpcollect" ); + } + + dataentries = (dst_data[index+1]/16); + i = 0; + + // Now loop through the data at this memory address and compare it to the data + for (int j = 0; j(va_mapdestTableAddr)); + + if (rc != 0) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectUnevenSrc:6 got an error back from unmap : RC=%X",rc); + TS_FAIL( "DumpTest::DumpCollectUnevenSrc:6 ERROR : BAD Rc from mmio_dev_unmap" ); + break; + } + + index+=2; + + // THIRD destination entry - part of last source!!!! + + // Get the Va for the page aligned Physical address + va_mapdestTableAddr = static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(dst_data[index])),THIRTYTWO_GB)); + + // copy the mapped VA to a VA pointer we will + va_destTableAddr = va_mapdestTableAddr; + + // calculate offset based on page alignment. + offset = dst_data[index] - ALIGN_PAGE_DOWN(dst_data[index]); + + // increment the offset to correct VA offset. + va_destTableAddr += (offset/(sizeof (uint64_t))); + + paddr = mm_virt_to_phys(va_destTableAddr); + + if (paddr != dst_data[index]) + { + TRACFCOMP(g_trac_dump, "DumpTest::DumpCollectUnevenSrc:3 mapping mismatch actual paddr = %lx, expected paddr = %lx", paddr, dst_data[index]); + TS_FAIL( "DumpTest::DumpCollectUnevenSrc:3 ERROR : Unexpected error log from dumpcollect" ); + } + + dataentries = (dst_data[index+1]/16); + + curSrcEntry = 0; + + + // Now loop through the data at this memory address and compare it to the data + for (int j = 0; j(va_mapdestTableAddr)); + + if (rc != 0) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectUnevenSrc:7 got an error back from unmap : RC=%X",rc); + TS_FAIL( "DumpTest::DumpCollectUnevenSrc:7 ERROR : BAD Rc from mmio_dev_unmap" ); + break; + } + index+=2; + + + // FOURTH SRC ENTRY !!!! + + // Get the Va for the page aligned Physical address + va_mapdestTableAddr = + static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(dst_data[index])), + THIRTYTWO_GB)); + + // copy the mapped VA to a VA pointer we will + va_destTableAddr = va_mapdestTableAddr; + + // calculate offset based on page alignment. + offset = dst_data[index] - ALIGN_PAGE_DOWN(dst_data[index]); + + // increment the offset to correct VA offset. + va_destTableAddr += (offset/(sizeof (uint64_t))); + + paddr = mm_virt_to_phys(va_destTableAddr); + + if (paddr != dst_data[index]) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectUnevenSrc:5 mapping mismatch actual paddr = %lx, expected paddr = %lx", + paddr, dst_data[index]); + TS_FAIL( "DumpTest::DumpCollectUnevenSrc:4 ERROR : Unexpected error log from dumpcollect" ); + } + + dataentries = (dst_data[index+1]/16); + + // Now loop through the data at this memory address and compare it to the data + for (int j = 0; j(va_mapdestTableAddr)); + + if (rc != 0) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectUnevenSrc:8 got an error back from unmap : RC=%X",rc); + TS_FAIL( "DumpTest::DumpCollectUnevenSrc:8 ERROR : BAD Rc from mmio_dev_unmap" ); + break; + } + index+=2; + + }while(0); + + + // Check the results table. + int result_rc = memcmp(resultTablePtr,result_data,sizeof (result_data)); + + if (result_rc!=0) + { + TRACFCOMP(g_trac_dump, "DumpTest::DumpCollectUnevenSRC:1 : Results Data mismatch rc = %d", result_rc); + TS_FAIL( "DumpTest::DumpCollectUnevenSrc ERROR : Unexpected error data mismatch in results table" ); + } + + + TRACFCOMP( g_trac_dump, "dumpTest::test_dumpCollectUnevenSrc COMPLETE" ); + } + + + /** + * @brief Basic dump test that forces an error condition that does not have + * enough destination space to hold the src size + * + */ + + void test_DumpCollectNotEnoughDest(void) + { + + TRACFCOMP( g_trac_dump, "dumpTest::test_dumpCollectNotEnoughDest START" ); + + errlHndl_t l_err = NULL; + + uint64_t srcTableAddr = 0; + uint64_t srcTableSize = 0; + + uint64_t dstTableAddr = 0; + uint64_t dstTableSize = 0; + + uint64_t resultsTableAddr = 0; + uint64_t resultsTableSize = 0; + + DUMP::dumpEntry *srcTableEntry = NULL; + DUMP::dumpEntry *destTableEntry = NULL; + DUMP::resultsEntry *resultsTableEntry = NULL; + + // Test locations of the MDST, MDDT, MDRT + srcTableAddr = DUMP_TEST_SRC_MEM_ADDR; + srcTableSize = DUMP_TEST_SRC_MEM_SIZE; + dstTableAddr = DUMP_TEST_DST_MEM_ADDR; + dstTableSize = DUMP_TEST_DST_MEM_SIZE; + resultsTableAddr = DUMP_TEST_RESULTS_MEM_ADDR; + resultsTableSize = DUMP_TEST_RESULTS_MEM_SIZE; + + uint64_t src_data[8] = {DUMP_TEST_SRC_DATA_AREA, 64, // 450000 + DUMP_TEST_SRC_DATA_AREA + 64, 64, + DUMP_TEST_SRC_DATA_AREA + 128, 64, + DUMP_TEST_SRC_DATA_AREA + 192, 64}; + + + uint64_t dst_data[8] = {DUMP_TEST_DST_DATA_AREA+4096, 64, // 4601000 + DUMP_TEST_DST_DATA_AREA + 4096 + 64, 64, + DUMP_TEST_DST_DATA_AREA + 4096 + 128, 64, + DUMP_TEST_DST_DATA_AREA + 4096 + 192, 32}; // NOTE>> TOO SMALL of a space.. + + + // Point to the location of the src Data pointer. + uint64_t *srcTablePtr = reinterpret_cast(srcTableAddr); + + // Point to the location of the dest Data pointer. + uint64_t *dstTablePtr = reinterpret_cast(dstTableAddr); + + // Put the src addresses defined above into the MDST + memcpy(srcTablePtr, src_data, sizeof(src_data)); + + // Put the src addresses defined above into the MDDT + memcpy(dstTablePtr, dst_data, sizeof(dst_data)); + + + // Need to memory map + uint64_t src_Inputdata[4][8] = { + {0x1111111111111111, 0x1111111111111111, + 0x1111111111111111, 0x1111111111111111, + 0x1111111111111111, 0x1111111111111111, + 0x1111111111111111, 0x1111111111111111}, + + {0x2222222222222222, 0x2222222222222222, + 0x2222222222222222, 0x2222222222222222, + 0x2222222222222222, 0x2222222222222222, + 0x2222222222222222, 0x2222222222222222}, + + {0x3333333333333333, 0x3333333333333333, + 0x3333333333333333, 0x3333333333333333, + 0x3333333333333333, 0x3333333333333333, + 0x3333333333333333,0x3333333333333333}, + + {0x4444444444444444, 0x4444444444444444, + 0x4444444444444444, 0x4444444444444444, + 0x4444444444444444, 0x4444444444444444, + 0x4444444444444444, 0x4444444444444444} + }; + + uint64_t *va_mapsrcTableAddr = 0; + uint64_t *va_srcTableAddr = 0; + uint64_t offset = 0; + int index = 0; + + for (int i = 0; i<4; i++) + { + + // Get the Va for the page aligned Physical address + va_mapsrcTableAddr = static_cast(mmio_dev_map(reinterpret_cast(ALIGN_PAGE_DOWN(src_data[index])),THIRTYTWO_GB)); + + // copy the mapped VA to a VA pointer we will + va_srcTableAddr = va_mapsrcTableAddr; + + // calculate offset based on page alignment. + offset = src_data[index] - ALIGN_PAGE_DOWN(src_data[index]); + + // increment the offset to correct VA offset. + va_srcTableAddr += (offset/(sizeof (uint64_t))); + + memcpy(va_srcTableAddr, src_Inputdata[i], sizeof(src_Inputdata[i])); + + // unmap the previous src entry + int rc = + mmio_dev_unmap(reinterpret_cast(va_mapsrcTableAddr)); + + if (rc != 0) + { + TRACFCOMP(g_trac_dump, "DumpTest::DumpCollectNotEnoughDest ERROR..got an error back from unmap : RC=%X",rc); + TS_FAIL( "DumpTest::DumpCollectNotEnoughDest ERROR : BAD Rc from mmio_dev_unmap" ); + break; + } + index+=2; + } + + + srcTableEntry = reinterpret_cast(srcTableAddr); + destTableEntry = reinterpret_cast(dstTableAddr); + resultsTableEntry = reinterpret_cast(resultsTableAddr); + + + l_err = DUMP::copySrcToDest(srcTableEntry,srcTableSize, + destTableEntry,dstTableSize, + resultsTableEntry,resultsTableSize); + + + // this testcase expects an error returned. + if( l_err ) + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectNotEnoughDest got an EXPECTED error back from copySrcToDest : RC=%X",l_err->reasonCode() ); + delete l_err; + } + else + { + TRACFCOMP(g_trac_dump, + "DumpTest::DumpCollectNotEnoughDest ERROR : Did NOT get errorlog back from copySrcToDest"); + TS_FAIL( "DumpTest::DumpCollectNotEnoughDest ERROR : DID not get expected error on too small dest entry" ); + } + + + TRACFCOMP( g_trac_dump, "dumpTest::test_dumpCollectNotEnoughDest COMPLETE" ); + + } +}; + +#endif diff --git a/src/usr/dump/test/makefile b/src/usr/dump/test/makefile new file mode 100644 index 000000000..42124c0d2 --- /dev/null +++ b/src/usr/dump/test/makefile @@ -0,0 +1,28 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/dump/test/makefile $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2012,2013 +# +# 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 otherwise +# divested of its trade secrets, irrespective of what has been +# deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END_TAG +ROOTPATH = ../../../.. + +MODULE = testdump +TESTS = *.H + +include ${ROOTPATH}/config.mk diff --git a/src/usr/initservice/extinitsvc/extinitsvctasks.H b/src/usr/initservice/extinitsvc/extinitsvctasks.H index b3f4912f8..7edd7b724 100644 --- a/src/usr/initservice/extinitsvc/extinitsvctasks.H +++ b/src/usr/initservice/extinitsvc/extinitsvctasks.H @@ -304,6 +304,21 @@ const TaskInfo g_exttaskinfolist[] = { } }, + /** + * @brief dump code library + */ + { + "libdump.so" , // taskname + NULL, // no pointer to fn + { + INIT_TASK, // task type + EXT_IMAGE, // Extended Module + } + }, + + +// end TODO. + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: libistepdisp.so needs to always be last in this list!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/src/usr/makefile b/src/usr/makefile index a93a1827a..49a7a5e05 100644 --- a/src/usr/makefile +++ b/src/usr/makefile @@ -30,6 +30,6 @@ SUBDIRS = example.d trace.d cxxtest.d testcore.d errl.d devicefw.d \ scom.d xscom.d targeting.d initservice.d hwpf.d \ ecmddatabuffer.d pnor.d i2c.d vfs.d fsi.d hwas.d fsiscom.d \ intr.d pore.d util.d mbox.d diag.d vpd.d scan.d \ - runtime.d ibscom.d + runtime.d ibscom.d dump.d include ${ROOTPATH}/config.mk diff --git a/src/usr/runtime/hdatservice.C b/src/usr/runtime/hdatservice.C index eef641bbd..733063281 100644 --- a/src/usr/runtime/hdatservice.C +++ b/src/usr/runtime/hdatservice.C @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ @@ -253,6 +253,21 @@ errlHndl_t get_standalone_section( RUNTIME::SectionId i_section, o_dataAddr = HSVC_TEST_MEMORY_ADDR + 512*KILOBYTE; o_dataSize = HSVC_TEST_MEMORY_SIZE - 512*KILOBYTE; } + else if( RUNTIME::MS_DUMP_SRC_TBL == i_section ) + { + o_dataAddr = DUMP_TEST_SRC_MEM_ADDR; + o_dataSize = DUMP_TEST_SRC_MEM_SIZE; + } + else if( RUNTIME::MS_DUMP_DST_TBL == i_section ) + { + o_dataAddr = DUMP_TEST_DST_MEM_ADDR; + o_dataSize = DUMP_TEST_DST_MEM_SIZE; + } + else if( RUNTIME::MS_DUMP_RESULTS_TBL == i_section ) + { + o_dataAddr = DUMP_TEST_RESULTS_MEM_ADDR; + o_dataSize = DUMP_TEST_RESULTS_MEM_SIZE; + } else { TRACFCOMP( g_trac_runtime, "get_standalone_section> Section %d not valid in standalone mode", i_section ); @@ -405,7 +420,38 @@ errlHndl_t RUNTIME::load_host_data( void ) HSVC_TEST_MEMORY_SIZE ); errhdl->collectTrace("RUNTIME",1024); break; + } + + // Map in some memory for the DumpCollect code to use + TRACFCOMP( g_trac_runtime, + "load_host_data> STANDALONE: Mapping in 0x%X-0x%X (%d MB)", DUMP_TEST_TABLE_START, DUMP_TEST_TABLE_END, DUMP_TEST_TABLE_SIZE); + + rc = mm_linear_map( + reinterpret_cast(DUMP_TEST_SRC_MEM_ADDR), + + DUMP_TEST_SRC_MEM_SIZE+DUMP_TEST_DST_MEM_SIZE+DUMP_TEST_RESULTS_MEM_SIZE); + + if (rc != 0) + { + TRACFCOMP( g_trac_runtime, "Failure calling mm_linear_map : rc=%d", rc ); + /*@ + * @errortype + * @moduleid RUNTIME::MOD_HDATSERVICE_LOAD_HOST_DATA + * @reasoncode RUNTIME::RC_CANNOT_MAP_MEMORY3 + * @userdata1 Starting Address + * @userdata2 Size + * @devdesc Error mapping in standalone DUMP memory + */ + errhdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + RUNTIME::MOD_HDATSERVICE_LOAD_HOST_DATA, + RUNTIME::RC_CANNOT_MAP_MEMORY3, + DUMP_TEST_SRC_MEM_ADDR, + DUMP_TEST_TABLE_SIZE); + errhdl->collectTrace("RUNTIME",1024); + break; } + } else { diff --git a/src/usr/runtime/test/hdatservicetest.H b/src/usr/runtime/test/hdatservicetest.H index 8d5dd72de..3b59651f0 100644 --- a/src/usr/runtime/test/hdatservicetest.H +++ b/src/usr/runtime/test/hdatservicetest.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ @@ -200,103 +200,106 @@ class HdatServiceTest: public CxxTest::TestSuite 0, dump_addr, dump_size ); - if( errhdl && (payload_kind == TARGETING::PAYLOAD_KIND_PHYP) ) + + if( errhdl + && ((payload_kind == TARGETING::PAYLOAD_KIND_PHYP) + || (payload_kind == TARGETING::PAYLOAD_KIND_NONE))) { - if( errhdl ) - { - TS_FAIL("testHdat> Error trying to locate MS_DUMP_SRC_TBL"); - errlCommit(errhdl,RUNTIME_COMP_ID); - } - else if( dump_addr == 0 ) - { - TS_FAIL("testHdat> NULL returned for get_host_data_section(MS_DUMP_SRC_TBL)"); - } - else if( dump_size < 16 ) //1 entry is 16 bytes - { - TRACFCOMP( g_trac_runtime, "testHdat> dump_size=%d", dump_size ); - TS_FAIL("testHdat> Size of MS_DUMP_SRC_TBL data too small"); - } + TS_FAIL("testHdat> Error trying to locate MS_DUMP_SRC_TBL"); + errlCommit(errhdl,RUNTIME_COMP_ID); } - else + else if( !errhdl + && (payload_kind != TARGETING::PAYLOAD_KIND_PHYP) + && (payload_kind != TARGETING::PAYLOAD_KIND_NONE) ) { - if( !errhdl ) - { - TS_FAIL("testHdat> Did not get expected error trying to locate MS_DUMP_SRC_TBL for non-PHYP Payload"); - } - else - { - delete errhdl; - } + TS_FAIL("testHdat> Did not get expected error trying to locate MS_DUMP_SRC_TBL for non-PHYP/Standalone Payload"); + } + else if( ((dump_addr == 0) || (dump_size < 16)) + && (payload_kind != TARGETING::PAYLOAD_KIND_PHYP) + && (payload_kind != TARGETING::PAYLOAD_KIND_NONE) ) + { + TS_FAIL("testHdat> NULL or zero size returned for get_host_data_section(MS_DUMP_SRC_TBL)"); + } + else if( (dump_size <16) + || (dump_size == RUNTIME::DATA_SIZE_UNKNOWN) ) + { + TS_FAIL("testHdat> Size of MS_DUMP_SRC_TBL is unexpected"); + } + if( errhdl ) + { + delete errhdl; } + errhdl = RUNTIME::get_host_data_section( RUNTIME::MS_DUMP_DST_TBL, 0, dump_addr, dump_size ); - if( errhdl && (payload_kind == TARGETING::PAYLOAD_KIND_PHYP) ) + if( errhdl + && ((payload_kind == TARGETING::PAYLOAD_KIND_PHYP) + || (payload_kind == TARGETING::PAYLOAD_KIND_NONE)) ) { - if( errhdl ) - { - TS_FAIL("testHdat> Error trying to locate MS_DUMP_DST_TBL"); - errlCommit(errhdl,RUNTIME_COMP_ID); - } - else if( dump_addr == 0 ) - { - TS_FAIL("testHdat> NULL returned for get_host_data_section(MS_DUMP_DST_TBL)"); - } - else if( dump_size < 16 ) //1 entry is 16 bytes - { - TRACFCOMP( g_trac_runtime, "testHdat> dump_size=%d", dump_size ); - TS_FAIL("testHdat> Size of MS_DUMP_DST_TBL data too small"); - } + TS_FAIL("testHdat> Error trying to locate MS_DUMP_DST_TBL"); + errlCommit(errhdl,RUNTIME_COMP_ID); } - else + else if( !errhdl + && (payload_kind != TARGETING::PAYLOAD_KIND_PHYP) + && (payload_kind != TARGETING::PAYLOAD_KIND_NONE) ) { - if( !errhdl ) - { - TS_FAIL("testHdat> Did not get expected error trying to locate MS_DUMP_DST_TBL for non-PHYP Payload"); - } - else - { - delete errhdl; - } + TS_FAIL("testHdat> Did not get expected error trying to locate MS_DUMP_DST_TBL for non-PHYP/Standalone Payload"); } + else if( ((dump_addr == 0) || (dump_size < 16)) + && (payload_kind != TARGETING::PAYLOAD_KIND_PHYP) + && (payload_kind != TARGETING::PAYLOAD_KIND_NONE) ) + { + TS_FAIL("testHdat> NULL or zero size returned for get_host_data_section(MS_DUMP_DST_TBL)"); + } + else if( (dump_size <16) + || (dump_size == RUNTIME::DATA_SIZE_UNKNOWN) ) + { + TS_FAIL("testHdat> Size of MS_DUMP_DST_TBL is unexpected"); + } + if( errhdl ) + { + delete errhdl; + } + errhdl = RUNTIME::get_host_data_section( RUNTIME::MS_DUMP_RESULTS_TBL, 0, dump_addr, dump_size ); - if( errhdl && (payload_kind == TARGETING::PAYLOAD_KIND_PHYP) ) + + if( errhdl + && ((payload_kind == TARGETING::PAYLOAD_KIND_PHYP) + || (payload_kind == TARGETING::PAYLOAD_KIND_NONE)) ) { - if( errhdl ) - { - TS_FAIL("testHdat> Error trying to locate MS_DUMP_RESULTS_TBL"); - errlCommit(errhdl,RUNTIME_COMP_ID); - } - else if( dump_addr == 0 ) - { - TS_FAIL("testHdat> NULL returned for get_host_data_section(MS_DUMP_RESULTS_TBL)"); - } - else if( dump_size < 16 ) //1 entry is 16 bytes - { - TRACFCOMP( g_trac_runtime, "testHdat> dump_size=%d", dump_size ); - TS_FAIL("testHdat> Size of MS_DUMP_RESULTS_TBL data too small"); - } + TS_FAIL("testHdat> Error trying to locate MS_DUMP_SRC_TBL"); + errlCommit(errhdl,RUNTIME_COMP_ID); } - else + else if( !errhdl + && (payload_kind != TARGETING::PAYLOAD_KIND_PHYP) + && (payload_kind != TARGETING::PAYLOAD_KIND_NONE) ) { - if( !errhdl ) - { - TS_FAIL("testHdat> Did not get expected error trying to locate MS_DUMP_RESULTS_TBL for non-PHYP Payload"); - } - else - { - delete errhdl; - } + TS_FAIL("testHdat> Did not get expected error trying to locate MS_DUMP_RESULTS_TBL for non-PHYP/Standalone Payload"); + } + else if( ((dump_addr == 0) || (dump_size < 16)) + && (payload_kind != TARGETING::PAYLOAD_KIND_PHYP) + && (payload_kind != TARGETING::PAYLOAD_KIND_NONE) ) + { + TS_FAIL("testHdat> NULL or zero size returned for get_host_data_section(MS_DUMP_RESULTS_TBL)"); + } + else if( (dump_size <16) + || (dump_size == RUNTIME::DATA_SIZE_UNKNOWN) ) + { + TS_FAIL("testHdat> Size of MS_DUMP_RESULTS_TBL is unexpected"); + } + if( errhdl ) + { + delete errhdl; } - TRACFCOMP( g_trac_runtime, "testHdat> finish" ); } -- cgit v1.2.1