]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-linux/mpm-transport.git/commitdiff
mpm_transport: Add new API for 64 bit direct read/write
authorSam Nelson <sam.nelson@ti.com>
Mon, 9 Mar 2015 19:19:47 +0000 (15:19 -0400)
committerSam Nelson <sam.nelson@ti.com>
Wed, 15 Apr 2015 20:30:22 +0000 (16:30 -0400)
- Add multithread protection for shared resources
- Modified test code to exercise new APIs
- testcode:  Added command line parameter to control size of xfers
- Fixed issues found in code review
- Updated mmap and unmap API return values to be consistent
- Code cleanup

Signed-off-by: Sam Nelson <sam.nelson@ti.com>
include/mpm_transport.h [changed mode: 0644->0755]
src/transport/hyplnk/mpm_transport_hyplnk.c [changed mode: 0644->0755]
src/transport/hyplnk/mpm_transport_hyplnk.h [changed mode: 0644->0755]
src/transport/mpm_transport.c [changed mode: 0644->0755]
src/transport/mpm_transport_cfg.h
src/transport/sharedmem/mpm_transport_sharedmem.c [changed mode: 0644->0755]
src/transport/sharedmem/mpm_transport_sharedmem.h [changed mode: 0644->0755]
src/transport/test/hyplnk/hyplnk_loopback64/mpm_transport_hyplnk_loopback64.c

old mode 100644 (file)
new mode 100755 (executable)
index 597e50f..3734811
@@ -279,7 +279,7 @@ typedef struct mpm_transport_open_tag {
 } mpm_transport_open_t;
 
 /**
- *  @b Description
+ *  @b Function mpm_transport_packet_send
  *  @n Pushes a message of size len from pointer buf to the destination specified by addr_info
  *
  *     @retval
@@ -291,7 +291,7 @@ typedef struct mpm_transport_open_tag {
 int mpm_transport_packet_send(mpm_transport_h h, char **buf, int *len, mpm_transport_packet_addr_t *addr_info, mpm_transport_send_t *cfg);
 
 /**
- *  @b Description
+ *  @b Function mpm_transport_packet_recv
  *  @n Pops information from the packet_addr_t binded to handle h. Data is copied to buf, of size len.
  *
  *     @retval
@@ -305,7 +305,7 @@ int mpm_transport_packet_recv(mpm_transport_h h, char **buf, int *len, mpm_trans
 
 
 /**
- *  @b Description
+ *  @b Function mpm_transport_peripheral_enable
  *  @n Sets up the transport portion defined by slave_name.
  *
  *  @param[in] slave_name
@@ -323,11 +323,10 @@ int mpm_transport_packet_recv(mpm_transport_h h, char **buf, int *len, mpm_trans
  *             Failure - returns value less than 0 (negative integer)
  *
  */
-
 int mpm_transport_peripheral_enable(char *slave_name, mpm_transport_open_t *cfg);
 
 /**
- *  @b Description
+ *  @b Function mpm_transport_peripheral_disable
  *  @n Disable the transport hardware defined by slave_name.
  *
  *  @param[in] slave_name
@@ -339,44 +338,231 @@ int mpm_transport_peripheral_enable(char *slave_name, mpm_transport_open_t *cfg)
  *             Failure - returns value less than 0 (negative integer)
  *
  */
-
 int mpm_transport_peripheral_disable(char *slave_name);
 
-/*
-       slave_name:  should match the name in config file.
-       cfg: runtime configuration needed for this device.
-       In case of shared memory it might not have anything.
-       Returns mpm_transport_handle or NULL on error.
-*/
+/**
+ *  @b Description: Function mpm_transport_open
+ *  @n Open mpm transport connection
+ *
+ *
+ *  @param[in] slave_name
+ *             Should match the name in config file.
+ *  @param[in] cfg
+ *             Runtime configuration needed for this device
+ *  @retval
+ *             mpm transport handle 
+ *  @retval
+ *             Failure - returns NULL on error
+ *
+ *  @pre
+ *  @post
+ */
 mpm_transport_h mpm_transport_open(char *slave_name, mpm_transport_open_t *cfg);
 
-/*
-       Close mpm_transport connection.
-*/
+/**
+ *  @b Description: Function mpm_transport_close
+ *  @n Close mpm transport connection
+ *
+ *
+ *  @param[in] h
+ *             mpm transport handle
+ *
+ *  @pre
+ *  @post
+ */
 void mpm_transport_close(mpm_transport_h h);
 
-/*
-       Read from slave[DSP] local address and length into the buffer.
-       Returns 0 on success, error code on error.
-*/
+/**
+ *  @b Description: Function mpm_transport_read
+ *  @n Read from specified address on slave device into local buffer
+ *
+ *
+ *  @param[in] h
+ *             mpm transport handle
+ *  @param[in] addr
+ *             Address to read from
+ *  @param[in] length
+ *             Number of bytes to read
+ *  @param[in] buf
+ *             Buffer for storing read bytes
+ *  @param[in] cfg
+ *             Configuration for the read operation
+ *  @retval
+ *             Success - returns 0
+ *  @retval
+ *             Failure - returns error code less than 0 (negative integer)
+ *
+ *  @pre  call to mpm_transport_open is needed before calling this routine
+ *  @post
+ */
 int mpm_transport_read(mpm_transport_h h, uint32_t addr, uint32_t length, char *buf, mpm_transport_read_t *cfg);
 
-/*
-       Write to slave[DSP] local address "addr" with "length" from the buffer "buf".
-       Returns 0 on success, error code on error.
-*/
+/**
+ *  @b Description: Function mpm_transport_write
+ *  @n Write to specified address on slave device from local buffer
+ *
+ *
+ *  @param[in] h
+ *             mpm transport handle
+ *  @param[in] addr
+ *             Address to write
+ *  @param[in] length
+ *             Number of bytes to write
+ *  @param[in] buf
+ *             Buffer with bytes to write
+ *  @param[in] cfg
+ *             Configuration for the write operation
+ *  @retval
+ *             Success - returns 0
+ *  @retval
+ *             Failure - returns error code less than 0 (negative integer)
+ *
+ *  @pre  call to mpm_transport_open is needed before calling this routine
+ *  @post
+ */
 int mpm_transport_write(mpm_transport_h h, uint32_t addr, uint32_t length, char *buf, mpm_transport_write_t *cfg);
 
