/* In-flight accumulation information */
union {
struct {
- unsigned port:16,size:16;
+ unsigned port:31,
+ is_write:1;
unsigned long val;
} io;
struct pf_xen_extra pf_xen;
}
-#define HVM_MMIO_ASSIST_WRITE 0x200
+#define HVM_IO_ASSIST_WRITE 0x200
void hvm_mmio_assist_process(struct record_info *ri, struct hvm_data *h)
{
struct pf_xen_extra *e = &h->inflight.pf_xen;
{
if(opt.dump_cooked)
{
- printf(" %s io_write port %x size %u val %lx\n",
+ printf(" %s io_write port %x val %lx\n",
h->dump_header, h->inflight.io.port,
- h->inflight.io.size,
h->inflight.io.val);
}
if(opt.with_pio_enumeration)
update_io_address(&h->summary.pio, h->inflight.io.port, 1, h->arc_cycles);
}
-void hvm_io_write_process(struct hvm_data *h)
-{
- struct {
- unsigned long port;
- int size;
- unsigned long val;
- } *r = (typeof(r))h->d;
-
- unsigned long long mask = ((1ULL<<(r->size<<3))-1);
-
- h->inflight.io.port = r->port;
- h->inflight.io.size = r->size;
- h->inflight.io.val = r->val & mask;
-
- if(opt.dump_all)
- {
- printf(" %s io_write port %lx size %d val %lx\n",
- h->dump_header,
- r->port, r->size, r->val);
- }
-
- h->post_process = hvm_io_write_postprocess;
-}
-
void hvm_io_read_postprocess(struct hvm_data *h)
{
if(opt.dump_cooked)
{
- printf(" %s io_read port %x size %u val %lx\n",
+ printf(" %s io_read port %x val %lx\n",
h->dump_header, h->inflight.io.port,
- h->inflight.io.size,
h->inflight.io.val);
}
if(opt.with_pio_enumeration)
scatterplot_vs_time(h->exit_tsc, P.now - h->exit_tsc);
}
-void hvm_io_assist_process(struct hvm_data *h)
+void hvm_io_assist_process(struct record_info *ri, struct hvm_data *h)
{
- struct {
- unsigned long val;
+ union {
+ struct {
+ unsigned long port;
+ unsigned long data;
+ } x32;
} *r = (typeof(r))h->d;
- int size = h->inflight.io.size;
- unsigned long long mask = ((1ULL<<(size<<3))-1);
-
- h->inflight.io.val = r->val & mask;
+ union {
+ unsigned event;
+ struct {
+ unsigned minor:8,
+ x64:1,
+ write:2;
+ };
+ } mevt = { .event = ri->event };
- if(opt.dump_all)
- {
- printf(" %s io_assist val %lx\n",
- h->dump_header,
- r->val);
+ if(mevt.x64) {
+ fprintf(stderr, "FATAL: Unexpected 64-bit PIO\n");
+ exit(1);
}
+ h->inflight.io.port = r->x32.port;
+ h->inflight.io.val = r->x32.data;
- if(!h->post_process)
- fprintf(warn, "Strange, io_assist but post_process not set!\n");
-}
-
-void hvm_io_read_process(struct hvm_data *h)
-{
- struct {
- unsigned long port;
- int size;
- } *r = (typeof(r))h->d;
-
- h->inflight.io.port = r->port;
- h->inflight.io.size = r->size;
- h->inflight.io.val = 0;
+ if(mevt.write) {
+ h->inflight.io.is_write = 1;
+ h->post_process = hvm_io_write_postprocess;
+ } else {
+ h->inflight.io.is_write = 0;
+ h->post_process = hvm_io_read_postprocess;
+ }
if(opt.dump_all)
{
- printf(" %s io_read port %lx size %d\n",
+ printf(" %s io %s port %lu val %lx\n",
h->dump_header,
- r->port, r->size);
+ mevt.write?"write":"read",
+ r->x32.port,
+ r->x32.data);
}
-
- h->post_process = hvm_io_read_postprocess;
}
/* cr_write */
case TRC_HVM_PF_XEN64:
hvm_pf_xen_process(ri, h);
break;
- case TRC_HVM_IO_READ:
- hvm_io_read_process(h);
- break;
- case TRC_HVM_IO_WRITE:
- hvm_io_write_process(h);
- break;
case TRC_HVM_IO_ASSIST:
- hvm_io_assist_process(h);
+ case TRC_HVM_IO_ASSIST|HVM_IO_ASSIST_WRITE:
+ hvm_io_assist_process(ri, h);
break;
case TRC_HVM_MMIO_ASSIST:
- case TRC_HVM_MMIO_ASSIST|HVM_MMIO_ASSIST_WRITE:
+ case TRC_HVM_MMIO_ASSIST|HVM_IO_ASSIST_WRITE:
+ /* FIXME: 64-bit */
hvm_mmio_assist_process(ri, h);
break;
case TRC_HVM_CR_WRITE: