Commit 423f0742a8483430fe031861c316b09f1967319d
1 parent
0ff596d0
Add periodic timer implementation.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2846 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
213 additions
and
116 deletions
hw/arm_timer.c
| @@ -22,114 +22,24 @@ | @@ -22,114 +22,24 @@ | ||
| 22 | #define TIMER_CTRL_ENABLE (1 << 7) | 22 | #define TIMER_CTRL_ENABLE (1 << 7) |
| 23 | 23 | ||
| 24 | typedef struct { | 24 | typedef struct { |
| 25 | - int64_t next_time; | ||
| 26 | - int64_t expires; | ||
| 27 | - int64_t loaded; | ||
| 28 | - QEMUTimer *timer; | 25 | + ptimer_state *timer; |
| 29 | uint32_t control; | 26 | uint32_t control; |
| 30 | - uint32_t count; | ||
| 31 | uint32_t limit; | 27 | uint32_t limit; |
| 32 | - int raw_freq; | ||
| 33 | int freq; | 28 | int freq; |
| 34 | int int_level; | 29 | int int_level; |
| 35 | qemu_irq irq; | 30 | qemu_irq irq; |
| 36 | } arm_timer_state; | 31 | } arm_timer_state; |
| 37 | 32 | ||
| 38 | -/* Calculate the new expiry time of the given timer. */ | ||
| 39 | - | ||
| 40 | -static void arm_timer_reload(arm_timer_state *s) | ||
| 41 | -{ | ||
| 42 | - int64_t delay; | ||
| 43 | - | ||
| 44 | - s->loaded = s->expires; | ||
| 45 | - delay = muldiv64(s->count, ticks_per_sec, s->freq); | ||
| 46 | - if (delay == 0) | ||
| 47 | - delay = 1; | ||
| 48 | - s->expires += delay; | ||
| 49 | -} | ||
| 50 | - | ||
| 51 | /* Check all active timers, and schedule the next timer interrupt. */ | 33 | /* Check all active timers, and schedule the next timer interrupt. */ |
| 52 | 34 | ||
| 53 | -static void arm_timer_update(arm_timer_state *s, int64_t now) | 35 | +static void arm_timer_update(arm_timer_state *s) |
| 54 | { | 36 | { |
| 55 | - int64_t next; | ||
| 56 | - | ||
| 57 | - /* Ignore disabled timers. */ | ||
| 58 | - if ((s->control & TIMER_CTRL_ENABLE) == 0) | ||
| 59 | - return; | ||
| 60 | - /* Ignore expired one-shot timers. */ | ||
| 61 | - if (s->count == 0 && (s->control & TIMER_CTRL_ONESHOT)) | ||
| 62 | - return; | ||
| 63 | - if (s->expires - now <= 0) { | ||
| 64 | - /* Timer has expired. */ | ||
| 65 | - s->int_level = 1; | ||
| 66 | - if (s->control & TIMER_CTRL_ONESHOT) { | ||
| 67 | - /* One-shot. */ | ||
| 68 | - s->count = 0; | ||
| 69 | - } else { | ||
| 70 | - if ((s->control & TIMER_CTRL_PERIODIC) == 0) { | ||
| 71 | - /* Free running. */ | ||
| 72 | - if (s->control & TIMER_CTRL_32BIT) | ||
| 73 | - s->count = 0xffffffff; | ||
| 74 | - else | ||
| 75 | - s->count = 0xffff; | ||
| 76 | - } else { | ||
| 77 | - /* Periodic. */ | ||
| 78 | - s->count = s->limit; | ||
| 79 | - } | ||
| 80 | - } | ||
| 81 | - } | ||
| 82 | - while (s->expires - now <= 0) { | ||
| 83 | - arm_timer_reload(s); | ||
| 84 | - } | ||
| 85 | /* Update interrupts. */ | 37 | /* Update interrupts. */ |
| 86 | if (s->int_level && (s->control & TIMER_CTRL_IE)) { | 38 | if (s->int_level && (s->control & TIMER_CTRL_IE)) { |
| 87 | qemu_irq_raise(s->irq); | 39 | qemu_irq_raise(s->irq); |
| 88 | } else { | 40 | } else { |
| 89 | qemu_irq_lower(s->irq); | 41 | qemu_irq_lower(s->irq); |
| 90 | } | 42 | } |
| 91 | - | ||
| 92 | - next = now; | ||
| 93 | - if (next - s->expires < 0) | ||
| 94 | - next = s->expires; | ||
| 95 | - | ||
| 96 | - /* Schedule the next timer interrupt. */ | ||
| 97 | - if (next == now) { | ||
| 98 | - qemu_del_timer(s->timer); | ||
| 99 | - s->next_time = 0; | ||
| 100 | - } else if (next != s->next_time) { | ||
| 101 | - qemu_mod_timer(s->timer, next); | ||
| 102 | - s->next_time = next; | ||
| 103 | - } | ||
| 104 | -} | ||
| 105 | - | ||
| 106 | -/* Return the current value of the timer. */ | ||
| 107 | -static uint32_t arm_timer_getcount(arm_timer_state *s, int64_t now) | ||
| 108 | -{ | ||
| 109 | - int64_t left; | ||
| 110 | - int64_t period; | ||
| 111 | - | ||
| 112 | - if (s->count == 0) | ||
| 113 | - return 0; | ||
| 114 | - if ((s->control & TIMER_CTRL_ENABLE) == 0) | ||
| 115 | - return s->count; | ||
| 116 | - left = s->expires - now; | ||
| 117 | - period = s->expires - s->loaded; | ||
| 118 | - /* If the timer should have expired then return 0. This can happen | ||
| 119 | - when the host timer signal doesnt occur immediately. It's better to | ||
| 120 | - have a timer appear to sit at zero for a while than have it wrap | ||
| 121 | - around before the guest interrupt is raised. */ | ||
| 122 | - /* ??? Could we trigger the interrupt here? */ | ||
| 123 | - if (left < 0) | ||
| 124 | - return 0; | ||
| 125 | - /* We need to calculate count * elapsed / period without overfowing. | ||
| 126 | - Scale both elapsed and period so they fit in a 32-bit int. */ | ||
| 127 | - while (period != (int32_t)period) { | ||
| 128 | - period >>= 1; | ||
| 129 | - left >>= 1; | ||
| 130 | - } | ||
| 131 | - return ((uint64_t)s->count * (uint64_t)(int32_t)left) | ||
| 132 | - / (int32_t)period; | ||
| 133 | } | 43 | } |
| 134 | 44 | ||
| 135 | uint32_t arm_timer_read(void *opaque, target_phys_addr_t offset) | 45 | uint32_t arm_timer_read(void *opaque, target_phys_addr_t offset) |
| @@ -141,7 +51,7 @@ uint32_t arm_timer_read(void *opaque, target_phys_addr_t offset) | @@ -141,7 +51,7 @@ uint32_t arm_timer_read(void *opaque, target_phys_addr_t offset) | ||
| 141 | case 6: /* TimerBGLoad */ | 51 | case 6: /* TimerBGLoad */ |
| 142 | return s->limit; | 52 | return s->limit; |
| 143 | case 1: /* TimerValue */ | 53 | case 1: /* TimerValue */ |
| 144 | - return arm_timer_getcount(s, qemu_get_clock(vm_clock)); | 54 | + return ptimer_get_count(s->timer); |
| 145 | case 2: /* TimerControl */ | 55 | case 2: /* TimerControl */ |
| 146 | return s->control; | 56 | return s->control; |
| 147 | case 4: /* TimerRIS */ | 57 | case 4: /* TimerRIS */ |
| @@ -151,24 +61,40 @@ uint32_t arm_timer_read(void *opaque, target_phys_addr_t offset) | @@ -151,24 +61,40 @@ uint32_t arm_timer_read(void *opaque, target_phys_addr_t offset) | ||
| 151 | return 0; | 61 | return 0; |
| 152 | return s->int_level; | 62 | return s->int_level; |
| 153 | default: | 63 | default: |
| 154 | - cpu_abort (cpu_single_env, "arm_timer_read: Bad offset %x\n", offset); | 64 | + cpu_abort (cpu_single_env, "arm_timer_read: Bad offset %x\n", |
| 65 | + (int)offset); | ||
| 155 | return 0; | 66 | return 0; |
| 156 | } | 67 | } |
| 157 | } | 68 | } |
| 158 | 69 | ||
| 70 | +/* Reset the timer limit after settings have changed. */ | ||
| 71 | +static void arm_timer_recalibrate(arm_timer_state *s, int reload) | ||
| 72 | +{ | ||
| 73 | + uint32_t limit; | ||
| 74 | + | ||
| 75 | + if ((s->control & TIMER_CTRL_PERIODIC) == 0) { | ||
| 76 | + /* Free running. */ | ||
| 77 | + if (s->control & TIMER_CTRL_32BIT) | ||
| 78 | + limit = 0xffffffff; | ||
| 79 | + else | ||
| 80 | + limit = 0xffff; | ||
| 81 | + } else { | ||
| 82 | + /* Periodic. */ | ||
| 83 | + limit = s->limit; | ||
| 84 | + } | ||
| 85 | + ptimer_set_limit(s->timer, limit, reload); | ||
| 86 | +} | ||
| 87 | + | ||
| 159 | static void arm_timer_write(void *opaque, target_phys_addr_t offset, | 88 | static void arm_timer_write(void *opaque, target_phys_addr_t offset, |
| 160 | uint32_t value) | 89 | uint32_t value) |
| 161 | { | 90 | { |
| 162 | arm_timer_state *s = (arm_timer_state *)opaque; | 91 | arm_timer_state *s = (arm_timer_state *)opaque; |
| 163 | - int64_t now; | 92 | + int freq; |
| 164 | 93 | ||
| 165 | - now = qemu_get_clock(vm_clock); | ||
| 166 | switch (offset >> 2) { | 94 | switch (offset >> 2) { |
| 167 | case 0: /* TimerLoad */ | 95 | case 0: /* TimerLoad */ |
| 168 | s->limit = value; | 96 | s->limit = value; |
| 169 | - s->count = value; | ||
| 170 | - s->expires = now; | ||
| 171 | - arm_timer_reload(s); | 97 | + arm_timer_recalibrate(s, 1); |
| 172 | break; | 98 | break; |
| 173 | case 1: /* TimerValue */ | 99 | case 1: /* TimerValue */ |
| 174 | /* ??? Linux seems to want to write to this readonly register. | 100 | /* ??? Linux seems to want to write to this readonly register. |
| @@ -179,19 +105,20 @@ static void arm_timer_write(void *opaque, target_phys_addr_t offset, | @@ -179,19 +105,20 @@ static void arm_timer_write(void *opaque, target_phys_addr_t offset, | ||
| 179 | /* Pause the timer if it is running. This may cause some | 105 | /* Pause the timer if it is running. This may cause some |
| 180 | inaccuracy dure to rounding, but avoids a whole lot of other | 106 | inaccuracy dure to rounding, but avoids a whole lot of other |
| 181 | messyness. */ | 107 | messyness. */ |
| 182 | - s->count = arm_timer_getcount(s, now); | 108 | + ptimer_stop(s->timer); |
| 183 | } | 109 | } |
| 184 | s->control = value; | 110 | s->control = value; |
| 185 | - s->freq = s->raw_freq; | 111 | + freq = s->freq; |
| 186 | /* ??? Need to recalculate expiry time after changing divisor. */ | 112 | /* ??? Need to recalculate expiry time after changing divisor. */ |
| 187 | switch ((value >> 2) & 3) { | 113 | switch ((value >> 2) & 3) { |
| 188 | - case 1: s->freq >>= 4; break; | ||
| 189 | - case 2: s->freq >>= 8; break; | 114 | + case 1: freq >>= 4; break; |
| 115 | + case 2: freq >>= 8; break; | ||
| 190 | } | 116 | } |
| 117 | + arm_timer_recalibrate(s, 0); | ||
| 118 | + ptimer_set_freq(s->timer, freq); | ||
| 191 | if (s->control & TIMER_CTRL_ENABLE) { | 119 | if (s->control & TIMER_CTRL_ENABLE) { |
| 192 | /* Restart the timer if still enabled. */ | 120 | /* Restart the timer if still enabled. */ |
| 193 | - s->expires = now; | ||
| 194 | - arm_timer_reload(s); | 121 | + ptimer_run(s->timer, (s->control & TIMER_CTRL_ONESHOT) != 0); |
| 195 | } | 122 | } |
| 196 | break; | 123 | break; |
| 197 | case 3: /* TimerIntClr */ | 124 | case 3: /* TimerIntClr */ |
| @@ -199,32 +126,34 @@ static void arm_timer_write(void *opaque, target_phys_addr_t offset, | @@ -199,32 +126,34 @@ static void arm_timer_write(void *opaque, target_phys_addr_t offset, | ||
| 199 | break; | 126 | break; |
| 200 | case 6: /* TimerBGLoad */ | 127 | case 6: /* TimerBGLoad */ |
| 201 | s->limit = value; | 128 | s->limit = value; |
| 129 | + arm_timer_recalibrate(s, 0); | ||
| 202 | break; | 130 | break; |
| 203 | default: | 131 | default: |
| 204 | - cpu_abort (cpu_single_env, "arm_timer_write: Bad offset %x\n", offset); | 132 | + cpu_abort (cpu_single_env, "arm_timer_write: Bad offset %x\n", |
| 133 | + (int)offset); | ||
| 205 | } | 134 | } |
| 206 | - arm_timer_update(s, now); | 135 | + arm_timer_update(s); |
| 207 | } | 136 | } |
| 208 | 137 | ||
| 209 | static void arm_timer_tick(void *opaque) | 138 | static void arm_timer_tick(void *opaque) |
| 210 | { | 139 | { |
| 211 | - int64_t now; | ||
| 212 | - | ||
| 213 | - now = qemu_get_clock(vm_clock); | ||
| 214 | - arm_timer_update((arm_timer_state *)opaque, now); | 140 | + arm_timer_state *s = (arm_timer_state *)opaque; |
| 141 | + s->int_level = 1; | ||
| 142 | + arm_timer_update(s); | ||
| 215 | } | 143 | } |
| 216 | 144 | ||
| 217 | static void *arm_timer_init(uint32_t freq, qemu_irq irq) | 145 | static void *arm_timer_init(uint32_t freq, qemu_irq irq) |
| 218 | { | 146 | { |
| 219 | arm_timer_state *s; | 147 | arm_timer_state *s; |
| 148 | + QEMUBH *bh; | ||
| 220 | 149 | ||
| 221 | s = (arm_timer_state *)qemu_mallocz(sizeof(arm_timer_state)); | 150 | s = (arm_timer_state *)qemu_mallocz(sizeof(arm_timer_state)); |
| 222 | s->irq = irq; | 151 | s->irq = irq; |
| 223 | - s->raw_freq = s->freq = 1000000; | 152 | + s->freq = freq; |
| 224 | s->control = TIMER_CTRL_IE; | 153 | s->control = TIMER_CTRL_IE; |
| 225 | - s->count = 0xffffffff; | ||
| 226 | 154 | ||
| 227 | - s->timer = qemu_new_timer(vm_clock, arm_timer_tick, s); | 155 | + bh = qemu_bh_new(arm_timer_tick, s); |
| 156 | + s->timer = ptimer_init(bh); | ||
| 228 | /* ??? Save/restore. */ | 157 | /* ??? Save/restore. */ |
| 229 | return s; | 158 | return s; |
| 230 | } | 159 | } |
hw/ptimer.c
0 โ 100644
| 1 | +/* | ||
| 2 | + * General purpose implementation of a simple periodic countdown timer. | ||
| 3 | + * | ||
| 4 | + * Copyright (c) 2007 CodeSourcery. | ||
| 5 | + * | ||
| 6 | + * This code is licenced under the GNU LGPL. | ||
| 7 | + */ | ||
| 8 | +#include "vl.h" | ||
| 9 | + | ||
| 10 | + | ||
| 11 | +struct ptimer_state | ||
| 12 | +{ | ||
| 13 | + int enabled; /* 0 = disabled, 1 = periodic, 2 = oneshot. */ | ||
| 14 | + uint32_t limit; | ||
| 15 | + uint32_t delta; | ||
| 16 | + uint32_t period_frac; | ||
| 17 | + int64_t period; | ||
| 18 | + int64_t last_event; | ||
| 19 | + int64_t next_event; | ||
| 20 | + QEMUBH *bh; | ||
| 21 | + QEMUTimer *timer; | ||
| 22 | +}; | ||
| 23 | + | ||
| 24 | +/* Use a bottom-half routine to avoid reentrancy issues. */ | ||
| 25 | +static void ptimer_trigger(ptimer_state *s) | ||
| 26 | +{ | ||
| 27 | + if (s->bh) { | ||
| 28 | + qemu_bh_schedule(s->bh); | ||
| 29 | + } | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +static void ptimer_reload(ptimer_state *s) | ||
| 33 | +{ | ||
| 34 | + if (s->delta == 0) { | ||
| 35 | + ptimer_trigger(s); | ||
| 36 | + s->delta = s->limit; | ||
| 37 | + } | ||
| 38 | + if (s->delta == 0 || s->period == 0) { | ||
| 39 | + fprintf(stderr, "Timer with period zero, disabling\n"); | ||
| 40 | + s->enabled = 0; | ||
| 41 | + return; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + s->last_event = s->next_event; | ||
| 45 | + s->next_event = s->last_event + s->delta * s->period; | ||
| 46 | + if (s->period_frac) { | ||
| 47 | + s->next_event += ((int64_t)s->period_frac * s->delta) >> 32; | ||
| 48 | + } | ||
| 49 | + qemu_mod_timer(s->timer, s->next_event); | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +static void ptimer_tick(void *opaque) | ||
| 53 | +{ | ||
| 54 | + ptimer_state *s = (ptimer_state *)opaque; | ||
| 55 | + ptimer_trigger(s); | ||
| 56 | + s->delta = 0; | ||
| 57 | + if (s->enabled == 2) { | ||
| 58 | + s->enabled = 0; | ||
| 59 | + } else { | ||
| 60 | + ptimer_reload(s); | ||
| 61 | + } | ||
| 62 | +} | ||
| 63 | + | ||
| 64 | +uint32_t ptimer_get_count(ptimer_state *s) | ||
| 65 | +{ | ||
| 66 | + int64_t now; | ||
| 67 | + uint32_t counter; | ||
| 68 | + | ||
| 69 | + if (s->enabled) { | ||
| 70 | + now = qemu_get_clock(vm_clock); | ||
| 71 | + /* Figure out the current counter value. */ | ||
| 72 | + if (now - s->next_event > 0 | ||
| 73 | + || s->period == 0) { | ||
| 74 | + /* Prevent timer underflowing if it should already have | ||
| 75 | + triggered. */ | ||
| 76 | + counter = 0; | ||
| 77 | + } else { | ||
| 78 | + int64_t rem; | ||
| 79 | + int64_t div; | ||
| 80 | + | ||
| 81 | + rem = s->next_event - now; | ||
| 82 | + div = s->period; | ||
| 83 | + counter = rem / div; | ||
| 84 | + } | ||
| 85 | + } else { | ||
| 86 | + counter = s->delta; | ||
| 87 | + } | ||
| 88 | + return counter; | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +void ptimer_set_count(ptimer_state *s, uint32_t count) | ||
| 92 | +{ | ||
| 93 | + s->delta = count; | ||
| 94 | + if (s->enabled) { | ||
| 95 | + s->next_event = qemu_get_clock(vm_clock); | ||
| 96 | + ptimer_reload(s); | ||
| 97 | + } | ||
| 98 | +} | ||
| 99 | + | ||
| 100 | +void ptimer_run(ptimer_state *s, int oneshot) | ||
| 101 | +{ | ||
| 102 | + if (s->period == 0) { | ||
| 103 | + fprintf(stderr, "Timer with period zero, disabling\n"); | ||
| 104 | + return; | ||
| 105 | + } | ||
| 106 | + s->enabled = oneshot ? 2 : 1; | ||
| 107 | + s->next_event = qemu_get_clock(vm_clock); | ||
| 108 | + ptimer_reload(s); | ||
| 109 | +} | ||
| 110 | + | ||
| 111 | +/* Pause a timer. Note that this may cause it to "loose" time, even if it | ||
| 112 | + is immediately restarted. */ | ||
| 113 | +void ptimer_stop(ptimer_state *s) | ||
| 114 | +{ | ||
| 115 | + if (!s->enabled) | ||
| 116 | + return; | ||
| 117 | + | ||
| 118 | + s->delta = ptimer_get_count(s); | ||
| 119 | + qemu_del_timer(s->timer); | ||
| 120 | + s->enabled = 0; | ||
| 121 | +} | ||
| 122 | + | ||
| 123 | +/* Set counter increment interval in nanoseconds. */ | ||
| 124 | +void ptimer_set_period(ptimer_state *s, int64_t period) | ||
| 125 | +{ | ||
| 126 | + if (s->enabled) { | ||
| 127 | + fprintf(stderr, "FIXME: ptimer_set_period with running timer"); | ||
| 128 | + } | ||
| 129 | + s->period = period; | ||
| 130 | + s->period_frac = 0; | ||
| 131 | +} | ||
| 132 | + | ||
| 133 | +/* Set counter frequency in Hz. */ | ||
| 134 | +void ptimer_set_freq(ptimer_state *s, uint32_t freq) | ||
| 135 | +{ | ||
| 136 | + if (s->enabled) { | ||
| 137 | + fprintf(stderr, "FIXME: ptimer_set_freq with running timer"); | ||
| 138 | + } | ||
| 139 | + s->period = 1000000000ll / freq; | ||
| 140 | + s->period_frac = (1000000000ll << 32) / freq; | ||
| 141 | +} | ||
| 142 | + | ||
| 143 | +/* Set the initial countdown value. If reload is nonzero then also set | ||
| 144 | + count = limit. */ | ||
| 145 | +void ptimer_set_limit(ptimer_state *s, uint32_t limit, int reload) | ||
| 146 | +{ | ||
| 147 | + if (s->enabled) { | ||
| 148 | + fprintf(stderr, "FIXME: ptimer_set_limit with running timer"); | ||
| 149 | + } | ||
| 150 | + s->limit = limit; | ||
| 151 | + if (reload) | ||
| 152 | + s->delta = limit; | ||
| 153 | +} | ||
| 154 | + | ||
| 155 | +ptimer_state *ptimer_init(QEMUBH *bh) | ||
| 156 | +{ | ||
| 157 | + ptimer_state *s; | ||
| 158 | + | ||
| 159 | + s = (ptimer_state *)qemu_mallocz(sizeof(ptimer_state)); | ||
| 160 | + s->bh = bh; | ||
| 161 | + s->timer = qemu_new_timer(vm_clock, ptimer_tick, s); | ||
| 162 | + return s; | ||
| 163 | +} | ||
| 164 | + |
vl.c
| @@ -6322,7 +6322,6 @@ void main_loop_wait(int timeout) | @@ -6322,7 +6322,6 @@ void main_loop_wait(int timeout) | ||
| 6322 | } | 6322 | } |
| 6323 | #endif | 6323 | #endif |
| 6324 | qemu_aio_poll(); | 6324 | qemu_aio_poll(); |
| 6325 | - qemu_bh_poll(); | ||
| 6326 | 6325 | ||
| 6327 | if (vm_running) { | 6326 | if (vm_running) { |
| 6328 | qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL], | 6327 | qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL], |
| @@ -6330,10 +6329,15 @@ void main_loop_wait(int timeout) | @@ -6330,10 +6329,15 @@ void main_loop_wait(int timeout) | ||
| 6330 | /* run dma transfers, if any */ | 6329 | /* run dma transfers, if any */ |
| 6331 | DMA_run(); | 6330 | DMA_run(); |
| 6332 | } | 6331 | } |
| 6333 | - | 6332 | + |
| 6334 | /* real time timers */ | 6333 | /* real time timers */ |
| 6335 | qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME], | 6334 | qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME], |
| 6336 | qemu_get_clock(rt_clock)); | 6335 | qemu_get_clock(rt_clock)); |
| 6336 | + | ||
| 6337 | + /* Check bottom-halves last in case any of the earlier events triggered | ||
| 6338 | + them. */ | ||
| 6339 | + qemu_bh_poll(); | ||
| 6340 | + | ||
| 6337 | } | 6341 | } |
| 6338 | 6342 | ||
| 6339 | static CPUState *cur_cpu; | 6343 | static CPUState *cur_cpu; |