[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH ARM v8 2/4] mini-os: arm: interrupt controller
Hi Ian and Thomas, On 10/21/2014 12:00 PM, Ian Campbell wrote: > On Fri, 2014-10-03 at 10:20 +0100, Thomas Leonard wrote: >> +static void gic_set_priority(struct gic *gic, int irq_number, unsigned char >> priority) >> +{ >> + uint32_t value; >> + uint32_t *addr = REG(gicd(gic, GICD_IPRIORITYR)) + (irq_number >> 2); >> + value = REG_READ32(addr); >> + value &= ~(0xff << (8 * (irq_number & 0x3))); // clear old priority >> + value |= priority << (8 * (irq_number & 0x3)); // set new priority >> + REG_WRITE32(addr, value); > > I believe the IPRIORITYR registers are byte addressable, so you can just > do a strb of the new value without needing to read-modify-write. > >> +static void gic_route_interrupt(struct gic *gic, int irq_number, unsigned >> char cpu_set) >> +{ >> + uint32_t value; >> + uint32_t *addr = REG(gicd(gic, GICD_ITARGETSR)) + (irq_number >> 2); >> + value = REG_READ32(addr); >> + value &= ~(0xff << (8 * (irq_number & 0x3))); // clear old target >> + value |= cpu_set << (8 * (irq_number & 0x3)); // set new target >> + REG_WRITE32(addr, value); > > Same for ITARGETSR. Our implementation of ITARGETSR doesn't handle correctly read/write per byte. If the register is RO (such as for the SGIs and PPIs), our write ignore is checking that the guest is writing a word. Even though we need to fix it in Xen (I could send a patch for it). We need to keep this implementation if we want mini-os to run on Xen 4.4.x. >> +/* Note: not thread safe (but we only support one CPU for now anyway) */ >> +static void gic_enable_interrupt(struct gic *gic, int irq_number, >> + unsigned char cpu_set, unsigned char level_sensitive, unsigned char >> ppi) >> +{ >> + void *set_enable_reg; >> + void *cfg_reg; >> + >> + // set priority >> + gic_set_priority(gic, irq_number, 0x0); >> + >> + // set target cpus for this interrupt >> + gic_route_interrupt(gic, irq_number, cpu_set); >> + >> + // set level/edge triggered >> + cfg_reg = (void *)gicd(gic, GICD_ICFGR); >> + if (level_sensitive) { >> + clear_bit_non_atomic((irq_number * 2) + 1, cfg_reg); >> + } else { >> + set_bit_non_atomic((irq_number * 2) + 1, cfg_reg); >> + } >> + if (ppi) > > missing else? Or should be folded in above as level_sensitive||ppi I would even drop this check. I don't think, we need to have specific configuration for PPIs. [..] >> + gic_enable_interrupt(&gic, EVENTS_IRQ /* interrupt number */, 0x1 >> /*cpu_set*/, 1 /*level_sensitive*/, 0 /* ppi */); >> + gic_enable_interrupt(&gic, VIRTUALTIMER_IRQ /* interrupt number */, 0x1 >> /*cpu_set*/, 1 /*level_sensitive*/, 1 /* ppi */); > > BTW, ppi or not is implicit in the irq number. At the same time, both interrupt are PPIs, why the former as ppi = 0 and the latter 1? Regards, -- Julien Grall _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |