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/runtime/makefile | 29 +++++++++++ src/runtime/rt_assert.C | 41 ++++++++++++++++ src/runtime/rt_console.C | 39 +++++++++++++++ src/runtime/rt_main.C | 123 ++++++++++++++++++++++++++++++++++++++++++++++ src/runtime/rt_start.S | 72 +++++++++++++++++++++++++++ src/runtime/rt_stdlib.C | 56 +++++++++++++++++++++ src/runtime/rt_sync.C | 29 +++++++++++ src/runtime/rt_vfs.C | 125 +++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 514 insertions(+) create mode 100644 src/runtime/makefile create mode 100644 src/runtime/rt_assert.C create mode 100644 src/runtime/rt_console.C create mode 100644 src/runtime/rt_main.C create mode 100644 src/runtime/rt_start.S create mode 100644 src/runtime/rt_stdlib.C create mode 100644 src/runtime/rt_sync.C create mode 100644 src/runtime/rt_vfs.C (limited to 'src/runtime') diff --git a/src/runtime/makefile b/src/runtime/makefile new file mode 100644 index 000000000..06ea1d3bc --- /dev/null +++ b/src/runtime/makefile @@ -0,0 +1,29 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/runtime/makefile $ +# +# 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 +HOSTBOOT_RUNTIME = 1 +ROOTPATH = ../.. + +OBJS = rt_start.o rt_main.o rt_console.o rt_stdlib.o rt_sync.o rt_assert.o \ + rt_vfs.o + +include ${ROOTPATH}/config.mk diff --git a/src/runtime/rt_assert.C b/src/runtime/rt_assert.C new file mode 100644 index 000000000..9821a0fad --- /dev/null +++ b/src/runtime/rt_assert.C @@ -0,0 +1,41 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/runtime/rt_assert.C $ */ +/* */ +/* 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 */ +#include +#include +#include +#include + +/** Hook location for trace module to set up when loaded. */ +namespace TRACE { void (*traceCallback)(void*, size_t) = NULL; }; + +extern "C" void __assert(AssertBehavior i_assertb, int i_line) +{ + if (i_assertb != ASSERT_TRACE_DONE) + { + printk("Assertion failed @%p on line %d.\n", + linkRegister(), i_line); + } + + g_hostInterfaces->assert(); + while(1); +} diff --git a/src/runtime/rt_console.C b/src/runtime/rt_console.C new file mode 100644 index 000000000..930e37462 --- /dev/null +++ b/src/runtime/rt_console.C @@ -0,0 +1,39 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/runtime/rt_console.C $ */ +/* */ +/* 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 */ +#include +#include +#include +#include + +void printk(const char* str, ...) +{ + va_list args; + va_start(args, str); + + char buffer[512]; + vsprintf(buffer, str, args); + + va_end(args); + + g_hostInterfaces->puts(buffer); +} diff --git a/src/runtime/rt_main.C b/src/runtime/rt_main.C new file mode 100644 index 000000000..910a0d1d8 --- /dev/null +++ b/src/runtime/rt_main.C @@ -0,0 +1,123 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/runtime/rt_main.C $ */ +/* */ +/* 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 */ +#include +#include +#include +#include +#include +#include + +// Address of the first writable page, initialized by the linker. +extern void* data_load_address; +// Forward declaration to vfs code. +void vfs_module_init(); + + +/** @fn _main + * + * @brief Entry point called from Sapphire to initialize RT image. + * + * @param[in] intf - Runtime interfaces structure from Sapphire. + * @param[in] base - Memory address of the start of the RT image. + * + * @return - runtimeInterfaces_t* - Pointer to RT image's interfaces. + * + * This function is required to be in the .text.intvects section so that + * it is placed into the first page (4k) of the image. When HB IPL + * loads the RT image for CxxTest execution it will only mark the first + * page executable. The remainder is marked execute via callbacks from + * within _main. + */ +extern "C" +{ + runtimeInterfaces_t* _main(hostInterfaces_t*, uint64_t base) + SYMB_SECTION(".text.intvects"); +} + +/** @fn rt_start + * + * @brief Remainder of RT image initializion. + * + * After _main marks pages executable we can leave the first page of the + * image. This function performs the bulk of the initialization: + * + * 1) Call C++ constructors for this image. + * 2) Load all modules in the image. + * + * @param[in] intf - Runtime interfaces structure from Sapphire. + */ +runtimeInterfaces_t* rt_start(hostInterfaces_t*) NEVER_INLINE; + +/** Call C++ constructors present in this image. */ +void rt_cppBootstrap(); + +runtimeInterfaces_t* _main(hostInterfaces_t* intf, uint64_t base) +{ + // Ensure remainder of image has text pages marked execute. + for (uint64_t i = base; + i < ALIGN_PAGE_DOWN((uint64_t)&data_load_address); + i += PAGESIZE) + { + (intf->set_page_execute)(reinterpret_cast(i)); + } + + // Tail-recurse to real entry point. + return rt_start(intf); +} + +runtimeInterfaces_t* rt_start(hostInterfaces_t* intf) +{ + (intf->puts)("Starting Runtime Services....\n"); + + // Save a pointer to interfaces from Sapphire. + g_hostInterfaces = intf; + + // Call C++ constructors. + rt_cppBootstrap(); + + // Initialize all modules. + vfs_module_init(); + + // Return our interface pointer structure. + return getRuntimeInterfaces(); +} + +void rt_cppBootstrap() +{ + // Call default constructors for any static objects. + extern void (*ctor_start_address)(); + extern void (*ctor_end_address)(); + void(**ctors)() = &ctor_start_address; + while(ctors != &ctor_end_address) + { + (*ctors)(); + ctors++; + } +} + +hostInterfaces_t* g_hostInterfaces = NULL; + +runtimeInterfaces_t* getRuntimeInterfaces() +{ + return &Singleton::instance(); +} diff --git a/src/runtime/rt_start.S b/src/runtime/rt_start.S new file mode 100644 index 000000000..cea710b57 --- /dev/null +++ b/src/runtime/rt_start.S @@ -0,0 +1,72 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/runtime/rt_start.S $ +# +# 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 +.include "kernel/ppcconsts.S" + +.section .text.intvects + +.org 0x100; +_init: + mflr r10 # Save LR + bl 1f # Get current address by branch-with-link. +1: + mflr r4 # Extract current address. + mtlr r10 # Restore LR. + clrrdi r4, r4, 12 # Align address to 4k. + + addi r10, r4, 0x2000 # Find VFS_LAST_ADDRESS symbol. + ld r10, 0(r10) # Read start of relocation table. + add r10, r10, r4 + + ld r8, 0(r10) # Get count of relocations. + + cmpi cr0, r8, 0 # Perform relocations (if any). + beq 2f + mtctr r8 +1: + ldu r8, 8(r10) # Get relocation destination + add r8, r8, r4 + ld r7, 0(r8) # Get relocation address + add r7, r7, r4 + std r7, 0(r8) # Update relocation address. + bdnz 1b # Decrement CTR and continue loop. +2: + addi r10, r4, 0x2008 # Find pointer to main TOC. + ld r10, 0(r10) # Dereference pointer to get TOC entry. + ld r2, 8(r10) + ld r10, 0(r10) + mtctr r10 + bctr + +.section .text.kernelasm # @2000 +.global VFS_LAST_ADDRESS +VFS_LAST_ADDRESS: + .space 8 +main_toc_ptr: + .quad _main + + +.section .data + +.global hbi_ImageId +hbi_ImageId: + .space 128 diff --git a/src/runtime/rt_stdlib.C b/src/runtime/rt_stdlib.C new file mode 100644 index 000000000..ec92badc6 --- /dev/null +++ b/src/runtime/rt_stdlib.C @@ -0,0 +1,56 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/runtime/rt_stdlib.C $ */ +/* */ +/* 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 */ +#include +#include +#include + +void* malloc(size_t s) +{ + return g_hostInterfaces->malloc(s); +} + +void free(void* p) +{ + g_hostInterfaces->free(p); +} + +void* realloc(void* p, size_t s) +{ + return g_hostInterfaces->realloc(p, s); +} + +void* calloc(size_t num, size_t size) +{ + // Allocate a block of memory for an array of 'num' elements, each of them + // 'size' bytes long and initialize to zero + size_t total_size = num * size; + void* mem = NULL; + + if (total_size) + { + mem = malloc(total_size); + memset(mem, 0, total_size); + } + + return mem; +} diff --git a/src/runtime/rt_sync.C b/src/runtime/rt_sync.C new file mode 100644 index 000000000..037bdaa25 --- /dev/null +++ b/src/runtime/rt_sync.C @@ -0,0 +1,29 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/runtime/rt_sync.C $ */ +/* */ +/* 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 */ +#include + +void mutex_init(mutex_t*) {}; +void mutex_destroy(mutex_t*) {}; +void mutex_lock(mutex_t*) {}; +void mutex_unlock(mutex_t*) {}; + diff --git a/src/runtime/rt_vfs.C b/src/runtime/rt_vfs.C new file mode 100644 index 000000000..7558f222c --- /dev/null +++ b/src/runtime/rt_vfs.C @@ -0,0 +1,125 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/runtime/rt_vfs.C $ */ +/* */ +/* 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 */ +#include +#include +#include +#include +#include +#include +#include + +VfsSystemModule VFS_MODULES[VFS_MODULE_MAX]; + +void vfs_module_init() +{ + printk("Initializing modules.\n"); + + VfsSystemModule* module = &VFS_MODULES[0]; + while ('\0' != module->module[0]) + { + uint64_t textsize = (uint64_t)module->data - (uint64_t)module->text; + if (textsize != 0) + { + for (uint64_t i = (uint64_t)module->text; + i < (uint64_t)module->data; + i += PAGESIZE) + { + g_hostInterfaces->set_page_execute(reinterpret_cast(i)); + } + } + + ++module; + } + + module = &VFS_MODULES[0]; + while ('\0' != module->module[0]) + { + printk("\tIniting module %s...", module->module); + if (NULL != module->init) + { + (module->init)(NULL); + } + printk("done.\n"); + + ++module; + } + + printk("Modules initialized.\n"); + +} + +VfsSystemModule * vfs_find_module(VfsSystemModule * i_table, + const char * i_name) +{ + VfsSystemModule* module = i_table; + VfsSystemModule* ret = NULL; + while ('\0' != module->module[0]) + { + if (0 == strcmp(i_name,module->module)) + { + ret = module; + break; + } + module++; + } + return ret; +} + +void* vfs_start_entrypoint(VfsSystemModule * i_module) +{ + void* ptr = reinterpret_cast(-ENOENT); + if(i_module != NULL) + { + if (i_module->start == NULL) + { + // module has no start() routine + ptr = reinterpret_cast(-ENOEXEC); + } + else + { + ptr = reinterpret_cast(i_module->start); + } + } + return ptr; +} + +namespace VFS +{ + void find_test_modules(std::vector & o_list) + { + o_list.clear(); + + for(VfsSystemModule* vfsItr = &VFS_MODULES[0]; + '\0' != vfsItr->module[0]; + vfsItr++) + { + if (0 == memcmp(vfsItr->module, "libtest", 7)) + { + if (NULL != vfsItr->start) + { + o_list.push_back(vfsItr->module); + } + } + } + } +} -- cgit v1.2.1