提交 e1cb9502 编写于 作者: B blueswir1

User timer limit fixes (Robert Reif)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3931 c046a42c-6fe2-441c-8c8c-71466251a162
上级 40a2e657
...@@ -122,10 +122,9 @@ static void slavio_timer_irq(void *opaque) ...@@ -122,10 +122,9 @@ static void slavio_timer_irq(void *opaque)
slavio_timer_get_out(s); slavio_timer_get_out(s);
DPRINTF("callback: count %x%08x\n", s->counthigh, s->count); DPRINTF("callback: count %x%08x\n", s->counthigh, s->count);
if (!slavio_timer_is_user(s)) {
s->reached = TIMER_REACHED; s->reached = TIMER_REACHED;
if (!slavio_timer_is_user(s))
qemu_irq_raise(s->irq); qemu_irq_raise(s->irq);
}
} }
static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr) static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr)
...@@ -141,7 +140,7 @@ static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr) ...@@ -141,7 +140,7 @@ static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr)
if (slavio_timer_is_user(s)) { if (slavio_timer_is_user(s)) {
// read user timer MSW // read user timer MSW
slavio_timer_get_out(s); slavio_timer_get_out(s);
ret = s->counthigh; ret = s->counthigh | s->reached;
} else { } else {
// read limit // read limit
// clear irq // clear irq
...@@ -155,7 +154,7 @@ static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr) ...@@ -155,7 +154,7 @@ static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr)
// of counter (user mode) // of counter (user mode)
slavio_timer_get_out(s); slavio_timer_get_out(s);
if (slavio_timer_is_user(s)) // read user timer LSW if (slavio_timer_is_user(s)) // read user timer LSW
ret = s->count & TIMER_COUNT_MASK32; ret = s->count & TIMER_MAX_COUNT64;
else // read limit else // read limit
ret = (s->count & TIMER_MAX_COUNT32) | s->reached; ret = (s->count & TIMER_MAX_COUNT32) | s->reached;
break; break;
...@@ -190,12 +189,20 @@ static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr, ...@@ -190,12 +189,20 @@ static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr,
switch (saddr) { switch (saddr) {
case TIMER_LIMIT: case TIMER_LIMIT:
if (slavio_timer_is_user(s)) { if (slavio_timer_is_user(s)) {
uint64_t count;
// set user counter MSW, reset counter // set user counter MSW, reset counter
qemu_irq_lower(s->irq); qemu_irq_lower(s->irq);
s->limit = TIMER_MAX_COUNT64; s->limit = TIMER_MAX_COUNT64;
DPRINTF("processor %d user timer reset\n", s->slave_index); s->counthigh = val & (TIMER_MAX_COUNT64 >> 32);
if (s->timer) s->reached = 0;
ptimer_set_limit(s->timer, LIMIT_TO_PERIODS(s->limit), 1); count = ((uint64_t)s->counthigh << 32) | s->count;
DPRINTF("processor %d user timer set to %016llx\n", s->slave_index,
count);
if (s->timer) {
ptimer_set_count(s->timer, LIMIT_TO_PERIODS(s->limit - count));
ptimer_set_limit(s->timer, LIMIT_TO_PERIODS(s->limit), 0);
}
} else { } else {
// set limit, reset counter // set limit, reset counter
qemu_irq_lower(s->irq); qemu_irq_lower(s->irq);
...@@ -210,12 +217,20 @@ static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr, ...@@ -210,12 +217,20 @@ static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr,
break; break;
case TIMER_COUNTER: case TIMER_COUNTER:
if (slavio_timer_is_user(s)) { if (slavio_timer_is_user(s)) {
uint64_t count;
// set user counter LSW, reset counter // set user counter LSW, reset counter
qemu_irq_lower(s->irq); qemu_irq_lower(s->irq);
s->limit = TIMER_MAX_COUNT64; s->limit = TIMER_MAX_COUNT64;
DPRINTF("processor %d user timer reset\n", s->slave_index); s->count = val & TIMER_MAX_COUNT64;
if (s->timer) s->reached = 0;
ptimer_set_limit(s->timer, LIMIT_TO_PERIODS(s->limit), 1); count = ((uint64_t)s->counthigh) << 32 | s->count;
DPRINTF("processor %d user timer set to %016llx\n", s->slave_index,
count);
if (s->timer) {
ptimer_set_count(s->timer, LIMIT_TO_PERIODS(s->limit - count));
ptimer_set_limit(s->timer, LIMIT_TO_PERIODS(s->limit), 0);
}
} else } else
DPRINTF("not user timer\n"); DPRINTF("not user timer\n");
break; break;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册