From 6cb4eec0d3c17149e6ed5910a518132b2e6b3322 Mon Sep 17 00:00:00 2001 From: Sam Nelson Date: Fri, 11 Nov 2016 18:17:35 -0500 Subject: transport_sharedmem:Update to work with memory sections not with same start address The memory configuration earlier in mpm_config.json was matched up with the start address in the sysfs entry or devicetree. Now the code is changed to just update the sections based on overlapping sections in the sysfs entry or devicetree. Also cleaned up the structure elements for the sake of code clarity Signed-off-by: Sam Nelson --- src/transport/sharedmem/mpm_transport_sharedmem.c | 243 +++++++++++++++++----- src/transport/sharedmem/mpm_transport_sharedmem.h | 15 +- 2 files changed, 201 insertions(+), 57 deletions(-) diff --git a/src/transport/sharedmem/mpm_transport_sharedmem.c b/src/transport/sharedmem/mpm_transport_sharedmem.c index a76a200..2cd3689 100755 --- a/src/transport/sharedmem/mpm_transport_sharedmem.c +++ b/src/transport/sharedmem/mpm_transport_sharedmem.c @@ -48,7 +48,7 @@ #define MAX_PARAM_VAL_LENGTH 32 #define HEXA_DECIMAL_BASE 16 -#define SYSFS_ENTRY_PREFIX /sys/class/misc +#define SYSFS_ENTRY_PREFIX "/sys/class/misc" static int mpm_transport_get_mem_details (mpm_transport_cfg_t *sp, @@ -84,14 +84,29 @@ mpm_transport_get_mem_details (mpm_transport_cfg_t *sp, } /* Function finds the mapping index based on the starting address */ -static int mpm_transport_find_map_index(mpm_transport_sharedmem_t *td, int fd_index, uint64_t global_start_addr) { +static int mpm_transport_find_map_index( + mpm_transport_sharedmem_t *td, int fd_index, uint64_t global_start_addr, + uint32_t length, int start_block) +{ int k; +#ifdef DEBUG + mpm_printf(1, "DEBUG: fd_index %d, global_start_addr 0x%x, length 0x%x num_mem_blocks %d start_block %d\n", + fd_index, (uint32_t)global_start_addr, length, + td->fd_mem.fd_mem_entry[fd_index].num_mem_blocks, start_block); +#endif + /* Find the mem_block region that is within the range of configured region */ - for (k = 0; k < td->fd_mem_block.num_mem_blocks[fd_index]; k++) { - if(((uint32_t)global_start_addr >= td->fd_mem_block.mem_block[fd_index][k].base) && - ((uint32_t)global_start_addr < (td->fd_mem_block.mem_block[fd_index][k].base - + td->fd_mem_block.mem_block[fd_index][k].length))) { + for (k = start_block; k < td->fd_mem.fd_mem_entry[fd_index].num_mem_blocks; k++) { +#ifdef DEBUG + mpm_printf(1, "DEBUG: k %d, base addr 0x%x: length 0x%x\n", + k, td->fd_mem.fd_mem_entry[fd_index].mem_block[k].base, + td->fd_mem.fd_mem_entry[fd_index].mem_block[k].length); +#endif + if((global_start_addr <= td->fd_mem.fd_mem_entry[fd_index].mem_block[k].base) + && + ((global_start_addr + length) + >= td->fd_mem.fd_mem_entry[fd_index].mem_block[k].base)) { #ifdef DEBUG mpm_printf(1, "DEBUG: Success map_index %d, global_start_addr 0x%x: fd_index %d\n", k, (uint32_t)global_start_addr, fd_index); @@ -102,6 +117,93 @@ static int mpm_transport_find_map_index(mpm_transport_sharedmem_t *td, int fd_in return -1; } +static int update_mem_entries(mpm_transport_cfg_t *sp, + mpm_transport_sharedmem_t *td, int section_index, + int fd_index, int map_index) +{ + int map_index2; +#ifdef DEBUG + mpm_printf(1, "DEBUG: section_index:%d, map_index %d, original config: Global addr: 0x%x, length 0x%x, : device Base 0x%x, length 0x%x\n", + section_index, map_index, (uint32_t)sp->mmap[section_index].global_addr, + (uint32_t)sp->mmap[section_index].length, + (uint32_t)td->fd_mem.fd_mem_entry[fd_index].mem_block[map_index].base, + (uint32_t)td->fd_mem.fd_mem_entry[fd_index].mem_block[map_index].length); +#endif + + map_index2 = map_index; + do { + /* Also check for additional sections within the range + and add as additional entries */ + /* Now find the matching map section */ + map_index2 = mpm_transport_find_map_index(td, fd_index, + sp->mmap[section_index].global_addr, + sp->mmap[section_index].length, map_index2+1); + if (map_index2 < 0) + break; + if (sp->num_mmap >= (MPM_MAX_MMAPS-1)) { + mpm_printf(1, "num mmaps exceeded%d\n"); + return MPM_TRANSPORT_SHM_OPEN_ERR_BLOCKS_EXCEED_MAX; + + } + sp->mmap[sp->num_mmap].local_addr = sp->mmap[section_index].local_addr + + (td->fd_mem.fd_mem_entry[fd_index].mem_block[map_index2].base + - sp->mmap[section_index].global_addr + ); + if ((td->fd_mem.fd_mem_entry[fd_index].mem_block[map_index2].base + + td->fd_mem.fd_mem_entry[fd_index].mem_block[map_index2].length) + > (sp->mmap[section_index].global_addr + sp->mmap[section_index].length)) { + sp->mmap[sp->num_mmap].length + = (sp->mmap[section_index].global_addr + sp->mmap[section_index].length) + - td->fd_mem.fd_mem_entry[fd_index].mem_block[map_index2].base; + } else { + sp->mmap[sp->num_mmap].length + = td->fd_mem.fd_mem_entry[fd_index].mem_block[map_index2].length; + } + + sp->mmap[sp->num_mmap].global_addr + = td->fd_mem.fd_mem_entry[fd_index].mem_block[map_index2].base; + strcpy(sp->mmap[sp->num_mmap].devicename, sp->mmap[section_index].devicename); +#ifdef DEBUG + mpm_printf(1, "DEBUG: local_addr 0x%x global addr 0x%x length 0x%x \n", + (uint32_t)sp->mmap[sp->num_mmap].local_addr, + (uint32_t)sp->mmap[sp->num_mmap].global_addr, + (uint32_t)sp->mmap[sp->num_mmap].length); +#endif + sp->num_mmap++; +#ifdef DEBUG + mpm_printf(1, "DEBUG: Added one more entry %d: \n", sp->num_mmap); +#endif + } while (1); + + /* Need to also update the configured addresses to restrict to what + is available in sysfs or device tree entry */ + /* Override local address with update based on global address */ + sp->mmap[section_index].local_addr = sp->mmap[section_index].local_addr + + (td->fd_mem.fd_mem_entry[fd_index].mem_block[map_index].base + - sp->mmap[section_index].global_addr); + if ((td->fd_mem.fd_mem_entry[fd_index].mem_block[map_index].base + + td->fd_mem.fd_mem_entry[fd_index].mem_block[map_index].length) + > (sp->mmap[section_index].global_addr + sp->mmap[section_index].length)) { + sp->mmap[section_index].length + = (sp->mmap[section_index].global_addr + sp->mmap[section_index].length) + - td->fd_mem.fd_mem_entry[fd_index].mem_block[map_index].base; + } else { + /* Override length to length in sysfs or device tree entry */ + sp->mmap[section_index].length + = td->fd_mem.fd_mem_entry[fd_index].mem_block[map_index].length; + } + /* Override global address with available address */ + sp->mmap[section_index].global_addr + = td->fd_mem.fd_mem_entry[fd_index].mem_block[map_index].base; + +#ifdef DEBUG + mpm_printf(1, "DEBUG: Updating: local_addr 0x%x global addr 0x%x length 0x%x \n", + (uint32_t)sp->mmap[section_index].local_addr, + (uint32_t)sp->mmap[section_index].global_addr, + (uint32_t)sp->mmap[section_index].length); +#endif + return 0; +} int mpm_transport_sharedmem_open(mpm_transport_cfg_t *sp, mpm_transport_open_t *ocfg) { @@ -114,7 +216,6 @@ int mpm_transport_sharedmem_open(mpm_transport_cfg_t *sp, mpm_transport_open_t * struct stat statbuf; char *scratch; char *devname; - int fd_index; int map_index; int ret; @@ -123,45 +224,59 @@ int mpm_transport_sharedmem_open(mpm_transport_cfg_t *sp, mpm_transport_open_t * mpm_printf(1, "can't allocate memory for transport data \n"); return MPM_TRANSPORT_SHM_OPEN_ERR_CALLOC; } - td->fd_mem_block.num_fds = 0; + td->fd_mem.num_fds = 0; for (i = 0; i < sp->num_mmap; i++) { /* check if fd for same device name is already opened */ - for (j = 0; j < td->fd_mem_block.num_fds; j++) { + for (j = 0; j < td->fd_mem.num_fds; j++) { #ifdef DEBUG mpm_printf(1, "DEBUG: string compare i:%d, j:%d, %s : %s\n", - i, j, sp->mmap[i].devicename, sp->mmap[j].devicename); + i, j, sp->mmap[i].devicename, + td->fd_mem.fd_mem_entry[j].devicename); #endif - if (!strncmp(sp->mmap[i].devicename, sp->mmap[j].devicename, MAX_DEVICE_NAME_LEN)) { - td->fd_index[i] = td->fd_index[j]; - fd_index = td->fd_index[i]; - map_index = mpm_transport_find_map_index(td, fd_index, sp->mmap[i].global_addr); + if (!strncmp(sp->mmap[i].devicename, + td->fd_mem.fd_mem_entry[j].devicename, + MAX_DEVICE_NAME_LEN)) { + td->fd_index[i] = j; + map_index = + mpm_transport_find_map_index( + td, j, + sp->mmap[i].global_addr, + sp->mmap[i].length, 0); if ( map_index < 0 ) { mpm_printf(1, "Could not find map index for address %llx error map_index %d\n", sp->mmap[i].global_addr, map_index); return MPM_TRANSPORT_SHM_OPEN_ERR_MAP_INDEX; } + if (((uint32_t)sp->mmap[i].global_addr + != (uint32_t)td->fd_mem.fd_mem_entry[j].mem_block[map_index].base) + || ((uint32_t)sp->mmap[i].length != (uint32_t)td->fd_mem.fd_mem_entry[j].mem_block[map_index].length)) { + ret = update_mem_entries(sp, td, i, j, map_index); + if (ret < 0) + return ret; + } td->map_index[i] = map_index; break; } } - if (j < i) { + if (j < td->fd_mem.num_fds) { continue; } - td->fd_mem_block.fd[td->fd_mem_block.num_fds] = open(sp->mmap[i].devicename, (O_RDWR | O_SYNC)); - if (td->fd_mem_block.fd[td->fd_mem_block.num_fds] < 0) { + td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].fd = + open(sp->mmap[i].devicename, (O_RDWR | O_SYNC)); + if (td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].fd < 0) { mpm_printf(1, "Failed to open %s :Error (%s)", sp->mmap[i].devicename, strerror(errno)); free(td); return MPM_TRANSPORT_SHM_OPEN_ERR_DEV_OPEN; } - td->fd_index[i] = td->fd_mem_block.num_fds; + td->fd_index[i] = td->fd_mem.num_fds; devname = strrchr(sp->mmap[i].devicename, '/')+1; k = 0; /* Check first if there are sysfs entries for the memory */ snprintf(filename, MAX_FILE_NAME_LENGTH, - "SYSFS_ENTRY_PREFIX""/%s/memory%d/addr", devname, k); + SYSFS_ENTRY_PREFIX"/%s/memory%d/addr", devname, k); if ((fd = open (filename, O_RDONLY)) != -1) { @@ -175,41 +290,52 @@ int mpm_transport_sharedmem_open(mpm_transport_cfg_t *sp, mpm_transport_open_t * } close(fd); /* And populate mem_block base information */ - td->fd_mem_block.mem_block[td->fd_mem_block.num_fds][k].base + td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].mem_block[k].base = (uint32_t)strtoul(hexstring, NULL, HEXA_DECIMAL_BASE); #ifdef DEBUG - mpm_printf(1, "Recording addr 0x%x\n", - td->fd_mem_block.mem_block[td->fd_mem_block.num_fds][k].base); + mpm_printf(1, "Recording addr 0x%x, ", + td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].mem_block[k].base); #endif snprintf(filename, MAX_FILE_NAME_LENGTH, - "SYSFS_ENTRY_PREFIX""/%s/memory%d/size", + SYSFS_ENTRY_PREFIX"/%s/memory%d/size", devname, k); fd = open(filename, O_RDONLY); if ( fd == -1 ) { - mpm_printf(1, "Failed to open \"%s\" err=%s\n", + mpm_printf(1, "\nFailed to open \"%s\" err=%s\n", filename, strerror(errno)); return MPM_TRANSPORT_SHM_OPEN_ERR_MEM_FILE_OPEN; } ret = read(fd, hexstring, MAX_PARAM_VAL_LENGTH); if ( ret <= 0 ) { - mpm_printf (1, "Failed to read %d bytes from %s: ret %d\n", + mpm_printf (1, "\nFailed to read %d bytes from %s: ret %d\n", (int) MAX_PARAM_VAL_LENGTH, filename, ret); return MPM_TRANSPORT_SHM_OPEN_ERR_READ; } close(fd); - td->fd_mem_block.mem_block[td->fd_mem_block.num_fds][k].length + td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].mem_block[k].length = (uint32_t)strtoul(hexstring, NULL, HEXA_DECIMAL_BASE); #ifdef DEBUG mpm_printf(1, "Recording length 0x%x\n", - td->fd_mem_block.mem_block[td->fd_mem_block.num_fds][k].length); + td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].mem_block[k].length); #endif k++; + if ( k >= MPM_MAX_MEM_ENTRIES) { + mpm_printf(1, "\nNumber of mem entries: %d exceed max allowed %d\n", + k, MPM_MAX_MEM_ENTRIES); + return MPM_TRANSPORT_SHM_OPEN_ERR_BLOCKS_EXCEED_MAX; + } snprintf(filename, MAX_FILE_NAME_LENGTH, - "SYSFS_ENTRY_PREFIX""/%s/memory%d/addr", + SYSFS_ENTRY_PREFIX"/%s/memory%d/addr", devname, k); } while ((fd = open(filename, O_RDONLY)) != -1 ); + td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].num_mem_blocks = k; + } else { +#ifdef DEBUG + mpm_printf(1, "\nFailed to open \"%s\" err=%s\n", + filename, strerror(errno)); +#endif /* Check device tree and record the index of the mmap */ snprintf(filename, MAX_FILE_NAME_LENGTH, "/proc/device-tree/soc/%s/reg", devname); @@ -226,12 +352,14 @@ int mpm_transport_sharedmem_open(mpm_transport_cfg_t *sp, mpm_transport_open_t * return MPM_TRANSPORT_SHM_OPEN_ERR_FIND_FILE_SIZE; } fileSize = statbuf.st_size; - td->fd_mem_block.num_mem_blocks[td->fd_mem_block.num_fds] = fileSize / sizeof(mem_block_t); - scratch = malloc (sizeof(mem_block_t) * td->fd_mem_block.num_mem_blocks[td->fd_mem_block.num_fds]); - if (!td->fd_mem_block.num_mem_blocks[td->fd_mem_block.num_fds] || !scratch) + td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].num_mem_blocks = + fileSize / sizeof(mem_block_t); + scratch = + malloc (sizeof(mem_block_t) * td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].num_mem_blocks); + if (!td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].num_mem_blocks || !scratch) { mpm_printf (1, "Failed to malloc size blocks for %d\n", - td->fd_mem_block.num_mem_blocks[td->fd_mem_block.num_fds]); + td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].num_mem_blocks); return MPM_TRANSPORT_SHM_OPEN_ERR_MALLOC; } if ( read (fd, scratch, fileSize) != fileSize) @@ -241,47 +369,58 @@ int mpm_transport_sharedmem_open(mpm_transport_cfg_t *sp, mpm_transport_open_t * return MPM_TRANSPORT_SHM_OPEN_ERR_READ; } close (fd); - if ( td->fd_mem_block.num_mem_blocks[td->fd_mem_block.num_fds] > MPM_MAX_MEM_ENTRIES) { + if ( td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].num_mem_blocks > MPM_MAX_MEM_ENTRIES) { mpm_printf (1, "Number of blocks %d exceeds max %d\n", - td->fd_mem_block.num_mem_blocks[td->fd_mem_block.num_fds], MPM_MAX_MEM_ENTRIES ); + td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].num_mem_blocks, MPM_MAX_MEM_ENTRIES ); return MPM_TRANSPORT_SHM_OPEN_ERR_BLOCKS_EXCEED_MAX; } - for (k = 0; k < td->fd_mem_block.num_mem_blocks[td->fd_mem_block.num_fds]; k++) + for (k = 0; k < td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].num_mem_blocks; k++) { /* Swizzle from big endian in proc */ - td->fd_mem_block.mem_block[td->fd_mem_block.num_fds][k].base = + td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].mem_block[k].base = (scratch[k*8 + 0] << 24) | (scratch[k*8 + 1] << 16) | (scratch[k*8 + 2] << 8) | (scratch[k*8 + 3] ); - td->fd_mem_block.mem_block[td->fd_mem_block.num_fds][k].length = + td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].mem_block[k].length = (scratch[k*8 + 4] << 24) | (scratch[k*8 + 5] << 16) | (scratch[k*8 + 6] << 8) | (scratch[k*8 + 7] ); #ifdef DEBUG mpm_printf(1, " DEBUG: Index %d: Base %x, length %x\n", k, - td->fd_mem_block.mem_block[td->fd_mem_block.num_fds][k].base, - td->fd_mem_block.mem_block[td->fd_mem_block.num_fds][k].length); + td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].mem_block[k].base, + td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].mem_block[k].length); #endif } free (scratch); } /* Now find the matching map section */ - map_index = mpm_transport_find_map_index(td, td->fd_mem_block.num_fds, - sp->mmap[i].global_addr); + map_index = mpm_transport_find_map_index(td, td->fd_mem.num_fds, + sp->mmap[i].global_addr, sp->mmap[i].length, 0); if ( map_index < 0 ) { mpm_printf(1, "Could not find map index for address 0x%llx error: map_index %d\n", sp->mmap[i].global_addr, map_index); return MPM_TRANSPORT_SHM_OPEN_ERR_MAP_INDEX; } + if ((sp->mmap[i].global_addr + != (td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].mem_block[map_index].base)) + || (sp->mmap[i].length + != td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].mem_block[map_index].length)) { + ret = update_mem_entries(sp, td, i, td->fd_mem.num_fds, map_index); + if (ret < 0) + return ret; + } + td->map_index[i] = map_index; + td->fd_mem.fd_mem_entry[td->fd_mem.num_fds].devicename = + sp->mmap[i].devicename; - td->fd_mem_block.num_fds++; - if ( td->fd_mem_block.num_fds >= MPM_MAX_NUM_FDS ) { + td->fd_mem.num_fds++; + if ( td->fd_mem.num_fds >= MPM_MAX_NUM_FDS ) { mpm_printf (1, "Number of fds %d exceeds max fds %d\n", - td->fd_mem_block.num_fds, MPM_MAX_NUM_FDS ); - return MPM_TRANSPORT_SHM_OPEN_ERR_EXCEED_NUM_FDS; + td->fd_mem.num_fds, MPM_MAX_NUM_FDS ); + return MPM_TRANSPORT_SHM_OPEN_ERR_EXCEED_NUM_FDS; } } @@ -324,7 +463,7 @@ void *mpm_transport_sharedmem_mmap(mpm_transport_cfg_t *sp, uint32_t addr, uint3 td->mmap_user[user_index].addr = mmap(NULL, mmap_length, mcfg->mmap_prot, mcfg->mmap_flags, - td->fd_mem_block.fd[td->fd_index[index]], + td->fd_mem.fd_mem_entry[td->fd_index[index]].fd, ((pg_offset) + (td->map_index[index] * page_size))); if (td->mmap_user[user_index].addr == MAP_FAILED) { mpm_printf(1, "can't mmap for the address 0x%x with length" @@ -389,7 +528,7 @@ static void *mpm_transport_sharedmem_rw_map (mpm_transport_cfg_t *sp, uint32_t a base_address, *index, offset, base_correction, mmap_length); if (!td->mmap_rw[*index].addr) { td->mmap_rw[*index].addr = mmap(NULL, mmap_length, (PROT_READ|PROT_WRITE), - MAP_SHARED, td->fd_mem_block.fd[td->fd_index[*index]], + MAP_SHARED, td->fd_mem.fd_mem_entry[td->fd_index[*index]].fd, (td->map_index[*index] * page_size)); if (td->mmap_rw[*index].addr == MAP_FAILED) { td->mmap_rw[*index].addr = 0; @@ -468,11 +607,11 @@ void mpm_transport_sharedmem_close(mpm_transport_cfg_t *sp) td->mmap_rw[i].addr = 0; } } - for (i = 0; i < td->fd_mem_block.num_fds; i++) { - if (td->fd_mem_block.fd[i]) { - fsync(td->fd_mem_block.fd[i]); - close(td->fd_mem_block.fd[i]); - td->fd_mem_block.fd[i] = 0; + for (i = 0; i < td->fd_mem.num_fds; i++) { + if (td->fd_mem.fd_mem_entry[i].fd) { + fsync(td->fd_mem.fd_mem_entry[i].fd); + close(td->fd_mem.fd_mem_entry[i].fd); + td->fd_mem.fd_mem_entry[i].fd = 0; } } diff --git a/src/transport/sharedmem/mpm_transport_sharedmem.h b/src/transport/sharedmem/mpm_transport_sharedmem.h index 485c971..cac2f88 100755 --- a/src/transport/sharedmem/mpm_transport_sharedmem.h +++ b/src/transport/sharedmem/mpm_transport_sharedmem.h @@ -57,17 +57,22 @@ typedef struct { uint32_t length; } mem_block_t; +typedef struct { + int fd; + char *devicename; + int num_mem_blocks; + mem_block_t mem_block[MPM_MAX_MEM_ENTRIES]; +} fd_mem_entry_t; + typedef struct { int num_fds; - int num_mem_blocks[MPM_MAX_NUM_FDS]; - int fd[MPM_MAX_NUM_FDS]; - mem_block_t mem_block[MPM_MAX_NUM_FDS][MPM_MAX_MEM_ENTRIES]; -} fd_mem_block_t; + fd_mem_entry_t fd_mem_entry[MPM_MAX_NUM_FDS]; +} fd_mem_t; typedef struct mpm_transport_sharedmem_tag { int fd_index[MPM_MAX_MMAPS]; int map_index[MPM_MAX_MMAPS]; - fd_mem_block_t fd_mem_block; + fd_mem_t fd_mem; mmap_data_t mmap_rw[MPM_MAX_MMAPS]; pthread_mutex_t mutex_rw[MPM_MAX_MMAPS]; mmap_data_t mmap_user[MPM_MAX_USER_MMAPS]; -- cgit v1.2.3-54-g00ecf