Lines Matching +full:- +full:- +full:-

25 #include "qemu/error-report.h"
28 #include "hw/qdev-properties.h"
37 return addr >= base && addr - base < num; in addr_between()
67 atomic_set_masked(&plic->pending[irq >> 5], 1 << (irq & 31), -!!level); in sifive_plic_set_pending()
72 atomic_set_masked(&plic->claimed[irq >> 5], 1 << (irq & 31), -!!level); in sifive_plic_set_claimed()
78 uint32_t max_prio = plic->target_priority[addrid]; in sifive_plic_claimed()
82 for (i = 0; i < plic->bitfield_words; i++) { in sifive_plic_claimed()
84 (plic->pending[i] & ~plic->claimed[i]) & in sifive_plic_claimed()
85 plic->enable[addrid * plic->bitfield_words + i]; in sifive_plic_claimed()
91 if (i == (plic->bitfield_words - 1)) { in sifive_plic_claimed()
93 * If plic->num_sources is not multiple of 32, num-of-irq in last in sifive_plic_claimed()
94 * word is not 32. Compute the num-of-irq of last word to avoid in sifive_plic_claimed()
95 * out-of-bound access of source_priority array. in sifive_plic_claimed()
97 num_irq_in_word = plic->num_sources - ((plic->bitfield_words - 1) << 5); in sifive_plic_claimed()
102 uint32_t prio = plic->source_priority[irq]; in sifive_plic_claimed()
120 for (addrid = 0; addrid < plic->num_addrs; addrid++) { in sifive_plic_update()
121 uint32_t hartid = plic->addr_config[addrid].hartid; in sifive_plic_update()
122 PLICMode mode = plic->addr_config[addrid].mode; in sifive_plic_update()
127 qemu_set_irq(plic->m_external_irqs[hartid - plic->hartid_base], level); in sifive_plic_update()
130 qemu_set_irq(plic->s_external_irqs[hartid - plic->hartid_base], level); in sifive_plic_update()
142 if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) { in sifive_plic_read()
143 uint32_t irq = (addr - plic->priority_base) >> 2; in sifive_plic_read()
145 return plic->source_priority[irq]; in sifive_plic_read()
146 } else if (addr_between(addr, plic->pending_base, in sifive_plic_read()
147 (plic->num_sources + 31) >> 3)) { in sifive_plic_read()
148 uint32_t word = (addr - plic->pending_base) >> 2; in sifive_plic_read()
150 return plic->pending[word]; in sifive_plic_read()
151 } else if (addr_between(addr, plic->enable_base, in sifive_plic_read()
152 plic->num_addrs * plic->enable_stride)) { in sifive_plic_read()
153 uint32_t addrid = (addr - plic->enable_base) / plic->enable_stride; in sifive_plic_read()
154 uint32_t wordid = (addr & (plic->enable_stride - 1)) >> 2; in sifive_plic_read()
156 if (wordid < plic->bitfield_words) { in sifive_plic_read()
157 return plic->enable[addrid * plic->bitfield_words + wordid]; in sifive_plic_read()
159 } else if (addr_between(addr, plic->context_base, in sifive_plic_read()
160 plic->num_addrs * plic->context_stride)) { in sifive_plic_read()
161 uint32_t addrid = (addr - plic->context_base) / plic->context_stride; in sifive_plic_read()
162 uint32_t contextid = (addr & (plic->context_stride - 1)); in sifive_plic_read()
165 return plic->target_priority[addrid]; in sifive_plic_read()
190 if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) { in sifive_plic_write()
191 uint32_t irq = (addr - plic->priority_base) >> 2; in sifive_plic_write()
198 } else if (((plic->num_priorities + 1) & plic->num_priorities) == 0) { in sifive_plic_write()
200 * if "num_priorities + 1" is power-of-2, make each register bit of in sifive_plic_write()
201 * interrupt priority WARL (Write-Any-Read-Legal). Just filter in sifive_plic_write()
204 plic->source_priority[irq] = value % (plic->num_priorities + 1); in sifive_plic_write()
206 } else if (value <= plic->num_priorities) { in sifive_plic_write()
207 plic->source_priority[irq] = value; in sifive_plic_write()
210 } else if (addr_between(addr, plic->pending_base, in sifive_plic_write()
211 (plic->num_sources + 31) >> 3)) { in sifive_plic_write()
215 } else if (addr_between(addr, plic->enable_base, in sifive_plic_write()
216 plic->num_addrs * plic->enable_stride)) { in sifive_plic_write()
217 uint32_t addrid = (addr - plic->enable_base) / plic->enable_stride; in sifive_plic_write()
218 uint32_t wordid = (addr & (plic->enable_stride - 1)) >> 2; in sifive_plic_write()
220 if (wordid < plic->bitfield_words) { in sifive_plic_write()
221 plic->enable[addrid * plic->bitfield_words + wordid] = value; in sifive_plic_write()
227 } else if (addr_between(addr, plic->context_base, in sifive_plic_write()
228 plic->num_addrs * plic->context_stride)) { in sifive_plic_write()
229 uint32_t addrid = (addr - plic->context_base) / plic->context_stride; in sifive_plic_write()
230 uint32_t contextid = (addr & (plic->context_stride - 1)); in sifive_plic_write()
233 if (((plic->num_priorities + 1) & plic->num_priorities) == 0) { in sifive_plic_write()
235 * if "num_priorities + 1" is power-of-2, each register bit of in sifive_plic_write()
236 * interrupt priority is WARL (Write-Any-Read-Legal). Just in sifive_plic_write()
239 plic->target_priority[addrid] = value % in sifive_plic_write()
240 (plic->num_priorities + 1); in sifive_plic_write()
242 } else if (value <= plic->num_priorities) { in sifive_plic_write()
243 plic->target_priority[addrid] = value; in sifive_plic_write()
247 if (value < plic->num_sources) { in sifive_plic_write()
278 memset(s->source_priority, 0, sizeof(uint32_t) * s->num_sources); in sifive_plic_reset()
279 memset(s->target_priority, 0, sizeof(uint32_t) * s->num_addrs); in sifive_plic_reset()
280 memset(s->pending, 0, sizeof(uint32_t) * s->bitfield_words); in sifive_plic_reset()
281 memset(s->claimed, 0, sizeof(uint32_t) * s->bitfield_words); in sifive_plic_reset()
282 memset(s->enable, 0, sizeof(uint32_t) * s->num_enables); in sifive_plic_reset()
284 for (i = 0; i < s->num_harts; i++) { in sifive_plic_reset()
285 qemu_set_irq(s->m_external_irqs[i], 0); in sifive_plic_reset()
286 qemu_set_irq(s->s_external_irqs[i], 0); in sifive_plic_reset()
294 * "MS,MS" 2 harts, 0-1 with M and S mode
295 * "M,MS,MS,MS,MS" 5 harts, 0 with M mode, 1-5 with M and S mode
305 p = plic->hart_config; in parse_hart_config()
317 c, plic->hart_config); in parse_hart_config()
329 plic->num_addrs = addrid; in parse_hart_config()
330 plic->num_harts = hartid; in parse_hart_config()
333 plic->addr_config = g_new(PLICAddr, plic->num_addrs); in parse_hart_config()
334 addrid = 0, hartid = plic->hartid_base; in parse_hart_config()
335 p = plic->hart_config; in parse_hart_config()
344 plic->addr_config[addrid].addrid = addrid; in parse_hart_config()
345 plic->addr_config[addrid].hartid = hartid; in parse_hart_config()
346 plic->addr_config[addrid].mode = m; in parse_hart_config()
368 memory_region_init_io(&s->mmio, OBJECT(dev), &sifive_plic_ops, s, in sifive_plic_realize()
369 TYPE_SIFIVE_PLIC, s->aperture_size); in sifive_plic_realize()
370 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio); in sifive_plic_realize()
374 if (!s->num_sources) { in sifive_plic_realize()
379 s->bitfield_words = (s->num_sources + 31) >> 5; in sifive_plic_realize()
380 s->num_enables = s->bitfield_words * s->num_addrs; in sifive_plic_realize()
381 s->source_priority = g_new0(uint32_t, s->num_sources); in sifive_plic_realize()
382 s->target_priority = g_new(uint32_t, s->num_addrs); in sifive_plic_realize()
383 s->pending = g_new0(uint32_t, s->bitfield_words); in sifive_plic_realize()
384 s->claimed = g_new0(uint32_t, s->bitfield_words); in sifive_plic_realize()
385 s->enable = g_new0(uint32_t, s->num_enables); in sifive_plic_realize()
387 qdev_init_gpio_in(dev, sifive_plic_irq_request, s->num_sources); in sifive_plic_realize()
389 s->s_external_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts); in sifive_plic_realize()
390 qdev_init_gpio_out(dev, s->s_external_irqs, s->num_harts); in sifive_plic_realize()
392 s->m_external_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts); in sifive_plic_realize()
393 qdev_init_gpio_out(dev, s->m_external_irqs, s->num_harts); in sifive_plic_realize()
401 for (i = 0; i < s->num_harts; i++) { in sifive_plic_realize()
402 RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i)); in sifive_plic_realize()
434 DEFINE_PROP_STRING("hart-config", SiFivePLICState, hart_config),
435 DEFINE_PROP_UINT32("hartid-base", SiFivePLICState, hartid_base, 0),
437 DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 1),
438 DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
440 DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
441 DEFINE_PROP_UINT32("pending-base", SiFivePLICState, pending_base, 0),
442 DEFINE_PROP_UINT32("enable-base", SiFivePLICState, enable_base, 0),
443 DEFINE_PROP_UINT32("enable-stride", SiFivePLICState, enable_stride, 0),
444 DEFINE_PROP_UINT32("context-base", SiFivePLICState, context_base, 0),
445 DEFINE_PROP_UINT32("context-stride", SiFivePLICState, context_stride, 0),
446 DEFINE_PROP_UINT32("aperture-size", SiFivePLICState, aperture_size, 0),
455 dc->realize = sifive_plic_realize; in sifive_plic_class_init()
456 dc->vmsd = &vmstate_sifive_plic; in sifive_plic_class_init()
488 assert(enable_stride == (enable_stride & -enable_stride)); in type_init()
489 assert(context_stride == (context_stride & -context_stride)); in type_init()
490 qdev_prop_set_string(dev, "hart-config", hart_config); in type_init()
491 qdev_prop_set_uint32(dev, "hartid-base", hartid_base); in type_init()
492 qdev_prop_set_uint32(dev, "num-sources", num_sources); in type_init()
493 qdev_prop_set_uint32(dev, "num-priorities", num_priorities); in type_init()
494 qdev_prop_set_uint32(dev, "priority-base", priority_base); in type_init()
495 qdev_prop_set_uint32(dev, "pending-base", pending_base); in type_init()
496 qdev_prop_set_uint32(dev, "enable-base", enable_base); in type_init()
497 qdev_prop_set_uint32(dev, "enable-stride", enable_stride); in type_init()
498 qdev_prop_set_uint32(dev, "context-base", context_base); in type_init()
499 qdev_prop_set_uint32(dev, "context-stride", context_stride); in type_init()
500 qdev_prop_set_uint32(dev, "aperture-size", aperture_size); in type_init()
506 for (i = 0; i < plic->num_addrs; i++) { in type_init()
507 int cpu_num = plic->addr_config[i].hartid; in type_init()
510 if (plic->addr_config[i].mode == PLICMode_M) { in type_init()
511 qdev_connect_gpio_out(dev, cpu_num - hartid_base + num_harts, in type_init()
514 if (plic->addr_config[i].mode == PLICMode_S) { in type_init()
515 qdev_connect_gpio_out(dev, cpu_num - hartid_base, in type_init()