diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/kernel/block.H | 21 | ||||
-rw-r--r-- | src/include/kernel/blockmsghdlr.H | 65 | ||||
-rw-r--r-- | src/kernel/basesegment.C | 3 | ||||
-rw-r--r-- | src/kernel/block.C | 27 | ||||
-rw-r--r-- | src/kernel/blockmsghdlr.C | 22 | ||||
-rw-r--r-- | src/kernel/makefile | 2 | ||||
-rw-r--r-- | src/makefile | 3 |
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 |