diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2013-07-16 15:29:15 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-09-17 16:45:31 -0500 |
commit | 5652d7c0c6a8db05699f2b4334e4615e1ba22127 (patch) | |
tree | a04321010213943bc44a908a0de0e88149a7e7de /src/usr/testcore/rtloader | |
parent | 7c3226b7ef2b3e09bd40823732f05fbf0fe6778f (diff) | |
download | talos-hostboot-5652d7c0c6a8db05699f2b4334e4615e1ba22127.tar.gz talos-hostboot-5652d7c0c6a8db05699f2b4334e4615e1ba22127.zip |
Initial Hostboot Runtime image support.
RTC: 76675
Change-Id: Ibd21cf5b555e6dcee182a2f1a292b47d4f384ba0
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/6127
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/testcore/rtloader')
-rw-r--r-- | src/usr/testcore/rtloader/loader.H | 164 | ||||
-rw-r--r-- | src/usr/testcore/rtloader/makefile | 28 |
2 files changed, 192 insertions, 0 deletions
diff --git a/src/usr/testcore/rtloader/loader.H b/src/usr/testcore/rtloader/loader.H new file mode 100644 index 000000000..9b17fcea5 --- /dev/null +++ b/src/usr/testcore/rtloader/loader.H @@ -0,0 +1,164 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/testcore/rtloader/loader.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 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 __TESTCORE_RTLOADER_LOADER_H +#define __TESTCORE_RTLOADER_LOADER_H + +#include <pnor/pnorif.H> +#include <util/align.H> +#include <sys/mm.h> + +#include <runtime/interface.h> + +class RuntimeLoaderTest : public CxxTest::TestSuite +{ + public: + void testLoader() + { + static const uint64_t HEADER_OFFSET = 0x2000; + + PNOR::SectionInfo_t runtimeSection; + + errlHndl_t l_errl = + PNOR::getSectionInfo(PNOR::HB_RUNTIME, PNOR::CURRENT_SIDE, + runtimeSection); + + if (l_errl) + { + TS_WARN("Could not find runtime section."); + delete l_errl; + return; + } + + if (runtimeSection.size < HEADER_OFFSET) + { + TS_FAIL("Runtime image is not big enough. %x", + runtimeSection.size); + return; + } + + uint64_t imageSize = + *reinterpret_cast<uint64_t*>(runtimeSection.vaddr + + HEADER_OFFSET); + if (runtimeSection.size < imageSize + sizeof(uint64_t)) + { + TS_FAIL("Image header has too big a size: %x, %x", + runtimeSection.size, imageSize); + return; + } + + uint64_t relocations = + *reinterpret_cast<uint64_t*>(runtimeSection.vaddr + imageSize); + imageSize += (relocations + 1) * sizeof(uint64_t); + + if (runtimeSection.size < imageSize) + { + TS_FAIL("Image header + relocations is too big: %x, %x, %d", + runtimeSection.size, imageSize, relocations); + return; + } + + void* imageArea = malloc(ALIGN_PAGE(imageSize)); + memcpy(imageArea, reinterpret_cast<void*>(runtimeSection.vaddr), + imageSize); + mm_icache_invalidate(imageArea, + ALIGN_PAGE(imageSize) / sizeof(uint64_t)); + + + mm_set_permission(imageArea, HEADER_OFFSET, EXECUTABLE); + + TRACFCOMP(g_trac_test, "Runtime image loaded @ %x", imageArea); + + do + { + hostInterfaces_t* intf = new hostInterfaces_t(); + intf->puts = rt_puts; + intf->set_page_execute = rt_setPageExecute; + intf->malloc = malloc; + intf->free = free; + intf->realloc = realloc; + intf->assert = rt_assert; + + // Call init. + runtimeInterfaces_t* rtInterface = + reinterpret_cast<runtimeInterfaces_t*>( + callViaCtr( + reinterpret_cast<uint64_t>(imageArea) + 0x100, + intf, NULL) + ); + if (NULL == rtInterface) + { + TS_FAIL("Failed to init runtime services."); + break; + } + + { + using namespace CxxTest; + + // Initialize statistics structure. + CxxTestStats cxxTestStats = + { &g_TotalTests, &g_TraceCalls, &g_Warnings, + &g_FailedTests, &g_ModulesStarted, + &g_ModulesCompleted }; + + // Call CxxTest entry. + (*rtInterface->cxxtestExecute)(&cxxTestStats); + } + + } while(0); + + mm_set_permission(imageArea, imageSize, WRITABLE); + free(imageArea); + } + + private: + uint64_t callViaCtr(uint64_t entry, void* param0, void* param1) + { + register uint64_t result = 0; + + asm volatile("mtctr %1; mr 3, %2 ; mr 4, %3; " + "std 2, 40(1); bctrl; ld 2, 40(1); " + "mr %0, 3" : + "=r" (result) : "r" (entry), "r" (param0), "r" (param1) : + "lr","ctr","r0","r3","r4","r5","r6","r7","r8","r9", + "r10","r11"); // TODO: Need to double check the ABI here. + + return result; + } + + static void rt_puts(const char* str) + { + TRACFCOMP(g_trac_test, "RUNTIME MSG: %s", str); + } + + static int rt_setPageExecute(void* addr) + { + return mm_set_permission(addr, PAGESIZE, EXECUTABLE); + } + + static void rt_assert() + { + assert(false); + } +}; + +#endif diff --git a/src/usr/testcore/rtloader/makefile b/src/usr/testcore/rtloader/makefile new file mode 100644 index 000000000..0fcd01d42 --- /dev/null +++ b/src/usr/testcore/rtloader/makefile @@ -0,0 +1,28 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/testcore/rtloader/makefile $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2011,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 = testrtloader +TESTS = *.H + +include ${ROOTPATH}/config.mk |