summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barth <msbarth@us.ibm.com>2011-07-22 09:38:14 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2011-08-08 14:21:57 -0500
commit6a8d93daac2c006c06aa1d0d9e963e651b9c64b2 (patch)
treefb7eeb89d0b7b80e64334896973649aab90a2d83
parent0709fbac11be8a30710a34dad5af5f37449d7255 (diff)
downloadtalos-hostboot-6a8d93daac2c006c06aa1d0d9e963e651b9c64b2.tar.gz
talos-hostboot-6a8d93daac2c006c06aa1d0d9e963e651b9c64b2.zip
Device segment MMIO map & unmap system calls
Change-Id: I233c2677909c0c16536133c189ebbd21e4415e22 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/208 Tested-by: Jenkins Server Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
-rw-r--r--src/include/kernel/devicesegment.H100
-rw-r--r--src/include/kernel/segmentmgr.H14
-rw-r--r--src/include/kernel/syscalls.H10
-rw-r--r--src/include/kernel/vmmmgr.H18
-rw-r--r--src/include/sys/mmio.h44
-rw-r--r--src/kernel/devicesegment.C138
-rw-r--r--src/kernel/ptmgr.C10
-rw-r--r--src/kernel/segmentmgr.C4
-rw-r--r--src/kernel/syscall.C29
-rw-r--r--src/kernel/vmmmgr.C27
-rw-r--r--src/lib/syscall_mmio.C10
-rw-r--r--src/usr/testcore/kernel/slbtest.H35
12 files changed, 382 insertions, 57 deletions
diff --git a/src/include/kernel/devicesegment.H b/src/include/kernel/devicesegment.H
index 5fc63819b..fab284165 100644
--- a/src/include/kernel/devicesegment.H
+++ b/src/include/kernel/devicesegment.H
@@ -2,32 +2,114 @@
#define __KERNEL_DEVICESEGMENT_H
#include <kernel/segment.H>
+#include <sys/mmio.h>
+/**
+ * @class DeviceSegment
+ * @brief Manages the device virtual memory segment
+ */
class DeviceSegment : public Segment
{
public:
- DeviceSegment() : Segment(0x020000000000ull)
- {
- for (int i = 0; i < MMIO_MAP_DEVICES; i++)
- iv_mmioMap[i] = 0;
- };
+ /**
+ * @brief Constructor (Device segment at 2TB)
+ */
+ DeviceSegment() : Segment(0x020000000000ull) {};
+
+ /**
+ * @brief Destructor
+ */
~DeviceSegment() {};
+ /**
+ * @brief Add the device segment
+ */
static void init();
+ /**
+ * @brief Handle a page fault for a device address access
+ * @param i_task[in] - Task pointer to the task requiring the page
+ * @param i_addr[in] - 64-bit address needed to be paged
+ * @return bool - true: Page added to page table
+ * false: Not a valid address to be paged
+ */
bool handlePageFault(task_t* i_task, uint64_t i_addr);
- static void* mmioMap(void* ra, size_t pages); // to be deprecated.
- static int mmioUnmap(void* ea, size_t pages); // to be deprecated.
+ /**
+ * @brief DEPRECATED
+ */
+ static void* mmioMap(void* ra, size_t pages);
+
+ /**
+ * @brief DEPRECATED
+ */
+ static int mmioUnmap(void* ea, size_t pages);
+
+ /**
+ * @brief Map a device into the device segment(2TB)
+ * @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
+ */
+ static void* devMap(void* ra, SEG_DATA_SIZES i_devDataSize);
+
+ /**
+ * @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
+ */
+ static int devUnmap(void* ea);
private:
- enum { MMIO_MAP_DEVICES = 32 };
- uint64_t iv_mmioMap[MMIO_MAP_DEVICES];
+ /**
+ * Attributes to represent a mapped device within a segment block
+ */
+ struct devSegData
+ {
+ uint64_t addr; /* Real address assigned to device */
+ SEG_DATA_SIZES size; /* A particular device's segment block size */
+ devSegData(): addr(0),size(THIRTYTWO_GB){};
+ };
+
+ /**
+ * Number of devices that can be mapped with a given segment block size
+ */
+ enum
+ {
+ MMIO_MAP_DEVICES = 32
+ }; //TODO - Only necessary if a device uses a SCOM region other than 32GB
+ devSegData iv_mmioMap[MMIO_MAP_DEVICES];
+
+ /**
+ * @brief Add the device segment
+ */
void _init();
+ /**
+ * @brief DEPRECATED
+ */
void* _mmioMap(void* ra, size_t pages);
+
+ /**
+ * @brief DEPRECATED
+ */
int _mmioUnmap(void* ea, size_t pages);
+
+ /**
+ * @brief Map a device into the device segment(2TB)
+ * @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* _devMap(void* ra, SEG_DATA_SIZES i_devDataSize);
+
+ /**
+ * @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 _devUnmap(void* ea);
};
#endif
diff --git a/src/include/kernel/segmentmgr.H b/src/include/kernel/segmentmgr.H
index 7048fa365..a2f36be20 100644
--- a/src/include/kernel/segmentmgr.H
+++ b/src/include/kernel/segmentmgr.H
@@ -22,11 +22,11 @@ class SegmentManager
/** Segment Identifiers */
enum SegmentIds
{
- /** Base Segment (0-1TB). */
+ /** Base Segment (0-1TB). */
BASE_SEGMENT_ID = 0,
- /** Task Stack Segment (1-2TB). */
+ /** Task Stack Segment (1-2TB). */
STACK_SEGMENT_ID = 1,
- /** MMIO Space Segment (2-3TB). */
+ /** MMIO Space Segment (2-3TB). */
MMIO_SEGMENT_ID = 2,
MAX_SEGMENTS = 4
@@ -78,14 +78,14 @@ class SegmentManager
static void initSLB();
private:
- /** See handlePageFault. */
+ /** See handlePageFault. */
bool _handlePageFault(task_t* i_task, uint64_t i_addr);
- /** See addSegment. */
+ /** See addSegment. */
void _addSegment(Segment* i_segment, size_t i_segId);
- /** See initSLB. */
+ /** See initSLB. */
void _initSLB();
- /** Array of segment objects to associated segment IDs. */
+ /** Array of segment objects to associated segment IDs. */
Segment* iv_segments[MAX_SEGMENTS];
};
diff --git a/src/include/kernel/syscalls.H b/src/include/kernel/syscalls.H
index 5b5e31fc3..a76bb82a9 100644
--- a/src/include/kernel/syscalls.H
+++ b/src/include/kernel/syscalls.H
@@ -46,18 +46,22 @@ namespace Systemcalls
MMIO_MAP,
/** mmio_unmap() */
MMIO_UNMAP,
+ /** dev_map() */
+ DEV_MAP,
+ /** dev_unmap() */
+ DEV_UNMAP,
/** nanosleep() */
TIME_NANOSLEEP,
/** futex_wait() */
- FUTEX_WAIT,
+ FUTEX_WAIT,
/** futex_wake() */
- FUTEX_WAKE,
+ FUTEX_WAKE,
/** shutdown() */
- MISC_SHUTDOWN,
+ MISC_SHUTDOWN,
/** cpu_core_type() */
MISC_CPUCORETYPE,
diff --git a/src/include/kernel/vmmmgr.H b/src/include/kernel/vmmmgr.H
index f57f01677..fe1c2cc73 100644
--- a/src/include/kernel/vmmmgr.H
+++ b/src/include/kernel/vmmmgr.H
@@ -2,12 +2,16 @@
#define __KERNEL_VMMMGR_H
#include <limits.h>
+#include <sys/mmio.h>
#include <kernel/types.h>
#include <kernel/spinlock.H>
class VmmManager
{
public:
+ /**
+ * Constants used throughout the virtual memory management classes
+ */
enum VMM_CONSTS
{
ONE_MEG = 1 * 1024 * 1024,
@@ -49,6 +53,20 @@ class VmmManager
static void* mmioMap(void*, size_t);
static int mmioUnmap(void*, size_t);
+ /**
+ * @brief Map a device into the device segment(2TB)
+ * @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
+ */
+ static void* devMap(void* ra, SEG_DATA_SIZES i_devDataSize);
+
+ /**
+ * @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
+ */
+ static int devUnmap(void* ea);
protected:
VmmManager();
diff --git a/src/include/sys/mmio.h b/src/include/sys/mmio.h
index 35392f22e..37c0a029d 100644
--- a/src/include/sys/mmio.h
+++ b/src/include/sys/mmio.h
@@ -9,29 +9,37 @@ extern "C"
{
#endif
-/** @fn mmio_map()
- * @brief Map a region into virtual address space.
- *
- * @param[in] ra - address of page
- * @param[in] pages - count of pages to map
- *
- * @returns The virtual address where mapped.
+/**
+ * Sizes used to determine segment block size during map/unmap functions
+ * within the kernel or user space
*/
-void* mmio_map(void* ra, size_t pages);
-
+enum SEG_DATA_SIZES
+{
+ THIRTYTWO_GB = 0x800000000,
+};
-/** @fn mmio_unmap()
- * @brief Unmap a region previously mapped into virtual address space.
- *
- * Appears not to be implemented. See _mmioUnmap in src/kernel/vmmmgr.C
- *
- * @param[in] ea - virtual address as returned from mmio_map()
- * @param[in] pages - count of pages to unmap
- *
- * @returns -1 from _mmioUnmap in src/kernel/vmmmgr.C
+/**
+ * @brief DEPRECATED
+ */
+void* mmio_map(void* ra, size_t pages);
+/**
+ * @brief DEPRECATED
*/
int mmio_unmap(void* ea, size_t pages);
+/**
+ * @brief System call to map a device into the device segment(2TB)
+ * @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* mmio_dev_map(void *ra, SEG_DATA_SIZES i_devDataSize);
+/**
+ * @brief System call to 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 mmio_dev_unmap(void *ea);
/** @fn mmio_hmer_read()
* @brief Reads and returns protected HMER register.
diff --git a/src/kernel/devicesegment.C b/src/kernel/devicesegment.C
index 446d17298..6d4a30da9 100644
--- a/src/kernel/devicesegment.C
+++ b/src/kernel/devicesegment.C
@@ -10,59 +10,102 @@
#include <kernel/console.H>
+/**
+ * STATIC
+ * @brief Add the device segment
+ */
void DeviceSegment::init()
{
Singleton<DeviceSegment>::instance()._init();
}
+/**
+ * @brief DEPRECATED
+ */
void* DeviceSegment::mmioMap(void* ra, size_t pages)
{
return Singleton<DeviceSegment>::instance()._mmioMap(ra, pages);
}
+/**
+ * @brief DEPRECATED
+ */
int DeviceSegment::mmioUnmap(void* ea, size_t pages)
{
return Singleton<DeviceSegment>::instance()._mmioUnmap(ea, pages);
}
+/**
+ * STATIC
+ * @brief Map a device into the device segment(2TB)
+ */
+void* DeviceSegment::devMap(void *ra, SEG_DATA_SIZES 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);
+}
+
+/**
+ * @brief Add the device segment
+ */
void DeviceSegment::_init()
{
SegmentManager::addSegment(this, SegmentManager::MMIO_SEGMENT_ID);
}
+/**
+ * @brief Handle a page fault for a device address access
+ * @param i_task[in] - Task pointer to the task requiring the page
+ * @param i_addr[in] - 64-bit address needed to be paged
+ * @return bool - TRUE: Page added to page table
+ * FALSE: Not a valid address to be paged
+ */
bool DeviceSegment::handlePageFault(task_t* i_task, uint64_t i_addr)
{
- // Check address range.
+ //Verify input address falls within this segment's address range
if (i_addr < this->getBaseAddress() ||
- i_addr >= (this->getBaseAddress() + 0x010000000000ull))
+ i_addr >= (this->getBaseAddress() + (1ull << SLBE_s)))
{
return false;
}
- // Check valid device.
+ //Verify the device is mapped
uint64_t segment_ea = i_addr - this->getBaseAddress();
size_t idx = segment_ea / ((1ull << SLBE_s) / MMIO_MAP_DEVICES);
uint64_t device_offset = segment_ea -
(idx * (1ull << SLBE_s) / MMIO_MAP_DEVICES);
-
- if (0 == iv_mmioMap[idx])
+
+ if (0 == iv_mmioMap[idx].addr ||
+ device_offset >= (uint64_t)iv_mmioMap[idx].size)
{
return false;
}
PageTableManager::addEntry((i_addr / PAGESIZE) * PAGESIZE,
- (iv_mmioMap[idx] + device_offset) / PAGESIZE,
+ (iv_mmioMap[idx].addr + device_offset) / PAGESIZE,
VmmManager::CI_ACCESS);
return true;
}
+/**
+ * @brief DEPRECATED
+ */
void* DeviceSegment::_mmioMap(void* ra, size_t pages)
{
for (size_t i = 0; i < MMIO_MAP_DEVICES; i++)
{
- if (0 == iv_mmioMap[i])
+ if (0 == iv_mmioMap[i].addr)
{
- iv_mmioMap[i] = reinterpret_cast<uint64_t>(ra);
+ iv_mmioMap[i].size = THIRTYTWO_GB;
+ iv_mmioMap[i].addr = reinterpret_cast<uint64_t>(ra);
return reinterpret_cast<void*>(i *
((1ull << SLBE_s) / MMIO_MAP_DEVICES) +
this->getBaseAddress());
@@ -72,20 +115,91 @@ void* DeviceSegment::_mmioMap(void* ra, size_t pages)
return NULL;
}
+/**
+ * @brief DEPRECATED
+ */
int DeviceSegment::_mmioUnmap(void* ea, size_t pages)
{
uint64_t segment_ea = reinterpret_cast<uint64_t>(ea) -
this->getBaseAddress();
size_t idx = segment_ea / ((1ull << SLBE_s) / MMIO_MAP_DEVICES);
- if (0 != iv_mmioMap[idx])
+ if (0 != iv_mmioMap[idx].addr)
{
- PageTableManager::delRangePN(iv_mmioMap[idx] / PAGESIZE,
- iv_mmioMap[idx] / PAGESIZE +
+ PageTableManager::delRangePN(iv_mmioMap[idx].addr / PAGESIZE,
+ iv_mmioMap[idx].addr / PAGESIZE +
pages);
- iv_mmioMap[idx] = 0;
+ iv_mmioMap[idx].addr = 0;
return 0;
}
return -1;
}
+/**
+ * @brief Map a device into the device segment(2TB)
+ * @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, SEG_DATA_SIZES i_devDataSize)
+{
+ void *segBlock = NULL;
+ if (i_devDataSize <= THIRTYTWO_GB)
+ {
+ //TODO - Use segment block size if/when new device size needed
+ for (size_t i = 0; i < MMIO_MAP_DEVICES; i++)
+ {
+ if (0 == iv_mmioMap[i].addr)
+ {
+ iv_mmioMap[i].size = i_devDataSize;
+ iv_mmioMap[i].addr = reinterpret_cast<uint64_t>(ra);
+ //TODO - Use segment block size if/when new device size needed
+ segBlock = reinterpret_cast<void*>(i *
+ ((1ull << SLBE_s) / MMIO_MAP_DEVICES) +
+ this->getBaseAddress());
+ break;
+ }
+ }
+ if (segBlock == NULL)
+ {
+ printk("Unable to map device, no empty segment blocks found\n");
+ }
+ }
+ else
+ {
+ printk("Unsupported device segment size(0x%lX), ",i_devDataSize);
+ printk("for address 0x%lX\n",reinterpret_cast<uint64_t>(ra));
+ }
+
+ 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 rc = -1;
+ uint64_t segment_ea = reinterpret_cast<uint64_t>(ea);
+ //Verify input address falls within this segment's address range
+ if (segment_ea < this->getBaseAddress() ||
+ segment_ea >= (this->getBaseAddress() + (1ull << SLBE_s)))
+ {
+ return rc;
+ }
+ segment_ea = segment_ea - this->getBaseAddress();
+ //TODO - Calculate idx by segment block size if/when new device size needed
+ size_t idx = segment_ea / ((1ull << SLBE_s) / MMIO_MAP_DEVICES);
+ if (0 != iv_mmioMap[idx].addr)
+ {
+ //Remove all of the defined block's size (<= 32GB)
+ PageTableManager::delRangePN(iv_mmioMap[idx].addr / PAGESIZE,
+ (iv_mmioMap[idx].addr + iv_mmioMap[idx].size) / PAGESIZE);
+ iv_mmioMap[idx].addr = 0;
+ rc = 0;
+ }
+
+ return rc;
+}
diff --git a/src/kernel/ptmgr.C b/src/kernel/ptmgr.C
index 536930322..c72ca9d24 100644
--- a/src/kernel/ptmgr.C
+++ b/src/kernel/ptmgr.C
@@ -607,11 +607,11 @@ void PageTableManager::writePTE( PageTableEntry* i_pte,
{
Dprintk( ">> PageTableManager::writePTE( i_dest=0x%.lX, i_valid=%d )\n", i_dest, i_valid );
- if( i_valid ) {
- // printPTE( "Writing", i_dest );
- } else {
- printPTE( "Removing", i_dest );
- }
+ //if( i_valid ) {
+ //printPTE( "Writing", i_dest );
+ //} else {
+ //printPTE( "Removing", i_dest );
+ //}
i_dest->V = 0; /* (other fields don't matter) */
diff --git a/src/kernel/segmentmgr.C b/src/kernel/segmentmgr.C
index fae9d3479..625ba61aa 100644
--- a/src/kernel/segmentmgr.C
+++ b/src/kernel/segmentmgr.C
@@ -23,7 +23,7 @@ void SegmentManager::initSLB()
bool SegmentManager::_handlePageFault(task_t* i_task, uint64_t i_addr)
{
- // This constant should come from page manager. Segment size.
+ // This constant should come from page manager. Segment size.
const size_t SLBE_s = 40;
// Get segment ID from effective address.
@@ -48,7 +48,7 @@ void SegmentManager::_initSLB()
{
// Flush SLB.
asm volatile("slbia" ::: "memory");
- isync(); // Ensure slbia completes prior to slbmtes.
+ isync(); // Ensure slbia completes prior to slbmtes.
register uint64_t slbRS, slbRB;
diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C
index 6242c4bcb..f96f8d372 100644
--- a/src/kernel/syscall.C
+++ b/src/kernel/syscall.C
@@ -1,3 +1,4 @@
+#include <assert.h>
#include <kernel/cpu.H>
#include <kernel/cpumgr.H>
#include <kernel/scheduler.H>
@@ -57,6 +58,8 @@ namespace Systemcalls
void MsgWait(task_t*);
void MmioMap(task_t*);
void MmioUnmap(task_t*);
+ void DevMap(task_t*);
+ void DevUnmap(task_t*);
void TimeNanosleep(task_t*);
void FutexWait(task_t *t);
void FutexWake(task_t *t);
@@ -82,6 +85,8 @@ namespace Systemcalls
&MmioMap, // MMIO_MAP
&MmioUnmap, // MMIO_UNMAP
+ &DevMap,
+ &DevUnmap,
&TimeNanosleep, // TIME_NANOSLEEP
@@ -309,6 +314,30 @@ namespace Systemcalls
TASK_SETRTN(t, VmmManager::mmioUnmap(ea,pages));
}
+ /**
+ * Map a device into virtual memory
+ * @param[in] t: The task used to map a device
+ */
+ void DevMap(task_t *t)
+ {
+ void *ra = (void*)TASK_GETARG0(t);
+ SEG_DATA_SIZES devDataSize = (SEG_DATA_SIZES)TASK_GETARG1(t);
+
+ kassert(TASK_SETRTN(t, (uint64_t)VmmManager::devMap(ra,devDataSize)) !=
+ NULL);
+ }
+
+ /**
+ * Unmap a device from virtual memory
+ * @param[in] t: The task used to unmap a device
+ */
+ void DevUnmap(task_t *t)
+ {
+ void *ea = (void*)TASK_GETARG0(t);
+
+ TASK_SETRTN(t, VmmManager::devUnmap(ea));
+ }
+
void TimeNanosleep(task_t* t)
{
TimeManager::delayTask(t, TASK_GETARG0(t), TASK_GETARG1(t));
diff --git a/src/kernel/vmmmgr.C b/src/kernel/vmmmgr.C
index 98e5a0410..bf6ff10d4 100644
--- a/src/kernel/vmmmgr.C
+++ b/src/kernel/vmmmgr.C
@@ -43,16 +43,42 @@ bool VmmManager::pteMiss(task_t* t, uint64_t effAddr)
return Singleton<VmmManager>::instance()._pteMiss(t, effAddr);
}
+/**
+ * STATIC
+ * @brief DEPRECATED
+ */
void* VmmManager::mmioMap(void* ra, size_t pages)
{
return DeviceSegment::mmioMap(ra, pages);
}
+/**
+ * STATIC
+ * @brief DEPRECATED
+ */
int VmmManager::mmioUnmap(void* ea, size_t pages)
{
return DeviceSegment::mmioUnmap(ea, pages);
}
+/**
+ * STATIC
+ * @brief A facade to map a device into the device segment(2TB)
+ */
+void* VmmManager::devMap(void* ra, SEG_DATA_SIZES i_devDataSize)
+{
+ return DeviceSegment::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);
+}
+
void VmmManager::initPTEs()
{
// Initialize and invalidate the page table
@@ -80,4 +106,3 @@ bool VmmManager::_pteMiss(task_t* t, uint64_t effAddr)
return rc;
}
-
diff --git a/src/lib/syscall_mmio.C b/src/lib/syscall_mmio.C
index 3c21c8902..411dfdb41 100644
--- a/src/lib/syscall_mmio.C
+++ b/src/lib/syscall_mmio.C
@@ -16,6 +16,16 @@ int mmio_unmap(void* ea, size_t pages)
return (int64_t) _syscall2(MMIO_UNMAP, ea, (void*)pages);
}
+void* mmio_dev_map(void *ra, SEG_DATA_SIZES i_devDataSize)
+{
+ return _syscall2(DEV_MAP, ra, (void*)i_devDataSize);
+}
+
+int mmio_dev_unmap(void *ea)
+{
+ return (int64_t) _syscall1(DEV_UNMAP, ea);
+}
+
uint64_t mmio_hmer_read()
{
return (uint64_t) _syscall0(MMIO_HMER_READ);
diff --git a/src/usr/testcore/kernel/slbtest.H b/src/usr/testcore/kernel/slbtest.H
index f773efe2d..65fe3bd08 100644
--- a/src/usr/testcore/kernel/slbtest.H
+++ b/src/usr/testcore/kernel/slbtest.H
@@ -9,6 +9,7 @@
#include <arch/ppc.H>
#include <sys/time.h>
#include <sys/task.h>
+#include <sys/mmio.h>
class slbtest: public CxxTest::TestSuite
{
@@ -19,6 +20,7 @@ class slbtest: public CxxTest::TestSuite
void testSLB()
{
rc = 0;
+ printk("Data Segment exception expected in 1TB segment test - ");
task_create(writeEA1TB, this);
while (rc == 0) task_yield();
task_yield();
@@ -28,6 +30,39 @@ class slbtest: public CxxTest::TestSuite
}
}
+ void testDevSeg()
+ {
+ int rc = 0;
+ uint64_t ra = 2*1024*1024;
+ printk("Map Device @ ra = 0x%lX using mmio_map\n",ra);
+ uint64_t* virtAddrMMIO = static_cast<uint64_t*>
+ (mmio_map(reinterpret_cast<void*>(ra), 1));
+ if (virtAddrMMIO == NULL)
+ {
+ TS_FAIL("Failed to map using mmio_map\n");
+ }
+ printk("Unmap Device @ va = %p using mmio_unmap\n",virtAddrMMIO);
+ rc = mmio_unmap(reinterpret_cast<void*>(virtAddrMMIO), 1);
+ if (rc != 0)
+ {
+ TS_FAIL("Failed to unmap using mmio_unmap\n");
+ }
+
+ printk("Map Device @ ra = 0x%lX using dev_map\n",ra);
+ uint64_t* virtAddrDEV = static_cast<uint64_t*>
+ (mmio_dev_map(reinterpret_cast<void*>(ra), THIRTYTWO_GB));
+ if (virtAddrDEV == NULL)
+ {
+ TS_FAIL("Failed to map using mmio_dev_map\n");
+ }
+ printk("Unmap Device @ va = %p using dev_unmap\n",virtAddrDEV);
+ rc = mmio_dev_unmap(reinterpret_cast<void*>(virtAddrDEV));
+ if (rc != 0)
+ {
+ TS_FAIL("Failed to unmap using mmio_dev_unmap\n");
+ }
+ }
+
private:
static void writeEA1TB(void *i_p)
OpenPOWER on IntegriCloud