- case APP_CMD_READ_MEM:
- assert(p.data_size <= APP_MAX_DATA_SIZE/HTIF_DATA_ALIGN);
- assert(p.addr < sim->memsz/HTIF_DATA_ALIGN);
- assert(p.addr+p.data_size <= sim->memsz/HTIF_DATA_ALIGN);
- ackpacket.data_size = p.data_size;
-
- assert(HTIF_DATA_ALIGN == sizeof(uint64_t));
- for(size_t i = 0; i < p.data_size; i++)
- ackpacket.data[i] = sim->mmu->load_uint64((p.addr+i)*HTIF_DATA_ALIGN);
- break;
- case APP_CMD_WRITE_MEM:
- assert(p.data_size*HTIF_DATA_ALIGN <= bytes - offsetof(packet,data));
- assert(p.addr < sim->memsz/HTIF_DATA_ALIGN);
- assert(p.addr+p.data_size <= sim->memsz/HTIF_DATA_ALIGN);
-
- for(size_t i = 0; i < p.data_size; i++)
- sim->mmu->store_uint64((p.addr+i)*HTIF_DATA_ALIGN, p.data[i]);
- break;
- case APP_CMD_READ_CONTROL_REG:
- assert(p.addr == PCR_TOHOST);
- assert(p.data_size == 1);
- ackpacket.data_size = 1;
- memcpy(ackpacket.data, &sim->tohost, sizeof(reg_t));
- break;
- case APP_CMD_WRITE_CONTROL_REG:
- assert(p.addr == PCR_FROMHOST || p.addr == PCR_RESET);
- assert(p.data_size == 1);
- sim->tohost = 0;
- if (p.addr == PCR_FROMHOST)
- memcpy(&sim->fromhost, p.data, sizeof(reg_t));
- else if (p.addr == PCR_RESET)
- {
- bool next_reset = p.data[0] & 1;
- if (!reset && next_reset)
- sim->stop();
- reset = next_reset;
- }
- break;
+ assert(hdr.data_size == 1);
+ reg_t coreid = hdr.addr >> 20;
+ reg_t regno = hdr.addr & ((1<<20)-1);
+ uint64_t old_val, new_val = 0 /* shut up gcc */;
+
+ packet_header_t ack(HTIF_CMD_ACK, seqno, 1, 0);
+ send(&ack, sizeof(ack));
+
+ processor_t* proc = sim->get_core(coreid);
+ bool write = hdr.cmd == HTIF_CMD_WRITE_CONTROL_REG;
+ if (write)
+ memcpy(&new_val, p.get_payload(), sizeof(new_val));
+
+ switch (regno)
+ {
+ case CSR_MRESET:
+ old_val = !proc->running();
+ if (write)
+ {
+ reset = reset & (new_val & 1);
+ proc->reset(new_val & 1);
+ }
+ break;
+ default:
+ abort();
+ }
+
+ send(&old_val, sizeof(old_val));
+ break;