static void sh_intc_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { struct intc_desc *desc = opaque; intc_enum *enum_ids = NULL; unsigned int first = 0; unsigned int width = 0; unsigned int mode = 0; unsigned int k; unsigned long *valuep; unsigned long mask; #ifdef DEBUG_INTC printf("sh_intc_write 0x%lx 0x%08x\n", (unsigned long) offset, value); #endif sh_intc_locate(desc, (unsigned long)offset, &valuep, &enum_ids, &first, &width, &mode); switch (mode) { case INTC_MODE_ENABLE_REG | INTC_MODE_IS_PRIO: break; case INTC_MODE_DUAL_SET: value |= *valuep; break; case INTC_MODE_DUAL_CLR: value = *valuep & ~value; break; default: abort(); } for (k = 0; k <= first; k++) { mask = ((1 << width) - 1) << ((first - k) * width); if ((*valuep & mask) == (value & mask)) continue; #if 0 printf("k = %d, first = %d, enum = %d, mask = 0x%08x\n", k, first, enum_ids[k], (unsigned int)mask); #endif sh_intc_toggle_mask(desc, enum_ids[k], value & mask, 0); } *valuep = value; #ifdef DEBUG_INTC printf("sh_intc_write 0x%lx -> 0x%08x\n", (unsigned long) offset, value); #endif }
static uint32_t sh_intc_read(void *opaque, target_phys_addr_t offset) { struct intc_desc *desc = opaque; intc_enum *enum_ids = NULL; unsigned int first = 0; unsigned int width = 0; unsigned int mode = 0; unsigned long *valuep; #ifdef DEBUG_INTC printf("sh_intc_read 0x%lx\n", (unsigned long) offset); #endif sh_intc_locate(desc, (unsigned long)offset, &valuep, &enum_ids, &first, &width, &mode); return *valuep; }