summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/kernel/block.H21
-rw-r--r--src/include/kernel/blockmsghdlr.H65
-rw-r--r--src/kernel/basesegment.C3
-rw-r--r--src/kernel/block.C27
-rw-r--r--src/kernel/blockmsghdlr.C22
-rw-r--r--src/kernel/makefile2
-rw-r--r--src/makefile3
7 files changed, 135 insertions, 8 deletions
diff --git a/src/include/kernel/block.H b/src/include/kernel/block.H
index 45b506a80..4e23d9710 100644
--- a/src/include/kernel/block.H
+++ b/src/include/kernel/block.H
@@ -7,7 +7,7 @@
#include <stdint.h>
#include <kernel/task.H>
#include <kernel/vmmmgr.H>
-#include <kernel/msghandler.H>
+#include <kernel/blockmsghdlr.H>
class ShadowPTE;
class Segment;
@@ -91,6 +91,23 @@ class Block
*/
bool handlePageFault(task_t* i_task, uint64_t i_addr);
+ /**
+ * @brief Sets the 'present' bit within the Shadow page table
+ *
+ * @param[in] i_vaddr - Virtual address within the Shadow page table
+ */
+ void setIsPresent(void* i_vaddr);
+
+ /**
+ * @brief Adds the page table entry for the given address
+ *
+ * @param[in] i_vaddr - Virtual address to add to the page table
+ *
+ * The permissions set within the Shadow page table are used for
+ * this address
+ */
+ void addPTE(void* i_vaddr);
+
friend class Segment;
friend class BaseSegment;
friend class StackSegment;
@@ -150,7 +167,7 @@ class Block
/** Pointer to the Shadow PTE entries. */
ShadowPTE* iv_ptes;
/** Pointer to the message handler */
- MessageHandler* iv_msgHdlr;
+ BlockMsgHdlr* iv_msgHdlr;
/**
* @brief Finish initialization of block.
diff --git a/src/include/kernel/blockmsghdlr.H b/src/include/kernel/blockmsghdlr.H
new file mode 100644
index 000000000..e67c1911d
--- /dev/null
+++ b/src/include/kernel/blockmsghdlr.H
@@ -0,0 +1,65 @@
+/** @file blockmsghdlr.H
+ * @brief Defines the implementation for a block's handling of messages.
+ */
+#ifndef __KERNEL_BLOCKMSGHDLR_H
+#define __KERNEL_BLOCKMSGHDLR_H
+
+#include <stdint.h>
+#include <kernel/types.h>
+#include <kernel/msghandler.H>
+
+//Forward declaration.
+class Spinlock;
+class MessageQueue;
+class Block;
+
+/**
+ * @class BlockMsgHdlr
+ * @brief Class to handle message data for blocks
+ *
+ * This class extends from the base MessageHandler so the base send/receive
+ * message functions can be utilized. It overrides how to handle the message
+ * responses for blocks within the base virtual memory segment.
+ */
+class BlockMsgHdlr : public MessageHandler
+{
+ public:
+
+ /**
+ * @brief Constructor
+ *
+ * @param[in] i_lock - Subsystem lock for this message handler, passed
+ * directly onto the MessageHandler
+ * @param[in] i_msgq - Queue used to send messages into userspace,
+ * passed directly onto the MessageHandler
+ * @param[in] i_block - Block to associate this message handler to
+ */
+ BlockMsgHdlr(Spinlock* i_lock, MessageQueue* i_msgq, Block* i_block) :
+ MessageHandler(i_lock,i_msgq), iv_block(i_block) {};
+
+ /**
+ * @brief Destructor
+ */
+ ~BlockMsgHdlr() {};
+
+ /**
+ * @brief Handle response to 'send message' associated with this block
+ *
+ * @param[in] i_type - The message type previously sent.
+ * @param[in] i_key - The key value for the received message.
+ * @param[in] i_task - The deferred task.
+ * @param[in] i_rc - The response rc from userspace.
+ *
+ * @return HandleResult - The desired behavior on the 'recv message'
+ * interface for this <key, task> pair.
+ */
+ virtual HandleResult handleResponse(msg_sys_types_t i_type,void* i_key,
+ task_t* i_task,int i_rc);
+
+ private:
+
+ /* Associated block for this message handler */
+ Block* const iv_block;
+};
+
+#endif
diff --git a/src/kernel/basesegment.C b/src/kernel/basesegment.C
index 35e6375a2..324a00bf9 100644
--- a/src/kernel/basesegment.C
+++ b/src/kernel/basesegment.C
@@ -7,6 +7,7 @@
#include <kernel/vmmmgr.H>
#include <kernel/cpuid.H>
//#include <kernel/console.H>
+
#define SLBE_s 40
BaseSegment::~BaseSegment()
@@ -88,7 +89,7 @@ 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)
{
uint64_t l_vaddr = reinterpret_cast<uint64_t>(i_va);
- uint64_t l_blockSizeTotal = 0;//iv_block->iv_size;
+ uint64_t l_blockSizeTotal = 0;
iv_block->totalBlocksAlloc(l_blockSizeTotal);
//Verify input address and size falls within this segment's address range
if ((l_vaddr < this->getBaseAddress() ||
diff --git a/src/kernel/block.C b/src/kernel/block.C
index 5d9b8d1e3..17d6a1d5c 100644
--- a/src/kernel/block.C
+++ b/src/kernel/block.C
@@ -8,6 +8,7 @@
#include <kernel/vmmmgr.H>
#include <kernel/ptmgr.H>
#include <kernel/pagemgr.H>
+//#include <kernel/console.H>
Block::~Block()
{
@@ -29,7 +30,7 @@ void Block::init(MessageQueue* i_msgQ)
if (i_msgQ != NULL)
{
//Create message handler attribute for this block with this msgq
- this->iv_msgHdlr = new MessageHandler(VmmManager::getLock(),i_msgQ);
+ this->iv_msgHdlr = new BlockMsgHdlr(VmmManager::getLock(),i_msgQ,this);
}
}
@@ -61,8 +62,8 @@ bool Block::handlePageFault(task_t* i_task, uint64_t i_addr)
//Add to ShadowPTE
pte->setPageAddr(reinterpret_cast<uint64_t>(l_page));
//TODO - Update to correct permissions requested
- pte->setExecutable(true);
- pte->setWritable(false);
+ pte->setExecutable(false);
+ pte->setWritable(true);
}
//Send message to handler to read page
this->iv_msgHdlr->sendMessage(MSG_MM_RP_READ,
@@ -132,3 +133,23 @@ void Block::setPhysicalPage(uint64_t i_vAddr, uint64_t i_pAddr,
break;
}
}
+
+void Block::setIsPresent(void* i_vaddr)
+{
+ uint64_t l_vaddr = reinterpret_cast<uint64_t>(i_vaddr);
+ ShadowPTE* l_pte = getPTE(l_vaddr);
+ //Set present bit
+ l_pte->setPresent(true);
+}
+
+void Block::addPTE(void* i_vaddr)
+{
+ uint64_t l_vaddr = reinterpret_cast<uint64_t>(i_vaddr);
+ ShadowPTE* l_pte = getPTE(l_vaddr);
+ //Add page table entry
+ PageTableManager::addEntry((l_vaddr / PAGESIZE) * PAGESIZE,
+ l_pte->getPage(),
+ (l_pte->isExecutable() ? VmmManager::RO_EXE_ACCESS :
+ (l_pte->isWritable() ? VmmManager::NORMAL_ACCESS :
+ VmmManager::READ_O_ACCESS)));
+}
diff --git a/src/kernel/blockmsghdlr.C b/src/kernel/blockmsghdlr.C
new file mode 100644
index 000000000..639e8c3af
--- /dev/null
+++ b/src/kernel/blockmsghdlr.C
@@ -0,0 +1,22 @@
+#include <kernel/blockmsghdlr.H>
+#include <kernel/block.H>
+//#include <kernel/console.H>
+
+MessageHandler::HandleResult BlockMsgHdlr::handleResponse(
+ msg_sys_types_t i_type, void* i_key, task_t* i_task, int i_rc)
+{
+ if (i_rc != 0)
+ {
+ // Indicate nothing specific has been done for this response. Request
+ // default behavior of resume/kill task based on rc.
+ return UNHANDLED_RC;
+ }
+ else
+ {
+ //Set the present bit for the address associated with this block
+ iv_block->setIsPresent(i_key);
+ //Add the address into the page table associated with this block
+ iv_block->addPTE(i_key);
+ return SUCCESS;
+ }
+}
diff --git a/src/kernel/makefile b/src/kernel/makefile
index 5ccbf8da9..b4ef607ed 100644
--- a/src/kernel/makefile
+++ b/src/kernel/makefile
@@ -3,7 +3,7 @@ ROOTPATH = ../..
OBJS = start.o kernel.o console.o pagemgr.o heapmgr.o taskmgr.o cpumgr.o
OBJS += syscall.o scheduler.o spinlock.o exception.o vmmmgr.o timemgr.o
OBJS += futexmgr.o ptmgr.o segmentmgr.o devicesegment.o basesegment.o
-OBJS += block.o cpuid.o misc.o msghandler.o
+OBJS += block.o cpuid.o misc.o msghandler.o blockmsghdlr.o
include ${ROOTPATH}/config.mk
diff --git a/src/makefile b/src/makefile
index 5de8aef96..20556c561 100644
--- a/src/makefile
+++ b/src/makefile
@@ -30,7 +30,8 @@ DIRECT_BOOT_OBJECTS = start.o kernel.o taskmgr.o cpumgr.o syscall.o \
syscall_msg.o syscall_mmio.o syscall_time.o \
syscall_mm.o init_main.o vfs_main.o sync.o futexmgr.o \
ptmgr.o segmentmgr.o basesegment.o devicesegment.o \
- block.o cxxtest_data.o cpuid.o misc.o msghandler.o
+ block.o cxxtest_data.o cpuid.o misc.o msghandler.o \
+ blockmsghdlr.o
## STUB_TESTCASE_OBJECT = cxxtest_stub.o
OpenPOWER on IntegriCloud