Esempio calcolo indice array da indirizzo device register
Jump to navigation
Jump to search
Ecco un esempio di codice:
#include "listx.h"
#include "umps3/umps/const.h"
#include "umps3/umps/arch.h"
#include "pandos_const.h"
#include "pandos_types.h"
// https://stackoverflow.com/questions/27581671/how-to-compute-log-with-the-preprocessor
// ---8<-----
#define NEEDS_BIT(N, B) (((unsigned long)N >> B) > 0)
#define BITS_TO_REPRESENT(N) \
(NEEDS_BIT(N, 0) + NEEDS_BIT(N, 1) + NEEDS_BIT(N, 2) + NEEDS_BIT(N, 3) + \
NEEDS_BIT(N, 4) + NEEDS_BIT(N, 5) + NEEDS_BIT(N, 6) + NEEDS_BIT(N, 7) + \
NEEDS_BIT(N, 8) + NEEDS_BIT(N, 9) + NEEDS_BIT(N, 10) + NEEDS_BIT(N, 11) + \
NEEDS_BIT(N, 12) + NEEDS_BIT(N, 13) + NEEDS_BIT(N, 14) + NEEDS_BIT(N, 15) + \
NEEDS_BIT(N, 16) + NEEDS_BIT(N, 17) + NEEDS_BIT(N, 18) + NEEDS_BIT(N, 19) + \
NEEDS_BIT(N, 20) + NEEDS_BIT(N, 21) + NEEDS_BIT(N, 22) + NEEDS_BIT(N, 23) + \
NEEDS_BIT(N, 24) + NEEDS_BIT(N, 25) + NEEDS_BIT(N, 26) + NEEDS_BIT(N, 27) + \
NEEDS_BIT(N, 28) + NEEDS_BIT(N, 29) + NEEDS_BIT(N, 30) + NEEDS_BIT(N, 31))
// ---8<-----
#define LOG_WORD_SIZE (BITS_TO_REPRESENT(WORD_SIZE) - 1)
#define LOG_DEV_REG_SIZE (BITS_TO_REPRESENT(DEV_REG_SIZE) - 1)
#define DEV_REG_MASK (DEV_REG_SIZE -1)
#define ERR -1
int devaddr_to_index(unsigned int addr) {
// consistency ck
if (addr < DEV_REG_START || addr >= DEV_REG_END)
return ERR;
else if (addr < DEV_REG_ADDR(IL_TERMINAL, 0)) {
// dev != terminal
addr -= DEV_REG_START;
if ((addr & DEV_REG_MASK) == (COMMAND << LOG_WORD_SIZE))
return addr >> LOG_DEV_REG_SIZE;
else
return ERR;
} else {
// dev == terminal
addr -= DEV_REG_START;
if ((addr & DEV_REG_MASK) == (RECVCOMMAND << LOG_WORD_SIZE))
return addr >> LOG_DEV_REG_SIZE;
else if ((addr & DEV_REG_MASK) == (TRANCOMMAND << LOG_WORD_SIZE))
return (addr >> LOG_DEV_REG_SIZE) + N_DEV_PER_IL;
else
return ERR;
}
}
#if TESTING
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
for (int i = 1; i < argc; i++) {
unsigned int addr = strtoul(argv[i], NULL, 0);
printf("%08x -> %d\n", addr, devaddr_to_index(addr));
}
}
#endif
Per provarlo (dopo averlo compilato con -DTESTING):
$ ./a.out 0x10000058
10000058 -> 0
$ ./a.out 0x10000068
10000068 -> 1
$ ./a.out 0x000002c8
000002c8 -> -1
$ ./a.out 0x100002c8
100002c8 -> 39
$ ./a.out 0x100002c0
100002c0 -> 46
$ ./a.out 0x100002d0
100002d0 -> 47