16 APP_CMD_READ_CONTROL_REG
,
17 APP_CMD_WRITE_CONTROL_REG
,
22 #define APP_MAX_DATA_SIZE 1024U
23 #define HTIF_DATA_ALIGN 8U
31 uint64_t data
[APP_MAX_DATA_SIZE
/8];
34 htif_t::htif_t(int _tohost_fd
, int _fromhost_fd
)
35 : sim(NULL
), tohost_fd(_tohost_fd
), fromhost_fd(_fromhost_fd
),
46 void htif_t::init(sim_t
* _sim
)
51 void htif_t::wait_for_start()
57 void htif_t::wait_for_tohost_write()
59 while(wait_for_packet() != APP_CMD_READ_CONTROL_REG
);
62 void htif_t::wait_for_fromhost_write()
64 while(wait_for_packet() != APP_CMD_WRITE_CONTROL_REG
);
67 void htif_t::send_packet(packet
* p
)
69 size_t data_size
= p
->data_size
*HTIF_DATA_ALIGN
;
70 size_t bytes
= write(tohost_fd
, p
, offsetof(packet
,data
) + data_size
);
71 if(bytes
!= offsetof(packet
,data
) + data_size
)
73 const char* error
= (ssize_t
)bytes
== -1 ? strerror(errno
) : "not all bytes sent";
74 fprintf(stderr
,"HTIF error: %s\n", error
);
79 void htif_t::nack(uint8_t nack_seqno
)
81 packet p
= {APP_CMD_NACK
,0,nack_seqno
,0};
92 if (::poll(&pfd
, 1, 0) > 0)
96 int htif_t::wait_for_packet()
101 ssize_t bytes
= read(fromhost_fd
,&p
,sizeof(p
));
102 if(bytes
< (ssize_t
)offsetof(packet
,data
))
104 const char* error
= bytes
== -1 ? strerror(errno
) : "too few bytes read";
105 fprintf(stderr
,"HTIF error: %s\n", error
);
115 packet ackpacket
= {APP_CMD_ACK
,0,seqno
,0};
119 case APP_CMD_READ_MEM
:
120 assert(p
.data_size
<= APP_MAX_DATA_SIZE
/HTIF_DATA_ALIGN
);
121 assert(p
.addr
< sim
->memsz
/HTIF_DATA_ALIGN
);
122 assert(p
.addr
+p
.data_size
<= sim
->memsz
/HTIF_DATA_ALIGN
);
123 ackpacket
.data_size
= p
.data_size
;
125 assert(HTIF_DATA_ALIGN
== sizeof(uint64_t));
126 for(size_t i
= 0; i
< p
.data_size
; i
++)
127 ackpacket
.data
[i
] = sim
->mmu
->load_uint64((p
.addr
+i
)*HTIF_DATA_ALIGN
);
129 case APP_CMD_WRITE_MEM
:
130 assert(p
.data_size
*HTIF_DATA_ALIGN
<= bytes
- offsetof(packet
,data
));
131 assert(p
.addr
< sim
->memsz
/HTIF_DATA_ALIGN
);
132 assert(p
.addr
+p
.data_size
<= sim
->memsz
/HTIF_DATA_ALIGN
);
134 for(size_t i
= 0; i
< p
.data_size
; i
++)
135 sim
->mmu
->store_uint64((p
.addr
+i
)*HTIF_DATA_ALIGN
, p
.data
[i
]);
137 case APP_CMD_READ_CONTROL_REG
:
138 assert(p
.addr
== PCR_TOHOST
);
139 assert(p
.data_size
== 1);
140 ackpacket
.data_size
= 1;
141 memcpy(ackpacket
.data
, &sim
->tohost
, sizeof(reg_t
));
143 case APP_CMD_WRITE_CONTROL_REG
:
144 assert(p
.addr
== PCR_FROMHOST
|| p
.addr
== PCR_RESET
);
145 assert(p
.data_size
== 1);
147 if (p
.addr
== PCR_FROMHOST
)
148 memcpy(&sim
->fromhost
, p
.data
, sizeof(reg_t
));
149 else if (p
.addr
== PCR_RESET
)
151 bool next_reset
= p
.data
[0] & 1;
152 if (!reset
&& next_reset
)
159 send_packet(&ackpacket
);