-/*
-       Creates a mmap for the memory location and returns virtual address.
-*/
+/**
+ *  @b Description: Function mpm_transport_read64
+ *  @n Read from specified address on slave device into local buffer
+ *
+ *
+ *  @param[in] h
+ *             mpm transport handle
+ *  @param[in] addr
+ *             64 bit Address to read from
+ *  @param[in] length
+ *             Number of bytes to read
+ *  @param[in] buf
+ *             Buffer for storing read bytes
+ *  @param[in] cfg
+ *             Configuration for the read operation
+ *  @retval
+ *             Success - returns 0
+ *  @retval
+ *             Failure - returns error code less than 0 (negative integer)
+ *
+ *  @pre  call to mpm_transport_open is needed before calling this routine
+ *  @post
+ */
+int mpm_transport_read64(mpm_transport_h h, uint64_t addr, uint32_t length, char *buf, mpm_transport_read_t *cfg);
+
+/**
+ *  @b Description: Function mpm_transport_write64
+ *  @n Write to specified address on slave device from local buffer
+ *
+ *
+ *  @param[in] h
+ *             mpm transport handle
+ *  @param[in] addr
+ *             64 bit Address to write
+ *  @param[in] length
+ *             Number of bytes to write
+ *  @param[in] buf
+ *             Buffer with bytes to write
+ *  @param[in] cfg
+ *             Configuration for the write operation
+ *  @retval
+ *             Success - returns 0
+ *  @retval
+ *             Failure - returns error code less than 0 (negative integer)
+ *
+ *  @pre  call to mpm_transport_open is needed before calling this routine
+ *  @post
+ */
+int mpm_transport_write64(mpm_transport_h h, uint64_t addr, uint32_t length, char *buf, mpm_transport_write_t *cfg);
+
+/**
+ *  @b Description: Function mpm_transport_mmap
+ *  @n Creates a mmap for the memory location and returns virtual address
+ *
+ *
+ *  @param[in] h
+ *             mpm transport handle
+ *  @param[in] addr
+ *             Address to mmap
+ *  @param[in] length
+ *             length of mmap
+ *  @param[in] cfg
+ *             Configuration for the mmap operation
+ *  @retval
+ *             mmaped Virtual address 
+ *  @retval
+ *             Failure - returns MAP_FAILED: (void *) (-1)
+ *
+ *  @pre  call to mpm_transport_open is needed before calling this routine
+ *  @post
+ */
 void *mpm_transport_mmap(mpm_transport_h h, uint32_t addr, uint32_t length, mpm_transport_mmap_t *cfg);
 
-/*
-       Unmaps transport mmap
-*/
-void mpm_transport_munmap(mpm_transport_h h, void *va, uint32_t length);
+/**
+ *  @b Description: Function mpm_transport_munmap
+ *  @n Undoes the previous mmap
+ *
+ *
+ *  @param[in] h
+ *             mpm transport handle
+ *  @param[in] va
+ *             Virtual address of previous mmap
+ *  @param[in] length
+ *             length of previous mmap
+ *  @param[in] cfg
+ *             Configuration for the mmap operation
+ *  @retval
+ *             Success - returns 0
+ *  @retval
+ *             Failure - returns error code less than 0 (negative integer)
+ *
+ *  @pre  call to mpm_transport_open is needed before calling this routine
+ *  @post
+ */
+int mpm_transport_munmap(mpm_transport_h h, void *va, uint32_t length);
 
+/**
+ *  @b Description: Function mpm_transport_mmap64
+ *  @n Creates a mmap for the memory location and returns virtual address
+ *
+ *
+ *  @param[in] h
+ *             mpm transport handle
+ *  @param[in] addr
+ *             64 bit Address to mmap
+ *  @param[in] length
+ *             length of mmap
+ *  @param[in] cfg
+ *             Configuration for the mmap operation
+ *  @retval
+ *             mmaped Virtual address 
+ *  @retval
+ *             Failure - returns MAP_FAILED: (void *) (-1)
+ *
+ *  @pre  call to mpm_transport_open is needed before calling this routine
+ *  @post
+ */
+void *mpm_transport_mmap64(mpm_transport_h h, uint64_t addr, uint32_t length, mpm_transport_mmap_t *cfg);
+
+/**
+ *  @b Description: Function mpm_transport_munmap64
+ *  @n Undoes the previous mmap
+ *
+ *
+ *  @param[in] h
+ *             mpm transport handle
+ *  @param[in] va
+ *             Virtual address of previous mmap
+ *  @param[in] length
+ *             length of previous mmap
+ *  @param[in] cfg
+ *             Configuration for the mmap operation
+ *  @retval
+ *             Success - returns 0
+ *  @retval
+ *             Failure - returns error code less than 0 (negative integer)
+ *
+ *  @pre  call to mpm_transport_open is needed before calling this routine
+ *  @post
+ */
+int mpm_transport_munmap64(mpm_transport_h h, void *va, uint32_t length);
 /*
        Similar to mpm_transport_read, except memcpy is replaced with EDMA3 operation.
        Returns transaction handle.
old mode 100644 (file)
new mode 100755 (executable)
index 4c33817..9e9b378
 
 #define MAX_DEVICE_NAME_LEN 32
 #define MAX_FDS 32
+
+/* Semaphores for multi thread protection */
 static sem_t context_sem;
+static sem_t mmap_sem;
+static sem_t mpax_sem;
 
 /* Only one set of config can be active at one time. Keep track of it globally */
 hyplnk_peripheral hyplnkActiveIF[NUM_INTERFACES];
@@ -58,6 +62,9 @@ uio_fd_list_t mpm_transport_uio_fd_list[NUM_INTERFACES];
 
 int edma3InstInit[NUM_EDMA3_INSTANCES];
 
+/* Prototype definition of functions */
+int mpm_transport_hyplnk_window_map64(mpm_transport_cfg_t *sp, uint64_t addr, uint32_t length, mpm_transport_mmap_t *mcfg);
+
 static int mpm_transport_get_global_addr (mpm_transport_cfg_t *sp, uint32_t laddr, uint32_t size, uint32_t *gaddr, int *index)
 {
        int i;
@@ -186,7 +193,10 @@ int mpm_transport_hyplnk_open(mpm_transport_cfg_t *sp, mpm_transport_open_t *ocf
                return -1;
        }
 
+       /* Initialise multi thread semaphores */
        sem_init(&context_sem, 0, 1);
+       sem_init(&mmap_sem, 0, 1);
+       sem_init(&mpax_sem, 0, 1);
 
        reg = mpm_transport_hyplnk_register_slave(sp);
        if (reg < 0) return -1;
@@ -259,6 +269,8 @@ int mpm_transport_hyplnk_open(mpm_transport_cfg_t *sp, mpm_transport_open_t *ocf
                        }
                }
        }
+       sp->msmc_cfg_index = -1;
+       sp->rhMpax = NULL;
 
        return 0;
 
