summaryrefslogtreecommitdiffstats
path: root/src/kernel
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2012-08-10 14:48:06 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-09-16 15:09:40 -0500
commit2f50c376a718ea6542b42e029a6735f719a8f407 (patch)
treef54c4c46d71f1a3226a3e12e69664614ce4db138 /src/kernel
parenta0206bc94f427a1a4e3913fa9122b5530c5500ad (diff)
downloadtalos-hostboot-2f50c376a718ea6542b42e029a6735f719a8f407.tar.gz
talos-hostboot-2f50c376a718ea6542b42e029a6735f719a8f407.zip
Support for Non-zero HRMOR
Changes to kernel code to support detection and use of HRMOR offset in memory Changes to tooling to handle the real memory offset New interface to retrieve the physical address that corresponds to a virtual address To test, run these commands before starting up Hostboot: system_cmp0.cpu0_0_05_0.write-reg HRMOR 0x8000000 proc_venicechip_cmp0.phys_mem.del-map p8Proc0.l3_cache_ram 0 0 RTC: 46032 Change-Id: I50ab248f941218a3a14a8f0fc12a551b56dc7cf3 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1553 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/basesegment.C2
-rw-r--r--src/kernel/block.C47
-rw-r--r--src/kernel/devicesegment.C74
-rw-r--r--src/kernel/exception.C2
-rw-r--r--src/kernel/ptmgr.C68
-rw-r--r--src/kernel/syscall.C66
-rw-r--r--src/kernel/vmmmgr.C64
7 files changed, 199 insertions, 124 deletions
diff --git a/src/kernel/basesegment.C b/src/kernel/basesegment.C
index 56f7b6229..c9a826f8e 100644
--- a/src/kernel/basesegment.C
+++ b/src/kernel/basesegment.C
@@ -131,7 +131,7 @@ uint64_t BaseSegment::findPhysicalAddress(uint64_t i_vaddr) const
// Anything in the physical address size is valid (and linear mapped)
// except NULL.
if (i_vaddr >= PAGE_SIZE)
- return i_vaddr;
+ return (i_vaddr | getHRMOR());
else return -EFAULT;
}
return (iv_block ? iv_block->findPhysicalAddress(i_vaddr) : -EFAULT);
diff --git a/src/kernel/block.C b/src/kernel/block.C
index 8afc39ae7..1ea12d2c0 100644
--- a/src/kernel/block.C
+++ b/src/kernel/block.C
@@ -1,26 +1,25 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/kernel/block.C $
-//
-// 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/kernel/block.C $ */
+/* */
+/* 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 */
#include <limits.h>
#include <assert.h>
#include <string.h>
@@ -38,6 +37,7 @@
#include <kernel/console.H>
#include <util/align.H>
#include <kernel/basesegment.H>
+#include <arch/ppc.H>
// Track eviction requests due to aging pages
uint32_t Block::cv_ro_evict_req = 0;
@@ -265,6 +265,7 @@ uint64_t Block::findPhysicalAddress(uint64_t i_vaddr) const
{
paddr = pte->getPageAddr();
paddr += i_vaddr % PAGESIZE;
+ paddr |= getHRMOR();
}
return paddr;
diff --git a/src/kernel/devicesegment.C b/src/kernel/devicesegment.C
index 04e41b7be..4236417e8 100644
--- a/src/kernel/devicesegment.C
+++ b/src/kernel/devicesegment.C
@@ -1,25 +1,25 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/kernel/devicesegment.C $
-//
-// 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/kernel/devicesegment.C $ */
+/* */
+/* 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 */
#include <util/singleton.H>
#include <limits.h>
#include <assert.h>
@@ -130,10 +130,38 @@ int DeviceSegment::devUnmap(void *ea)
{
//Remove all of the defined block's size (<= 32GB)
PageTableManager::delRangePN(iv_mmioMap[idx].addr / PAGESIZE,
- (iv_mmioMap[idx].addr + iv_mmioMap[idx].size) / PAGESIZE);
+ (iv_mmioMap[idx].addr + iv_mmioMap[idx].size) / PAGESIZE,
+ false);
iv_mmioMap[idx].addr = 0;
rc = 0;
}
return rc;
}
+
+/**
+ * Locate the physical address of the given virtual address
+ */
+uint64_t DeviceSegment::findPhysicalAddress(uint64_t i_vaddr) const
+{
+ uint64_t rc = -EFAULT;
+ uint64_t segment_ea = i_vaddr;
+ //Verify input address falls within this segment's address range
+ if (segment_ea < this->getBaseAddress() ||
+ segment_ea >= (this->getBaseAddress() + (1ull << SLBE_s)))
+ {
+ return rc;
+ }
+ segment_ea = segment_ea - this->getBaseAddress();
+ //TODO - Calculate idx by segment block size if/when new device size needed
+ size_t idx = segment_ea / ((1ull << SLBE_s) / MMIO_MAP_DEVICES);
+ if (0 != iv_mmioMap[idx].addr)
+ {
+ //memory offset within this device's window
+ uint64_t offset = segment_ea - idx*((1ull << SLBE_s) / MMIO_MAP_DEVICES);
+ return (iv_mmioMap[idx].addr + offset);
+ }
+
+ return rc;
+}
+
diff --git a/src/kernel/exception.C b/src/kernel/exception.C
index 836a57a57..d1b365535 100644
--- a/src/kernel/exception.C
+++ b/src/kernel/exception.C
@@ -161,7 +161,7 @@ namespace ExceptionHandles
{
bool PrivInstr(task_t* t)
{
- uint64_t phys_addr = VmmManager::findPhysicalAddress(
+ uint64_t phys_addr = VmmManager::findKernelAddress(
reinterpret_cast<uint64_t>(t->context.nip));
if (-EFAULT != static_cast<int64_t>(phys_addr))
diff --git a/src/kernel/ptmgr.C b/src/kernel/ptmgr.C
index bf8937b78..573712994 100644
--- a/src/kernel/ptmgr.C
+++ b/src/kernel/ptmgr.C
@@ -1,26 +1,25 @@
-/* IBM_PROLOG_BEGIN_TAG
- * This is an automatically generated prolog.
- *
- * $Source: src/kernel/ptmgr.C $
- *
- * 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/kernel/ptmgr.C $ */
+/* */
+/* 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 */
#include <kernel/ptmgr.H>
#include <kernel/vmmmgr.H>
#include <util/singleton.H>
@@ -35,6 +34,7 @@
#define Tprintk(args...)
#define Eprintk(args...) printk(args)
+
// Utilities to do some bit manipulation
/**
@@ -208,7 +208,15 @@ void PageTableManager::addEntry( uint64_t i_vAddr,
uint64_t i_page,
uint64_t i_accessType )
{
- return Singleton<PageTableManager>::instance()._addEntry( i_vAddr, i_page, i_accessType );
+ // adjust physical address for the HRMOR unless this is a mmio
+ if( SegmentManager::CI_ACCESS != i_accessType )
+ {
+ i_page |= (getHRMOR() / PAGESIZE);
+ }
+
+ return Singleton<PageTableManager>::instance()._addEntry( i_vAddr,
+ i_page,
+ i_accessType );
}
/**
@@ -235,8 +243,16 @@ void PageTableManager::delRangeVA( uint64_t i_vAddrStart,
* @brief Remove a range of entries from the hardware page table
*/
void PageTableManager::delRangePN( uint64_t i_pnStart,
- uint64_t i_pnFinish )
+ uint64_t i_pnFinish,
+ bool i_applyHRMOR )
{
+ // adjust physical address for the HRMOR unless this is a mmio
+ if( i_applyHRMOR )
+ {
+ i_pnStart |= (getHRMOR() / PAGESIZE);
+ i_pnFinish |= (getHRMOR() / PAGESIZE);
+ }
+
return Singleton<PageTableManager>::instance()._delRangePN(i_pnStart,i_pnFinish);
}
@@ -857,7 +873,7 @@ uint64_t PageTableManager::getAddress( void )
if(unlikely(ivTABLE != NULL)) {
return (uint64_t)ivTABLE;
} else {
- return VmmManager::HTABORG;
+ return VmmManager::HTABORG();
}
}
diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C
index 94c6a5860..a38f08b78 100644
--- a/src/kernel/syscall.C
+++ b/src/kernel/syscall.C
@@ -1,26 +1,25 @@
-/* IBM_PROLOG_BEGIN_TAG
- * This is an automatically generated prolog.
- *
- * $Source: src/kernel/syscall.C $
- *
- * 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/kernel/syscall.C $ */
+/* */
+/* 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 */
#include <assert.h>
#include <errno.h>
#include <kernel/cpu.H>
@@ -92,6 +91,7 @@ namespace Systemcalls
void MmRemovePages(task_t *t);
void MmSetPermission(task_t *t);
void MmAllocPages(task_t *t);
+ void MmVirtToPhys(task_t *t);
syscall syscalls[] =
@@ -130,6 +130,7 @@ namespace Systemcalls
&MmRemovePages, // MM_REMOVE_PAGES
&MmSetPermission, // MM_SET_PERMISSION
&MmAllocPages, // MM_ALLOC_PAGES
+ &MmVirtToPhys, // MM_VIRT_TO_PHYS
};
};
@@ -207,7 +208,7 @@ namespace Systemcalls
if (status != NULL)
{
uint64_t addr =
- VmmManager::findPhysicalAddress(
+ VmmManager::findKernelAddress(
reinterpret_cast<uint64_t>(status));
if (addr == (static_cast<uint64_t>(-EFAULT)))
@@ -222,7 +223,7 @@ namespace Systemcalls
if (retval != NULL)
{
uint64_t addr =
- VmmManager::findPhysicalAddress(
+ VmmManager::findKernelAddress(
reinterpret_cast<uint64_t>(retval));
if (addr == (static_cast<uint64_t>(-EFAULT)))
@@ -543,7 +544,7 @@ namespace Systemcalls
// Set RC to success initially.
TASK_SETRTN(t,0);
- futex = VmmManager::findPhysicalAddress(futex);
+ futex = VmmManager::findKernelAddress(futex);
if(futex == (static_cast<uint64_t>(-EFAULT)))
{
printk("Task %d terminated. No physical address found for address 0x%p",
@@ -579,7 +580,7 @@ namespace Systemcalls
case FUTEX_REQUEUE:
// Wake (val) task(s) on futex && requeue remaining tasks on futex2
- futex2 = VmmManager::findPhysicalAddress(futex2);
+ futex2 = VmmManager::findKernelAddress(futex2);
if(futex2 == (static_cast<uint64_t>(-EFAULT)))
{
printk("Task %d terminated. No physical address found for address 0x%p",
@@ -779,5 +780,16 @@ namespace Systemcalls
}
}
+
+ /**
+ * Return the physical address backing a virtual address
+ * @param[in] t: The task used
+ */
+ void MmVirtToPhys(task_t* t)
+ {
+ uint64_t i_vaddr = (uint64_t)TASK_GETARG0(t);
+ uint64_t phys = VmmManager::findPhysicalAddress(i_vaddr);
+ TASK_SETRTN(t, phys);
+ }
};
diff --git a/src/kernel/vmmmgr.C b/src/kernel/vmmmgr.C
index ed88a4879..b7c98a0c5 100644
--- a/src/kernel/vmmmgr.C
+++ b/src/kernel/vmmmgr.C
@@ -1,25 +1,25 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/kernel/vmmmgr.C $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2010 - 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/kernel/vmmmgr.C $ */
+/* */
+/* 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 */
#include <limits.h>
#include <util/singleton.H>
#include <kernel/vmmmgr.H>
@@ -31,10 +31,12 @@
#include <kernel/stacksegment.H>
#include <kernel/devicesegment.H>
+
extern void* data_load_address;
VmmManager::VmmManager() : lock()
{
+ printk("HRMOR = %lX\n", getHRMOR());
}
void VmmManager::init()
@@ -108,7 +110,7 @@ void VmmManager::initPTEs()
void VmmManager::initSDR1()
{
// HTABORG, HTABSIZE = 0 (11 bits, 256k table)
- register uint64_t sdr1 = (uint64_t)HTABORG;
+ register uint64_t sdr1 = HTABORG();
asm volatile("mtsdr1 %0" :: "r"(sdr1) : "memory");
}
@@ -229,3 +231,19 @@ int VmmManager::_devUnmap(void* ea)
return rc;
}
+uint64_t VmmManager::HTABORG()
+{
+ return ((uint32_t)HTABORG_OFFSET + getHRMOR());
+}
+
+uint64_t VmmManager::findKernelAddress(uint64_t i_vaddr)
+{
+ //in hypervisor mode the HRMOR is automatically ORed onto
+ // the address so we need to tell the hardware to ignore it
+ uint64_t phys = VmmManager::findPhysicalAddress(i_vaddr);
+ if( static_cast<uint64_t>(-EFAULT) != phys )
+ {
+ phys |= FORCE_PHYS_ADDR;
+ }
+ return phys;
+}
OpenPOWER on IntegriCloud