runtime,coredevice: support session reset for serial

This commit is contained in:
Sebastien Bourdeauducq 2015-04-28 02:11:58 +08:00
parent 27d94a22de
commit 9b62e7e77b
3 changed files with 37 additions and 22 deletions

View File

@ -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

View File

@ -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)

View File

@ -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;
}
}