diff options
| author | Patrick Williams <iawillia@us.ibm.com> | 2012-01-11 10:25:12 -0600 |
|---|---|---|
| committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2012-01-18 09:52:45 -0600 |
| commit | b699fc329722088174afe6031351d3bddb559f6c (patch) | |
| tree | 62e2ad43fb7becba393346fbb2aeca1ba140efdf /src/kernel | |
| parent | 811a7e18fb3630f4af77c545f057aa147b18334c (diff) | |
| download | talos-hostboot-b699fc329722088174afe6031351d3bddb559f6c.tar.gz talos-hostboot-b699fc329722088174afe6031351d3bddb559f6c.zip | |
Support additional device segments and MMIO blocks
Change-Id: Icd2e9ed7de2c0227b25979622d0f37a77595570a
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/609
Tested-by: Jenkins Server
Reviewed-by: MATTHEW S. BARTH <msbarth@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/kernel')
| -rw-r--r-- | src/kernel/devicesegment.C | 50 | ||||
| -rw-r--r-- | src/kernel/segmentmgr.C | 48 | ||||
| -rw-r--r-- | src/kernel/vmmmgr.C | 42 |
3 files changed, 87 insertions, 53 deletions
diff --git a/src/kernel/devicesegment.C b/src/kernel/devicesegment.C index 479183d4c..fae4b7032 100644 --- a/src/kernel/devicesegment.C +++ b/src/kernel/devicesegment.C @@ -22,6 +22,7 @@ // IBM_PROLOG_END #include <util/singleton.H> #include <limits.h> +#include <assert.h> #include <kernel/vmmmgr.H> #include <kernel/ptmgr.H> @@ -31,38 +32,14 @@ #include <kernel/console.H> /** - * STATIC - * @brief Add the device segment + * @brief Add the device segment to the SegmentManager. */ -void DeviceSegment::init() +void DeviceSegment::init(size_t segId) { - Singleton<DeviceSegment>::instance()._init(); -} - -/** - * STATIC - * @brief Map a device into the device segment(2TB) - */ -void* DeviceSegment::devMap(void *ra, uint64_t i_devDataSize) -{ - return Singleton<DeviceSegment>::instance()._devMap(ra,i_devDataSize); -} - -/** - * STATIC - * @brief Unmap a device from the device segment(2TB) - */ -int DeviceSegment::devUnmap(void *ea) -{ - return Singleton<DeviceSegment>::instance()._devUnmap(ea); -} + kassert((segId >= SegmentManager::MMIO_FIRST_SEGMENT_ID) && + (segId <= SegmentManager::MMIO_LAST_SEGMENT_ID)); -/** - * @brief Add the device segment - */ -void DeviceSegment::_init() -{ - SegmentManager::addSegment(this, SegmentManager::MMIO_SEGMENT_ID); + SegmentManager::addSegment(this, segId); } /** @@ -101,12 +78,12 @@ bool DeviceSegment::handlePageFault(task_t* i_task, uint64_t i_addr) /** - * @brief Map a device into the device segment(2TB) + * @brief Map a device into the device segment. * @param ra[in] - Void pointer to real address to be mapped in * @param i_devDataSize[in] - Size of device segment block * @return void* - Pointer to beginning virtual address, NULL otherwise */ -void *DeviceSegment::_devMap(void *ra, uint64_t i_devDataSize) +void *DeviceSegment::devMap(void *ra, uint64_t i_devDataSize) { void *segBlock = NULL; if (i_devDataSize <= THIRTYTWO_GB) @@ -125,10 +102,6 @@ void *DeviceSegment::_devMap(void *ra, uint64_t i_devDataSize) break; } } - if (segBlock == NULL) - { - printk("Unable to map device, no empty segment blocks found\n"); - } } else { @@ -139,12 +112,7 @@ void *DeviceSegment::_devMap(void *ra, uint64_t i_devDataSize) return segBlock; } -/** - * @brief Unmap a device from the device segment(2TB) - * @param ea[in] - Void pointer to effective address - * @return int - 0 for successful unmap, non-zero otherwise - */ -int DeviceSegment::_devUnmap(void *ea) +int DeviceSegment::devUnmap(void *ea) { int rc = -EINVAL; uint64_t segment_ea = reinterpret_cast<uint64_t>(ea); diff --git a/src/kernel/segmentmgr.C b/src/kernel/segmentmgr.C index 0b4370cfa..6659c634c 100644 --- a/src/kernel/segmentmgr.C +++ b/src/kernel/segmentmgr.C @@ -24,9 +24,11 @@ #include <errno.h> #include <arch/ppc.H> #include <util/singleton.H> +#include <kernel/console.H> #include <kernel/segmentmgr.H> #include <kernel/segment.H> +#include <kernel/devicesegment.H> bool SegmentManager::handlePageFault(task_t* i_task, uint64_t i_addr) { @@ -60,6 +62,16 @@ void SegmentManager::castOutPages(uint64_t i_type) Singleton<SegmentManager>::instance()._castOutPages(i_type); } +void* SegmentManager::devMap(void* ra, uint64_t i_devDataSize) +{ + return Singleton<SegmentManager>::instance()._devMap(ra, i_devDataSize); +} + +int SegmentManager::devUnmap(void* ea) +{ + return Singleton<SegmentManager>::instance()._devUnmap(ea); +} + bool SegmentManager::_handlePageFault(task_t* i_task, uint64_t i_addr) { size_t segId = getSegmentIdFromAddress(i_addr); @@ -146,3 +158,39 @@ void SegmentManager::_castOutPages(uint64_t i_type) } } } + +void* SegmentManager::_devMap(void* ra, uint64_t i_devDataSize) +{ + void* ea = NULL; + for (size_t i = MMIO_FIRST_SEGMENT_ID; i <= MMIO_LAST_SEGMENT_ID; i++) + { + if (NULL == iv_segments[i]) continue; + + ea = reinterpret_cast<DeviceSegment*>(iv_segments[i])-> + devMap(ra, i_devDataSize); + + if (ea != NULL) break; + } + + if (ea == NULL) + { + printk("SegmentManager: Ran out of device segment blocks.\n"); + } + + return ea; +} + +int SegmentManager::_devUnmap(void* ea) +{ + size_t segId = getSegmentIdFromAddress(reinterpret_cast<uint64_t>(ea)); + if ((segId < MMIO_FIRST_SEGMENT_ID) || + (segId > MMIO_LAST_SEGMENT_ID) || + (NULL == iv_segments[segId])) + { + return -EINVAL; + } + + return reinterpret_cast<DeviceSegment*>(iv_segments[segId])->devUnmap(ea); +} + + diff --git a/src/kernel/vmmmgr.C b/src/kernel/vmmmgr.C index b0fe28415..b1f13f1a3 100644 --- a/src/kernel/vmmmgr.C +++ b/src/kernel/vmmmgr.C @@ -45,7 +45,11 @@ void VmmManager::init() BaseSegment::init(); StackSegment::init(); - DeviceSegment::init(); + for (size_t i = SegmentManager::MMIO_FIRST_SEGMENT_ID; + i < SegmentManager::MMIO_LAST_SEGMENT_ID; ++i) + { + new DeviceSegment(i); // Self-registers with SegmentManager. + } SegmentManager::initSLB(); v.initPTEs(); @@ -82,23 +86,14 @@ void VmmManager::flushPageTable( void ) Singleton<VmmManager>::instance()._flushPageTable(); } - -/** - * STATIC - * @brief A facade to map a device into the device segment(2TB) - */ void* VmmManager::devMap(void* ra, uint64_t i_devDataSize) { - return DeviceSegment::devMap(ra, i_devDataSize); + return Singleton<VmmManager>::instance()._devMap(ra, i_devDataSize); } -/** - * STATIC - * @brief A facade to unmap a device from the device segment(2TB) - */ int VmmManager::devUnmap(void* ea) { - return DeviceSegment::devUnmap(ea); + return Singleton<VmmManager>::instance()._devUnmap(ea); } void VmmManager::initPTEs() @@ -211,3 +206,26 @@ void VmmManager::_flushPageTable( void ) lock.unlock(); } + +void* VmmManager::_devMap(void* ra, uint64_t i_devDataSize) +{ + void* ea = NULL; + + lock.lock(); + ea = SegmentManager::devMap(ra, i_devDataSize); + lock.unlock(); + + return ea; +} + +int VmmManager::_devUnmap(void* ea) +{ + int rc = 0; + + lock.lock(); + rc = SegmentManager::devUnmap(ea); + lock.unlock(); + + return rc; +} + |

