Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions libs/h2_compat/coproc/h2_coproc.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,18 @@ Count coprocessor (context) instances
*/
int h2_coproc_set(h2_coproc_type_t type, h2_coproc_subtype_t subtype, h2_cfg_unit_entry entry_type, unsigned int unit_mask, unsigned int num, unsigned int enable);

typedef enum {
H2_COPROC_INIT_OK = 0,
H2_COPROC_INIT_OLDSTYLE = 1,
H2_COPROC_INIT_ERROR = -1,
} h2_coproc_init_result_t;

/**
Initialize coprocessor data
@returns 0 on success; 1 to indicate absence of multi-unit configuration; -1 on error
@returns H2_COPROC_INIT_OK on success; H2_COPROC_INIT_OLDSTYLE if multi-unit configuration is absent; H2_COPROC_INIT_ERROR on error
@dependencies None
*/
int h2_coproc_init();
h2_coproc_init_result_t h2_coproc_init();

/** @} */

Expand Down
133 changes: 67 additions & 66 deletions libs/h2_compat/coproc/h2_coproc.ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,40 @@
#include <h2_coproc.h>
#include <h2_alloc.h>

/* Number of context bits in a unit's context mask (one unsigned int). */
#define COPROC_BITS_PER_UNIT (sizeof(unsigned int) * 8)

static unsigned int *configs[CFG_TYPE_MAX][CFG_SUBTYPE_MAX] = {NULL};
static unsigned int nunits[CFG_TYPE_MAX][CFG_SUBTYPE_MAX] = {0};
static unsigned int *counts[CFG_TYPE_MAX][CFG_SUBTYPE_MAX][CFG_MAX] = {NULL};
static unsigned char *bitpos[CFG_TYPE_MAX][CFG_SUBTYPE_MAX][CFG_MAX] = {NULL};
static unsigned int oldstyle = 0;
static unsigned int init_done = 0;

/* Record the bit positions of the set bits in `bits`, in ascending order, into `out`. */
static void coproc_build_bitpos(unsigned int bits, unsigned char *out) {
unsigned int pos = 0;
unsigned int k = 0;

while (bits) {
if (bits & 0x1) {
out[k++] = (unsigned char)pos;
}
bits >>= 1;
pos++;
}
}

static int coproc_grow(void **slot, int newsize) {
void *p = h2_realloc(*slot, newsize);

if (NULL == p) {
return -1;
}
*slot = p;
return 0;
}

