diff options
-rw-r--r-- | src/include/kernel/basesegment.H | 109 | ||||
-rw-r--r-- | src/include/kernel/block.H | 69 | ||||
-rw-r--r-- | src/include/kernel/pagemgr.H | 56 | ||||
-rw-r--r-- | src/include/kernel/syscalls.H | 6 | ||||
-rw-r--r-- | src/include/kernel/vmmmgr.H | 22 | ||||
-rw-r--r-- | src/include/sys/mm.h | 17 | ||||
-rw-r--r-- | src/include/usr/hwpf/plat/fapiPlatReasonCodes.H | 2 | ||||
-rw-r--r-- | src/include/usr/vmmconst.h | 60 | ||||
-rw-r--r-- | src/kernel/basesegment.C | 143 | ||||
-rw-r--r-- | src/kernel/block.C | 26 | ||||
-rw-r--r-- | src/kernel/pagemgr.C | 19 | ||||
-rw-r--r-- | src/kernel/syscall.C | 28 | ||||
-rw-r--r-- | src/kernel/vmmmgr.C | 29 | ||||
-rw-r--r-- | src/lib/syscall_mm.C | 20 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/dram_initialization/dram_initialization.C | 35 | ||||
-rw-r--r-- | src/usr/testcore/kernel/segmenttest.H | 90 |
16 files changed, 586 insertions, 145 deletions
diff --git a/src/include/kernel/basesegment.H b/src/include/kernel/basesegment.H index 293b24f1c..f9761ce2d 100644 --- a/src/include/kernel/basesegment.H +++ b/src/include/kernel/basesegment.H @@ -1,25 +1,25 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/include/kernel/basesegment.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/kernel/basesegment.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ /** @file basesegment.H * @brief Defines the base segment (0TB) class. */ @@ -83,10 +83,17 @@ class BaseSegment : public Segment * @param i_va[in] - Page aligned base virtual address of the block * to be allocated * @param i_size[in] - Requested virtual memory size of the block + * @param i_mappedToPhy[in] - bool value assigned to the block to + * determine if this blocked is mapped directly to a physical + * address + * DEFAULT - FALSE + * @param i_SPTEaddr[in] - address of where the SPTE should be put. + * DEFAULT = NULL (no specific address) * @return int - 0 for successful block allocation, non-zero otherwise */ - static int mmAllocBlock(MessageQueue* i_mq,void* i_va, - uint64_t i_size); + static int mmAllocBlock(MessageQueue* i_mq,void* i_va,uint64_t i_size, + bool iv_mappedToPhy = false, + uint64_t *i_SPTEaddr = NULL ); /** * @brief Locate the physical address of the given virtual address @@ -119,11 +126,28 @@ class BaseSegment : public Segment static int mmSetPermission(void* i_va, uint64_t i_size, uint64_t i_access_type); - /** - * @breif Cast out older physical memory pages - * @param[in] castout Constraint - */ - virtual void castOutPages(uint64_t i_type); + /** + * @brief Cast out older physical memory pages + * @param[in] castout Constraint + */ + virtual void castOutPages(uint64_t i_type); + + /** + * @brief Allocates a block of virtual memory that extends the VMM + * space upto 32MEG of Mainstore. + */ + static int mmExtend(void); + + /** + * @brief Allocates a block of memory of the given size to at a + * specified physical address. + * @param i_paddr[in] - physical address of the location of the block of + * memory + * @param i_size[in] - range of memory being created + * @return int - 0 for successful block allocation, non-zero otherwise + */ + static int mmLinearMap(void *i_paddr, uint64_t i_size); + private: /** @@ -142,9 +166,17 @@ class BaseSegment : public Segment * @param i_mq[in] - Message queue to be associated with the block * @param i_va[in] - Base virtual address of the block to be allocated * @param i_size[in] - Requested virtual memory size of the block + * @param i_mappedToPhy[in] - bool value assigned to the block to + * determine if this blocked is mapped directly to a physical + * address + * DEFAULT - FALSE + * @param i_SPTEaddr[in] - address of where the SPTE should be put. + * DEFAULT = NULL (no specific address) * @return int - 0 for successful block allocation, non-zero otherwise */ - int _mmAllocBlock(MessageQueue* i_mq,void* i_va,uint64_t i_size); + int _mmAllocBlock(MessageQueue* i_mq,void* i_va,uint64_t i_size, + bool iv_mappedToPhy = false, + uint64_t *i_SPTEaddr = NULL); /** * @brief Sets the page permissions for a given virtual address and size. @@ -170,6 +202,23 @@ class BaseSegment : public Segment int _mmRemovePages(VmmManager::PAGE_REMOVAL_OPS i_op, void* i_vaddr, uint64_t i_size, task_t* i_task); + /** + * @brief Allocates a block of virtual memory that extends the VMM + * space upto 32MEG of Mainstore. + */ + int _mmExtend(void); + + /** + * @brief Allocates a block of memory of the given size to at a + * specified physical address. + * @param i_paddr[in] - physical address of the location of the block of + * memory + * @param i_size[in] - range of memory being created + * @return int - 0 for successful block allocation, non-zero otherwise + */ + int _mmLinearMap(void* i_paddr, uint64_t i_size); + + }; #endif diff --git a/src/include/kernel/block.H b/src/include/kernel/block.H index 5d80ea7c6..403daec83 100644 --- a/src/include/kernel/block.H +++ b/src/include/kernel/block.H @@ -1,25 +1,25 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/include/kernel/block.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/kernel/block.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ /** @file block.H * @brief Defines the implementation for the generic VMM block class. */ @@ -65,15 +65,23 @@ class Block * @param[in] i_size - Size of the block (in bytes). * @param[in] i_msgQueue - Message queue passed along to the handler * Default: NULL + * @param[in] i_mappedToPhy - boolean value indicating whether this + * block is a mapped to physical block. + * Default: false + * @param[in] i_spteAddr - address that the SPTE will be created + * at if a specific location is required. + * Default: NULL * * Will allocate enough shadow PTEs to track pages in the block. */ Block(uint64_t i_baseAddr, uint64_t i_size, - MessageQueue* i_msgQueue = NULL) : - iv_baseAddr(i_baseAddr), iv_size(i_size), - iv_parent(NULL), iv_nextBlock(NULL), iv_ptes(NULL), - iv_readMsgHdlr(NULL), iv_writeMsgHdlr(NULL) - { init(i_msgQueue); }; + MessageQueue* i_msgQueue = NULL, bool i_mappedToPhy = false, + uint64_t *i_spteAddr = NULL) : iv_baseAddr(i_baseAddr), + iv_size(i_size),iv_parent(NULL), iv_nextBlock(NULL), + iv_ptes(NULL), iv_readMsgHdlr(NULL),iv_writeMsgHdlr(NULL), + iv_mappedToPhysical(i_mappedToPhy) + {init(i_msgQueue, i_spteAddr);}; + /** * @brief Destructor. @@ -298,10 +306,15 @@ class Block static uint32_t cv_ro_evict_req; //!< memstat ro eviction requests static uint32_t cv_rw_evict_req; //!< memstat rw eviction requests + + bool iv_mappedToPhysical; /** * @brief Finish initialization of block. * * @param[in] i_msgQ - The message queue associated with this block + * @param[in] i_spteAddr - address that the SPTE will be created + * at if a specific address is required. + * Default: NULL * * Construct ShadowPTE entries. * @@ -310,7 +323,7 @@ class Block * "not-in-charge" version of each constructor, so put as much * common code into an init function. */ - void init(MessageQueue* i_msgQ); + void init(MessageQueue* i_msgQ, uint64_t *i_spteAddr); /** * @brief Find the Shadow PTE for a virtual address. diff --git a/src/include/kernel/pagemgr.H b/src/include/kernel/pagemgr.H index 93cd82bb5..ad94d0522 100644 --- a/src/include/kernel/pagemgr.H +++ b/src/include/kernel/pagemgr.H @@ -1,26 +1,25 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/include/kernel/pagemgr.H $ - * - * IBM CONFIDENTIAL - * - * COPYRIGHT International Business Machines Corp. 2010-2012 - * - * p1 - * - * Object Code Only (OCO) source materials - * Licensed Internal Code Source Materials - * IBM HostBoot Licensed Internal Code - * - * The source code for this program is not published or other- - * wise divested of its trade secrets, irrespective of what has - * been deposited with the U.S. Copyright Office. - * - * Origin: 30 - * - * IBM_PROLOG_END_TAG - */ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/kernel/pagemgr.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2010,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or 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 __KERNEL_PAGEMGR_H #define __KERNEL_PAGEMGR_H @@ -167,6 +166,14 @@ class PageManager */ static uint64_t availPages(); + /** + * Add memory to the page manager + * @param[in] i_addr, The start address of the memory to add + * @param[in] i_pageCount, The number of pages to add + * @note i_addr must be on a page boundary + */ + static void addMemory(size_t i_addr, size_t i_pageCount); + enum { MEMLEN = VmmManager::MBOX_DMA_ADDR, @@ -186,9 +193,10 @@ class PageManager private: - void* _allocatePage(size_t,bool); //!< see allocatePage() + void* _allocatePage(size_t,bool); //!< see allocatePage() void _freePage(void*, size_t); //!< see freePage() void _coalesce( void ); //!< see coalesce() + void _addMemory(size_t, size_t); //!< see addMemory() /** see queryAvail() */ ALWAYS_INLINE uint64_t _queryAvail() const diff --git a/src/include/kernel/syscalls.H b/src/include/kernel/syscalls.H index f31526868..2a3ba6095 100644 --- a/src/include/kernel/syscalls.H +++ b/src/include/kernel/syscalls.H @@ -110,6 +110,12 @@ namespace Systemcalls /** mm_virt_to_phys() */ MM_VIRT_TO_PHYS, + /** mm_extend() */ + MM_EXTEND, + + /** mm_linear_map() */ + MM_LINEAR_MAP, + SYSCALL_MAX }; diff --git a/src/include/kernel/vmmmgr.H b/src/include/kernel/vmmmgr.H index 0c11ffeb8..7b8bd07bc 100644 --- a/src/include/kernel/vmmmgr.H +++ b/src/include/kernel/vmmmgr.H @@ -185,6 +185,22 @@ class VmmManager */ static uint64_t findKernelAddress(uint64_t i_vaddr); + /** + * @brief Allocates a block of virtual memory that extends the VMM + * space upto 32MEG of Mainstore. + */ + static int mmExtend( void); + + /** @fn mm_linear_map() + * @brief Allocates a block of memory of the given size + * to at a specified address (direct pa to va mapping) + * @param[in] i_paddr - physical address of the location for the block + * @param[in] i_size - size of the block requested + * + * @return int - 0 for successful add, non-zero otherwise + */ + static int mmLinearMap(void *i_paddr, uint64_t i_size); + protected: VmmManager(); ~VmmManager() {}; @@ -223,11 +239,17 @@ class VmmManager int _mmRemovePages(VmmManager::PAGE_REMOVAL_OPS i_op,void* i_vaddr, uint64_t i_size,task_t* i_task); + /** See mmExtend */ + int _mmExtend( void ); + /** See devMap */ void* _devMap(void* ra, uint64_t i_devDataSize); /** See devUnmap */ int _devUnmap(void* ea); + /** See mmLinearMap */ + int _mmLinearMap(void*, uint64_t); + public: friend class Block; friend class StackSegment; diff --git a/src/include/sys/mm.h b/src/include/sys/mm.h index 82e32bf46..34a60fc20 100644 --- a/src/include/sys/mm.h +++ b/src/include/sys/mm.h @@ -96,6 +96,23 @@ int mm_remove_pages(PAGE_REMOVAL_OPS i_op, void* i_vaddr, uint64_t i_size); */ int mm_set_permission(void* va, uint64_t size, uint64_t access_type); +/** @fn mm_extend() + * @brief System call to extend Memory to 32MEG + * + * @return int - 0 for successful extension of memory, non-zero otherwise + */ +int mm_extend(void); + +/** @fn mm_linear_map() + * @brief Allocates a block of memory of the given size at a specified + * address (direct physical to virtual mapping) + * @param[in] i_paddr - physical address of the location for the block + * @param[in] size - size of the block requested + * + * @return int - 0 for successful add, non-zero otherwise + */ +int mm_linear_map(void *i_paddr, uint64_t i_size); + #ifdef __cplusplus } #endif diff --git a/src/include/usr/hwpf/plat/fapiPlatReasonCodes.H b/src/include/usr/hwpf/plat/fapiPlatReasonCodes.H index 1de3d90b1..4ea439e17 100644 --- a/src/include/usr/hwpf/plat/fapiPlatReasonCodes.H +++ b/src/include/usr/hwpf/plat/fapiPlatReasonCodes.H @@ -76,6 +76,7 @@ namespace fapi MOD_ATTR_PROC_PCIE_BAR_BASE_ADDR_GET = 0x25, MOD_ATTR_PROC_PCIE_BAR_SIZE_GET = 0x26, MOD_MVPD_ACCESS = 0x27, + MOD_EXIT_CACHE_CONTAINED = 0x28, }; /** @@ -111,6 +112,7 @@ namespace fapi RC_ATTR_UNSUPPORTED_PROC_NUM = HWPF_COMP_ID | 0x22, RC_INVALID_RECORD = HWPF_COMP_ID | 0x23, RC_INVALID_KEYWORD = HWPF_COMP_ID | 0x24, + RC_MM_EXTEND_FAILED = HWPF_COMP_ID | 0x25, }; /** diff --git a/src/include/usr/vmmconst.h b/src/include/usr/vmmconst.h index 9c569289d..7a5250cce 100644 --- a/src/include/usr/vmmconst.h +++ b/src/include/usr/vmmconst.h @@ -1,26 +1,25 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/include/usr/vmmconst.h $ - * - * IBM CONFIDENTIAL - * - * COPYRIGHT International Business Machines Corp. 2011-2012 - * - * p1 - * - * Object Code Only (OCO) source materials - * Licensed Internal Code Source Materials - * IBM HostBoot Licensed Internal Code - * - * The source code for this program is not published or other- - * wise divested of its trade secrets, irrespective of what has - * been deposited with the U.S. Copyright Office. - * - * Origin: 30 - * - * IBM_PROLOG_END_TAG - */ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/vmmconst.h $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or 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 _VMMCONST_H #define _VMMCONST_H @@ -52,6 +51,21 @@ (VMM_VADDR_DEVICE_SEGMENT_FIRST + (8 * VMM_SEGMENT_SIZE)) /** + * Blocks + */ + +/** Base Segment Base Block Base Address */ +#define VMM_ADDR_BASE_BLOCK 0 + +/** Base Segment Base Block size */ +#define VMM_BASE_BLOCK_SIZE 8*MEGABYTE + +/** Base Segment Extended Memory Block Base Address */ +#define VMM_ADDR_EXTEND_BLOCK VMM_ADDR_BASE_BLOCK + VMM_BASE_BLOCK_SIZE + +/** Base Segment Extended Memory Block Size */ +#define VMM_EXTEND_BLOCK_SIZE (32*MEGABYTE)-VMM_BASE_BLOCK_SIZE +/** * Resource Providers */ diff --git a/src/kernel/basesegment.C b/src/kernel/basesegment.C index c9a826f8e..79cf7ada8 100644 --- a/src/kernel/basesegment.C +++ b/src/kernel/basesegment.C @@ -30,7 +30,8 @@ #include <kernel/block.H> #include <kernel/cpuid.H> #include <kernel/console.H> - +#include <kernel/pagemgr.H> +#include <kernel/spte.H> BaseSegment::~BaseSegment() { @@ -53,7 +54,7 @@ void BaseSegment::_init() case CORE_POWER8_MURANO: case CORE_POWER8_VENICE: default: - iv_physMemSize = (8*MEGABYTE); + iv_physMemSize = VMM_BASE_BLOCK_SIZE; break; } // Base block is L3 cache physical memory size @@ -63,10 +64,10 @@ void BaseSegment::_init() // TODO iv_physMemSize needs to be recalculated when DIMM memory is avail. // Set default page permissions on block. - for (uint64_t i = 0; i < 0x800000; i += PAGESIZE) + for (uint64_t i = 0; i < VMM_BASE_BLOCK_SIZE; i += PAGESIZE) { - // External address filled in by linker as start of kernel's - // data pages. + // External address filled in by linker as start of kernel's + // data pages. extern void* data_load_address; // Don't map in the 0 (NULL) page. @@ -97,15 +98,21 @@ bool BaseSegment::handlePageFault(task_t* i_task, uint64_t i_addr, bool i_store) * STATIC * Allocates a block of virtual memory of the given size */ -int BaseSegment::mmAllocBlock(MessageQueue* i_mq,void* i_va,uint64_t i_size) +int BaseSegment::mmAllocBlock(MessageQueue* i_mq,void* i_va,uint64_t i_size, + bool i_mappedToPhy, uint64_t *i_SPTEaddr) { - return Singleton<BaseSegment>::instance()._mmAllocBlock(i_mq,i_va,i_size); + return Singleton<BaseSegment>::instance()._mmAllocBlock(i_mq,i_va,i_size, + i_mappedToPhy, + i_SPTEaddr); + } /** * Allocates a block of virtual memory of the given size */ -int BaseSegment::_mmAllocBlock(MessageQueue* i_mq,void* i_va,uint64_t i_size) +int BaseSegment::_mmAllocBlock(MessageQueue* i_mq,void* i_va,uint64_t i_size, + bool i_mappedToPhy, uint64_t *i_SPTEaddr) + { uint64_t l_vaddr = reinterpret_cast<uint64_t>(i_va); uint64_t l_blockSizeTotal = 0; @@ -118,7 +125,26 @@ int BaseSegment::_mmAllocBlock(MessageQueue* i_mq,void* i_va,uint64_t i_size) { return -EINVAL; } - Block* l_block = new Block(l_vaddr, ALIGN_PAGE(i_size), i_mq); + + // Verify that the block we are adding is not already contained within + // another block in the base segment + Block* temp_block = iv_block; + while (temp_block != NULL) + { + // Checking to see if the l_vaddr is already contained in another + // block.. if so return error + if (temp_block->isContained(l_vaddr)) + { + printk("mmAllocBlock Address = %lx is already in a block\n",l_vaddr); + return -EINVAL; + } + + temp_block = temp_block->iv_nextBlock; + } + + Block* l_block = new Block(l_vaddr, ALIGN_PAGE(i_size), i_mq,i_mappedToPhy, + i_SPTEaddr ); + l_block->setParent(this); iv_block->appendBlock(l_block); return 0; @@ -191,3 +217,102 @@ int BaseSegment::_mmRemovePages(VmmManager::PAGE_REMOVAL_OPS i_op, iv_block->iv_nextBlock->removePages(i_op,i_vaddr,i_size,i_task): -EINVAL); } + + +/** + * STATIC + * Allocates a block of virtual memory to extend the VMM + */ +int BaseSegment::mmExtend(void) +{ + return Singleton<BaseSegment>::instance()._mmExtend(); +} + +/** + * Allocates a block of virtual memory of the given size + * to extend the VMM to 32MEG in size in mainstore + */ +int BaseSegment::_mmExtend(void) +{ + // The base address of the extended memory is 8Mg.. The first x pages is + // for the SPTE.. The remaining pages from 8MG + SPTE to 32MEG is added to + // the HEAP.. + + uint64_t l_vaddr = VMM_ADDR_EXTEND_BLOCK; // 8MEG + uint64_t l_size = VMM_EXTEND_BLOCK_SIZE; // 32MEG - 8MB (base block) + + // Call to allocate a block passing in the requested address of where the + // SPTEs should be created + int rc = _mmAllocBlock(NULL, reinterpret_cast<void *>(l_vaddr), l_size, false, + /*(uint64_t *)*/reinterpret_cast<uint64_t *>(l_vaddr)); + + if (rc) + { + printk("Got an error in mmAllocBlock\n"); + return rc; + } + + // Set default page permissions on block. + for (uint64_t i = l_vaddr; i < l_vaddr + l_size; i += PAGESIZE) + { + iv_block->setPhysicalPage(i, i, WRITABLE); + } + + // Now need to take the pages past the SPTE and add them to the heap. + + //get the number of pages needed to hold the SPTE entries. + uint64_t spte_pages = (ALIGN_PAGE(l_size)/PAGESIZE * sizeof(ShadowPTE))/PAGESIZE; + + printkd("Number of SPTE pages %ld\n", spte_pages); + + // Need to setup the starting address of the memory we need to add to the + // heap to be the address of the block + the number of pages that are being + // used for the SPTE. + + // Call Add Memory with the starting address , size.. it will put the pages + // on the heap call this with the address being the first page past the SPTE. + PageManager::addMemory(l_vaddr + (spte_pages*PAGESIZE), + l_size/PAGESIZE - spte_pages); + + // Update the physical Memory size to now be 32MEG. by adding the extended + // block size to the physical mem size. + iv_physMemSize += VMM_EXTEND_BLOCK_SIZE; + + return 0; +} + +/** + * Allocates a block of virtual memory of the given size + * to at a specified physical address. + */ +int BaseSegment::mmLinearMap(void *i_paddr, uint64_t i_size) +{ + return Singleton<BaseSegment>::instance()._mmLinearMap(i_paddr, i_size); +} + +/** + * Allocates a block of virtual memory of the given size + * to at a specified physical address + */ +int BaseSegment::_mmLinearMap(void *i_paddr, uint64_t i_size) +{ + + int rc = _mmAllocBlock(NULL, i_paddr, i_size, true); + + if (rc) + { + printk("Got an error in mmAllocBlock\n"); + return rc; + } + + uint64_t l_addr = reinterpret_cast<uint64_t>(i_paddr); + + // set the default permissions and the va-pa mapping in the SPTE + for (uint64_t i = l_addr; i < l_addr + i_size; i += PAGESIZE) + { + iv_block->setPhysicalPage(i, i, WRITABLE); + } + + return 0; + +} diff --git a/src/kernel/block.C b/src/kernel/block.C index 1ea12d2c0..c8546f760 100644 --- a/src/kernel/block.C +++ b/src/kernel/block.C @@ -39,6 +39,8 @@ #include <kernel/basesegment.H> #include <arch/ppc.H> +#include <new> + // Track eviction requests due to aging pages uint32_t Block::cv_ro_evict_req = 0; uint32_t Block::cv_rw_evict_req = 0; @@ -58,10 +60,21 @@ Block::~Block() } } -void Block::init(MessageQueue* i_msgQ) +void Block::init(MessageQueue* i_msgQ, uint64_t *i_spteAddr) { - // Create a shadow PTE for each page. - iv_ptes = new ShadowPTE[iv_size / PAGESIZE]; + + if (i_spteAddr == NULL) + { + // Create a shadow PTE for each page. + iv_ptes = new ShadowPTE[iv_size / PAGESIZE]; + } + else // set the page table to reside at the address requested + { + // Doing a placement new to put the SPTE at the beginging + // of the block we allocated. + iv_ptes = new(i_spteAddr) ShadowPTE[iv_size / PAGESIZE]; + } + if (i_msgQ != NULL) { //Create message handler to handle read operations for this block @@ -265,7 +278,12 @@ uint64_t Block::findPhysicalAddress(uint64_t i_vaddr) const { paddr = pte->getPageAddr(); paddr += i_vaddr % PAGESIZE; - paddr |= getHRMOR(); + + // If not a physically mapped block then add HRMOR + if (!iv_mappedToPhysical) + { + paddr |= getHRMOR(); + } } return paddr; diff --git a/src/kernel/pagemgr.C b/src/kernel/pagemgr.C index 4415cb81d..ca534efdd 100644 --- a/src/kernel/pagemgr.C +++ b/src/kernel/pagemgr.C @@ -388,3 +388,22 @@ void PageManagerCore::coalesce( void ) printkd("PAGEMGR low page count %ld\n", PageManager::cv_low_page_count); } +void PageManager::addMemory(size_t i_addr, size_t i_pageCount) +{ + PageManager& pmgr = Singleton<PageManager>::instance(); + return pmgr._addMemory(i_addr, i_pageCount); +} + +// add memory to the heap +void PageManager::_addMemory(size_t i_addr, size_t i_pageCount) +{ + iv_heap.addMemory(i_addr,i_pageCount); + + // Update statistics. + __sync_add_and_fetch(&iv_pagesAvail, i_pageCount); + + // Update statistics. + __sync_add_and_fetch(&iv_pagesTotal, i_pageCount); + + return; +} diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C index 4eb3b4fa8..23239a8a3 100644 --- a/src/kernel/syscall.C +++ b/src/kernel/syscall.C @@ -42,6 +42,7 @@ #include <kernel/intmsghandler.H> #include <sys/sync.h> + extern "C" void kernel_execute_decrementer() { @@ -92,6 +93,8 @@ namespace Systemcalls void MmSetPermission(task_t *t); void MmAllocPages(task_t *t); void MmVirtToPhys(task_t *t); + void MmExtend(task_t *t); + void MmLinearMap(task_t *t); syscall syscalls[] = @@ -131,6 +134,8 @@ namespace Systemcalls &MmSetPermission, // MM_SET_PERMISSION &MmAllocPages, // MM_ALLOC_PAGES &MmVirtToPhys, // MM_VIRT_TO_PHYS + &MmExtend, // MM_EXTEND + &MmLinearMap, // MM_LINEAR_MAP }; }; @@ -794,5 +799,28 @@ namespace Systemcalls uint64_t phys = VmmManager::findPhysicalAddress(i_vaddr); TASK_SETRTN(t, phys); } + + /** + * Allocates a block of virtual memory that extends the VMM + * space upto 32MEG of Mainstore. + * @param[in] t: The task used to extend Memory + */ + void MmExtend(task_t* t) + { + TASK_SETRTN(t, VmmManager::mmExtend()); + } + + /** + * Allocates a block of memory of the given size + * to at a specified physical address + */ + void MmLinearMap(task_t* t) + { + void* paddr = (void *)TASK_GETARG0(t); + uint64_t size = (uint64_t)TASK_GETARG1(t); + + TASK_SETRTN(t, VmmManager::mmLinearMap(paddr,size)); + } + }; diff --git a/src/kernel/vmmmgr.C b/src/kernel/vmmmgr.C index b7c98a0c5..d5152bf11 100644 --- a/src/kernel/vmmmgr.C +++ b/src/kernel/vmmmgr.C @@ -41,7 +41,6 @@ VmmManager::VmmManager() : lock() void VmmManager::init() { - printk("Starting VMM...\n"); VmmManager& v = Singleton<VmmManager>::instance(); @@ -57,7 +56,6 @@ void VmmManager::init() v.initPTEs(); v.initSDR1(); /*no effect*/ // BEAM Fix. - printk("...done.\n"); }; void VmmManager::init_slb() @@ -209,6 +207,20 @@ void VmmManager::_flushPageTable( void ) lock.unlock(); } + +int VmmManager::mmExtend(void) +{ + return Singleton<VmmManager>::instance()._mmExtend(); +} + +int VmmManager::_mmExtend(void) +{ + lock.lock(); + int rc = BaseSegment::mmExtend(); + lock.unlock(); + return rc; +} + void* VmmManager::_devMap(void* ra, uint64_t i_devDataSize) { void* ea = NULL; @@ -247,3 +259,16 @@ uint64_t VmmManager::findKernelAddress(uint64_t i_vaddr) } return phys; } + +int VmmManager::mmLinearMap(void *i_paddr, uint64_t i_size) +{ + return Singleton<VmmManager>::instance()._mmLinearMap(i_paddr, i_size); +} + +int VmmManager::_mmLinearMap(void *i_paddr, uint64_t i_size) +{ + lock.lock(); + int rc = BaseSegment::mmLinearMap(i_paddr, i_size); + lock.unlock(); + return rc; +} diff --git a/src/lib/syscall_mm.C b/src/lib/syscall_mm.C index 72c520db6..7b6ba672d 100644 --- a/src/lib/syscall_mm.C +++ b/src/lib/syscall_mm.C @@ -25,6 +25,8 @@ #include <arch/ppc.H> #include <kernel/vmmmgr.H> + + using namespace Systemcalls; /** @@ -81,6 +83,7 @@ int mm_set_permission(void* va, uint64_t size, uint64_t access_type) return (int64_t)_syscall3(MM_SET_PERMISSION, va, (void*)size, (void*)access_type); } + /** * System call to return the physical address backing a virtual address */ @@ -88,3 +91,20 @@ uint64_t mm_virt_to_phys( void* i_vaddr ) { return (uint64_t) _syscall1(MM_VIRT_TO_PHYS,i_vaddr); } + +/** + * System call to extend Memory to 32Meg. + */ +int mm_extend(void) +{ + return (int64_t)_syscall0(MM_EXTEND); +} + + +/** + * System call to create a block of memory at a specific physical address + */ +int mm_linear_map(void *i_paddr, uint64_t i_size) +{ + return (int64_t)_syscall2(MM_LINEAR_MAP, i_paddr, (void*)i_size); +} diff --git a/src/usr/hwpf/hwp/dram_initialization/dram_initialization.C b/src/usr/hwpf/hwp/dram_initialization/dram_initialization.C index a20c31edc..0fb777893 100644 --- a/src/usr/hwpf/hwp/dram_initialization/dram_initialization.C +++ b/src/usr/hwpf/hwp/dram_initialization/dram_initialization.C @@ -68,11 +68,13 @@ #include "proc_setup_bars/proc_setup_bars.H" // #include "proc_pcie_config/proc_pcie_config.H" #include "proc_exit_cache_contained/proc_exit_cache_contained.H" - +#include <hwpf/plat/fapiPlatReasonCodes.H> //remove these once memory setup workaround is removed #include <devicefw/driverif.H> #include <spd/spdenums.H> #include <sys/time.h> +#include <sys/mm.h> + namespace DRAM_INITIALIZATION { @@ -558,6 +560,7 @@ void call_proc_exit_cache_contained( void *io_pArgs ) // figure out what targets we need // customize any other inputs // set up loops to go through all targets (if parallel, spin off a task) + // extend the memory space from 8MEG to 32Meg // call the HWP with each fapi::Target FAPI_INVOKE_HWP( l_errl, @@ -574,11 +577,39 @@ void call_proc_exit_cache_contained( void *io_pArgs ) TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "SUCCESS : call_proc_exit_cache_contained" ); } - // @@@@@ END CUSTOM BLOCK: @@@@@ + + + // Call the function to extend VMM to 32MEG + int rc = mm_extend(); + + if (rc!=0) + { + /*@ + * @errortype + * @moduleid fapi::MOD_EXIT_CACHE_CONTAINED + * @reasoncode fapi::RC_MM_EXTEND_FAILED + * @userdata1 rc from mm_extend + * @userdata2 <UNUSED> + * + * @devdesc Failure extending memory to 32MEG after + * exiting cache contained mode. + */ + l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi::MOD_EXIT_CACHE_CONTAINED, + fapi::RC_MM_EXTEND_FAILED, + rc, + 0); + + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "ERROR : call_proc_exit_cache_contained - extendVMM, rc=0x%x", + rc ); + } TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_proc_exit_cache_contained exit" ); + // @@@@@ END CUSTOM BLOCK: @@@@@ + // end task, returning any errorlogs to IStepDisp task_end2( l_errl ); } diff --git a/src/usr/testcore/kernel/segmenttest.H b/src/usr/testcore/kernel/segmenttest.H index 72ae8f23a..478f63657 100644 --- a/src/usr/testcore/kernel/segmenttest.H +++ b/src/usr/testcore/kernel/segmenttest.H @@ -1,26 +1,25 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/usr/testcore/kernel/segmenttest.H $ - * - * IBM CONFIDENTIAL - * - * COPYRIGHT International Business Machines Corp. 2011-2012 - * - * p1 - * - * Object Code Only (OCO) source materials - * Licensed Internal Code Source Materials - * IBM HostBoot Licensed Internal Code - * - * The source code for this program is not published or other- - * wise divested of its trade secrets, irrespective of what has - * been deposited with the U.S. Copyright Office. - * - * Origin: 30 - * - * IBM_PROLOG_END_TAG - */ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/testcore/kernel/segmenttest.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or 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 __SEGMENTTEST_H #define __SEGMENTTEST_H /** @@ -112,6 +111,51 @@ class segmenttest: public CxxTest::TestSuite } } + // Create 2 blocks at different specified address's and sizes and direct + // map this. + void testSegLinearBlock() + { + int rc = -1; + uint64_t phys = 0; + uint64_t addr = 0x8000000 - 0x5000; //128M- 16K + uint64_t size = 0x1000; //4K + + rc = mm_linear_map(reinterpret_cast<void*>(addr),size); + if (rc != 0) + { + TS_FAIL("Failed to create BaseSegment block\n"); + } + + phys = mm_virt_to_phys( reinterpret_cast<void*>(addr) ); + + if( phys != addr ) + { + TS_TRACE( "Block> virt=%lX, phys=%lX", &addr, phys ); + TS_FAIL("Unexpected Physical Address for block."); + } + + + uint64_t addr2 = 0x8000000 - 0x3000; //128M- 12k + uint64_t size2 = 0x3000; //12K + + rc = mm_linear_map(reinterpret_cast<void*>(addr2),size2); + + if (rc != 0) + { + TS_FAIL("Failed to create BaseSegment block\n"); + } + + phys = mm_virt_to_phys( reinterpret_cast<void*>(addr2) ); + + if( phys != addr2 ) + { + TS_TRACE( "Block> virt=%lX, phys=%lX", &addr2, phys ); + TS_FAIL("Unexpected Physical Address for block."); + + } + + } + }; #endif |