1 /* 2 * QEMU GRLIB GPTimer Emulator 3 * 4 * Copyright (c) 2010-2019 AdaCore 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/grlib.h" 27 #include "hw/sysbus.h" 28 #include "qemu/timer.h" 29 #include "hw/irq.h" 30 #include "hw/ptimer.h" 31 #include "hw/qdev-properties.h" 32 #include "qemu/main-loop.h" 33 #include "qemu/module.h" 34 35 #include "trace.h" 36 37 #define UNIT_REG_SIZE 16 /* Size of memory mapped regs for the unit */ 38 #define GPTIMER_REG_SIZE 16 /* Size of memory mapped regs for a GPTimer */ 39 40 #define GPTIMER_MAX_TIMERS 8 41 42 /* GPTimer Config register fields */ 43 #define GPTIMER_ENABLE (1 << 0) 44 #define GPTIMER_RESTART (1 << 1) 45 #define GPTIMER_LOAD (1 << 2) 46 #define GPTIMER_INT_ENABLE (1 << 3) 47 #define GPTIMER_INT_PENDING (1 << 4) 48 #define GPTIMER_CHAIN (1 << 5) /* Not supported */ 49 #define GPTIMER_DEBUG_HALT (1 << 6) /* Not supported */ 50 51 /* Memory mapped register offsets */ 52 #define SCALER_OFFSET 0x00 53 #define SCALER_RELOAD_OFFSET 0x04 54 #define CONFIG_OFFSET 0x08 55 #define COUNTER_OFFSET 0x00 56 #define COUNTER_RELOAD_OFFSET 0x04 57 #define TIMER_BASE 0x10 58 59 #define GRLIB_GPTIMER(obj) \ 60 OBJECT_CHECK(GPTimerUnit, (obj), TYPE_GRLIB_GPTIMER) 61 62 typedef struct GPTimer GPTimer; 63 typedef struct GPTimerUnit GPTimerUnit; 64 65 struct GPTimer { 66 QEMUBH *bh; 67 struct ptimer_state *ptimer; 68 69 qemu_irq irq; 70 int id; 71 GPTimerUnit *unit; 72 73 /* registers */ 74 uint32_t counter; 75 uint32_t reload; 76 uint32_t config; 77 }; 78 79 struct GPTimerUnit { 80 SysBusDevice parent_obj; 81 82 MemoryRegion iomem; 83 84 uint32_t nr_timers; /* Number of timers available */ 85 uint32_t freq_hz; /* System frequency */ 86 uint32_t irq_line; /* Base irq line */ 87 88 GPTimer *timers; 89 90 /* registers */ 91 uint32_t scaler; 92 uint32_t reload; 93 uint32_t config; 94 }; 95 96 static void grlib_gptimer_enable(GPTimer *timer) 97 { 98 assert(timer != NULL); 99 100 101 ptimer_stop(timer->ptimer); 102 103 if (!(timer->config & GPTIMER_ENABLE)) { 104 /* Timer disabled */ 105 trace_grlib_gptimer_disabled(timer->id, timer->config); 106 return; 107 } 108 109 /* ptimer is triggered when the counter reach 0 but GPTimer is triggered at 110 underflow. Set count + 1 to simulate the GPTimer behavior. */ 111 112 trace_grlib_gptimer_enable(timer->id, timer->counter); 113 114 ptimer_set_count(timer->ptimer, (uint64_t)timer->counter + 1); 115 ptimer_run(timer->ptimer, 1); 116 } 117 118 static void grlib_gptimer_restart(GPTimer *timer) 119 { 120 assert(timer != NULL); 121 122 trace_grlib_gptimer_restart(timer->id, timer->reload); 123 124 timer->counter = timer->reload; 125 grlib_gptimer_enable(timer); 126 } 127 128 static void grlib_gptimer_set_scaler(GPTimerUnit *unit, uint32_t scaler) 129 { 130 int i = 0; 131 uint32_t value = 0; 132 133 assert(unit != NULL); 134 135 if (scaler > 0) { 136 value = unit->freq_hz / (scaler + 1); 137 } else { 138 value = unit->freq_hz; 139 } 140 141 trace_grlib_gptimer_set_scaler(scaler, value); 142 143 for (i = 0; i < unit->nr_timers; i++) { 144 ptimer_set_freq(unit->timers[i].ptimer, value); 145 } 146 } 147 148 static void grlib_gptimer_hit(void *opaque) 149 { 150 GPTimer *timer = opaque; 151 assert(timer != NULL); 152 153 trace_grlib_gptimer_hit(timer->id); 154 155 /* Timer expired */ 156 157 if (timer->config & GPTIMER_INT_ENABLE) { 158 /* Set the pending bit (only unset by write in the config register) */ 159 timer->config |= GPTIMER_INT_PENDING; 160 qemu_irq_pulse(timer->irq); 161 } 162 163 if (timer->config & GPTIMER_RESTART) { 164 grlib_gptimer_restart(timer); 165 } 166 } 167 168 static uint64_t grlib_gptimer_read(void *opaque, hwaddr addr, 169 unsigned size) 170 { 171 GPTimerUnit *unit = opaque; 172 hwaddr timer_addr; 173 int id; 174 uint32_t value = 0; 175 176 addr &= 0xff; 177 178 /* Unit registers */ 179 switch (addr) { 180 case SCALER_OFFSET: 181 trace_grlib_gptimer_readl(-1, addr, unit->scaler); 182 return unit->scaler; 183 184 case SCALER_RELOAD_OFFSET: 185 trace_grlib_gptimer_readl(-1, addr, unit->reload); 186 return unit->reload; 187 188 case CONFIG_OFFSET: 189 trace_grlib_gptimer_readl(-1, addr, unit->config); 190 return unit->config; 191 192 default: 193 break; 194 } 195 196 timer_addr = (addr % TIMER_BASE); 197 id = (addr - TIMER_BASE) / TIMER_BASE; 198 199 if (id >= 0 && id < unit->nr_timers) { 200 201 /* GPTimer registers */ 202 switch (timer_addr) { 203 case COUNTER_OFFSET: 204 value = ptimer_get_count(unit->timers[id].ptimer); 205 trace_grlib_gptimer_readl(id, addr, value); 206 return value; 207 208 case COUNTER_RELOAD_OFFSET: 209 value = unit->timers[id].reload; 210 trace_grlib_gptimer_readl(id, addr, value); 211 return value; 212 213 case CONFIG_OFFSET: 214 trace_grlib_gptimer_readl(id, addr, unit->timers[id].config); 215 return unit->timers[id].config; 216 217 default: 218 break; 219 } 220 221 } 222 223 trace_grlib_gptimer_readl(-1, addr, 0); 224 return 0; 225 } 226 227 static void grlib_gptimer_write(void *opaque, hwaddr addr, 228 uint64_t value, unsigned size) 229 { 230 GPTimerUnit *unit = opaque; 231 hwaddr timer_addr; 232 int id; 233 234 addr &= 0xff; 235 236 /* Unit registers */ 237 switch (addr) { 238 case SCALER_OFFSET: 239 value &= 0xFFFF; /* clean up the value */ 240 unit->scaler = value; 241 trace_grlib_gptimer_writel(-1, addr, unit->scaler); 242 return; 243 244 case SCALER_RELOAD_OFFSET: 245 value &= 0xFFFF; /* clean up the value */ 246 unit->reload = value; 247 trace_grlib_gptimer_writel(-1, addr, unit->reload); 248 grlib_gptimer_set_scaler(unit, value); 249 return; 250 251 case CONFIG_OFFSET: 252 /* Read Only (disable timer freeze not supported) */ 253 trace_grlib_gptimer_writel(-1, addr, 0); 254 return; 255 256 default: 257 break; 258 } 259 260 timer_addr = (addr % TIMER_BASE); 261 id = (addr - TIMER_BASE) / TIMER_BASE; 262 263 if (id >= 0 && id < unit->nr_timers) { 264 265 /* GPTimer registers */ 266 switch (timer_addr) { 267 case COUNTER_OFFSET: 268 trace_grlib_gptimer_writel(id, addr, value); 269 unit->timers[id].counter = value; 270 grlib_gptimer_enable(&unit->timers[id]); 271 return; 272 273 case COUNTER_RELOAD_OFFSET: 274 trace_grlib_gptimer_writel(id, addr, value); 275 unit->timers[id].reload = value; 276 return; 277 278 case CONFIG_OFFSET: 279 trace_grlib_gptimer_writel(id, addr, value); 280 281 if (value & GPTIMER_INT_PENDING) { 282 /* clear pending bit */ 283 value &= ~GPTIMER_INT_PENDING; 284 } else { 285 /* keep pending bit */ 286 value |= unit->timers[id].config & GPTIMER_INT_PENDING; 287 } 288 289 unit->timers[id].config = value; 290 291 /* gptimer_restart calls gptimer_enable, so if "enable" and "load" 292 bits are present, we just have to call restart. */ 293 294 if (value & GPTIMER_LOAD) { 295 grlib_gptimer_restart(&unit->timers[id]); 296 } else if (value & GPTIMER_ENABLE) { 297 grlib_gptimer_enable(&unit->timers[id]); 298 } 299 300 /* These fields must always be read as 0 */ 301 value &= ~(GPTIMER_LOAD & GPTIMER_DEBUG_HALT); 302 303 unit->timers[id].config = value; 304 return; 305 306 default: 307 break; 308 } 309 310 } 311 312 trace_grlib_gptimer_writel(-1, addr, value); 313 } 314 315 static const MemoryRegionOps grlib_gptimer_ops = { 316 .read = grlib_gptimer_read, 317 .write = grlib_gptimer_write, 318 .endianness = DEVICE_NATIVE_ENDIAN, 319 .valid = { 320 .min_access_size = 4, 321 .max_access_size = 4, 322 }, 323 }; 324 325 static void grlib_gptimer_reset(DeviceState *d) 326 { 327 GPTimerUnit *unit = GRLIB_GPTIMER(d); 328 int i = 0; 329 330 assert(unit != NULL); 331 332 unit->scaler = 0; 333 unit->reload = 0; 334 335 unit->config = unit->nr_timers; 336 unit->config |= unit->irq_line << 3; 337 unit->config |= 1 << 8; /* separate interrupt */ 338 unit->config |= 1 << 9; /* Disable timer freeze */ 339 340 341 for (i = 0; i < unit->nr_timers; i++) { 342 GPTimer *timer = &unit->timers[i]; 343 344 timer->counter = 0; 345 timer->reload = 0; 346 timer->config = 0; 347 ptimer_stop(timer->ptimer); 348 ptimer_set_count(timer->ptimer, 0); 349 ptimer_set_freq(timer->ptimer, unit->freq_hz); 350 } 351 } 352 353 static void grlib_gptimer_realize(DeviceState *dev, Error **errp) 354 { 355 GPTimerUnit *unit = GRLIB_GPTIMER(dev); 356 unsigned int i; 357 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 358 359 assert(unit->nr_timers > 0); 360 assert(unit->nr_timers <= GPTIMER_MAX_TIMERS); 361 362 unit->timers = g_malloc0(sizeof unit->timers[0] * unit->nr_timers); 363 364 for (i = 0; i < unit->nr_timers; i++) { 365 GPTimer *timer = &unit->timers[i]; 366 367 timer->unit = unit; 368 timer->bh = qemu_bh_new(grlib_gptimer_hit, timer); 369 timer->ptimer = ptimer_init(timer->bh, PTIMER_POLICY_DEFAULT); 370 timer->id = i; 371 372 /* One IRQ line for each timer */ 373 sysbus_init_irq(sbd, &timer->irq); 374 375 ptimer_set_freq(timer->ptimer, unit->freq_hz); 376 } 377 378 memory_region_init_io(&unit->iomem, OBJECT(unit), &grlib_gptimer_ops, 379 unit, "gptimer", 380 UNIT_REG_SIZE + GPTIMER_REG_SIZE * unit->nr_timers); 381 382 sysbus_init_mmio(sbd, &unit->iomem); 383 } 384 385 static Property grlib_gptimer_properties[] = { 386 DEFINE_PROP_UINT32("frequency", GPTimerUnit, freq_hz, 40000000), 387 DEFINE_PROP_UINT32("irq-line", GPTimerUnit, irq_line, 8), 388 DEFINE_PROP_UINT32("nr-timers", GPTimerUnit, nr_timers, 2), 389 DEFINE_PROP_END_OF_LIST(), 390 }; 391 392 static void grlib_gptimer_class_init(ObjectClass *klass, void *data) 393 { 394 DeviceClass *dc = DEVICE_CLASS(klass); 395 396 dc->realize = grlib_gptimer_realize; 397 dc->reset = grlib_gptimer_reset; 398 dc->props = grlib_gptimer_properties; 399 } 400 401 static const TypeInfo grlib_gptimer_info = { 402 .name = TYPE_GRLIB_GPTIMER, 403 .parent = TYPE_SYS_BUS_DEVICE, 404 .instance_size = sizeof(GPTimerUnit), 405 .class_init = grlib_gptimer_class_init, 406 }; 407 408 static void grlib_gptimer_register_types(void) 409 { 410 type_register_static(&grlib_gptimer_info); 411 } 412 413 type_init(grlib_gptimer_register_types) 414