#include #include #include #include #include "comm.h" #ifndef ARTIQ_AMP #include "exceptions.h" #endif /* host to device */ enum { MSGTYPE_SET_BAUD_RATE = 1, MSGTYPE_REQUEST_IDENT, MSGTYPE_SWITCH_CLOCK, MSGTYPE_LOAD_OBJECT, MSGTYPE_RUN_KERNEL, }; /* device to host */ enum { MSGTYPE_MESSAGE_UNRECOGNIZED = 1, MSGTYPE_LOG, MSGTYPE_IDENT, MSGTYPE_CLOCK_SWITCH_COMPLETED, MSGTYPE_CLOCK_SWITCH_FAILED, MSGTYPE_OBJECT_LOADED, MSGTYPE_OBJECT_INCORRECT_LENGTH, MSGTYPE_OBJECT_CRC_FAILED, MSGTYPE_OBJECT_UNRECOGNIZED, MSGTYPE_KERNEL_FINISHED, MSGTYPE_KERNEL_STARTUP_FAILED, MSGTYPE_KERNEL_EXCEPTION, MSGTYPE_RPC_REQUEST, }; static int receive_int(void) { unsigned int r; int i; r = 0; for(i=0;i<4;i++) { r <<= 8; r |= (unsigned char)uart_read(); } return r; } static char receive_char(void) { return uart_read(); } static void send_llint(long long int x) { int i; for(i=0;i<8;i++) { uart_write((x & 0xff00000000000000LL) >> 56); x <<= 8; } } static void send_int(int x) { int i; for(i=0;i<4;i++) { uart_write((x & 0xff000000) >> 24); x <<= 8; } } static void send_sint(short int i) { uart_write((i >> 8) & 0xff); uart_write(i & 0xff); } static void send_char(char c) { uart_write(c); } static void receive_sync(void) { char c; int recognized; recognized = 0; while(recognized < 4) { c = uart_read(); if(c == 0x5a) recognized++; else recognized = 0; } } static void receive_and_load_object(object_loader load_object) { int length; int i; unsigned char buffer[256*1024]; unsigned int crc; length = receive_int(); if(length > sizeof(buffer)) { send_char(MSGTYPE_OBJECT_INCORRECT_LENGTH); return; } crc = receive_int(); for(i=0;i (sizeof(kernel_name)-1)) { send_char(MSGTYPE_OBJECT_INCORRECT_LENGTH); return; } for(i=0;i> 8, (char *)value + p); send_char(0); return p; } return 0; } void comm_rpc_va(int rpc_num, va_list args, int *eid, int *retval) { int type_tag; send_char(MSGTYPE_RPC_REQUEST); send_sint(rpc_num); while((type_tag = va_arg(args, int))) send_value(type_tag, type_tag == 'n' ? NULL : va_arg(args, void *)); send_char(0); *eid = receive_int(); *retval = receive_int(); } #ifndef ARTIQ_AMP int comm_rpc(int rpc_num, ...) { va_list args; int eid, retval; va_start(args, rpc_num); comm_rpc_va(rpc_num, args, &eid, &retval); va_end(args); if(eid != EID_NONE) exception_raise(eid); return retval; } #endif void comm_log_va(const char *fmt, va_list args) { int len; char outbuf[256]; int i; len = vscnprintf(outbuf, sizeof(outbuf), fmt, args); send_char(MSGTYPE_LOG); send_sint(len); for(i=0;i