int h2_coproc_count(h2_coproc_type_t type, h2_coproc_subtype_t subtype, h2_cfg_unit_entry entry_type, unsigned int unit_mask) {
unsigned int i;
int ret = 0;
Expand Down Expand Up @@ -63,39 +91,22 @@ int h2_coproc_set(h2_coproc_type_t type, h2_coproc_subtype_t subtype, h2_cfg_uni

unsigned int idx = 0; // unit being considered
unsigned int ncontexts;
unsigned int bits;
unsigned int xa;
unsigned int *entry;

if (oldstyle || !enable) {
return setbits(type, subtype, entry_type, num, enable); //
return setbits(type, subtype, entry_type, num, enable);
}

num += 1; // num == number of existing contexts left to find

while (num && idx < nunits[type][subtype]) { // still searching and in range
if (unit_mask & (0x1 << idx)) { // unit selected
entry = &configs[type][subtype][idx * CFG_MAX];
bits = entry[entry_type];
ncontexts = Q6_R_popcount_P(bits);
ncontexts = counts[type][subtype][entry_type][idx];
if (num <= ncontexts) { // requested context # is in this unit
xa = 0; // index of bit
do {
if (bits & 0x1) { // context exists
if (0 == (--num)) { // none left to find; now xa is correct
break;
} else {
xa++;
continue;
}
} else { // context is missing
bits >>= 1; // check next bit
xa++;
continue;
}
} while (1);

// now xa is the index of the bit in the current unit that corresponds to the requested context #
xa = bitpos[type][subtype][entry_type][idx * COPROC_BITS_PER_UNIT + (num - 1)];

setbits(type, subtype, entry_type, xa, enable);
h2_hwconfig_set_coprocbits(entry[CFG_VXU_UNIT_ID]); // FIXME: need to get the ID field for this unit type
return 0;
Expand All @@ -109,33 +120,46 @@ int h2_coproc_set(h2_coproc_type_t type, h2_coproc_subtype_t subtype, h2_cfg_uni
return -1;
}

/*
* Populate the per-unit context count and logical->physical bit map for one
* entry type (HVX/HLX/HMX) of a unit. Grows the count array to cover `idx`
* and the bitpos array to cover this unit's COPROC_BITS_PER_UNIT slot.
*/
static int init_entry_contexts(h2_coproc_type_t type, h2_coproc_subtype_t subtype, h2_cfg_unit_entry entry_type, unsigned int idx, unsigned int bits) {
if (-1 == coproc_grow((void **)&counts[type][subtype][entry_type], (idx + 1) * sizeof(unsigned int))) {
return -1;
}
counts[type][subtype][entry_type][idx] = Q6_R_popcount_P(bits);

if (-1 == coproc_grow((void **)&bitpos[type][subtype][entry_type], (idx + 1) * COPROC_BITS_PER_UNIT * sizeof(unsigned char))) {
return -1;
}
coproc_build_bitpos(bits, &bitpos[type][subtype][entry_type][idx * COPROC_BITS_PER_UNIT]);

return 0;
}

static int init_entry_vxu0(unsigned int unit, h2_coproc_type_t type, h2_coproc_subtype_t subtype, unsigned int idx) {
unsigned int *entry;

entry = &configs[type][subtype][idx * CFG_MAX];
entry[CFG_VXU_UNIT_ID] = h2_info_unit(unit, CFG_VXU_UNIT_ID);

entry[CFG_HVX_CONTEXTS] = h2_info_unit(unit, CFG_HVX_CONTEXTS);
if (NULL == (counts[type][subtype][CFG_HVX_CONTEXTS] =
h2_realloc(counts[type][subtype][CFG_HVX_CONTEXTS], (idx + 1) * sizeof(unsigned int)))) {
if (-1 == init_entry_contexts(type, subtype, CFG_HVX_CONTEXTS, idx, entry[CFG_HVX_CONTEXTS])) {
return -1;
}
counts[type][subtype][CFG_HVX_CONTEXTS][idx] = Q6_R_popcount_P(entry[CFG_HVX_CONTEXTS]);


entry[CFG_HLX_CONTEXTS] = h2_info_unit(unit, CFG_HLX_CONTEXTS);
if (NULL == (counts[type][subtype][CFG_HLX_CONTEXTS] =
h2_realloc(counts[type][subtype][CFG_HLX_CONTEXTS], (idx + 1) * sizeof(unsigned int)))) {
if (-1 == init_entry_contexts(type, subtype, CFG_HLX_CONTEXTS, idx, entry[CFG_HLX_CONTEXTS])) {
return -1;
}
counts[type][subtype][CFG_HLX_CONTEXTS][idx] = Q6_R_popcount_P(entry[CFG_HLX_CONTEXTS]);


entry[CFG_HMX_CONTEXTS] = h2_info_unit(unit, CFG_HMX_CONTEXTS);
if (NULL == (counts[type][subtype][CFG_HMX_CONTEXTS] =
h2_realloc(counts[type][subtype][CFG_HMX_CONTEXTS], (idx + 1) * sizeof(unsigned int)))) {
if (-1 == init_entry_contexts(type, subtype, CFG_HMX_CONTEXTS, idx, entry[CFG_HMX_CONTEXTS])) {
return -1;
}
counts[type][subtype][CFG_HMX_CONTEXTS][idx] = Q6_R_popcount_P(entry[CFG_HMX_CONTEXTS]);


return 0;
}

Expand All @@ -147,58 +171,35 @@ static const initptr_t inits[CFG_TYPE_MAX][CFG_SUBTYPE_MAX] = {
}
};

int h2_coproc_init() {
h2_coproc_init_result_t h2_coproc_init() {
unsigned int unit;
h2_coproc_type_t type;
h2_coproc_subtype_t subtype;
unsigned int idx;

if (init_done) {
return 0;
return oldstyle ? H2_COPROC_INIT_OLDSTYLE : H2_COPROC_INIT_OK;
}

if (0 == (unit = h2_info(INFO_UNIT_START))) { // old style
oldstyle = 1;
init_done = 1;
return 1;
return H2_COPROC_INIT_OLDSTYLE;
}

init_done = 1;
while (unit) {
type = h2_info_unit(unit, CFG_UNIT_ID);
subtype = h2_info_unit(unit, CFG_UNIT_SUBID);
idx = nunits[type][subtype];
if (NULL == (configs[type][subtype] =
h2_realloc(configs[type][subtype], CFG_MAX * (idx + 1) * sizeof(unsigned int)))) {
return -1;
if (-1 == coproc_grow((void **)&configs[type][subtype], CFG_MAX * (idx + 1) * sizeof(unsigned int))) {
return H2_COPROC_INIT_ERROR;
}
nunits[type][subtype]++;
if (-1 == inits[type][subtype](unit, type, subtype, idx)) return -1;
if (-1 == inits[type][subtype](unit, type, subtype, idx)) return H2_COPROC_INIT_ERROR;
unit = h2_info_unit(unit, CFG_UNIT_NEXT);
}

/* printf ("nunits 0x%08x\n", nunits[0][0]); */

/* printf ("unit ID 0x%08x\n", configs[0][0][CFG_VXU_UNIT_ID]); */

/* printf ("configs 0x%08x\n", configs[0][0][CFG_HVX_CONTEXTS]); */
/* printf ("configs 0x%08x\n", configs[0][0][CFG_HLX_CONTEXTS]); */
/* printf ("configs 0x%08x\n", configs[0][0][CFG_HMX_CONTEXTS]); */

/* printf ("counts 0x%08x\n", counts[0][0][CFG_HVX_CONTEXTS][0]); */
/* printf ("counts 0x%08x\n", counts[0][0][CFG_HLX_CONTEXTS][0]); */
/* printf ("counts 0x%08x\n", counts[0][0][CFG_HMX_CONTEXTS][0]); */

/* printf ("unit ID 0x%08x\n", configs[0][0][CFG_MAX + CFG_VXU_UNIT_ID]); */

/* printf ("configs 0x%08x\n", configs[0][0][CFG_MAX + CFG_HVX_CONTEXTS]); */
/* printf ("configs 0x%08x\n", configs[0][0][CFG_MAX + CFG_HLX_CONTEXTS]); */
/* printf ("configs 0x%08x\n", configs[0][0][CFG_MAX + CFG_HMX_CONTEXTS]); */

/* printf ("counts 0x%08x\n", counts[0][0][CFG_HVX_CONTEXTS][1]); */
/* printf ("counts 0x%08x\n", counts[0][0][CFG_HLX_CONTEXTS][1]); */
/* printf ("counts 0x%08x\n", counts[0][0][CFG_HMX_CONTEXTS][1]); */

return 0;
init_done = 1;
return H2_COPROC_INIT_OK;
}

14 changes: 9 additions & 5 deletions libs/h2_compat/lxaccess/h2_lxaccess.ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@

int h2_lxaccess_unit_init(h2_lxaccess_state_t *lxacc, h2_coproc_type_t type, h2_coproc_subtype_t subtype, h2_cfg_unit_entry entry_type, unsigned int unit_mask) {
#ifdef HMX_HLX_SUPPORT
int ret;
h2_coproc_init_result_t ret;

if ((ret = h2_coproc_init()) < 0) return ret;

if (1 == ret) { // old style
if (H2_COPROC_INIT_OLDSTYLE == ret) { // old style
h2_sem_init_val(&lxacc->sem, h2_info(INFO_HLX_CONTEXTS));
} else {
h2_sem_init_val(&lxacc->sem, h2_coproc_count(type, subtype, entry_type, unit_mask));
Expand Down Expand Up @@ -63,12 +63,16 @@ int h2_lxaccess_acquire(h2_lxaccess_state_t *lxacc) {
#endif
}

int h2_lxaccess_release(h2_lxaccess_state_t *lxacc, int idx)
int h2_lxaccess_release(h2_lxaccess_state_t *lxacc, int idx)
{
#ifdef HMX_HLX_SUPPORT
int ret;

ret = h2_coproc_set(lxacc->type, lxacc->subtype, lxacc->entry_type, lxacc->unit_mask, 0, 0);
if (!(lxacc->active & (1u << idx))) {
return -1;
}

ret = h2_coproc_set(lxacc->type, lxacc->subtype, lxacc->entry_type, lxacc->unit_mask, idx, 0);
h2_atomic_clrbit32(&lxacc->active, idx);
h2_sem_up(&lxacc->sem);

Expand Down
8 changes: 8 additions & 0 deletions libs/h2_compat/lxaccess/test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#Hey emacs this is a -*- Makefile -*-
BOOT=1
OBJS+=test.o
EXEC=test.elf

include Makefile.inc

CFLAGS += -v -G0
5 changes: 5 additions & 0 deletions libs/h2_compat/lxaccess/test/Makefile.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Hey emacs this is a -*- Makefile -*-

H2DIR=${UPDIR}../../../..

include ${H2DIR}/scripts/Makefile.inc.test
Loading
Loading