14 APP_CMD_READ_CONTROL_REG
,
15 APP_CMD_WRITE_CONTROL_REG
,
22 #define APP_DATA_ALIGN 8
23 #define APP_MAX_DATA_SIZE 1024
30 uint8_t data
[APP_MAX_DATA_SIZE
];
33 htif_t::htif_t(int _tohost_fd
, int _fromhost_fd
)
34 : sim(NULL
), tohost_fd(_tohost_fd
), fromhost_fd(_fromhost_fd
), seqno(1)
44 void htif_t::init(sim_t
* _sim
)
49 void htif_t::wait_for_start()
51 while(wait_for_packet() != APP_CMD_START
);
54 void htif_t::wait_for_fromhost_write()
56 while(wait_for_packet() != APP_CMD_WRITE_CONTROL_REG
);
59 void htif_t::send_packet(packet
* p
)
61 int bytes
= write(tohost_fd
,p
,offsetof(packet
,data
)+p
->data_size
);
62 if((size_t)bytes
!= offsetof(packet
,data
) + p
->data_size
)
64 const char* error
= bytes
== -1 ? strerror(errno
) : "not all bytes sent";
65 fprintf(stderr
,"HTIF error: %s\n", error
);
70 void htif_t::nack(uint16_t nack_seqno
)
72 packet p
= {APP_CMD_NACK
,nack_seqno
,0,0};
76 int htif_t::wait_for_packet()
81 int bytes
= read(fromhost_fd
,&p
,sizeof(p
));
82 if(bytes
< (int)offsetof(packet
,data
))
84 const char* error
= bytes
== -1 ? strerror(errno
) : "too few bytes read";
85 fprintf(stderr
,"HTIF error: %s\n", error
);
95 packet ackpacket
= {APP_CMD_ACK
,seqno
,0,0};
104 case APP_CMD_READ_MEM
:
105 assert(p
.addr
% APP_DATA_ALIGN
== 0);
106 assert(p
.data_size
% APP_DATA_ALIGN
== 0);
107 assert(p
.data_size
<= APP_MAX_DATA_SIZE
);
108 assert(p
.addr
<= sim
->memsz
&& p
.addr
+p
.data_size
<= sim
->memsz
);
109 ackpacket
.data_size
= p
.data_size
;
111 static_assert(APP_DATA_ALIGN
>= sizeof(uint64_t))
112 for(size_t i
= 0; i
< p
.data_size
/8; i
++)
113 ((uint64_t*)ackpacket
.data
)[i
] = sim
->mmu
->load_uint64(p
.addr
+i
*8);
115 case APP_CMD_WRITE_MEM
:
116 assert(p
.addr
% APP_DATA_ALIGN
== 0);
117 assert(p
.data_size
% APP_DATA_ALIGN
== 0);
118 assert(p
.data_size
<= bytes
- offsetof(packet
,data
));
119 assert(p
.addr
<= sim
->memsz
&& p
.addr
+p
.data_size
<= sim
->memsz
);
121 for(size_t i
= 0; i
< p
.data_size
/8; i
++)
122 sim
->mmu
->store_uint64(p
.addr
+i
*8, ((uint64_t*)p
.data
)[i
]);
124 case APP_CMD_READ_CONTROL_REG
:
125 assert(p
.addr
== 16);
126 assert(p
.data_size
== sizeof(reg_t
));
127 ackpacket
.data_size
= sizeof(reg_t
);
128 memcpy(ackpacket
.data
,&sim
->tohost
,sizeof(reg_t
));
130 case APP_CMD_WRITE_CONTROL_REG
:
131 assert(p
.addr
== 17);
132 assert(p
.data_size
== sizeof(reg_t
));
134 memcpy(&sim
->fromhost
,p
.data
,sizeof(reg_t
));
138 send_packet(&ackpacket
);