diff options
Diffstat (limited to 'core.c')
-rw-r--r-- | core.c | 89 |
1 files changed, 56 insertions, 33 deletions
@@ -4,7 +4,7 @@ * This module contains code to probe the FPGA for its installed cores. * * Author: Paul Selkirk, Rob Austein - * Copyright (c) 2015-2016, NORDUnet A/S All rights reserved. + * Copyright (c) 2015-2017, NORDUnet A/S All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -97,7 +97,7 @@ static int name_matches(const hal_core_t *const core, const char * const name) static const struct { const char *name; hal_addr_t extra; } gaps[] = { { "csprng", 11 * CORE_SIZE }, /* empty slots after csprng */ { "modexps6", 3 * CORE_SIZE }, /* ModexpS6 uses four slots */ - { "modexpa7", 3 * CORE_SIZE }, /* ModexpA7 uses four slots */ + { "modexpa7", 7 * CORE_SIZE }, /* ModexpA7 uses eight slots */ }; static hal_core_t *head = NULL; @@ -135,7 +135,7 @@ static hal_core_t *probe_cores(void) if (core->info.name[0] == 0x00 || core->info.name[0] == 0xff) continue; - for (int i = 0; i < sizeof(gaps)/sizeof(*gaps); i++) { + for (size_t i = 0; i < sizeof(gaps)/sizeof(*gaps); i++) { if (name_matches(core, gaps[i].name)) { addr += gaps[i].extra; break; @@ -201,17 +201,19 @@ hal_core_t *hal_core_find(const char *name, hal_core_t *core) return NULL; } -hal_error_t hal_core_alloc(const char *name, hal_core_t **pcore) +static hal_error_t hal_core_alloc_no_wait(const char *name, hal_core_t **pcore) { - hal_core_t *core; - hal_error_t err = HAL_ERROR_CORE_NOT_FOUND; + /* + * This used to allow name == NULL iff *core != NULL, but the + * semantics were fragile and in practice we always pass a name + * anyway, so simplify by requiring name != NULL, always. + */ - if (name == NULL && (pcore == NULL || *pcore == NULL)) + if (name == NULL || pcore == NULL) return HAL_ERROR_BAD_ARGUMENTS; - core = *pcore; - if (name == NULL) - name = core->info.name; + hal_error_t err = HAL_ERROR_CORE_NOT_FOUND; + hal_core_t *core = *pcore; if (core != NULL) { /* if we can reallocate the same core, do it now */ @@ -221,35 +223,56 @@ hal_error_t hal_core_alloc(const char *name, hal_core_t **pcore) hal_critical_section_end(); return HAL_OK; } - /* else fall through to search */ + /* else forget that core and fall through to search */ + *pcore = NULL; } - while (1) { - hal_critical_section_start(); - for (core = hal_core_iterate(NULL); core != NULL; core = core->next) { - if (name_matches(core, name)) { - if (core->busy) { - err = HAL_ERROR_CORE_BUSY; - continue; - } - else { - err = HAL_OK; - *pcore = core; - core->busy = 1; - break; - } - } + hal_critical_section_start(); + for (core = hal_core_find(name, NULL); core != NULL; core = hal_core_find(name, core)) { + if (core->busy) { + err = HAL_ERROR_CORE_BUSY; + continue; } - hal_critical_section_end(); - if (err == HAL_ERROR_CORE_BUSY) - hal_task_yield(); - else - break; - } + err = HAL_OK; + *pcore = core; + core->busy = 1; + break; + } + hal_critical_section_end(); return err; } +hal_error_t hal_core_alloc(const char *name, hal_core_t **pcore) +{ + hal_error_t err; + + while ((err = hal_core_alloc_no_wait(name, pcore)) == HAL_ERROR_CORE_BUSY) + hal_task_yield(); + + return err; +} + +hal_error_t hal_core_alloc2(const char *name1, hal_core_t **pcore1, + const char *name2, hal_core_t **pcore2) +{ + hal_error_t err; + + while (1) { + if ((err = hal_core_alloc(name1, pcore1)) != HAL_OK) + return err; + + if ((err = hal_core_alloc_no_wait(name2, pcore2)) == HAL_OK) + return HAL_OK; + + hal_core_free(*pcore1); + /* hal_core_free does a yield, so we don't need to do another one */ + + if (err != HAL_ERROR_CORE_BUSY) + return err; + } +} + void hal_core_free(hal_core_t *core) { if (core != NULL) { @@ -270,7 +293,7 @@ const hal_core_info_t *hal_core_info(const hal_core_t *core) return core == NULL ? NULL : &core->info; } -const int hal_core_busy(const hal_core_t *core) +int hal_core_busy(const hal_core_t *core) { return (int)core->busy; } |