16 APP_CMD_READ_CONTROL_REG
,
17 APP_CMD_WRITE_CONTROL_REG
,
24 #define APP_MAX_DATA_SIZE 1024
25 #define HTIF_DATA_ALIGN 8
33 uint8_t data
[APP_MAX_DATA_SIZE
];
36 htif_t::htif_t(int _tohost_fd
, int _fromhost_fd
)
37 : sim(NULL
), tohost_fd(_tohost_fd
), fromhost_fd(_fromhost_fd
), seqno(1)
47 void htif_t::init(sim_t
* _sim
)
52 void htif_t::wait_for_start()
54 while(wait_for_packet() != APP_CMD_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 int bytes
= read(fromhost_fd
,&p
,sizeof(p
));
102 if(bytes
< (int)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};
124 case APP_CMD_READ_MEM
:
125 assert(p
.data_size
<= APP_MAX_DATA_SIZE
/HTIF_DATA_ALIGN
);
126 assert(p
.addr
< sim
->memsz
/HTIF_DATA_ALIGN
);
127 assert(p
.addr
+p
.data_size
<= sim
->memsz
/HTIF_DATA_ALIGN
);
128 ackpacket
.data_size
= p
.data_size
;
130 assert(HTIF_DATA_ALIGN
== sizeof(uint64_t));
131 for(size_t i
= 0; i
< p
.data_size
; i
++)
132 ((uint64_t*)ackpacket
.data
)[i
] = sim
->mmu
->load_uint64((p
.addr
+i
)*HTIF_DATA_ALIGN
);
134 case APP_CMD_WRITE_MEM
:
135 assert(p
.data_size
*HTIF_DATA_ALIGN
<= bytes
- offsetof(packet
,data
));
136 assert(p
.addr
< sim
->memsz
/HTIF_DATA_ALIGN
);
137 assert(p
.addr
+p
.data_size
<= sim
->memsz
/HTIF_DATA_ALIGN
);
139 for(size_t i
= 0; i
< p
.data_size
; i
++)
140 sim
->mmu
->store_uint64((p
.addr
+i
)*HTIF_DATA_ALIGN
, ((uint64_t*)p
.data
)[i
]);
142 case APP_CMD_READ_CONTROL_REG
:
143 assert(p
.addr
== 16);
144 assert(p
.data_size
== 1);
145 ackpacket
.data_size
= 1;
146 memcpy(ackpacket
.data
,&sim
->tohost
,sizeof(reg_t
));
148 case APP_CMD_WRITE_CONTROL_REG
:
149 assert(p
.addr
== 17);
150 assert(p
.data_size
== 1);
152 memcpy(&sim
->fromhost
,p
.data
,sizeof(reg_t
));
156 send_packet(&ackpacket
);