summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/kernel/basesegment.H109
-rw-r--r--src/include/kernel/block.H69
-rw-r--r--src/include/kernel/pagemgr.H56
-rw-r--r--src/include/kernel/syscalls.H6
-rw-r--r--src/include/kernel/vmmmgr.H22
-rw-r--r--src/include/sys/mm.h17
-rw-r--r--src/include/usr/hwpf/plat/fapiPlatReasonCodes.H2
-rw-r--r--src/include/usr/vmmconst.h60
-rw-r--r--src/kernel/basesegment.C143
-rw-r--r--src/kernel/block.C26
-rw-r--r--src/kernel/pagemgr.C19
-rw-r--r--src/kernel/syscall.C28
-rw-r--r--src/kernel/vmmmgr.C29
-rw-r--r--src/lib/syscall_mm.C20
-rw-r--r--src/usr/hwpf/hwp/dram_initialization/dram_initialization.C35
-rw-r--r--src/usr/testcore/kernel/segmenttest.H90
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
OpenPOWER on IntegriCloud