summaryrefslogtreecommitdiffstats
path: root/src/kernel/segmentmgr.C
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2011-07-08 19:33:40 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2011-07-20 14:58:43 -0500
commit471f09f1a9bcc46fc385fa8aca776cb682075c0b (patch)
treee0a4969825799dcc4c28a71975cb68439f507390 /src/kernel/segmentmgr.C
parent3ecf7085ccc55eb4f815a62f47ea09f55bb6688e (diff)
downloadtalos-hostboot-471f09f1a9bcc46fc385fa8aca776cb682075c0b.tar.gz
talos-hostboot-471f09f1a9bcc46fc385fa8aca776cb682075c0b.zip
VMM Improvements.
- Segment Manager - Base / Device Segments - Block for Base image. Change-Id: Ic0c058e5c5b210ec1c48d30f6ed9f9837d74a3c8 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/193 Tested-by: Jenkins Server Reviewed-by: MATTHEW S. BARTH <msbarth@us.ibm.com>
Diffstat (limited to 'src/kernel/segmentmgr.C')
-rw-r--r--src/kernel/segmentmgr.C76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/kernel/segmentmgr.C b/src/kernel/segmentmgr.C
new file mode 100644
index 000000000..fae9d3479
--- /dev/null
+++ b/src/kernel/segmentmgr.C
@@ -0,0 +1,76 @@
+#include <assert.h>
+#include <arch/ppc.H>
+#include <util/singleton.H>
+
+#include <kernel/segmentmgr.H>
+#include <kernel/segment.H>
+
+bool SegmentManager::handlePageFault(task_t* i_task, uint64_t i_addr)
+{
+ return Singleton<SegmentManager>::instance().
+ _handlePageFault(i_task, i_addr);
+}
+
+void SegmentManager::addSegment(Segment* i_segment, size_t i_segId)
+{
+ Singleton<SegmentManager>::instance()._addSegment(i_segment, i_segId);
+}
+
+void SegmentManager::initSLB()
+{
+ Singleton<SegmentManager>::instance()._initSLB();
+}
+
+bool SegmentManager::_handlePageFault(task_t* i_task, uint64_t i_addr)
+{
+ // This constant should come from page manager. Segment size.
+ const size_t SLBE_s = 40;
+
+ // Get segment ID from effective address.
+ size_t segId = i_addr >> SLBE_s;
+
+ // Call contained segment object to handle page fault.
+ if ((segId < MAX_SEGMENTS) && (NULL != iv_segments[segId]))
+ {
+ return iv_segments[segId]->handlePageFault(i_task, i_addr);
+ }
+
+ return false;
+}
+
+void SegmentManager::_addSegment(Segment* i_segment, size_t i_segId)
+{
+ kassert(i_segId < MAX_SEGMENTS);
+ iv_segments[i_segId] = i_segment;
+}
+
+void SegmentManager::_initSLB()
+{
+ // Flush SLB.
+ asm volatile("slbia" ::: "memory");
+ isync(); // Ensure slbia completes prior to slbmtes.
+
+ register uint64_t slbRS, slbRB;
+
+ // Default segment descriptors.
+ // ESID = 0, V = 1, Index = 1.
+ slbRB = 0x0000000008000001;
+ // B = 01 (1TB), VSID = 0, Ks = 0, Kp = 1, NLCLP = 0
+ slbRS = 0x4000000000000400;
+
+ // Add all segments to SLB.
+ for (size_t i = 0; i < MAX_SEGMENTS; i++)
+ {
+ // Add segment to SLB.
+ if (NULL != iv_segments[i])
+ {
+ asm volatile("slbmte %0, %1" :: "r"(slbRS), "r"(slbRB) : "memory");
+ }
+
+ // Increment ESID, VSID, Index.
+ slbRB += 0x0000010000000001;
+ slbRS += 0x0000000001000000;
+ }
+
+ isync(); // Ensure slbmtes complete prior to continuing on.
+}
OpenPOWER on IntegriCloud