15 APP_CMD_READ_CONTROL_REG
,
16 APP_CMD_WRITE_CONTROL_REG
,
23 #define APP_DATA_ALIGN 8
24 #define APP_MAX_DATA_SIZE 1024
31 uint8_t data
[APP_MAX_DATA_SIZE
];
34 htif_t::htif_t(int _tohost_fd
, int _fromhost_fd
)
35 : sim(NULL
), tohost_fd(_tohost_fd
), fromhost_fd(_fromhost_fd
), seqno(1)
45 void htif_t::init(sim_t
* _sim
)
50 void htif_t::wait_for_start()
52 while(wait_for_packet() != APP_CMD_START
);
55 void htif_t::wait_for_tohost_write()
57 while(wait_for_packet() != APP_CMD_READ_CONTROL_REG
);
60 void htif_t::wait_for_fromhost_write()
62 while(wait_for_packet() != APP_CMD_WRITE_CONTROL_REG
);
65 void htif_t::send_packet(packet
* p
)
67 int bytes
= write(tohost_fd
,p
,offsetof(packet
,data
)+p
->data_size
);
68 if((size_t)bytes
!= offsetof(packet
,data
) + p
->data_size
)
70 const char* error
= bytes
== -1 ? strerror(errno
) : "not all bytes sent";
71 fprintf(stderr
,"HTIF error: %s\n", error
);
76 void htif_t::nack(uint16_t nack_seqno
)
78 packet p
= {APP_CMD_NACK
,nack_seqno
,0,0};
82 int htif_t::wait_for_packet()
87 int bytes
= read(fromhost_fd
,&p
,sizeof(p
));
88 if(bytes
< (int)offsetof(packet
,data
))
90 const char* error
= bytes
== -1 ? strerror(errno
) : "too few bytes read";
91 fprintf(stderr
,"HTIF error: %s\n", error
);
101 packet ackpacket
= {APP_CMD_ACK
,seqno
,0,0};
110 case APP_CMD_READ_MEM
:
111 assert(p
.addr
% APP_DATA_ALIGN
== 0);
112 assert(p
.data_size
% APP_DATA_ALIGN
== 0);
113 assert(p
.data_size
<= APP_MAX_DATA_SIZE
);
114 assert(p
.addr
<= sim
->memsz
&& p
.addr
+p
.data_size
<= sim
->memsz
);
115 ackpacket
.data_size
= p
.data_size
;
117 static_assert(APP_DATA_ALIGN
>= sizeof(uint64_t))
118 for(size_t i
= 0; i
< p
.data_size
/8; i
++)
119 ((uint64_t*)ackpacket
.data
)[i
] = sim
->mmu
->load_uint64(p
.addr
+i
*8);
121 case APP_CMD_WRITE_MEM
:
122 assert(p
.addr
% APP_DATA_ALIGN
== 0);
123 assert(p
.data_size
% APP_DATA_ALIGN
== 0);
124 assert(p
.data_size
<= bytes
- offsetof(packet
,data
));
125 assert(p
.addr
<= sim
->memsz
&& p
.addr
+p
.data_size
<= sim
->memsz
);
127 for(size_t i
= 0; i
< p
.data_size
/8; i
++)
128 sim
->mmu
->store_uint64(p
.addr
+i
*8, ((uint64_t*)p
.data
)[i
]);
130 case APP_CMD_READ_CONTROL_REG
:
131 assert(p
.addr
== 16);
132 assert(p
.data_size
== sizeof(reg_t
));
133 ackpacket
.data_size
= sizeof(reg_t
);
134 memcpy(ackpacket
.data
,&sim
->tohost
,sizeof(reg_t
));
136 case APP_CMD_WRITE_CONTROL_REG
:
137 assert(p
.addr
== 17);
138 assert(p
.data_size
== sizeof(reg_t
));
140 memcpy(&sim
->fromhost
,p
.data
,sizeof(reg_t
));
144 send_packet(&ackpacket
);