From 8004ffb6491872529da5453942bd0a04822a5f46 Mon Sep 17 00:00:00 2001 From: Arvid Bjorkengren Date: Mon, 15 Oct 2018 08:46:32 +0200 Subject: leon,gr1553b: Only align allocated memory. Verify alignment of memory. Update #4303. --- bsps/shared/grlib/1553/gr1553bc.c | 76 ++++++++++++++++----------- bsps/shared/grlib/1553/gr1553bm.c | 49 ++++++++++++------ bsps/shared/grlib/1553/gr1553rt.c | 105 ++++++++++++++++++++++++-------------- 3 files changed, 147 insertions(+), 83 deletions(-) diff --git a/bsps/shared/grlib/1553/gr1553bc.c b/bsps/shared/grlib/1553/gr1553bc.c index a22e2d8007..f37364e0ea 100644 --- a/bsps/shared/grlib/1553/gr1553bc.c +++ b/bsps/shared/grlib/1553/gr1553bc.c @@ -63,7 +63,7 @@ struct gr1553bc_priv { */ #define NEXT_MINOR_MARKER 0x01 -/* To separate ASYNC list from SYNC list we mark them differently, but with +/* To separate ASYNC list from SYNC list we mark them differently, but with * LSB always set. This can be used to get the list the descriptor is a part * of. */ @@ -71,7 +71,7 @@ struct gr1553bc_priv { struct gr1553bc_list_cfg gr1553bc_def_cfg = { - .rt_timeout = + .rt_timeout = { 20, 20, 20, 20, 20, 20, 20, 20, @@ -80,7 +80,7 @@ struct gr1553bc_list_cfg gr1553bc_def_cfg = 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20 + 20, 20, 20 }, .bc_timeout = 30, .tropt_irq_on_err = 0, @@ -132,7 +132,7 @@ int gr1553bc_list_config /* RT Time Tolerances */ for (i=0; i<31; i++) { - /* 0=14us, 1=18us ... 0xf=74us + /* 0=14us, 1=18us ... 0xf=74us * round upwards: 15us will be 18us */ timeout = ((cfg->rt_timeout[i] + 1) - 14) / 4; @@ -167,7 +167,7 @@ void gr1553bc_list_link_major( if ( major ) { major->next = next; if ( next ) { - major->minors[major->cfg->minor_cnt-1]->next = + major->minors[major->cfg->minor_cnt-1]->next = next->minors[0]; } else { major->minors[major->cfg->minor_cnt-1]->next = NULL; @@ -195,7 +195,7 @@ int gr1553bc_list_set_major( prev = list->majors[list->major_cnt-1]; } - /* Link to next Major if not the last one and if there is + /* Link to next Major if not the last one and if there is * a next major */ if ( no == list->major_cnt-1 ) { @@ -262,7 +262,7 @@ int gr1553bc_list_table_size(struct gr1553bc_list *list) minor_cnt = major->cfg->minor_cnt; for (j=0; jbc; + int retval = 0; /* Free previous allocated descriptor table */ gr1553bc_list_table_free(list); @@ -298,8 +299,8 @@ int gr1553bc_list_table_alloc /* Address given in Hardware accessible address, we * convert it into CPU-accessible address. */ - list->table_hw = (unsigned int)bdtab_custom & ~0x1; - list->_table = bdtab_custom; + list->_table = (void*)((unsigned int)bdtab_custom & ~0x1); + list->table_hw = (unsigned int)list->_table; drvmgr_translate_check( *bcpriv->pdev, DMAMEM_TO_CPU, @@ -310,16 +311,19 @@ int gr1553bc_list_table_alloc if (bdtab_custom == NULL) { /* Allocate descriptors */ list->_table = grlib_malloc(size + (GR1553BC_BD_ALIGN-1)); - if ( list->_table == NULL ) - return -1; + if ( list->_table == NULL ) { + retval = -1; + goto err; + } + /* 128-bit Alignment required by HW */ + list->table_cpu = + (((unsigned int)list->_table + (GR1553BC_BD_ALIGN-1)) & + ~(GR1553BC_BD_ALIGN-1)); } else { /* Custom address, given in CPU-accessible address */ list->_table = bdtab_custom; + list->table_cpu = (unsigned int)list->_table; } - /* 128-bit Alignment required by HW */ - list->table_cpu = - (((unsigned int)list->_table + (GR1553BC_BD_ALIGN-1)) & - ~(GR1553BC_BD_ALIGN-1)); /* We got CPU accessible descriptor table address, now we * translate that into an address that the Hardware can @@ -338,6 +342,12 @@ int gr1553bc_list_table_alloc } } + /* Verify alignment */ + if (list->table_hw & (GR1553BC_BD_ALIGN-1)) { + retval = -2; + goto err; + } + /* Write End-Of-List all over the descriptor table here, * For debugging/safety? */ @@ -359,8 +369,16 @@ int gr1553bc_list_table_alloc table += gr1553bc_minor_table_size(major->minors[j]); } } - - return 0; +err: + if (retval) { + if (list->_table_custom == NULL && list->_table) { + free(list->_table); + } + list->table_hw = 0; + list->table_cpu = 0; + list->_table = NULL; + } + return retval; } void gr1553bc_list_table_free(struct gr1553bc_list *list) @@ -399,7 +417,7 @@ int gr1553bc_list_table_build(struct gr1553bc_list *list) bds = minor->bds; /* BD[0..SLOTCNT-1] = message slots - * BD[SLOTCNT+0] = END + * BD[SLOTCNT+0] = END * BD[SLOTCNT+1] = JUMP * * or if no optional time slot handling: @@ -485,7 +503,7 @@ void gr1553bc_bd_init( ((word0 & GR1553BC_BD_TYPE) == 0) ) { /* Don't touch timeslot previously allocated */ word0 &= ~GR1553BC_TR_TIME; - word0 |= GR1553BC_READ_MEM(&raw->words[0]) & + word0 |= GR1553BC_READ_MEM(&raw->words[0]) & GR1553BC_TR_TIME; } GR1553BC_WRITE_MEM(&raw->words[0], word0); @@ -523,7 +541,7 @@ int gr1553bc_major_alloc_skel maj->cfg = cfg; maj->next = NULL; - /* Create links between minor frames, and from minor frames + /* Create links between minor frames, and from minor frames * to configuration structure. */ minor = (struct gr1553bc_minor *)&maj->minors[cfg->minor_cnt]; @@ -697,7 +715,7 @@ int gr1553bc_slot_alloc2( set0 = (set0 & ~GR1553BC_TR_TIME) | timefree; GR1553BC_WRITE_MEM(&trbd->settings[0], set0); /* Note: at the moment the minor frame can be executed faster - * than expected, we hurry up writing requested + * than expected, we hurry up writing requested * descriptor. */ } @@ -886,7 +904,7 @@ int gr1553bc_slot_irq_prepare union gr1553bc_bd *bd; int slot_no, to_mid; - /* Build unconditional IRQ descriptor. The padding is used + /* Build unconditional IRQ descriptor. The padding is used * for identifying the MINOR frame and function and custom data. * * The IRQ is disabled at first, a unconditional jump to next @@ -1115,7 +1133,7 @@ int gr1553bc_slot_update *stat = GR1553BC_READ_MEM(&bd->tr.status); if ( status ) { /* Clear status fields user selects, then - * or bit31 if user wants that. The bit31 + * or bit31 if user wants that. The bit31 * may be used to indicate if the BC has * performed the access. */ @@ -1192,7 +1210,7 @@ int gr1553bc_mid_from_bd( found_mid: /* Get MID of JUMP descriptor */ bdmid = word2 >> 8; - /* Subtract distance from JUMP descriptor to find MID + /* Subtract distance from JUMP descriptor to find MID * of requested BD. */ slot_no = GR1553BC_SLOTID_FROM_ID(bdmid); @@ -1445,7 +1463,7 @@ void gr1553bc_device_init(struct gr1553bc_priv *priv) /* Stop BC if not already stopped */ GR1553BC_WRITE_REG(&priv->regs->bc_ctrl, GR1553BC_KEY | 0x0204); - /* Since RT can not be used at the same time as BC, we stop + /* Since RT can not be used at the same time as BC, we stop * RT rx, it should already be stopped... */ GR1553BC_WRITE_REG(&priv->regs->rt_cfg, GR1553RT_KEY); @@ -1463,7 +1481,7 @@ void gr1553bc_device_init(struct gr1553bc_priv *priv) priv->alist = NULL; priv->irq_log_base = (uint32_t *) - (((uint32_t)priv->irq_log_p + (GR1553BC_IRQLOG_SIZE-1)) & + (((uint32_t)priv->irq_log_p + (GR1553BC_IRQLOG_SIZE-1)) & ~(GR1553BC_IRQLOG_SIZE-1)); /* Translate into a hardware accessible address */ drvmgr_translate_check( @@ -1487,7 +1505,7 @@ void gr1553bc_device_uninit(struct gr1553bc_priv *priv) /* Stop BC if not already stopped */ GR1553BC_WRITE_REG(&priv->regs->bc_ctrl, GR1553BC_KEY | 0x0204); - /* Since RT can not be used at the same time as BC, we stop + /* Since RT can not be used at the same time as BC, we stop * RT rx, it should already be stopped... */ GR1553BC_WRITE_REG(&priv->regs->rt_cfg, GR1553RT_KEY); @@ -1518,7 +1536,7 @@ void gr1553bc_isr(void *arg) /* Clear handled IRQs */ GR1553BC_WRITE_REG(&priv->regs->irq, irq); - /* DMA error. This IRQ does not affect the IRQ log. + /* DMA error. This IRQ does not affect the IRQ log. * We let standard IRQ handle handle it. */ if ( irq & GR1553B_IRQEN_BCDE ) { @@ -1563,7 +1581,7 @@ void gr1553bc_isr(void *arg) bd = NULL; } - /* Handle Descriptor that cased IRQ + /* Handle Descriptor that cased IRQ * * If someone have inserted an IRQ descriptor and tied * that to a custom function we call that function, otherwise diff --git a/bsps/shared/grlib/1553/gr1553bm.c b/bsps/shared/grlib/1553/gr1553bm.c index 482e574d78..0672c468a4 100644 --- a/bsps/shared/grlib/1553/gr1553bm.c +++ b/bsps/shared/grlib/1553/gr1553bm.c @@ -89,7 +89,7 @@ static void gr1553bm_hw_start(struct gr1553bm_priv *priv) /* Start logging */ priv->regs->bm_ctrl = - (priv->cfg.filt_error_options & + (priv->cfg.filt_error_options & (GR1553B_BM_CTRL_MANL|GR1553B_BM_CTRL_UDWL|GR1553B_BM_CTRL_IMCL)) | GR1553B_BM_CTRL_BMEN; @@ -178,6 +178,7 @@ void gr1553bm_close(void *bm) /* Configure the BM driver */ int gr1553bm_config(void *bm, struct gr1553bm_config *cfg) { + int retval = 0; struct gr1553bm_priv *priv = bm; if ( priv->started ) @@ -193,12 +194,11 @@ int gr1553bm_config(void *bm, struct gr1553bm_config *cfg) } priv->buffer_size = cfg->buffer_size & ~0x7; /* on 8 byte bounadry */ if ((unsigned int)cfg->buffer_custom & 1) { - /* Custom Address Given in Remote address. We need - * to convert it intoTranslate into Hardware a - * hardware accessible address + /* Custom address given in remote address. We need + * to convert it into a hardware accessible address */ - priv->buffer_base_hw = (unsigned int)cfg->buffer_custom & ~1; - priv->buffer = cfg->buffer_custom; + priv->buffer = (void*)((unsigned int)cfg->buffer_custom & ~1); + priv->buffer_base_hw = (unsigned int)priv->buffer; drvmgr_translate_check( *priv->pdev, DMAMEM_TO_CPU, @@ -209,17 +209,19 @@ int gr1553bm_config(void *bm, struct gr1553bm_config *cfg) if (cfg->buffer_custom == NULL) { /* Allocate new buffer dynamically */ priv->buffer = grlib_malloc(priv->buffer_size + 8); - if (priv->buffer == NULL) - return -1; + if (priv->buffer == NULL) { + retval = -1; + goto err; + } + /* Align to 8 bytes */ + priv->buffer_base = ((unsigned int)priv->buffer + (8-1)) & ~(8-1); } else { /* Address given in CPU accessible address, no * translation required. */ priv->buffer = cfg->buffer_custom; + priv->buffer_base = (unsigned int)priv->buffer; } - /* Align to 16 bytes */ - priv->buffer_base = ((unsigned int)priv->buffer + (8-1)) & - ~(8-1); /* Translate address of buffer base into address that Hardware must * use to access the buffer. */ @@ -229,13 +231,28 @@ int gr1553bm_config(void *bm, struct gr1553bm_config *cfg) (void *)priv->buffer_base, (void **)&priv->buffer_base_hw, priv->buffer_size); - + + } + + /* Verify alignment */ + if (priv->buffer_base_hw & (8-1)) { + retval = -2; + goto err; } /* Copy valid config */ priv->cfg = *cfg; - return 0; +err: + if (retval) { + if (cfg->buffer_custom == NULL && priv->buffer) { + free(priv->buffer); + } + priv->buffer_base_hw = (unsigned int)NULL; + priv->buffer_base = (unsigned int)NULL; + priv->buffer = NULL; + } + return retval; } /* Start logging */ @@ -249,7 +266,7 @@ int gr1553bm_start(void *bm) return -2; /* Start at Time = 0 */ - priv->regs->bm_ttag = + priv->regs->bm_ttag = priv->cfg.time_resolution << GR1553B_BM_TTAG_RES_BIT; /* Configure Filters */ @@ -282,7 +299,7 @@ void gr1553bm_stop(void *bm) /* Stop Hardware */ gr1553bm_hw_stop(priv); - /* At this point the hardware must be stopped and IRQ + /* At this point the hardware must be stopped and IRQ * sources unmasked. */ @@ -331,7 +348,7 @@ resample: hwtime2 = priv->regs->bm_ttag & GR1553B_BM_TTAG_VAL; if ( hwtime > hwtime2 ) { /* priv->time and hwtime may be out of sync if - * IRQ updated priv->time just after bm_ttag was read + * IRQ updated priv->time just after bm_ttag was read * here, we resample if we detect inconsistancy. */ goto resample; diff --git a/bsps/shared/grlib/1553/gr1553rt.c b/bsps/shared/grlib/1553/gr1553rt.c index cea84ac338..7f35138376 100644 --- a/bsps/shared/grlib/1553/gr1553rt.c +++ b/bsps/shared/grlib/1553/gr1553rt.c @@ -159,11 +159,11 @@ static void gr1553rt_list_unreg(struct gr1553rt_list *list) static int gr1553rt_bdid(void *rt, struct gr1553rt_sw_bd *bd) { struct gr1553rt_priv *priv = rt; - + unsigned short index; /* Get Index of Software BD */ - index = ((unsigned int)bd - (unsigned int)&priv->swbds[0]) / + index = ((unsigned int)bd - (unsigned int)&priv->swbds[0]) / sizeof(struct gr1553rt_sw_bd); return index; @@ -195,10 +195,9 @@ static int gr1553rt_bd_alloc(void *rt, struct gr1553rt_sw_bd **bd, int cnt) } *bd = &priv->swbds[priv->swbd_free]; + curr = &priv->swbds[priv->swbd_free]; for (i=0; iswbds[priv->swbd_free]; - } else { + if ( i != 0) { curr = &priv->swbds[curr->this_next]; } if ( curr->this_next == 0xffff ) { @@ -358,7 +357,7 @@ int gr1553rt_bd_init( bd->next = nextbd; SPIN_UNLOCK_IRQ(&priv->devlock, irqflags); - return 0; + return 0; } int gr1553rt_bd_update( @@ -733,7 +732,7 @@ void gr1553rt_hw_stop(struct gr1553rt_priv *priv) GR1553RT_WRITE_REG(&priv->regs->rt_cfg, GR1553RT_KEY); /* Stop BC if not already stopped: BC can not be used simultaneously - * as the RT anyway + * as the RT anyway */ GR1553RT_WRITE_REG(&priv->regs->bc_ctrl, GR1553BC_KEY | 0x0204); @@ -772,17 +771,17 @@ void gr1553rt_sw_free(struct gr1553rt_priv *priv) } } -/* Free dynamically allocated buffers, if any */ static int gr1553rt_sw_alloc(struct gr1553rt_priv *priv) { int size; + int retval = 0; /* Allocate Event log */ if ((unsigned int)priv->cfg.evlog_buffer & 1) { /* Translate Address from HARDWARE (REMOTE) to CPU-LOCAL */ - priv->evlog_hw_base = (unsigned int *) + priv->evlog_buffer = (void *) ((unsigned int)priv->cfg.evlog_buffer & ~0x1); - priv->evlog_buffer = priv->cfg.evlog_buffer; + priv->evlog_hw_base = (unsigned int*)priv->evlog_buffer; drvmgr_translate_check( *priv->pdev, DMAMEM_TO_CPU, @@ -794,16 +793,19 @@ static int gr1553rt_sw_alloc(struct gr1553rt_priv *priv) if (priv->cfg.evlog_buffer == NULL) { priv->evlog_buffer = grlib_malloc( priv->cfg.evlog_size * 2); - if (priv->evlog_buffer == NULL) - return -1; + if (priv->evlog_buffer == NULL) { + retval = -1; + goto err; + } + /* Align to SIZE bytes boundary */ + priv->evlog_cpu_base = (unsigned int *) + (((unsigned int)priv->evlog_buffer + + (priv->cfg.evlog_size-1)) & ~(priv->cfg.evlog_size-1)); } else { /* Addess already CPU-LOCAL */ priv->evlog_buffer = priv->cfg.evlog_buffer; + priv->evlog_cpu_base = (unsigned int *)priv->evlog_buffer; } - /* Align to SIZE bytes boundary */ - priv->evlog_cpu_base = (unsigned int *) - (((unsigned int)priv->evlog_buffer + - (priv->cfg.evlog_size-1)) & ~(priv->cfg.evlog_size-1)); drvmgr_translate_check( *priv->pdev, @@ -813,6 +815,11 @@ static int gr1553rt_sw_alloc(struct gr1553rt_priv *priv) priv->cfg.evlog_size ); } + /* Verify alignment */ + if ((unsigned int)priv->evlog_hw_base & (priv->cfg.evlog_size-1)) { + retval = -2; + goto err; + } priv->evlog_cpu_end = priv->evlog_cpu_base + priv->cfg.evlog_size/sizeof(unsigned int *); @@ -821,9 +828,9 @@ static int gr1553rt_sw_alloc(struct gr1553rt_priv *priv) size = priv->bds_cnt * sizeof(struct gr1553rt_bd); if ((unsigned int)priv->cfg.bd_buffer & 1) { /* Translate Address from HARDWARE (REMOTE) to CPU-LOCAL */ - priv->bds_hw = (struct gr1553rt_bd *) + priv->bd_buffer = (void *) ((unsigned int)priv->cfg.bd_buffer & ~0x1); - priv->bd_buffer = priv->cfg.bd_buffer; + priv->bds_hw = (struct gr1553rt_bd *)priv->bd_buffer; drvmgr_translate_check( *priv->pdev, DMAMEM_TO_CPU, @@ -834,15 +841,18 @@ static int gr1553rt_sw_alloc(struct gr1553rt_priv *priv) } else { if ( priv->cfg.bd_buffer == NULL ) { priv->bd_buffer = grlib_malloc(size + 0xf); - if (priv->bd_buffer == NULL) - return -1; + if (priv->bd_buffer == NULL) { + retval = -1; + goto err; + } + /* Align to 16 bytes boundary */ + priv->bds_cpu = (struct gr1553rt_bd *) + (((unsigned int)priv->bd_buffer + 0xf) & ~0xf); } else { /* Addess already CPU-LOCAL */ priv->bd_buffer = priv->cfg.bd_buffer; + priv->bds_cpu = (struct gr1553rt_bd *)priv->bd_buffer; } - /* Align to 16 bytes boundary */ - priv->bds_cpu = (struct gr1553rt_bd *) - (((unsigned int)priv->bd_buffer + 0xf) & ~0xf); /* Translate from CPU address to hardware address */ drvmgr_translate_check( @@ -853,21 +863,28 @@ static int gr1553rt_sw_alloc(struct gr1553rt_priv *priv) size ); } + /* Verify alignment */ + if ((unsigned int)priv->bds_hw & (0xf)) { + retval = -2; + goto err; + } #if (RTBD_MAX == 0) /* Allocate software description of */ priv->swbds = grlib_malloc(priv->cfg.bd_count * sizeof(*priv->swbds)); if ( priv->swbds == NULL ) { - return -1; + retval = -1; + goto err; } #endif /* Allocate Sub address table */ if ((unsigned int)priv->cfg.satab_buffer & 1) { /* Translate Address from HARDWARE (REMOTE) to CPU-LOCAL */ - priv->sas_hw = (struct gr1553rt_sa *) + priv->satab_buffer = (void *) ((unsigned int)priv->cfg.satab_buffer & ~0x1); - priv->satab_buffer = priv->cfg.satab_buffer; + priv->sas_hw = (struct gr1553rt_sa *)priv->satab_buffer; + drvmgr_translate_check( *priv->pdev, DMAMEM_TO_CPU, @@ -877,16 +894,18 @@ static int gr1553rt_sw_alloc(struct gr1553rt_priv *priv) } else { if (priv->cfg.satab_buffer == NULL) { priv->satab_buffer = grlib_malloc((16 * 32) * 2); - if (priv->satab_buffer == NULL) - return -1; + if (priv->satab_buffer == NULL) { + retval = -1; + goto err; + } + /* Align to 512 bytes boundary */ + priv->sas_cpu = (struct gr1553rt_sa *) + (((unsigned int)priv->satab_buffer + 0x1ff) & ~0x1ff); } else { /* Addess already CPU-LOCAL */ priv->satab_buffer = priv->cfg.satab_buffer; + priv->sas_cpu = (struct gr1553rt_sa *)priv->satab_buffer; } - /* Align to 512 bytes boundary */ - priv->sas_cpu = (struct gr1553rt_sa *) - (((unsigned int)priv->satab_buffer + 0x1ff) & - ~0x1ff); /* Translate Address from CPU-LOCAL to HARDWARE (REMOTE) */ drvmgr_translate_check( @@ -896,8 +915,17 @@ static int gr1553rt_sw_alloc(struct gr1553rt_priv *priv) (void **)&priv->sas_hw, 16 * 32); } + /* Verify alignment */ + if ((unsigned int)priv->sas_hw & (0x1ff)) { + retval = -2; + goto err; + } - return 0; +err: + if (retval) { + gr1553rt_sw_free(priv); + } + return retval; } void gr1553rt_sw_init(struct gr1553rt_priv *priv) @@ -943,7 +971,7 @@ void gr1553rt_sw_init(struct gr1553rt_priv *priv) int gr1553rt_config(void *rt, struct gr1553rt_cfg *cfg) { struct gr1553rt_priv *priv = rt; - + int retval = 0; if ( priv->started ) return -1; @@ -955,9 +983,9 @@ int gr1553rt_config(void *rt, struct gr1553rt_cfg *cfg) if ( cfg->rtaddress > 30 ) return -1; if ( (cfg->evlog_size & (cfg->evlog_size-1)) != 0) - return -1; /* SIZE: Not aligned to a power of 2 */ + return -2; /* SIZE: Not aligned to a power of 2 */ if ( ((unsigned int)priv->cfg.evlog_buffer & (cfg->evlog_size-1)) != 0 ) - return -1; /* Buffer: Not aligned to size */ + return -2; /* Buffer: Not aligned to size */ #if (RTBD_MAX > 0) if ( cfg->bd_count > RTBD_MAX ) return -1; @@ -968,8 +996,9 @@ int gr1553rt_config(void *rt, struct gr1553rt_cfg *cfg) /*** Adapt to new config ***/ - if ( gr1553rt_sw_alloc(priv) != 0 ) - return -1; + if ( (retval=gr1553rt_sw_alloc(priv)) != 0 ) { + return retval; + } gr1553rt_sw_init(priv); -- cgit v1.2.3