From 5652d7c0c6a8db05699f2b4334e4615e1ba22127 Mon Sep 17 00:00:00 2001 From: Patrick Williams Date: Tue, 16 Jul 2013 15:29:15 -0500 Subject: 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 --- src/usr/testcore/rtloader/loader.H | 164 +++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 src/usr/testcore/rtloader/loader.H (limited to 'src/usr/testcore/rtloader/loader.H') 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 +#include +#include + +#include + +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(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(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(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( + callViaCtr( + reinterpret_cast(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 -- cgit v1.2.1