static void test_tco_max_timeout(void) { TestData d; const uint16_t ticks = 0xffff; uint32_t val; int ret; d.args = NULL; d.noreboot = true; test_init(&d); stop_tco(&d); clear_tco_status(&d); reset_on_second_timeout(false); set_tco_timeout(&d, ticks); load_tco(&d); start_tco(&d); clock_step(((ticks & TCO_TMR_MASK) - 1) * TCO_TICK_NSEC); val = qpci_io_readw(d.dev, d.tco_io_bar, TCO_RLD); g_assert_cmpint(val & TCO_RLD_MASK, ==, 1); val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS); ret = val & TCO_TIMEOUT ? 1 : 0; g_assert(ret == 0); clock_step(TCO_TICK_NSEC); val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS); ret = val & TCO_TIMEOUT ? 1 : 0; g_assert(ret == 1); stop_tco(&d); test_end(&d); }
static void test_tco2_status_bits(void) { TestData d; uint16_t ticks = 8; uint16_t val; int ret; d.args = NULL; d.noreboot = true; test_init(&d); stop_tco(&d); clear_tco_status(&d); reset_on_second_timeout(true); set_tco_timeout(&d, ticks); load_tco(&d); start_tco(&d); clock_step(ticks * TCO_TICK_NSEC * 2); val = qpci_io_readw(d.dev, d.tco_io_bar, TCO2_STS); ret = val & (TCO_SECOND_TO_STS | TCO_BOOT_STS) ? 1 : 0; g_assert(ret == 1); qpci_io_writew(d.dev, d.tco_io_bar, TCO2_STS, val); g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_bar, TCO2_STS), ==, 0); test_end(&d); }
static void test_tco1_status_bits(void) { TestData d; uint16_t ticks = 8; uint16_t val; int ret; d.args = NULL; d.noreboot = true; test_init(&d); stop_tco(&d); clear_tco_status(&d); reset_on_second_timeout(false); set_tco_timeout(&d, ticks); load_tco(&d); start_tco(&d); clock_step(ticks * TCO_TICK_NSEC); qpci_io_writeb(d.dev, d.tco_io_bar, TCO_DAT_IN, 0); qpci_io_writeb(d.dev, d.tco_io_bar, TCO_DAT_OUT, 0); val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS); ret = val & (TCO_TIMEOUT | SW_TCO_SMI | TCO_INT_STS) ? 1 : 0; g_assert(ret == 1); qpci_io_writew(d.dev, d.tco_io_bar, TCO1_STS, val); g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS), ==, 0); test_end(&d); }
static void test_tco_ticks_counter(void) { TestData d; uint16_t ticks = TCO_SECS_TO_TICKS(8); uint16_t rld; d.args = NULL; d.noreboot = true; test_init(&d); stop_tco(&d); clear_tco_status(&d); reset_on_second_timeout(false); set_tco_timeout(&d, ticks); load_tco(&d); start_tco(&d); do { rld = qpci_io_readw(d.dev, d.tco_io_bar, TCO_RLD) & TCO_RLD_MASK; g_assert_cmpint(rld, ==, ticks); clock_step(TCO_TICK_NSEC); ticks--; } while (!(qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS) & TCO_TIMEOUT)); stop_tco(&d); test_end(&d); }
static void test_tco_timeout(void) { TestData d; const uint16_t ticks = TCO_SECS_TO_TICKS(4); uint32_t val; int ret; d.args = NULL; d.noreboot = true; test_init(&d); stop_tco(&d); clear_tco_status(&d); reset_on_second_timeout(false); set_tco_timeout(&d, ticks); load_tco(&d); start_tco(&d); clock_step(ticks * TCO_TICK_NSEC); /* test first timeout */ val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS); ret = val & TCO_TIMEOUT ? 1 : 0; g_assert(ret == 1); /* test clearing timeout bit */ val |= TCO_TIMEOUT; qpci_io_writew(d.dev, d.tco_io_bar, TCO1_STS, val); val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS); ret = val & TCO_TIMEOUT ? 1 : 0; g_assert(ret == 0); /* test second timeout */ clock_step(ticks * TCO_TICK_NSEC); val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS); ret = val & TCO_TIMEOUT ? 1 : 0; g_assert(ret == 1); val = qpci_io_readw(d.dev, d.tco_io_bar, TCO2_STS); ret = val & TCO_SECOND_TO_STS ? 1 : 0; g_assert(ret == 1); stop_tco(&d); test_end(&d); }
bool qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d, uint64_t timeout) { do { clock_step(10); if (bus->get_config_isr_status(d)) { break; /* It has ended */ } } while (--timeout); return timeout != 0; }
void qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d, QVirtQueue *vq, gint64 timeout_us) { gint64 start_time = g_get_monotonic_time(); for (;;) { clock_step(100); if (bus->get_queue_isr_status(d, vq)) { return; } g_assert(g_get_monotonic_time() - start_time <= timeout_us); } }
static int monitor_update(struct sk_buff *skb, int instance, psched_time_t now) { //printk(KERN_ALERT "RK: Inside monitor_update...\n"); struct monitor_instance *m = &monitors[instance]; struct ethhdr *ethhdr; psched_time_t clock; int ret; u64 rate; u64 n; spin_lock_bh(&m->lock); /* If not the ACC monitor and its status is MON_FREE, skip it */ if (m->ifindex != ACC_IFINDEX && m->status == MON_FREE) { spin_unlock_bh(&m->lock); return MON_FREED; } clock = clock_step(now); //printk(KERN_ALERT "RK: ifindex: %d monitor_interval: %lld m->prev: %lld clock: %lld diff: %lld diff_frac: %lld pkts: %d\n", m->ifindex, monitor_interval, m->prev, clock, clock - m->prev, (clock - m->prev)/monitor_interval, m->pkt_ctr); /* If monitor_interval time has not passed yet?? */ if (likely(m->prev == clock)) { m->pkt_ctr = m->pkt_ctr; m->byte_ctr += skb->len; m->pkt_ctr += 1; //printk(KERN_ALERT "RK: if\n"); } /* If twice the monitor_interval has not passed?? */ else if (likely(now < (m->prev + (monitor_interval << 1)))) { //printk(KERN_ALERT "RK: elif\n"); m->prev = clock; rate = m->byte_ctr >> (monitor_interval_s); //printk(KERN_ALERT "RK: rate: %lld monitor_interval_s: %d\n", rate, monitor_interval_s); /* Moving average */ m->rate = (rate + m->rate) >> 1; //printk(KERN_ALERT "RK: %d: rate=%llu threshold=%llu\n", m->ifindex, // (u64) bypus2mbps(m->rate), (u64) bypus2mbps(m->limit)); // (u64) (m->rate)/0.125 //print_monitor(m); //printk(KERN_ALERT "RK: MARIO: ifindex %d: rate=%lld bytes=%lld pkts=%d\n", m->ifindex, m->rate, m->byte_ctr, m->pkt_ctr); if (!m->is_tnic) monitor_congestion(m); /*reset byte and packet counter for next interval*//*MARIO WHY??*/ m->byte_ctr = skb->len; m->pkt_ctr = 1; }
/* Wait for the status byte at given guest memory address to be set * * The virtqueue interrupt must not be raised, making this useful for testing * event_index functionality. */ uint8_t qvirtio_wait_status_byte_no_isr(QVirtioDevice *d, QVirtQueue *vq, uint64_t addr, gint64 timeout_us) { gint64 start_time = g_get_monotonic_time(); uint8_t val; while ((val = readb(addr)) == 0xff) { clock_step(100); g_assert(!d->bus->get_queue_isr_status(d, vq)); g_assert(g_get_monotonic_time() - start_time <= timeout_us); } return val; }
/* * qvirtio_wait_used_elem: * @desc_idx: The next expected vq->desc[] index in the used ring * @timeout_us: How many microseconds to wait before failing * * This function waits for the next completed request on the used ring. */ void qvirtio_wait_used_elem(QVirtioDevice *d, QVirtQueue *vq, uint32_t desc_idx, gint64 timeout_us) { gint64 start_time = g_get_monotonic_time(); for (;;) { uint32_t got_desc_idx; clock_step(100); if (d->bus->get_queue_isr_status(d, vq) && qvirtqueue_get_buf(vq, &got_desc_idx)) { g_assert_cmpint(got_desc_idx, ==, desc_idx); return; } g_assert(g_get_monotonic_time() - start_time <= timeout_us); }
static void test_tco_second_timeout_none(void) { TestData td; const uint16_t ticks = TCO_SECS_TO_TICKS(256); QDict *ad; td.args = "-watchdog-action none"; td.noreboot = false; test_init(&td); stop_tco(&td); clear_tco_status(&td); reset_on_second_timeout(true); set_tco_timeout(&td, ticks); load_tco(&td); start_tco(&td); clock_step(ticks * TCO_TICK_NSEC * 2); ad = get_watchdog_action(); g_assert(!strcmp(qdict_get_str(ad, "action"), "none")); qobject_unref(ad); stop_tco(&td); test_end(&td); }
static void test_read_id(void) { uint8_t drive = 0; uint8_t head = 0; uint8_t cyl; uint8_t st0; /* Seek to track 0 and check with READ ID */ send_seek(0); floppy_send(CMD_READ_ID); g_assert(!get_irq(FLOPPY_IRQ)); floppy_send(head << 2 | drive); while (!get_irq(FLOPPY_IRQ)) { /* qemu involves a timer with READ ID... */ clock_step(1000000000LL / 50); } st0 = floppy_recv(); floppy_recv(); floppy_recv(); cyl = floppy_recv(); head = floppy_recv(); floppy_recv(); floppy_recv(); g_assert_cmpint(cyl, ==, 0); g_assert_cmpint(head, ==, 0); g_assert_cmpint(st0, ==, head << 2); /* Seek to track 8 on head 1 and check with READ ID */ head = 1; cyl = 8; floppy_send(CMD_SEEK); floppy_send(head << 2 | drive); g_assert(!get_irq(FLOPPY_IRQ)); floppy_send(cyl); g_assert(get_irq(FLOPPY_IRQ)); ack_irq(NULL); floppy_send(CMD_READ_ID); g_assert(!get_irq(FLOPPY_IRQ)); floppy_send(head << 2 | drive); while (!get_irq(FLOPPY_IRQ)) { /* qemu involves a timer with READ ID... */ clock_step(1000000000LL / 50); } st0 = floppy_recv(); floppy_recv(); floppy_recv(); cyl = floppy_recv(); head = floppy_recv(); floppy_recv(); floppy_recv(); g_assert_cmpint(cyl, ==, 8); g_assert_cmpint(head, ==, 1); g_assert_cmpint(st0, ==, head << 2); }
static void test_timer(void) { const unsigned from = 0.95 * CLK; const unsigned to = 1.6 * CLK; unsigned prev, curr, next; unsigned cnt, diff; out_IntrMask(0); in_IntrStatus(); in_Timer(); in_Timer(); /* Test 1. test counter continue and continue */ out_TimerInt(0); /* disable timer */ out_IntrStatus(0x4000); out_Timer(12345); /* reset timer to 0 */ curr = in_Timer(); if (curr > 0.1 * CLK) { fatal("time too big %u\n", curr); } for (cnt = 0; ; ) { clock_step(1 * NANOSECONDS_PER_SECOND); prev = curr; curr = in_Timer(); /* test skip is in a specific range */ diff = (curr-prev) & 0xffffffffu; if (diff < from || diff > to) { fatal("Invalid diff %u (%u-%u)\n", diff, from, to); } if (curr < prev && ++cnt == 3) { break; } } /* Test 2. Check we didn't get an interrupt with TimerInt == 0 */ if (in_IntrStatus() & 0x4000) { fatal("got an interrupt\n"); } /* Test 3. Setting TimerInt to 1 and Timer to 0 get interrupt */ out_TimerInt(1); out_Timer(0); clock_step(40); if ((in_IntrStatus() & 0x4000) == 0) { fatal("we should have an interrupt here!\n"); } /* Test 3. Check acknowledge */ out_IntrStatus(0x4000); if (in_IntrStatus() & 0x4000) { fatal("got an interrupt\n"); } /* Test. Status set after Timer reset */ out_Timer(0); out_TimerInt(0); out_IntrStatus(0x4000); curr = in_Timer(); out_TimerInt(curr + 0.5 * CLK); clock_step(1 * NANOSECONDS_PER_SECOND); out_Timer(0); if ((in_IntrStatus() & 0x4000) == 0) { fatal("we should have an interrupt here!\n"); } /* Test. Status set after TimerInt reset */ out_Timer(0); out_TimerInt(0); out_IntrStatus(0x4000); curr = in_Timer(); out_TimerInt(curr + 0.5 * CLK); clock_step(1 * NANOSECONDS_PER_SECOND); out_TimerInt(0); if ((in_IntrStatus() & 0x4000) == 0) { fatal("we should have an interrupt here!\n"); } /* Test 4. Increment TimerInt we should see an interrupt */ curr = in_Timer(); next = curr + 5.0 * CLK; out_TimerInt(next); for (cnt = 0; ; ) { clock_step(1 * NANOSECONDS_PER_SECOND); prev = curr; curr = in_Timer(); diff = (curr-prev) & 0xffffffffu; if (diff < from || diff > to) { fatal("Invalid diff %u (%u-%u)\n", diff, from, to); } if (cnt < 3 && curr > next) { if ((in_IntrStatus() & 0x4000) == 0) { fatal("we should have an interrupt here!\n"); } out_IntrStatus(0x4000); next = curr + 5.0 * CLK; out_TimerInt(next); if (++cnt == 3) { out_TimerInt(1); } /* Test 5. Second time we pass from 0 should see an interrupt */ } else if (cnt >= 3 && curr < prev) { /* here we should have an interrupt */ if ((in_IntrStatus() & 0x4000) == 0) { fatal("we should have an interrupt here!\n"); } out_IntrStatus(0x4000); if (++cnt == 5) { break; } } } g_test_message("Everythink is ok!\n"); }