1 /* 2 * QEMU Sparc SLAVIO timer controller emulation 3 * 4 * Copyright (c) 2003-2005 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25 #include "qemu/osdep.h" 26 #include "hw/sparc/sun4m.h" 27 #include "qemu/timer.h" 28 #include "hw/ptimer.h" 29 #include "hw/sysbus.h" 30 #include "trace.h" 31 #include "qemu/main-loop.h" 32 33 /* 34 * Registers of hardware timer in sun4m. 35 * 36 * This is the timer/counter part of chip STP2001 (Slave I/O), also 37 * produced as NCR89C105. See 38 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt 39 * 40 * The 31-bit counter is incremented every 500ns by bit 9. Bits 8..0 41 * are zero. Bit 31 is 1 when count has been reached. 42 * 43 * Per-CPU timers interrupt local CPU, system timer uses normal 44 * interrupt routing. 45 * 46 */ 47 48 #define MAX_CPUS 16 49 50 typedef struct CPUTimerState { 51 qemu_irq irq; 52 ptimer_state *timer; 53 uint32_t count, counthigh, reached; 54 /* processor only */ 55 uint32_t run; 56 uint64_t limit; 57 } CPUTimerState; 58 59 #define TYPE_SLAVIO_TIMER "slavio_timer" 60 #define SLAVIO_TIMER(obj) \ 61 OBJECT_CHECK(SLAVIO_TIMERState, (obj), TYPE_SLAVIO_TIMER) 62 63 typedef struct SLAVIO_TIMERState { 64 SysBusDevice parent_obj; 65 66 uint32_t num_cpus; 67 uint32_t cputimer_mode; 68 CPUTimerState cputimer[MAX_CPUS + 1]; 69 } SLAVIO_TIMERState; 70 71 typedef struct TimerContext { 72 MemoryRegion iomem; 73 SLAVIO_TIMERState *s; 74 unsigned int timer_index; /* 0 for system, 1 ... MAX_CPUS for CPU timers */ 75 } TimerContext; 76 77 #define SYS_TIMER_SIZE 0x14 78 #define CPU_TIMER_SIZE 0x10 79 80 #define TIMER_LIMIT 0 81 #define TIMER_COUNTER 1 82 #define TIMER_COUNTER_NORST 2 83 #define TIMER_STATUS 3 84 #define TIMER_MODE 4 85 86 #define TIMER_COUNT_MASK32 0xfffffe00 87 #define TIMER_LIMIT_MASK32 0x7fffffff 88 #define TIMER_MAX_COUNT64 0x7ffffffffffffe00ULL 89 #define TIMER_MAX_COUNT32 0x7ffffe00ULL 90 #define TIMER_REACHED 0x80000000 91 #define TIMER_PERIOD 500ULL // 500ns 92 #define LIMIT_TO_PERIODS(l) (((l) >> 9) - 1) 93 #define PERIODS_TO_LIMIT(l) (((l) + 1) << 9) 94 95 static int slavio_timer_is_user(TimerContext *tc) 96 { 97 SLAVIO_TIMERState *s = tc->s; 98 unsigned int timer_index = tc->timer_index; 99 100 return timer_index != 0 && (s->cputimer_mode & (1 << (timer_index - 1))); 101 } 102 103 // Update count, set irq, update expire_time 104 // Convert from ptimer countdown units 105 static void slavio_timer_get_out(CPUTimerState *t) 106 { 107 uint64_t count, limit; 108 109 if (t->limit == 0) { /* free-run system or processor counter */ 110 limit = TIMER_MAX_COUNT32; 111 } else { 112 limit = t->limit; 113 } 114 count = limit - PERIODS_TO_LIMIT(ptimer_get_count(t->timer)); 115 116 trace_slavio_timer_get_out(t->limit, t->counthigh, t->count); 117 t->count = count & TIMER_COUNT_MASK32; 118 t->counthigh = count >> 32; 119 } 120 121 // timer callback 122 static void slavio_timer_irq(void *opaque) 123 { 124 TimerContext *tc = opaque; 125 SLAVIO_TIMERState *s = tc->s; 126 CPUTimerState *t = &s->cputimer[tc->timer_index]; 127 128 slavio_timer_get_out(t); 129 trace_slavio_timer_irq(t->counthigh, t->count); 130 /* if limit is 0 (free-run), there will be no match */ 131 if (t->limit != 0) { 132 t->reached = TIMER_REACHED; 133 } 134 /* there is no interrupt if user timer or free-run */ 135 if (!slavio_timer_is_user(tc) && t->limit != 0) { 136 qemu_irq_raise(t->irq); 137 } 138 } 139 140 static uint64_t slavio_timer_mem_readl(void *opaque, hwaddr addr, 141 unsigned size) 142 { 143 TimerContext *tc = opaque; 144 SLAVIO_TIMERState *s = tc->s; 145 uint32_t saddr, ret; 146 unsigned int timer_index = tc->timer_index; 147 CPUTimerState *t = &s->cputimer[timer_index]; 148 149 saddr = addr >> 2; 150 switch (saddr) { 151 case TIMER_LIMIT: 152 // read limit (system counter mode) or read most signifying 153 // part of counter (user mode) 154 if (slavio_timer_is_user(tc)) { 155 // read user timer MSW 156 slavio_timer_get_out(t); 157 ret = t->counthigh | t->reached; 158 } else { 159 // read limit 160 // clear irq 161 qemu_irq_lower(t->irq); 162 t->reached = 0; 163 ret = t->limit & TIMER_LIMIT_MASK32; 164 } 165 break; 166 case TIMER_COUNTER: 167 // read counter and reached bit (system mode) or read lsbits 168 // of counter (user mode) 169 slavio_timer_get_out(t); 170 if (slavio_timer_is_user(tc)) { // read user timer LSW 171 ret = t->count & TIMER_MAX_COUNT64; 172 } else { // read limit 173 ret = (t->count & TIMER_MAX_COUNT32) | 174 t->reached; 175 } 176 break; 177 case TIMER_STATUS: 178 // only available in processor counter/timer 179 // read start/stop status 180 if (timer_index > 0) { 181 ret = t->run; 182 } else { 183 ret = 0; 184 } 185 break; 186 case TIMER_MODE: 187 // only available in system counter 188 // read user/system mode 189 ret = s->cputimer_mode; 190 break; 191 default: 192 trace_slavio_timer_mem_readl_invalid(addr); 193 ret = 0; 194 break; 195 } 196 trace_slavio_timer_mem_readl(addr, ret); 197 return ret; 198 } 199 200 static void slavio_timer_mem_writel(void *opaque, hwaddr addr, 201 uint64_t val, unsigned size) 202 { 203 TimerContext *tc = opaque; 204 SLAVIO_TIMERState *s = tc->s; 205 uint32_t saddr; 206 unsigned int timer_index = tc->timer_index; 207 CPUTimerState *t = &s->cputimer[timer_index]; 208 209 trace_slavio_timer_mem_writel(addr, val); 210 saddr = addr >> 2; 211 switch (saddr) { 212 case TIMER_LIMIT: 213 if (slavio_timer_is_user(tc)) { 214 uint64_t count; 215 216 // set user counter MSW, reset counter 217 t->limit = TIMER_MAX_COUNT64; 218 t->counthigh = val & (TIMER_MAX_COUNT64 >> 32); 219 t->reached = 0; 220 count = ((uint64_t)t->counthigh << 32) | t->count; 221 trace_slavio_timer_mem_writel_limit(timer_index, count); 222 ptimer_set_count(t->timer, LIMIT_TO_PERIODS(t->limit - count)); 223 } else { 224 // set limit, reset counter 225 qemu_irq_lower(t->irq); 226 t->limit = val & TIMER_MAX_COUNT32; 227 if (t->timer) { 228 if (t->limit == 0) { /* free-run */ 229 ptimer_set_limit(t->timer, 230 LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 1); 231 } else { 232 ptimer_set_limit(t->timer, LIMIT_TO_PERIODS(t->limit), 1); 233 } 234 } 235 } 236 break; 237 case TIMER_COUNTER: 238 if (slavio_timer_is_user(tc)) { 239 uint64_t count; 240 241 // set user counter LSW, reset counter 242 t->limit = TIMER_MAX_COUNT64; 243 t->count = val & TIMER_MAX_COUNT64; 244 t->reached = 0; 245 count = ((uint64_t)t->counthigh) << 32 | t->count; 246 trace_slavio_timer_mem_writel_limit(timer_index, count); 247 ptimer_set_count(t->timer, LIMIT_TO_PERIODS(t->limit - count)); 248 } else { 249 trace_slavio_timer_mem_writel_counter_invalid(); 250 } 251 break; 252 case TIMER_COUNTER_NORST: 253 // set limit without resetting counter 254 t->limit = val & TIMER_MAX_COUNT32; 255 if (t->limit == 0) { /* free-run */ 256 ptimer_set_limit(t->timer, LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 0); 257 } else { 258 ptimer_set_limit(t->timer, LIMIT_TO_PERIODS(t->limit), 0); 259 } 260 break; 261 case TIMER_STATUS: 262 if (slavio_timer_is_user(tc)) { 263 // start/stop user counter 264 if (val & 1) { 265 trace_slavio_timer_mem_writel_status_start(timer_index); 266 ptimer_run(t->timer, 0); 267 } else { 268 trace_slavio_timer_mem_writel_status_stop(timer_index); 269 ptimer_stop(t->timer); 270 } 271 } 272 t->run = val & 1; 273 break; 274 case TIMER_MODE: 275 if (timer_index == 0) { 276 unsigned int i; 277 278 for (i = 0; i < s->num_cpus; i++) { 279 unsigned int processor = 1 << i; 280 CPUTimerState *curr_timer = &s->cputimer[i + 1]; 281 282 // check for a change in timer mode for this processor 283 if ((val & processor) != (s->cputimer_mode & processor)) { 284 if (val & processor) { // counter -> user timer 285 qemu_irq_lower(curr_timer->irq); 286 // counters are always running 287 if (!curr_timer->run) { 288 ptimer_stop(curr_timer->timer); 289 } 290 // user timer limit is always the same 291 curr_timer->limit = TIMER_MAX_COUNT64; 292 ptimer_set_limit(curr_timer->timer, 293 LIMIT_TO_PERIODS(curr_timer->limit), 294 1); 295 // set this processors user timer bit in config 296 // register 297 s->cputimer_mode |= processor; 298 trace_slavio_timer_mem_writel_mode_user(timer_index); 299 } else { // user timer -> counter 300 // start the counter 301 ptimer_run(curr_timer->timer, 0); 302 // clear this processors user timer bit in config 303 // register 304 s->cputimer_mode &= ~processor; 305 trace_slavio_timer_mem_writel_mode_counter(timer_index); 306 } 307 } 308 } 309 } else { 310 trace_slavio_timer_mem_writel_mode_invalid(); 311 } 312 break; 313 default: 314 trace_slavio_timer_mem_writel_invalid(addr); 315 break; 316 } 317 } 318 319 static const MemoryRegionOps slavio_timer_mem_ops = { 320 .read = slavio_timer_mem_readl, 321 .write = slavio_timer_mem_writel, 322 .endianness = DEVICE_NATIVE_ENDIAN, 323 .valid = { 324 .min_access_size = 4, 325 .max_access_size = 4, 326 }, 327 }; 328 329 static const VMStateDescription vmstate_timer = { 330 .name ="timer", 331 .version_id = 3, 332 .minimum_version_id = 3, 333 .fields = (VMStateField[]) { 334 VMSTATE_UINT64(limit, CPUTimerState), 335 VMSTATE_UINT32(count, CPUTimerState), 336 VMSTATE_UINT32(counthigh, CPUTimerState), 337 VMSTATE_UINT32(reached, CPUTimerState), 338 VMSTATE_UINT32(run , CPUTimerState), 339 VMSTATE_PTIMER(timer, CPUTimerState), 340 VMSTATE_END_OF_LIST() 341 } 342 }; 343 344 static const VMStateDescription vmstate_slavio_timer = { 345 .name ="slavio_timer", 346 .version_id = 3, 347 .minimum_version_id = 3, 348 .fields = (VMStateField[]) { 349 VMSTATE_STRUCT_ARRAY(cputimer, SLAVIO_TIMERState, MAX_CPUS + 1, 3, 350 vmstate_timer, CPUTimerState), 351 VMSTATE_END_OF_LIST() 352 } 353 }; 354 355 static void slavio_timer_reset(DeviceState *d) 356 { 357 SLAVIO_TIMERState *s = SLAVIO_TIMER(d); 358 unsigned int i; 359 CPUTimerState *curr_timer; 360 361 for (i = 0; i <= MAX_CPUS; i++) { 362 curr_timer = &s->cputimer[i]; 363 curr_timer->limit = 0; 364 curr_timer->count = 0; 365 curr_timer->reached = 0; 366 if (i <= s->num_cpus) { 367 ptimer_set_limit(curr_timer->timer, 368 LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 1); 369 ptimer_run(curr_timer->timer, 0); 370 curr_timer->run = 1; 371 } 372 } 373 s->cputimer_mode = 0; 374 } 375 376 static void slavio_timer_init(Object *obj) 377 { 378 SLAVIO_TIMERState *s = SLAVIO_TIMER(obj); 379 SysBusDevice *dev = SYS_BUS_DEVICE(obj); 380 QEMUBH *bh; 381 unsigned int i; 382 TimerContext *tc; 383 384 for (i = 0; i <= MAX_CPUS; i++) { 385 uint64_t size; 386 char timer_name[20]; 387 388 tc = g_malloc0(sizeof(TimerContext)); 389 tc->s = s; 390 tc->timer_index = i; 391 392 bh = qemu_bh_new(slavio_timer_irq, tc); 393 s->cputimer[i].timer = ptimer_init(bh, PTIMER_POLICY_DEFAULT); 394 ptimer_set_period(s->cputimer[i].timer, TIMER_PERIOD); 395 396 size = i == 0 ? SYS_TIMER_SIZE : CPU_TIMER_SIZE; 397 snprintf(timer_name, sizeof(timer_name), "timer-%i", i); 398 memory_region_init_io(&tc->iomem, obj, &slavio_timer_mem_ops, tc, 399 timer_name, size); 400 sysbus_init_mmio(dev, &tc->iomem); 401 402 sysbus_init_irq(dev, &s->cputimer[i].irq); 403 } 404 } 405 406 static Property slavio_timer_properties[] = { 407 DEFINE_PROP_UINT32("num_cpus", SLAVIO_TIMERState, num_cpus, 0), 408 DEFINE_PROP_END_OF_LIST(), 409 }; 410 411 static void slavio_timer_class_init(ObjectClass *klass, void *data) 412 { 413 DeviceClass *dc = DEVICE_CLASS(klass); 414 415 dc->reset = slavio_timer_reset; 416 dc->vmsd = &vmstate_slavio_timer; 417 dc->props = slavio_timer_properties; 418 } 419 420 static const TypeInfo slavio_timer_info = { 421 .name = TYPE_SLAVIO_TIMER, 422 .parent = TYPE_SYS_BUS_DEVICE, 423 .instance_size = sizeof(SLAVIO_TIMERState), 424 .instance_init = slavio_timer_init, 425 .class_init = slavio_timer_class_init, 426 }; 427 428 static void slavio_timer_register_types(void) 429 { 430 type_register_static(&slavio_timer_info); 431 } 432 433 type_init(slavio_timer_register_types) 434