diff options
| author | Patrick Williams <iawillia@us.ibm.com> | 2011-07-08 19:33:40 -0500 |
|---|---|---|
| committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2011-07-20 14:58:43 -0500 |
| commit | 471f09f1a9bcc46fc385fa8aca776cb682075c0b (patch) | |
| tree | e0a4969825799dcc4c28a71975cb68439f507390 /src/include/kernel/block.H | |
| parent | 3ecf7085ccc55eb4f815a62f47ea09f55bb6688e (diff) | |
| download | blackbird-hostboot-471f09f1a9bcc46fc385fa8aca776cb682075c0b.tar.gz blackbird-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/include/kernel/block.H')
| -rw-r--r-- | src/include/kernel/block.H | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/src/include/kernel/block.H b/src/include/kernel/block.H new file mode 100644 index 000000000..1de1c1280 --- /dev/null +++ b/src/include/kernel/block.H @@ -0,0 +1,161 @@ +/** @file block.H + * @brief Defines the implementation for the generic VMM block class. + */ +#ifndef __KERNEL_BLOCK_H +#define __KERNEL_BLOCK_H + +#include <stdint.h> +#include <kernel/task.H> +#include <kernel/vmmmgr.H> + +class ShadowPTE; +class Segment; + +/** @class Block + * @brief Provides management of the memory pages associated with a block of + * virtual memory. + * + * This class is organized to be either an independent block (typically + * managed by the Segment container in some way) or as a chain of blocks. + * + * When the instance is assigned down-stream blocks, the instance will + * forward requests that do not belong to it down the chain for handling + * by a block responsible for the request. Also, when used in this manner, + * this block is responsible for the ownership of all down-stream blocks, + * including calling their destructor when necessary. + * + * There is currently no mechanism for dynamically removing blocks from the + * chain. The expectation is that all known use cases would suggest either + * a fixed (increasing-only) chain or a known-sized array of blocks. + */ +class Block +{ + public: + /** + * @brief Constructor. + * + * @param[in] i_baseAddr - Base virtual Address of the block. + * @param[in] i_size - Size of the block (in bytes). + * + * Will allocate enough shadow PTEs to track pages in the block. + */ + Block(uint64_t i_baseAddr, uint64_t i_size) : + iv_baseAddr(i_baseAddr), iv_size(i_size), + iv_parent(NULL), iv_nextBlock(NULL), iv_ptes(NULL) + { init(); }; + + /** + * @brief Destructor. + * + * Releases associated memory and down-stream blocks. + */ + ~Block(); + + /** + * @brief Get the base address of this block. + * @return Base address (as uint64_t). + */ + uint64_t getBaseAddress() const { return iv_baseAddr; }; + + /** + * @brief Determines if a virtual address is in the range of the block. + * + * @param[in] i_addr - The virtual address in question. + * @return true - Address is contained within the block. + * @return false - Address is not contained within the block. + */ + bool isContained(uint64_t i_addr) const + { return (i_addr >= iv_baseAddr) && + (i_addr < iv_baseAddr + iv_size); }; + + /** + * @brief Responsible for handling page faults within the block [chain]. + * + * @param[in] i_task - Task causing the page fault. + * @param[in] i_addr - Effective address accessed to cause fault. + * + * @return true - Page fault was successfully handled. + * + * If the page fault is not successfully handled the expectation is + * that the VMM will perform appropriate action, such as killing the + * task. + * + * If the address is not within this block, the block will attempt to + * make calls down the block-chain if it exists. + */ + bool handlePageFault(task_t* i_task, uint64_t i_addr); + + friend class Segment; + friend class BaseSegment; + friend class StackSegment; + + protected: + /** + * @brief Assign a segment to a parent relationship to this block. + * + * @param[in] i_parent - The segment to assign as a parent. + */ + void setParent(Segment* i_parent) { iv_parent = i_parent; }; + + /** + * @brief Add a block to the end of this block-chain. + * + * @param[in] i_block - The block tp append. + */ + void appendBlock(Block* i_block) + { + if (NULL == iv_nextBlock) iv_nextBlock = i_block; + else iv_nextBlock->appendBlock(i_block); + } + + /** + * @brief Set up a virtual-physical mapping for a static page. + * + * @param[in] i_vAddr - The virtual address of the page. + * @param[in] i_pAddr - The physical address of the page. + * @param[in] i_access - The permissions of the page. + */ + void setPhysicalPage(uint64_t i_vAddr, uint64_t i_pAddr, + VmmManager::ACCESS_TYPES i_access); + + private: + /** Base address of the block */ + const uint64_t iv_baseAddr; + /** Size of the block */ + const uint64_t iv_size; + + /** Pointer to the parent (containing) segment. */ + Segment* iv_parent; + /** Pointer to the next block in the chain. */ + Block* iv_nextBlock; + + /** Pointer to the Shadow PTE entries. */ + ShadowPTE* iv_ptes; + + /** + * @brief Finish initialization of block. + * + * Construct ShadowPTE entries. + * + * This is defined as a separate function to reduce the code + * footprint of the class constructors. GCC emits an "in-charge" and + * "not-in-charge" version of each constructor, so put as much + * common code into an init function. + */ + void init(); + + /** + * @brief Find the Shadow PTE for a virtual address. + * + * @param[in] i_addr - The virtual address to find a page for. + * @note This function does no bounds checking. + */ + ShadowPTE* getPTE(uint64_t i_addr) const; + + + Block(const Block&); // prohibit copy. + Block& operator=(const Block&); // prohibit assignment. + +}; + +#endif |

