11 APP_CMD_READ_CONTROL_REG
,
12 APP_CMD_WRITE_CONTROL_REG
,
19 #define APP_DATA_ALIGN 8
20 #define APP_MAX_DATA_SIZE 1024
27 uint8_t data
[APP_MAX_DATA_SIZE
];
30 class packet_error
: public std::runtime_error
33 packet_error(const std::string
& s
) : std::runtime_error(s
) {}
35 class io_error
: public packet_error
38 io_error(const std::string
& s
) : packet_error(s
) {}
41 appserver_link_t::appserver_link_t(int _tohost_fd
, int _fromhost_fd
)
42 : sim(NULL
), tohost_fd(_tohost_fd
), fromhost_fd(_fromhost_fd
), seqno(1)
46 void appserver_link_t::init(sim_t
* _sim
)
51 void appserver_link_t::wait_for_start()
53 while(wait_for_packet() != APP_CMD_START
);
56 void appserver_link_t::send_packet(packet
* p
)
60 int bytes
= write(tohost_fd
,p
,offsetof(packet
,data
)+p
->data_size
);
61 if(bytes
== -1 || (size_t)bytes
!= offsetof(packet
,data
)+p
->data_size
)
62 throw io_error("write failed");
67 fprintf(stderr
,"warning: %s\n",e
.what());
71 void appserver_link_t::nack(uint16_t nack_seqno
)
73 packet p
= {APP_CMD_NACK
,nack_seqno
,0,0};
77 int appserver_link_t::wait_for_packet()
82 int bytes
= read(fromhost_fd
,&p
,sizeof(p
));
83 if(bytes
< (signed)offsetof(packet
,data
))
84 throw io_error("read failed");
92 packet ackpacket
= {APP_CMD_ACK
,seqno
,0,0};
99 send_packet(&ackpacket
);
101 case APP_CMD_READ_MEM
:
102 demand(p
.addr
% APP_DATA_ALIGN
== 0, "misaligned address");
103 demand(p
.data_size
% APP_DATA_ALIGN
== 0, "misaligned data");
104 demand(p
.data_size
<= APP_MAX_DATA_SIZE
, "long read data");
105 demand(p
.addr
<= sim
->memsz
&& p
.addr
+p
.data_size
<= sim
->memsz
, "out of bounds");
106 memcpy(ackpacket
.data
,sim
->mem
+p
.addr
,p
.data_size
);
107 ackpacket
.data_size
= p
.data_size
;
109 case APP_CMD_WRITE_MEM
:
110 demand(p
.addr
% APP_DATA_ALIGN
== 0, "misaligned address");
111 demand(p
.data_size
% APP_DATA_ALIGN
== 0, "misaligned data");
112 demand(p
.data_size
<= bytes
- offsetof(packet
,data
), "short packet");
113 demand(p
.addr
<= sim
->memsz
&& p
.addr
+p
.data_size
<= sim
->memsz
, "out of bounds");
114 memcpy(sim
->mem
+p
.addr
,p
.data
,p
.data_size
);
116 case APP_CMD_READ_CONTROL_REG
:
117 demand(p
.addr
== 16,"bad control reg");
118 demand(p
.data_size
== sizeof(reg_t
),"bad control reg size");
119 ackpacket
.data_size
= sizeof(reg_t
);
120 memcpy(ackpacket
.data
,&sim
->tohost
,sizeof(reg_t
));
122 case APP_CMD_WRITE_CONTROL_REG
:
123 demand(p
.addr
== 17,"bad control reg");
124 demand(p
.data_size
== sizeof(reg_t
),"bad control reg size");
126 memcpy(&sim
->fromhost
,p
.data
,sizeof(reg_t
));
130 send_packet(&ackpacket
);
136 fprintf(stderr
,"warning: %s\n",e
.what());