From 9b62e7e77bce43346a9abe5816d267636bc52c52 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Tue, 28 Apr 2015 02:11:58 +0800 Subject: [PATCH] runtime,coredevice: support session reset for serial --- artiq/coredevice/comm_generic.py | 5 ++++- soc/runtime/main.c | 24 +++++++++++++++++++----- soc/runtime/session.c | 30 ++++++++++++++---------------- 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/artiq/coredevice/comm_generic.py b/artiq/coredevice/comm_generic.py index e1e0fbe47..d8bf00b4b 100644 --- a/artiq/coredevice/comm_generic.py +++ b/artiq/coredevice/comm_generic.py @@ -76,7 +76,10 @@ class CommGeneric: sync_count += 1 else: sync_count = 0 - length, tyv = struct.unpack(">lB", self.read(5)) + length = struct.unpack(">l", self.read(4))[0] + if not length: # inband connection close + raise OSError("Connection closed") + tyv = struct.unpack("B", self.read(1))[0] ty = _D2HMsgType(tyv) logger.debug("receiving message: type=%r length=%d", ty, length) return length, ty diff --git a/soc/runtime/main.c b/soc/runtime/main.c index 608a7cac3..e664c7b57 100644 --- a/soc/runtime/main.c +++ b/soc/runtime/main.c @@ -269,6 +269,8 @@ static void kserver_service(void) tcp_write(active_pcb, data, len, 0); session_ack_data(len); } + if(len < 0) + kserver_close(active_cs, active_pcb); } } @@ -285,6 +287,19 @@ static void regular_main(void) #else /* CSR_ETHMAC_BASE */ +static void reset_serial_session(void) +{ + int i; + + session_end(); + /* Signal end-of-session inband with zero length packet. */ + for(i=0;i<4;i++) + uart_write(0x5a); + for(i=0;i<4;i++) + uart_write(0x00); + session_start(); +} + static void serial_service(void) { char *txdata; @@ -301,10 +316,8 @@ static void serial_service(void) r = session_input(&rxdata, 1); if(r > 0) rxpending = 0; - if(r < 0) { - session_end(); - session_start(); - } + if(r < 0) + reset_serial_session(); } session_poll((void **)&txdata, &txlen); @@ -313,7 +326,8 @@ static void serial_service(void) uart_write(txdata[i]); session_ack_data(txlen); session_ack_mem(txlen); - } + } else if(txlen < 0) + reset_serial_session(); } static void regular_main(void) diff --git a/soc/runtime/session.c b/soc/runtime/session.c index 21f22bc69..169105333 100644 --- a/soc/runtime/session.c +++ b/soc/runtime/session.c @@ -362,11 +362,11 @@ int session_input(void *data, int len) } /* assumes output buffer is empty when called */ -static void process_kmsg(struct msg_base *umsg) +static int process_kmsg(struct msg_base *umsg) { if(user_kernel_state != USER_KERNEL_RUNNING) { log("Received message from kernel CPU while not in running state"); - return; + return 0; } switch(umsg->type) { @@ -392,7 +392,8 @@ static void process_kmsg(struct msg_base *umsg) case MESSAGE_TYPE_RPC_REQUEST: { struct msg_rpc_request *msg = (struct msg_rpc_request *)umsg; - send_rpc_request(msg->rpc_num, msg->args); + if(!send_rpc_request(msg->rpc_num, msg->args)) + return 0; user_kernel_state = USER_KERNEL_WAIT_RPC; break; } @@ -403,23 +404,16 @@ static void process_kmsg(struct msg_base *umsg) break; } default: { - int eid; - log("Received invalid message type from kernel CPU"); - - buffer_out[8] = REMOTEMSG_TYPE_KERNEL_EXCEPTION; - eid = EID_INTERNAL_ERROR; - memcpy(&buffer_out[9], &eid, 4); - memset(&buffer_out[13], 0, 3*8); - submit_output(9+4+3*8); - - kloader_stop_kernel(); - user_kernel_state = USER_KERNEL_LOADED; - break; + return 0; } } + return 1; } +/* len is set to -1 in case of irrecoverable error + * (the session must be dropped and session_end called) + */ void session_poll(void **data, int *len) { int l; @@ -434,7 +428,10 @@ void session_poll(void **data, int *len) umsg = mailbox_receive(); if(umsg) { - process_kmsg(umsg); + if(!process_kmsg(umsg)) { + *len = -1; + return; + } mailbox_acknowledge(); } l = get_out_packet_len(); @@ -454,6 +451,7 @@ void session_ack_mem(int len) buffer_out_index_mem += len; if(buffer_out_index_mem >= get_out_packet_len()) { memset(&buffer_out[4], 0, 4); + buffer_out_index_data = 0; buffer_out_index_mem = 0; } }