81class Pl011 :
public sc_core::sc_module
88 tlm_utils::simple_target_socket<Pl011, DEFAULT_TLM_BUSWIDTH> socket;
94 sc_core::sc_event update_event;
96 Pl011(sc_core::sc_module_name name)
97 : irq(
"irq"), s(
nullptr), socket(
"target_socket"), backend_socket(
"backend_socket")
101 socket.register_b_transport(
this, &Pl011::b_transport);
111 static const unsigned char pl011_id_arm[8] = { 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
121 switch (offset >> 2) {
125 if (value ==
'\r' || value ==
'\n') {
134 void b_transport(tlm::tlm_generic_payload&
trans, sc_core::sc_time& delay)
136 unsigned char*
ptr =
trans.get_data_ptr();
138 unsigned int len =
trans.get_data_length();
140 trans.set_dmi_allowed(
false);
141 trans.set_response_status(tlm::TLM_OK_RESPONSE);
143 switch (
trans.get_command()) {
144 case tlm::TLM_WRITE_COMMAND:
156 SCP_FATAL(()) <<
"Incorrect transaction size";
160 case tlm::TLM_READ_COMMAND:
172 SCP_FATAL(()) <<
"Incorrect transaction size";
181 void pl011_update() { update_event.notify(); }
183 void pl011_update_sysc()
188 flags = s->int_level & s->int_enabled;
189 if (irqmask[0] & s->int_enabled) {
190 irq->write((flags & irqmask[0]) != 0);
199 switch (offset >> 2) {
201 s->flags &= ~PL011_FLAG_RXFF;
202 c = s->read_fifo[s->read_pos];
203 if (s->read_count > 0) {
206 if (++s->read_pos == 16) s->read_pos = 0;
208 if (s->read_count == 0) {
209 s->flags |= PL011_FLAG_RXFE;
211 if (s->read_count == s->read_trigger - 1) s->int_level &= ~PL011_INT_RX;
247 r = s->int_level & s->int_enabled;
253 if ((offset >> 2) >= 0x3f8 && (offset >> 2) <= 0x400) {
254 r = s->id[(offset - 0xfe0) >> 2];
264 void pl011_set_read_trigger()
272 s->read_trigger = (s->ifl >> 1) & 0x1c;
286 switch (offset >> 2) {
289 ch = (
unsigned char)(value & 0xff);
291 s->int_level |= PL011_INT_TX;
311 if ((s->lcr ^ value) & 0x10) {
316 pl011_set_read_trigger();
324 pl011_set_read_trigger();
327 s->int_enabled = value;
331 s->int_level &= ~value;
348 slot = s->read_pos + s->read_count;
350 s->read_fifo[
slot] = value;
352 s->flags &= ~PL011_FLAG_RXFE;
353 if (!(s->lcr & 0x10) || s->read_count == 16) {
354 s->flags |= PL011_FLAG_RXFF;
356 if (s->read_count == s->read_trigger) {
357 s->int_level |= PL011_INT_RX;
361 void pl011_receive(tlm::tlm_generic_payload&
txn, sc_core::sc_time&
t)
364 for (
int i = 0;
i <
txn.get_streaming_width();
i++) {
365 pl011_put_fifo(data[
i]);
void register_b_transport(MODULE *mod, void(MODULE::*cb)(tlm::tlm_generic_payload &, sc_core::sc_time &))
Register b_transport to be called whenever data is received from the socket.
Definition biflow-socket.h:227