@@ -279,6 +291,7 @@ int mpm_transport_hyplnk_window_map(mpm_transport_cfg_t *sp, uint32_t addr, uint
 #if TIME_PROFILE_HYPLNK_WINDOW_MAP
        clock_gettime(CLOCK_MONOTONIC, &tp_start);
 #endif
+       sem_wait(&mmap_sem);
        /* Find a free mmap index to use */
        for (user_index = 0; user_index < MPM_MAX_USER_MMAPS; user_index++) {
                if (!td->mmap_user[user_index].addr) {
@@ -288,12 +301,14 @@ int mpm_transport_hyplnk_window_map(mpm_transport_cfg_t *sp, uint32_t addr, uint
 
        if (user_index >= MPM_MAX_USER_MMAPS) {
                mpm_printf(1, "exceeded maximum user mmap limits (%d)\n",
-                       MPM_MAX_USER_MMAPS);
+                       MPM_MAX_USER_MMAPS);
+               sem_post(&mmap_sem);
                return -1;
        }
 
        if(mpm_transport_get_global_addr(sp, addr, length, &gaddr, &index)) {
                mpm_printf(1, "can't find global address for local address 0x%x\n", addr);
+               sem_post(&mmap_sem);
                return -1;
        }
 
@@ -316,7 +331,8 @@ int mpm_transport_hyplnk_window_map(mpm_transport_cfg_t *sp, uint32_t addr, uint
        td->mmap_user[user_index].addr = mpm_transport_hyplnk_get_window(td, gaddr, seg_idx, &hlink_offset);
        if (td->mmap_user[user_index].addr == NULL) {
                mpm_printf(1, "can't mmap for the address 0x%x with length 0x%x (err: %s)\n",
-                       addr, length, strerror(errno));
+                       addr, length, strerror(errno));
+               sem_post(&mmap_sem);
                return -1;
        }
        else {
@@ -330,6 +346,7 @@ int mpm_transport_hyplnk_window_map(mpm_transport_cfg_t *sp, uint32_t addr, uint
        td->mmap_user[user_index].size = length;
        td->mmap_user[user_index].addr_usr = td->mmap_user[user_index].addr + hlink_offset;
        td->mmap_user[user_index].phy_addr = hyplnkActiveIF[td->hyplnkIF].physWindowBase + hlink_offset;
+       sem_post(&mmap_sem);
 
        return user_index;
 }
@@ -342,7 +359,25 @@ void *mpm_transport_hyplnk_mmap(mpm_transport_cfg_t *sp, uint32_t addr, uint32_t
        if (index < 0)
        {
                mpm_printf(1, "hyperlink window mapping error!\n");
-               return 0;
+               return MAP_FAILED;
+       }
+       mpm_printf(2, "[debug] index is %d\n",index);
+       mpm_printf(2, "[debug] addr is 0x%08x\n", (uint32_t) td->mmap_user[index].addr);
+       mpm_printf(2, "[debug] addr_usr is 0x%08x\n",(uint32_t) td->mmap_user[index].addr_usr);
+       mpm_printf(2, "[debug] phy_addr is 0x%08x\n",td->mmap_user[index].phy_addr);
+       return (td->mmap_user[index].addr_usr);
+}
+
+
+void *mpm_transport_hyplnk_mmap64(mpm_transport_cfg_t *sp, uint64_t addr, uint32_t length, mpm_transport_mmap_t *mcfg)
+{
+       int index;
+       mpm_transport_hyplnk_t *td = (mpm_transport_hyplnk_t *) sp->td;
+       index = mpm_transport_hyplnk_window_map64(sp, addr, length, mcfg);
+       if (index < 0)
+       {
+               mpm_printf(1, "hyperlink window map64 mapping error!\n");
+               return MAP_FAILED;
        }
        mpm_printf(2, "[debug] index is %d\n",index);
        mpm_printf(2, "[debug] addr is 0x%08x\n", (uint32_t) td->mmap_user[index].addr);
@@ -368,11 +403,23 @@ uint32_t mpm_transport_hyplnk_phys_map(mpm_transport_cfg_t *sp, uint32_t addr, u
        return (td->mmap_user[index].phy_addr);
 }
 
+static void clear_mmap_entry(mpm_transport_hyplnk_t *td, int user_index)
+{
+       hyplnkActiveIF[td->hyplnkIF].hyplnkSegments &= ~(1<<td->mmap_user[user_index].hyplnk_idx);
+       td->mmap_user[user_index].addr = 0;
+       td->mmap_user[user_index].size = 0;
+       td->mmap_user[user_index].addr_usr = 0;
+       td->mmap_user[user_index].phy_addr = 0;
+       td->mmap_user[user_index].logical_addr = 0;
+       td->mmap_user[user_index].hyplnk_idx = 0;
+}
+
 int mpm_transport_hyplnk_munmap(mpm_transport_cfg_t *sp, void *va, uint32_t length)
 {
        int user_index;
        mpm_transport_hyplnk_t *td = (mpm_transport_hyplnk_t *) sp->td;
 
+       sem_wait(&mmap_sem);
        for (user_index = 0; user_index < MPM_MAX_USER_MMAPS; user_index++) {
                if (td->mmap_user[user_index].addr_usr == va) {
                        break;
@@ -381,62 +428,72 @@ int mpm_transport_hyplnk_munmap(mpm_transport_cfg_t *sp, void *va, uint32_t leng
 
        if (user_index >= MPM_MAX_USER_MMAPS) {
                mpm_printf(1, "can't find mapping to unmap\n");
+               sem_post(&mmap_sem);
                return -1;
        }
-       hyplnkActiveIF[td->hyplnkIF].hyplnkSegments &= ~(1<<td->mmap_user[user_index].hyplnk_idx);
-       td->mmap_user[user_index].addr = 0;
-       td->mmap_user[user_index].size = 0;
-       td->mmap_user[user_index].addr_usr = 0;
-       td->mmap_user[user_index].phy_addr = 0;
-       td->mmap_user[user_index].logical_addr = 0;
-       td->mmap_user[user_index].hyplnk_idx = 0;
+       clear_mmap_entry(td, user_index);
+       sem_post(&mmap_sem);
+
        return 0;
 }
 
-int mpm_transport_hyplnk_phys_unmap(mpm_transport_cfg_t *sp, void *va, uint32_t length)
+static void mpm_transport_hyplnk_rw_unmap(mpm_transport_cfg_t *sp, int user_index, uint32_t length) 
 {
-       int user_index, logical_idx, logical_addr;
+       int logical_idx, logical_addr;
        mpm_transport_hyplnk_t *td = (mpm_transport_hyplnk_t *) sp->td;
 
+       /* Record logical address */
+       logical_addr = td->mmap_user[user_index].logical_addr;
+       if (logical_addr)
+               mpm_transport_keystone_unmap(sp->rhMpax, logical_addr, length);
+
+       clear_mmap_entry(td, user_index);
+}
+
+int mpm_transport_hyplnk_munmap64(mpm_transport_cfg_t *sp, void *va, uint32_t length)
+{
+       int user_index;
+       mpm_transport_hyplnk_t *td = (mpm_transport_hyplnk_t *) sp->td;
+
+       sem_wait(&mmap_sem);
+
+       /* Find entry of virtual address in list */
        for (user_index = 0; user_index < MPM_MAX_USER_MMAPS; user_index++) {
-               if (td->mmap_user[user_index].phy_addr == (uint32_t) va) {
+               if (td->mmap_user[user_index].addr_usr == va) {
                        break;
                }
        }
 
        if (user_index >= MPM_MAX_USER_MMAPS) {
                mpm_printf(1, "can't find mapping to unmap\n");
+               sem_post(&mmap_sem);
                return -1;
        }
-       logical_addr = td->mmap_user[user_index].logical_addr;
-       if (logical_addr)
-       {
-               for (logical_idx = 0; logical_idx < MPM_MAX_USER_MMAPS; logical_idx++) {
-                       if (td->mmap_user[logical_idx].logical_addr == logical_addr) {
-                               break;
-                       }
-               }
+       mpm_transport_hyplnk_rw_unmap(sp, user_index, length);
+       sem_post(&mmap_sem);
+
+       return 0;
+}
 
-               /* Found logical address to unmap. Otherwise, skip this part */
-               if (logical_idx < MPM_MAX_USER_MMAPS) {
-                       mpm_transport_keystone_unmap(sp->rhMpax,logical_addr,sp->mpax_size);
-                       hyplnkActiveIF[td->hyplnkIF].hyplnkSegments &= ~(1<<td->mmap_user[logical_idx].hyplnk_idx);
-                       td->mmap_user[logical_idx].addr = 0;
-                       td->mmap_user[logical_idx].size = 0;
-                       td->mmap_user[logical_idx].addr_usr = 0;
-                       td->mmap_user[logical_idx].phy_addr = 0;
-                       td->mmap_user[logical_idx].logical_addr = 0;
-                       td->mmap_user[logical_idx].hyplnk_idx = 0;
+int mpm_transport_hyplnk_phys_unmap(mpm_transport_cfg_t *sp, void *va, uint32_t length)
+{
+       int user_index, logical_idx, logical_addr;
+       mpm_transport_hyplnk_t *td = (mpm_transport_hyplnk_t *) sp->td;
+
+       sem_wait(&mmap_sem);
+       for (user_index = 0; user_index < MPM_MAX_USER_MMAPS; user_index++) {
+               if (td->mmap_user[user_index].phy_addr == (uint32_t) va) {
+                       break;
                }
        }
 
-       hyplnkActiveIF[td->hyplnkIF].hyplnkSegments &= ~(1<<td->mmap_user[user_index].hyplnk_idx);
-       td->mmap_user[user_index].addr = 0;
-       td->mmap_user[user_index].size = 0;
-       td->mmap_user[user_index].addr_usr = 0;
-       td->mmap_user[user_index].phy_addr = 0;
-       td->mmap_user[user_index].logical_addr = 0;
-       td->mmap_user[user_index].hyplnk_idx = 0;
+       if (user_index >= MPM_MAX_USER_MMAPS) {
+               mpm_printf(1, "can't find mapping to unmap\n");
+               sem_post(&mmap_sem);
+               return -1;
+       }
+       mpm_transport_hyplnk_rw_unmap(sp, user_index, length);
+       sem_post(&mmap_sem);
        return 0;
 }
 
@@ -457,6 +514,23 @@ void *mpm_transport_hyplnk_rw_map (mpm_transport_cfg_t *sp, uint32_t addr, uint3
        return (td->mmap_user[*index].addr_usr);
 }
 
+void *mpm_transport_hyplnk_rw_map64 (mpm_transport_cfg_t *sp, uint64_t addr, uint32_t length, int *index)
+{
+       mpm_transport_hyplnk_t *td = (mpm_transport_hyplnk_t *) sp->td;
+       mpm_transport_mmap_t mcfg = {
+               .mmap_prot      = (PROT_READ|PROT_WRITE),
+               .mmap_flags     = MAP_SHARED,
+       };
+
+       *index = mpm_transport_hyplnk_window_map64(sp, addr, length, &mcfg);
+       if (*index < 0)
+       {
+               mpm_printf(1, "hyperlink window mapping error!\n");
+               return 0;
+       }
+       return (td->mmap_user[*index].addr_usr);
+}
+
 int mpm_transport_hyplnk_read(mpm_transport_cfg_t *sp, uint32_t addr, uint32_t length, char *buf, mpm_transport_read_t *rcfg)
 {
        int index = 0;
@@ -469,7 +543,9 @@ int mpm_transport_hyplnk_read(mpm_transport_cfg_t *sp, uint32_t addr, uint32_t l
                return -1;
        }
        memcpy(buf, mmap_addr, length);
-       mpm_transport_hyplnk_munmap(sp, mmap_addr, length);
+       sem_wait(&mmap_sem);
+       mpm_transport_hyplnk_rw_unmap(sp, index, length);
+       sem_post(&mmap_sem);
        return 0;
 }
 
@@ -485,10 +561,49 @@ int mpm_transport_hyplnk_write(mpm_transport_cfg_t *sp, uint32_t addr, uint32_t
                return -1;
        }
        memcpy(mmap_addr, buf, length);
-       mpm_transport_hyplnk_munmap(sp, mmap_addr, length);
+       sem_wait(&mmap_sem);
+       mpm_transport_hyplnk_rw_unmap(sp, index, length);
+       sem_post(&mmap_sem);
+       return 0;
+}
+
+int mpm_transport_hyplnk_read64(mpm_transport_cfg_t *sp, uint64_t addr, uint32_t length, char *buf, mpm_transport_read_t *rcfg)
+{
+       int index = 0;
+       void *mmap_addr;
+
+       mmap_addr = mpm_transport_hyplnk_rw_map64 (sp, addr, length, &index);
+       if (!mmap_addr) {
+               mpm_printf(1, "can't map for address 0x%x\n", addr);
+               return -1;
+       }
+
+       memcpy(buf, mmap_addr, length);
+       sem_wait(&mmap_sem);
+       mpm_transport_hyplnk_rw_unmap(sp, index, length);
+       sem_post(&mmap_sem);
        return 0;
 }
 
+int mpm_transport_hyplnk_write64(mpm_transport_cfg_t *sp, uint64_t addr, uint32_t length, char *buf, mpm_transport_write_t *cfg)
+{
+       int index = 0;
+       void *mmap_addr;
+
+       mmap_addr = mpm_transport_hyplnk_rw_map64 (sp, addr, length, &index);
+
+       if (!mmap_addr) {
+               mpm_printf(1, "can't map for address 0x%x\n", addr);
+               return -1;
+       }
+       memcpy(mmap_addr, buf, length);
+       sem_wait(&mmap_sem);
+       mpm_transport_hyplnk_rw_unmap(sp, index, length);
+       sem_post(&mmap_sem);
+       return 0;
+}
+
+
 mpm_transport_trans_h mpm_transport_hyplnk_get_initiate(mpm_transport_cfg_t *sp, uint32_t from_addr, uint32_t to_addr, uint32_t length, bool is_blocking, mpm_transport_read_t *cfg)
 {
 #if TIME_PROFILE_HYPLNK_GET_INITIATE
@@ -830,6 +945,12 @@ void mpm_transport_hyplnk_close(mpm_transport_cfg_t *sp)
        if (!td) {
                return;
        }
+
+       if (sp->msmc_cfg_index >= 0) {
+               clear_mmap_entry(td, sp->msmc_cfg_index);
+               sp->msmc_cfg_index = -1;
+       }
+
        index = td->hyplnkIF;
        reg = mpm_transport_hyplnk_unregister_slave(sp);
        if (reg) {
@@ -850,6 +971,7 @@ void mpm_transport_hyplnk_close(mpm_transport_cfg_t *sp)
 
        if (sp->rhMpax) {
                mpm_transport_keystone_free(sp->rhMpax);
+               sp->rhMpax = NULL;
        }
 
        for (i = 0; i < MPM_MAX_USER_MMAPS; i++) {
@@ -875,36 +997,56 @@ void mpm_transport_hyplnk_close(mpm_transport_cfg_t *sp)
                memset( mpm_transport_uio_fd_list, 0, sizeof(uio_fd_list_t)*2);
                memset(hyplnkActiveIF, 0, sizeof(hyplnk_peripheral)*2);
        }
+       sem_destroy(&context_sem);
+       sem_destroy(&mmap_sem);
+       sem_destroy(&mpax_sem);
        if (td) free(td);
 }
 
-uint32_t mpm_transport_hyplnk_phys_map64(mpm_transport_cfg_t *sp, uint64_t addr, uint32_t length, mpm_transport_mmap_t *mcfg)
+int mpm_transport_hyplnk_window_map64(mpm_transport_cfg_t *sp, uint64_t addr, uint32_t length, mpm_transport_mmap_t *mcfg)
 {
        int index, logical_addr;
        mpm_transport_hyplnk_t *td = (mpm_transport_hyplnk_t *) sp->td;
        if (((addr>>32)&(0xFFFFFFFF)) == 0)
-               index = mpm_transport_hyplnk_window_map(sp, addr, length, mcfg);
+               index = mpm_transport_hyplnk_window_map(sp, (uint32_t)addr, length, mcfg);
        else
        {
-               index = mpm_transport_hyplnk_window_map(sp, CSL_MSMC_CFG_REGS, 0x100000, mcfg);
-               if (index < 0) {
-                       mpm_printf(1, "mpm_transport_hyplnk_phys_map64: Error mapping to remote MSMC!\n");
-                       return 0;
+               sem_wait(&mpax_sem);
+               if(sp->msmc_cfg_index < 0) {
+                       index = mpm_transport_hyplnk_window_map(sp, CSL_MSMC_CFG_REGS, 0x100000, mcfg); 
+                       if (index < 0) {
+                               mpm_printf(1, "mpm_transport_hyplnk_phys_map64: Error mapping to remote MSMC!\n");
+                               return -1;
+                       }
+                       sp->msmc_cfg_index = index;
                }
                if (!(sp->rhMpax)) {
-                       sp->rhMpax = mpm_transport_keystone_mmap_open(sp->mpax_base, sp->mpax_size, sp->mpax_index, sp->mpax_count, td->mmap_user[index].phy_addr, td->fd[td->hyplnkIF], 14);
+                       sp->rhMpax = mpm_transport_keystone_mmap_open(sp->mpax_base, sp->mpax_size,
+                               sp->mpax_index, sp->mpax_count, td->mmap_user[sp->msmc_cfg_index].phy_addr, 
+                               td->fd[td->hyplnkIF], 14);
+                       if(sp->rhMpax == NULL)
+                               return -1;
                }
+               sem_post(&mpax_sem);
                logical_addr = mpm_transport_keystone_mmap(sp->rhMpax, addr, length);
                mpm_printf(2, "Got hyplnk-mapped msmc config logical_addr: 0x%08x\n",logical_addr);
-               //mpm_transport_hyplnk_phys_unmap(sp, td->mmap_user[index].phy_addr, 0);
-               td->mmap_user[index].logical_addr = logical_addr;
+
                index = mpm_transport_hyplnk_window_map(sp, logical_addr, length, mcfg);
                if (index < 0) {
                        mpm_printf(1, "mpm_transport_hyplnk_phys_map64: Error mapping to remote logical address!\n");
-                       return 0;
+                       return -1;
                }
                td->mmap_user[index].logical_addr = logical_addr;
        }
+       return(index);
+}
+
+uint32_t mpm_transport_hyplnk_phys_map64(mpm_transport_cfg_t *sp, uint64_t addr, uint32_t length, mpm_transport_mmap_t *mcfg)
+{
+       int index;
+       mpm_transport_hyplnk_t *td = (mpm_transport_hyplnk_t *) sp->td;
+
+       index = mpm_transport_hyplnk_window_map64(sp, addr,length, mcfg);
        if (index < 0)
        {
                mpm_printf(1, "hyperlink window mapping error!\n");
old mode 100644 (file)
new mode 100755 (executable)
index d10bf5e..d0347b7
@@ -96,11 +96,17 @@ int mpm_transport_hyplnk_read(mpm_transport_cfg_t *sp, uint32_t addr, uint32_t l
 
 int mpm_transport_hyplnk_write(mpm_transport_cfg_t *sp, uint32_t addr, uint32_t length, char *buf, mpm_transport_write_t *wcfg);
 
+int mpm_transport_hyplnk_read64(mpm_transport_cfg_t *sp, uint64_t addr, uint32_t length, char *buf, mpm_transport_read_t *rcfg);
+
+int mpm_transport_hyplnk_write64(mpm_transport_cfg_t *sp, uint64_t addr, uint32_t length, char *buf, mpm_transport_write_t *cfg);
+
 void *mpm_transport_hyplnk_mmap(mpm_transport_cfg_t *sp, uint32_t addr, uint32_t length, mpm_transport_mmap_t *mcfg);
 
 int mpm_transport_hyplnk_munmap(mpm_transport_cfg_t *sp, void *va, uint32_t length);
 
-int mpm_transport_hyplnk_munmap(mpm_transport_cfg_t *sp, void *va, uint32_t length);
+void *mpm_transport_hyplnk_mmap64(mpm_transport_cfg_t *sp, uint64_t addr, uint32_t length, mpm_transport_mmap_t *mcfg);
+\r
+int mpm_transport_hyplnk_munmap64(mpm_transport_cfg_t *sp, void *va, uint32_t length);
 
 void mpm_transport_hyplnk_close(mpm_transport_cfg_t *sp);
 
old mode 100644 (file)
new mode 100755 (executable)
index 22e51b4..8d61f44
@@ -1234,6 +1234,32 @@ int mpm_transport_read(mpm_transport_h h, uint32_t addr, uint32_t length, char *
        return 0;
 }
 
+/*
+       Read from slave[DSP] local address and length into the buffer.
+       Returns 0 on success, error code on error.
+*/
+int mpm_transport_read64(mpm_transport_h h, uint64_t addr, uint32_t length, char *buf, mpm_transport_read_t *cfg)
+{
+       mpm_transport_cfg_t *sp = (mpm_transport_cfg_t *)h;
+       if (!h) {
+               mpm_printf(1, "invalid handle \n");
+               return -1;
+       }
+       switch (sp->transport) {
+               case hyperlink:
+                       if (mpm_transport_hyplnk_read64(sp, addr, length, buf, cfg)) {
+                               mpm_printf(1, "hyplnk read failed\n");
+                               return -1;
+                       }
+                       break;
+               case shared_memory:
+               default:
+                       mpm_printf(1, "unsupported transport %d\n", sp->transport);
+                       return -1;
+       }
+       return 0;
+}
+
 /*
        Similar to mpm_transport_read, except memcpy is replaced with EDMA3 operation.
        Returns 0 on success, error code on error.
@@ -1263,6 +1289,32 @@ mpm_transport_trans_h mpm_transport_get_initiate(mpm_transport_h h, uint32_t fro
        return tp;
 }
 
+/*
+       Write to slave[DSP] local address "addr" with "length" from the buffer "buf".
+       Returns 0 on success, error code on error.
+*/
+int mpm_transport_write64(mpm_transport_h h, uint64_t addr, uint32_t length, char *buf, mpm_transport_write_t *cfg)
+{
+       mpm_transport_cfg_t *sp = (mpm_transport_cfg_t *)h;
+       if (!h) {
+               mpm_printf(1, "invalid handle \n");
+               return -1;
+       }
+       switch (sp->transport) {
+               case hyperlink:
+                       if (mpm_transport_hyplnk_write64(sp, addr, length, buf, cfg)) {
+                               mpm_printf(1, "hyplnk write64 failed\n");
+                               return -1;
+                       }
+                       break;
+               case shared_memory:
+               default:
+                       mpm_printf(1, "unsupported transport %d\n", sp->transport);
+                       return -1;
+       }
+       return 0;
+}
+
 /*
        Write to slave[DSP] local address "addr" with "length" from the buffer "buf".
        Returns 0 on success, error code on error.
@@ -1418,7 +1470,7 @@ void *mpm_transport_mmap(mpm_transport_h h, uint32_t addr, uint32_t length, mpm_
        mpm_transport_cfg_t *sp = (mpm_transport_cfg_t *)h;
        if (!h) {
                mpm_printf(1, "invalid handle \n");
-               return (void *) -1;
+               return MAP_FAILED;
        }
        switch (sp->transport) {
                case shared_memory:
@@ -1430,7 +1482,28 @@ void *mpm_transport_mmap(mpm_transport_h h, uint32_t addr, uint32_t length, mpm_
                default:
                        mpm_printf(1, "unsupported transport %d\n", sp->transport);
        }
-       return (void *) -1;
+       return MAP_FAILED;
+}
+
+/*
+       Creates a mmap for the 64 bit memory location and returns virtual address.
+*/
+void *mpm_transport_mmap64(mpm_transport_h h, uint64_t addr, uint32_t length, mpm_transport_mmap_t *cfg)
+{
+       mpm_transport_cfg_t *sp = (mpm_transport_cfg_t *)h;
+       if (!h) {
+               mpm_printf(1, "invalid handle \n");
+               return MAP_FAILED;
+       }
+       switch (sp->transport) {
+               case hyperlink:
+                       return (mpm_transport_hyplnk_mmap64(sp, addr, length, cfg));
+                       break;
+               case shared_memory:
+               default:
+                       mpm_printf(1, "unsupported transport %d\n", sp->transport);
+       }
+       return MAP_FAILED;
 }
 
 /*
@@ -1457,32 +1530,60 @@ uint32_t mpm_transport_phys_map(mpm_transport_h h, uint32_t addr, uint32_t lengt
 }
 
 /*
-       Creates a mmap for the memory location and returns virtual address.
+       Unmaps previous mmap from mapped virtual address
 */
-void mpm_transport_munmap(mpm_transport_h h, void *va, uint32_t length)
+int mpm_transport_munmap(mpm_transport_h h, void *va, uint32_t length)
 {
        mpm_transport_cfg_t *sp = (mpm_transport_cfg_t *)h;
        if (!h) {
                mpm_printf(1, "invalid handle \n");
-               return;
+               return -1;
        }
        switch (sp->transport) {
                case shared_memory:
                        if (mpm_transport_sharedmem_munmap(sp, va, length)) {
                                mpm_printf(1, "shm munmap failed\n");
-                               return;
+                               return -1;
                        }
                        break;
                case hyperlink:
                        if (mpm_transport_hyplnk_munmap(sp, va, length)) {
                                mpm_printf(1, "shm munmap failed\n");
-                               return;
+                               return -1;
                        }
                        break;
                default:
                        mpm_printf(1, "unsupported transport %d\n", sp->transport);
-                       return;
+                       return -1;
        }
+       return 0;
+}
+
+/*
+       Unmaps previous 64 bit mmap from mapped virtual address
+*/
+int mpm_transport_munmap64(mpm_transport_h h, void *va, uint32_t length)
+{
+       mpm_transport_cfg_t *sp = (mpm_transport_cfg_t *)h;
+       if (!h) {
+               mpm_printf(1, "invalid handle \n");
+               return -1;
+       }
+       switch (sp->transport) {
+
+               case hyperlink:
+                       if (mpm_transport_hyplnk_munmap64(sp, va, length)) {
+                               mpm_printf(1, "shm munmap failed\n");
+                               return -1;
+                       }
+                       break;
+
+               case shared_memory:
+               default:
+                       mpm_printf(1, "unsupported transport %d\n", sp->transport);
+                       return -1;
+       }
+       return 0;
 }
 
 /*
index cef83f802cf4de161d9f6bc3f0499bcc36a06548..f8ee3b16abfc0f1460f79c5cea7f9008f3e818bc 100644 (file)
@@ -120,6 +120,7 @@ typedef struct mpm_transport_cfg {
        unsigned int mpax_count;
        char mpax_name[MPM_MAX_NAME_LENGTH];
        Rm_ServiceHandle *rmClientServiceHandle;
+       int msmc_cfg_index;
        void *td;
 } mpm_transport_cfg_t;
 
old mode 100644 (file)
new mode 100755 (executable)
index fbc7600..fec6849
@@ -128,12 +128,12 @@ void *mpm_transport_sharedmem_mmap(mpm_transport_cfg_t *sp, uint32_t addr, uint3
        if (user_index >= MPM_MAX_USER_MMAPS) {
                mpm_printf(1, "exceeded maximum user mmap limits (%d)\n",
                                MPM_MAX_USER_MMAPS);
-               return -1;
+               return MAP_FAILED;
        }
 
        if(mpm_transport_get_global_addr(sp, addr, length, &gaddr, &index)) {
                mpm_printf(1, "can't find global address for local address 0x%x\n", addr);
-               return -1;
+               return MAP_FAILED;
        }
 
        offset = gaddr;
@@ -148,7 +148,7 @@ void *mpm_transport_sharedmem_mmap(mpm_transport_cfg_t *sp, uint32_t addr, uint3
        if (td->mmap_user[user_index].addr == MAP_FAILED) {
                mpm_printf(1, "can't mmap for the address 0x%x with length 0x%x (err: %s)\n",
                        addr, length, strerror(errno));
-               return 0;
+               return MAP_FAILED;
        }
        td->mmap_user[user_index].size = mmap_length;
        td->mmap_user[user_index].addr_usr = td->mmap_user[user_index].addr + (offset - pg_offset);
index daa1379eda885324586700c21c7031e1fe6bc8f7..c7ad733f87e062fddcd14151804131dea9c67f1f 100644 (file)
@@ -39,6 +39,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <time.h>
 
 #include <sys/mman.h>
 #include <errno.h>
 #include <semaphore.h>
 #include <ti/sdo/edma3/drv/edma3_drv.h>
 #include "mpm_transport.h"
+static int64_t clock_diff (struct timespec *start, struct timespec *end)
+{
+    return (end->tv_sec - start->tv_sec) * 1000000000 
+             + end->tv_nsec - start->tv_nsec;
+}
 
 #define CONVERT_ULL_TO_ALIAS(x) (0x80000000 + (x - 0x800000000))
 
@@ -103,22 +109,65 @@ int verify_data(uint32_t dst, uint32_t length, uint32_t val)
                if ( *(dstBuff+i) != val) {
                        printf(" FAILED!\n");
                        printf("!! Data verification failed for address 0x%08x\n",dst+i);
+                       printf("!! Index %d:  Expected %x : got %x \n", i, val, *(dstBuff+i));
                        return -1;
                }
        }
        printf(" PASSED!\n");
        return 0;
 }
+int verify_buffer_data(uint32_t *dstBuff, uint32_t length, uint32_t val)
+{
+       uint32_t i;
+       printf("->Verifying data for test destination 0x%08x... \t",dstBuff);
+       for (i = 0; i<length/4; i++) {
+               if ( *(dstBuff+i) != val) {
+                       printf(" FAILED!\n");
+                       printf("!! Data verification failed for address 0x%08x\n",dstBuff+i);
+                       printf("!! Index %d: Expected %x : got %x \n", i, val, *(dstBuff+i));
+                       return -1;
+               }
+       }
+       printf(" PASSED!\n");
+       return 0;
+}
+int verify_buffer_data1(uint32_t *dstBuff, uint32_t length, uint32_t val)
+{
+       uint32_t i;
+       uint32_t diff_time;
+       struct timespec tp_start, tp_end;
+       printf("->Verifying data for test destination 0x%08x... \t",dstBuff);
 
-int main()
+       clock_gettime(CLOCK_MONOTONIC, &tp_start);
+
+       for (i = 0; i<length/4; i++) {
+               if ( *(dstBuff+i) != val) {
+                       printf(" FAILED!\n");
+                       printf("!! Data verification failed for address 0x%08x\n",dstBuff+i);
+                       printf("!! Index %d: Expected %x : got %x \n", i, val, *(dstBuff+i));
+                       return -1;
+               }
+       }
+       clock_gettime(CLOCK_MONOTONIC, &tp_end);
+       printf(" PASSED!\n");
+       diff_time = clock_diff (&tp_start, &tp_end);
+       printf(" verify mmap64 diff time  %d ns \n",diff_time);
+
+       return 0;
+}
+int main(int argc, char *argv[])
 {
        int i, ret =0;
        int check1, check2;
        uint32_t *srcBuff;
+       uint32_t *testBuf, *testBuf1;
        mpm_transport_h h = NULL;
        mpm_transport_h h2 = NULL;
        mpm_transport_trans_h th;
        mpm_transport_trans_h th2;
+       uint32_t diff_time;
+       struct timespec tp_start, tp_end, tp_end1, tp_end2;
+       int read_write_size = TEST_BUFFER_SIZE;
 
        mpm_transport_open_t ocfg = {
                .open_mode      = (O_SYNC|O_RDWR),
@@ -126,37 +175,136 @@ int main()
                .serdes_init = 0,
        };
 
+       if( argc >= 2 )
+               sscanf (argv[1], "%x", &read_write_size);
+
+       printf("\n Test read write size 0x%x \n", read_write_size);
+       testBuf = malloc(read_write_size*sizeof(uint32_t));
+       if (testBuf == NULL) {
+               printf("\n Error allocating test buffer *");
+               exit(0);
+       }
+
        // Fill in some dummy data...
        dev_mem_fd = open("/dev/mem", (O_RDWR|O_SYNC));
-       srcBuff = (uint32_t *) my_mmap(CONVERT_ULL_TO_ALIAS(TEST_SOURCE1), TEST_BUFFER_SIZE);
-       for (i = 0; i<TEST_BUFFER_SIZE/4; i++) {
+       srcBuff = (uint32_t *) my_mmap(CONVERT_ULL_TO_ALIAS(TEST_SOURCE1), read_write_size );
+       for (i = 0; i<read_write_size /4; i++) {
                *(srcBuff+i) = 0xFEEDFEED;
        }
-       srcBuff = (uint32_t *) my_mmap(CONVERT_ULL_TO_ALIAS(TEST_SOURCE2), TEST_BUFFER_SIZE);
-       for (i = 0; i<TEST_BUFFER_SIZE/4; i++) {
+       srcBuff = (uint32_t *) my_mmap(CONVERT_ULL_TO_ALIAS(TEST_SOURCE2), read_write_size );
+       for (i = 0; i<read_write_size /4; i++) {
                *(srcBuff+i) = 0xBABEBABE;
        }
-       srcBuff = (uint32_t *) my_mmap(CONVERT_ULL_TO_ALIAS(TEST_SOURCE3), TEST_BUFFER_SIZE);
-       for (i = 0; i<TEST_BUFFER_SIZE/4; i++) {
+       srcBuff = (uint32_t *) my_mmap(CONVERT_ULL_TO_ALIAS(TEST_SOURCE3), read_write_size );
+       for (i = 0; i<read_write_size /4; i++) {
                *(srcBuff+i) = 0xDEADDEAD;
        }
 
+       for (i = 0; i<read_write_size /4; i++) {
+               *(testBuf+i) = 0xDEAFDEAF;
+       }
+
        if (check1=check_device_exist("hyperlink0")) {
-               printf("testing hyperlink put_initiate 36-bit addr to remote 36-bit addr\n");
+
+               /* Open mpm transport */
+               printf("\nOpening mpmtransport with arm-loopback-hyplnk64-0\n");
                h = mpm_transport_open("arm-loopback-hyplnk64-0",&ocfg);
                if (!h) {
                printf("h open failed\n");
                ret = -1;
                goto end;
                }
+               printf("Opened mpm transport arm-loopback-hyplnk64-0\n");
+
+               /* mpm transport first time dummy write 64 test */
+               printf("testing mpm_transport write64 36-bit addr \n");
+               clock_gettime(CLOCK_MONOTONIC, &tp_start);
+               ret = mpm_transport_write64(h, TEST_DESTINATION1, read_write_size, (char *)testBuf, NULL);
+               clock_gettime(CLOCK_MONOTONIC, &tp_end);
+               if(ret < 0) {
+                       printf(" Error in mpm transport write64\n"); 
+                       goto end;
+               }
+               printf("mpm_transport write64 complete \n");
+               diff_time = clock_diff (&tp_start, &tp_end);
+               printf(" Dummy write64 diff time  %d ns \n",diff_time);
+
+               /* mpm transport write 64 test */
+               printf("testing mpm_transport write64 36-bit addr \n");
+               clock_gettime(CLOCK_MONOTONIC, &tp_start);
+               ret = mpm_transport_write64(h, TEST_DESTINATION1, read_write_size, (char *)testBuf, NULL);
+               clock_gettime(CLOCK_MONOTONIC, &tp_end);
+               if(ret < 0) {
+                       printf(" Error in mpm transport write64\n"); 
+                       goto end;
+               }
+               printf("mpm_transport write64 complete \n");
+
+               ret = verify_data(CONVERT_ULL_TO_ALIAS(TEST_DESTINATION1), read_write_size, 0xDEAFDEAF);
+               if (ret == -1) goto end;
+               diff_time = clock_diff (&tp_start, &tp_end);
+               printf(" write64 diff time  %d ns \n",diff_time);
+
+               /* mpm transport mmap 64 test */
+               printf(" Testing mpm-transport mmap64 \n");
+
+               clock_gettime(CLOCK_MONOTONIC, &tp_start);
+               testBuf1 = mpm_transport_mmap64(h, TEST_DESTINATION1, read_write_size, NULL);
+               clock_gettime(CLOCK_MONOTONIC, &tp_end);
+               if ( testBuf1 == MAP_FAILED ) {
+                       printf("\n Error mmap64 "); 
+                       goto end;
+               }
+
+               diff_time = clock_diff (&tp_start, &tp_end);
+               printf(" mmap64 diff time  %d ns \n",diff_time);
+
+               ret = verify_buffer_data1(testBuf1, read_write_size, 0xDEAFDEAF);
+               if (ret == -1) goto end;
+
+               printf(" Testing mpm-transport munmap64 \n");
+               clock_gettime(CLOCK_MONOTONIC, &tp_start);
+               ret = mpm_transport_munmap64(h, testBuf1, read_write_size);
+               clock_gettime(CLOCK_MONOTONIC, &tp_end);
+               if( ret < 0 ) {
+                       printf("\n Error unmap64 ");
+                       goto end;
+               }
+               diff_time = clock_diff (&tp_start, &tp_end);
+               printf(" munmap64 diff time  %d ns \n",diff_time);
+
+               /* mpm transport read 64 test */
+               printf("testing mpm_transport read64 36-bit addr \n");
+               clock_gettime(CLOCK_MONOTONIC, &tp_start);
+               ret = mpm_transport_read64(h, TEST_DESTINATION1, read_write_size, (char *)testBuf, NULL);
+               clock_gettime(CLOCK_MONOTONIC, &tp_end);
+               printf("mpm_transport read64 complete \n");
+               ret = verify_buffer_data(testBuf, read_write_size, 0xDEAFDEAF);
+               if (ret == -1) goto end;
+               diff_time = clock_diff (&tp_start, &tp_end);
+               printf(" read64 diff time  %d ns \n",diff_time);
+
+               /* mpm transport hyplnk put initate 64 test */
+               printf("testing hyperlink put_initiate 36-bit addr to remote 36-bit addr\n");
+
                printf("Writing to 0x%09llx, from 0x%09llx...\n", TEST_DESTINATION1, TEST_SOURCE1);
-               th = mpm_transport_put_initiate64(h, TEST_DESTINATION1, TEST_SOURCE1, TEST_BUFFER_SIZE, false, NULL);
+               clock_gettime(CLOCK_MONOTONIC, &tp_start);
+               th = mpm_transport_put_initiate64(h, TEST_DESTINATION1, TEST_SOURCE1, read_write_size, false, NULL);
+               clock_gettime(CLOCK_MONOTONIC, &tp_end);
                while(mpm_transport_transfer_check(h, th) != 1);
+               clock_gettime(CLOCK_MONOTONIC, &tp_end1);
+               diff_time = clock_diff (&tp_start, &tp_end);
+               printf(" put_initiate 36-bit addr to remote 36-bit addr diff time  %d ns \n",diff_time);
+               diff_time = clock_diff (&tp_end, &tp_end1);
+               printf(" put_initiate transfer check diff time  %d ns \n",diff_time);
+
                printf("Verifying data...\n");
-               ret = verify_data(CONVERT_ULL_TO_ALIAS(TEST_DESTINATION1), TEST_BUFFER_SIZE, 0xFEEDFEED);
+               ret = verify_data(CONVERT_ULL_TO_ALIAS(TEST_DESTINATION1), read_write_size, 0xFEEDFEED);
+
                if (ret == -1) goto end;
                mpm_transport_close(h);
 
+               /* mpm transport hyplnk put initate 64 test2 */
                printf("testing hyperlink put_initiate 36-bit addr to remote 32-bit addr\n");
                h = mpm_transport_open("arm-loopback-hyplnk64-0",&ocfg);
                if (!h) {
@@ -164,26 +312,48 @@ int main()
                ret = -1;
                goto end;
                }
-               mpm_transport_put_initiate64(h, TEST_DESTINATION2, TEST_SOURCE2, TEST_BUFFER_SIZE, true, NULL);
+               clock_gettime(CLOCK_MONOTONIC, &tp_start);
+               mpm_transport_put_initiate64(h, TEST_DESTINATION2, TEST_SOURCE2, read_write_size, true, NULL);
+               clock_gettime(CLOCK_MONOTONIC, &tp_end);
                printf("Verifying data...\n");
-               ret = verify_data(TEST_DESTINATION2, TEST_BUFFER_SIZE, 0xBABEBABE);
+               ret = verify_data(TEST_DESTINATION2, read_write_size, 0xBABEBABE);
                if (ret == -1) goto end;
+               diff_time = clock_diff (&tp_start, &tp_end);
+               printf(" put_initiate 36-bit addr to remote 32-bit diff time  %d ns \n",diff_time);
 
+               /* mpm transport hyplnk get initate 64 test */
                printf("testing hyperlink get_initiate 36-bit addr to remote 36-bit addr\n");
-               th2 = mpm_transport_get_initiate64(h, TEST_SOURCE1, TEST_GET_DESTINATION, TEST_BUFFER_SIZE, false, NULL);
+               clock_gettime(CLOCK_MONOTONIC, &tp_start);
+               th2 = mpm_transport_get_initiate64(h, TEST_SOURCE1, TEST_GET_DESTINATION, read_write_size, false, NULL);
+               clock_gettime(CLOCK_MONOTONIC, &tp_end);
                while(mpm_transport_transfer_check(h, th2) != 1);
-               ret = verify_data(CONVERT_ULL_TO_ALIAS(TEST_GET_DESTINATION), TEST_BUFFER_SIZE, 0xFEEDFEED);
+               clock_gettime(CLOCK_MONOTONIC, &tp_end1);
+               ret = verify_data(CONVERT_ULL_TO_ALIAS(TEST_GET_DESTINATION), read_write_size, 0xFEEDFEED);
                if (ret == -1) goto end;
+               clock_gettime(CLOCK_MONOTONIC, &tp_end1);
+               diff_time = clock_diff (&tp_start, &tp_end);
+               printf(" get_initiate 36-bit addr to remote 36-bit add diff time  %d ns \n",diff_time);
+               diff_time = clock_diff (&tp_end, &tp_end1);
+               printf(" get_initiate transfer check diff time  %d ns \n",diff_time);
 
                if (check2=check_device_exist("hyperlink1")) {
+                       /* mpm transport hyplnk 1 test */
                        h2 = mpm_transport_open("arm-loopback-hyplnk64-1", &ocfg);
                        if (!h2) {
                        printf("h2 open failed\n");
                        ret = -1;
                        goto end;
                        }
-                       mpm_transport_put_initiate64(h2, TEST_DESTINATION3, TEST_SOURCE3, TEST_BUFFER_SIZE, true, NULL);
-                       ret = verify_data(TEST_DESTINATION3, TEST_BUFFER_SIZE, 0xDEADDEAD);
+
+                       /* mpm transport hyplnk put initate 64 test with hyperlink1 */
+                       printf("testing hyperlink 1 put_initiate 36-bit addr to remote 32-bit addr\n");
+                       clock_gettime(CLOCK_MONOTONIC, &tp_start);
+                       mpm_transport_put_initiate64(h2, TEST_DESTINATION3, TEST_SOURCE3, read_write_size, true, NULL);
+                       clock_gettime(CLOCK_MONOTONIC, &tp_end);
+                       ret = verify_data(TEST_DESTINATION3, read_write_size, 0xDEADDEAD);
+                       diff_time = clock_diff (&tp_start, &tp_end);
+                       printf(" put_initiate hyperlink 1 36-bit addr to remote 32-bit diff time  %d ns \n",diff_time);
+
                        mpm_transport_close(h2);
                }
                else {
@@ -197,7 +367,8 @@ int main()
        }
 
 end:
-       if (h && check1) mpm_transport_close(h);
+       free(testBuf);
+       if      (h && check1) mpm_transport_close(h);
        if (ret == -1)
                printf("mpm transport64: hyperlink loopback test failed!!\n");
        else