131 lines
4.2 KiB
C
131 lines
4.2 KiB
C
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <sys/types.h>
|
|
|
|
#define debug(format, ...) printf("DEBUG - " format "\n",##__VA_ARGS__)
|
|
|
|
volatile u_int32_t ganimede_read_data[1024] __attribute__ ((aligned (1024)));
|
|
volatile u_int32_t ganimede_write_data[1024] __attribute__ ((aligned (1024)));
|
|
|
|
const uint32_t size_bias = 10;
|
|
|
|
enum OpType{ WRITE_ONE_SHOT, WRITE_LOOP, READ_ONE_SHOT, READ_LOOP };
|
|
int ceil_log2(unsigned long long x)
|
|
{
|
|
static const unsigned long long t[6] = {
|
|
0xFFFFFFFF00000000ull,
|
|
0x00000000FFFF0000ull,
|
|
0x000000000000FF00ull,
|
|
0x00000000000000F0ull,
|
|
0x000000000000000Cull,
|
|
0x0000000000000002ull
|
|
};
|
|
|
|
int y = (((x & (x - 1)) == 0) ? 0 : 1);
|
|
int j = 32;
|
|
int i;
|
|
|
|
for (i = 0; i < 6; i++) {
|
|
int k = (((x & t[i]) == 0) ? 0 : j);
|
|
y += k;
|
|
x >>= k;
|
|
j >>= 1;
|
|
}
|
|
|
|
return y;
|
|
}
|
|
// Address will forcibly floored to be aligned to KB.
|
|
// byteSize must be smaller than
|
|
u_int32_t create_ganimede_instruction(u_int32_t address, enum OpType optype, u_int32_t byteSize){
|
|
u_int32_t addressPart = (address & 0xfffffc00);
|
|
u_int32_t optypePart = 0x00000000;
|
|
u_int32_t byteSizePart = 0;
|
|
|
|
byteSize = byteSize > 1 << 25? 1<<25 :byteSize;
|
|
byteSizePart = ceil_log2(byteSize) - size_bias;
|
|
byteSizePart = (byteSizePart & 0xf) << 6;
|
|
switch (optype) {
|
|
case WRITE_ONE_SHOT: optypePart |= 0b001000; break;
|
|
case WRITE_LOOP: optypePart |= 0b011000; break;
|
|
case READ_ONE_SHOT: optypePart |= 0b000000; break;
|
|
case READ_LOOP: optypePart |= 0b010000; break;
|
|
}
|
|
return addressPart | optypePart | byteSizePart;
|
|
}
|
|
|
|
char* show_optype(u_int32_t optype){
|
|
switch ((optype & 0b111000) >> 3) {
|
|
case 0b001: return "WRITE_ONE_SHOT"; break;
|
|
case 0b011: return "WRITE_LOOP"; break;
|
|
case 0b000: return "READ_ONE_SHOT"; break;
|
|
case 0b010: return "READ_LOOP"; break;
|
|
}
|
|
return "UNKNOWN";
|
|
}
|
|
|
|
void print_gan_inst(u_int32_t inst){
|
|
int size = ((inst & 0b1111000000) >> 6) + size_bias;
|
|
if (size >= 30){
|
|
debug( "command vector is | address: %#011x\n"
|
|
" | operation: %s\n"
|
|
" | size: %d MB\n"
|
|
, inst & 0xfffffc00, show_optype(inst), 1 << (size - 30));
|
|
} else if (size >= 20){
|
|
debug( "command vector is | address: %#011x\n"
|
|
" | operation: %s\n"
|
|
" | size: %d MB\n"
|
|
, inst & 0xfffffc00, show_optype(inst), 1 << (size - 20));
|
|
} else if(size >= 10){
|
|
debug( "command vector is | address: %#011x\n"
|
|
" | operation: %s\n"
|
|
" | size: %d KB\n"
|
|
, inst & 0xfffffc00, show_optype(inst), 1 << (size - 10));
|
|
} else {
|
|
debug( "command vector is | address: %#011x\n"
|
|
" | operation: %s\n"
|
|
" | size: %d B\n"
|
|
, inst & 0xfffffc00, show_optype(inst), 1 << size);
|
|
}
|
|
}
|
|
|
|
int main(){
|
|
volatile u_int32_t* data_ptr = (u_int32_t*) 0x10000000;
|
|
volatile u_int32_t* cfg_ptr = (u_int32_t*) 0x80000d00;
|
|
//for(int i = 0; i < 10; i++){
|
|
// ((int*) (0x80000000))[i] = 0x12345678 + i;
|
|
//}
|
|
printf("\n");
|
|
debug("Initializing socbridge and GANIMEDE");
|
|
debug("setting socbridge config");
|
|
// Setting omaxsz = 7 and orxqen = true
|
|
cfg_ptr[0] = 0x0001bfff;
|
|
cfg_ptr[1] = 0x00000000;
|
|
debug("setting parif config.");
|
|
cfg_ptr[4] = 0x00000071;
|
|
cfg_ptr[5] = 0x00001002;
|
|
|
|
debug("initializing test data to read");
|
|
for(int i = 0; i < sizeof(ganimede_read_data)/sizeof(u_int32_t); i++){
|
|
ganimede_read_data[i] = i;
|
|
}
|
|
|
|
debug("Finished initializing\n");
|
|
|
|
|
|
|
|
debug("Sending commands to GANIMEDE");
|
|
debug("creating and sending a read instruction");
|
|
int readInst = create_ganimede_instruction((u_int32_t) &ganimede_read_data[0], READ_ONE_SHOT, 1024 );
|
|
print_gan_inst(readInst);
|
|
//data_ptr[0] = readInst;
|
|
|
|
debug("creating and sending a write instruction");
|
|
int writeInst = create_ganimede_instruction((u_int32_t) &ganimede_write_data[0], WRITE_ONE_SHOT, 1024);
|
|
print_gan_inst(writeInst);
|
|
//data_ptr[1] = writeInst;
|
|
|
|
debug("Finished sending commands\n");
|
|
return 0;
|
|
}
|