sh_intc: convert interrupt controller to memory API
Signed-off-by: Benoit Canet <benoit.canet@gmail.com> Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
		
							parent
							
								
									89e2945140
								
							
						
					
					
						commit
						b279e5efc0
					
				| 
						 | 
				
			
			@ -756,7 +756,7 @@ SH7750State *sh7750_init(CPUSH4State * cpu, MemoryRegion *sysmem)
 | 
			
		|||
                          "cache-and-tlb", 0x08000000);
 | 
			
		||||
    memory_region_add_subregion(sysmem, 0xf0000000, &s->mmct_iomem);
 | 
			
		||||
 | 
			
		||||
    sh_intc_init(&s->intc, NR_SOURCES,
 | 
			
		||||
    sh_intc_init(sysmem, &s->intc, NR_SOURCES,
 | 
			
		||||
		 _INTC_ARRAY(mask_registers),
 | 
			
		||||
		 _INTC_ARRAY(prio_registers));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										85
									
								
								hw/sh_intc.c
								
								
								
								
							
							
						
						
									
										85
									
								
								hw/sh_intc.c
								
								
								
								
							| 
						 | 
				
			
			@ -219,7 +219,8 @@ static void sh_intc_toggle_mask(struct intc_desc *desc, intc_enum id,
 | 
			
		|||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t sh_intc_read(void *opaque, target_phys_addr_t offset)
 | 
			
		||||
static uint64_t sh_intc_read(void *opaque, target_phys_addr_t offset,
 | 
			
		||||
                             unsigned size)
 | 
			
		||||
{
 | 
			
		||||
    struct intc_desc *desc = opaque;
 | 
			
		||||
    intc_enum *enum_ids = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -238,7 +239,7 @@ static uint32_t sh_intc_read(void *opaque, target_phys_addr_t offset)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static void sh_intc_write(void *opaque, target_phys_addr_t offset,
 | 
			
		||||
			  uint32_t value)
 | 
			
		||||
                          uint64_t value, unsigned size)
 | 
			
		||||
{
 | 
			
		||||
    struct intc_desc *desc = opaque;
 | 
			
		||||
    intc_enum *enum_ids = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -282,16 +283,10 @@ static void sh_intc_write(void *opaque, target_phys_addr_t offset,
 | 
			
		|||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static CPUReadMemoryFunc * const sh_intc_readfn[] = {
 | 
			
		||||
    sh_intc_read,
 | 
			
		||||
    sh_intc_read,
 | 
			
		||||
    sh_intc_read
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static CPUWriteMemoryFunc * const sh_intc_writefn[] = {
 | 
			
		||||
    sh_intc_write,
 | 
			
		||||
    sh_intc_write,
 | 
			
		||||
    sh_intc_write
 | 
			
		||||
static const struct MemoryRegionOps sh_intc_ops = {
 | 
			
		||||
    .read = sh_intc_read,
 | 
			
		||||
    .write = sh_intc_write,
 | 
			
		||||
    .endianness = DEVICE_NATIVE_ENDIAN,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct intc_source *sh_intc_source(struct intc_desc *desc, intc_enum id)
 | 
			
		||||
| 
						 | 
				
			
			@ -302,15 +297,36 @@ struct intc_source *sh_intc_source(struct intc_desc *desc, intc_enum id)
 | 
			
		|||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void sh_intc_register(struct intc_desc *desc, 
 | 
			
		||||
			     unsigned long address)
 | 
			
		||||
static unsigned int sh_intc_register(MemoryRegion *sysmem,
 | 
			
		||||
                             struct intc_desc *desc,
 | 
			
		||||
                             const unsigned long address,
 | 
			
		||||
                             const char *type,
 | 
			
		||||
                             const char *action,
 | 
			
		||||
                             const unsigned int index)
 | 
			
		||||
{
 | 
			
		||||
    if (address) {
 | 
			
		||||
        cpu_register_physical_memory_offset(P4ADDR(address), 4,
 | 
			
		||||
                                            desc->iomemtype, INTC_A7(address));
 | 
			
		||||
        cpu_register_physical_memory_offset(A7ADDR(address), 4,
 | 
			
		||||
                                            desc->iomemtype, INTC_A7(address));
 | 
			
		||||
    char name[60];
 | 
			
		||||
    MemoryRegion *iomem, *iomem_p4, *iomem_a7;
 | 
			
		||||
 | 
			
		||||
    if (!address) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    iomem = &desc->iomem;
 | 
			
		||||
    iomem_p4 = desc->iomem_aliases + index;
 | 
			
		||||
    iomem_a7 = iomem_p4 + 1;
 | 
			
		||||
 | 
			
		||||
#define SH_INTC_IOMEM_FORMAT "interrupt-controller-%s-%s-%s"
 | 
			
		||||
    snprintf(name, sizeof(name), SH_INTC_IOMEM_FORMAT, type, action, "p4");
 | 
			
		||||
    memory_region_init_alias(iomem_p4, name, iomem, INTC_A7(address), 4);
 | 
			
		||||
    memory_region_add_subregion(sysmem, P4ADDR(address), iomem_p4);
 | 
			
		||||
 | 
			
		||||
    snprintf(name, sizeof(name), SH_INTC_IOMEM_FORMAT, type, action, "a7");
 | 
			
		||||
    memory_region_init_alias(iomem_a7, name, iomem, INTC_A7(address), 4);
 | 
			
		||||
    memory_region_add_subregion(sysmem, A7ADDR(address), iomem_a7);
 | 
			
		||||
#undef SH_INTC_IOMEM_FORMAT
 | 
			
		||||
 | 
			
		||||
    /* used to increment aliases index */
 | 
			
		||||
    return 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void sh_intc_register_source(struct intc_desc *desc,
 | 
			
		||||
| 
						 | 
				
			
			@ -415,14 +431,15 @@ void sh_intc_register_sources(struct intc_desc *desc,
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sh_intc_init(struct intc_desc *desc,
 | 
			
		||||
int sh_intc_init(MemoryRegion *sysmem,
 | 
			
		||||
         struct intc_desc *desc,
 | 
			
		||||
		 int nr_sources,
 | 
			
		||||
		 struct intc_mask_reg *mask_regs,
 | 
			
		||||
		 int nr_mask_regs,
 | 
			
		||||
		 struct intc_prio_reg *prio_regs,
 | 
			
		||||
		 int nr_prio_regs)
 | 
			
		||||
{
 | 
			
		||||
    unsigned int i;
 | 
			
		||||
    unsigned int i, j;
 | 
			
		||||
 | 
			
		||||
    desc->pending = 0;
 | 
			
		||||
    desc->nr_sources = nr_sources;
 | 
			
		||||
| 
						 | 
				
			
			@ -430,7 +447,12 @@ int sh_intc_init(struct intc_desc *desc,
 | 
			
		|||
    desc->nr_mask_regs = nr_mask_regs;
 | 
			
		||||
    desc->prio_regs = prio_regs;
 | 
			
		||||
    desc->nr_prio_regs = nr_prio_regs;
 | 
			
		||||
    /* Allocate 4 MemoryRegions per register (2 actions * 2 aliases).
 | 
			
		||||
     **/
 | 
			
		||||
    desc->iomem_aliases = g_new0(MemoryRegion,
 | 
			
		||||
                                 (nr_mask_regs + nr_prio_regs) * 4);
 | 
			
		||||
 | 
			
		||||
    j = 0;
 | 
			
		||||
    i = sizeof(struct intc_source) * nr_sources;
 | 
			
		||||
    desc->sources = g_malloc0(i);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -442,15 +464,19 @@ int sh_intc_init(struct intc_desc *desc,
 | 
			
		|||
 | 
			
		||||
    desc->irqs = qemu_allocate_irqs(sh_intc_set_irq, desc, nr_sources);
 | 
			
		||||
 
 | 
			
		||||
    desc->iomemtype = cpu_register_io_memory(sh_intc_readfn,
 | 
			
		||||
					     sh_intc_writefn, desc,
 | 
			
		||||
                                             DEVICE_NATIVE_ENDIAN);
 | 
			
		||||
    memory_region_init_io(&desc->iomem, &sh_intc_ops, desc,
 | 
			
		||||
                          "interrupt-controller", 0x100000000ULL);
 | 
			
		||||
 | 
			
		||||
#define INT_REG_PARAMS(reg_struct, type, action, j) \
 | 
			
		||||
        reg_struct->action##_reg, #type, #action, j
 | 
			
		||||
    if (desc->mask_regs) {
 | 
			
		||||
        for (i = 0; i < desc->nr_mask_regs; i++) {
 | 
			
		||||
	    struct intc_mask_reg *mr = desc->mask_regs + i;
 | 
			
		||||
 | 
			
		||||
	    sh_intc_register(desc, mr->set_reg);
 | 
			
		||||
	    sh_intc_register(desc, mr->clr_reg);
 | 
			
		||||
            j += sh_intc_register(sysmem, desc,
 | 
			
		||||
                                  INT_REG_PARAMS(mr, mask, set, j));
 | 
			
		||||
            j += sh_intc_register(sysmem, desc,
 | 
			
		||||
                                  INT_REG_PARAMS(mr, mask, clr, j));
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -458,10 +484,13 @@ int sh_intc_init(struct intc_desc *desc,
 | 
			
		|||
        for (i = 0; i < desc->nr_prio_regs; i++) {
 | 
			
		||||
	    struct intc_prio_reg *pr = desc->prio_regs + i;
 | 
			
		||||
 | 
			
		||||
	    sh_intc_register(desc, pr->set_reg);
 | 
			
		||||
	    sh_intc_register(desc, pr->clr_reg);
 | 
			
		||||
            j += sh_intc_register(sysmem, desc,
 | 
			
		||||
                                  INT_REG_PARAMS(pr, prio, set, j));
 | 
			
		||||
            j += sh_intc_register(sysmem, desc,
 | 
			
		||||
                                  INT_REG_PARAMS(pr, prio, clr, j));
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
#undef INT_REG_PARAMS
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@
 | 
			
		|||
 | 
			
		||||
#include "qemu-common.h"
 | 
			
		||||
#include "irq.h"
 | 
			
		||||
#include "exec-memory.h"
 | 
			
		||||
 | 
			
		||||
typedef unsigned char intc_enum;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -46,6 +47,8 @@ struct intc_source {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
struct intc_desc {
 | 
			
		||||
    MemoryRegion iomem;
 | 
			
		||||
    MemoryRegion *iomem_aliases;
 | 
			
		||||
    qemu_irq *irqs;
 | 
			
		||||
    struct intc_source *sources;
 | 
			
		||||
    int nr_sources;
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +56,6 @@ struct intc_desc {
 | 
			
		|||
    int nr_mask_regs;
 | 
			
		||||
    struct intc_prio_reg *prio_regs;
 | 
			
		||||
    int nr_prio_regs;
 | 
			
		||||
    int iomemtype;
 | 
			
		||||
    int pending; /* number of interrupt sources that has pending set */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -68,7 +70,8 @@ void sh_intc_register_sources(struct intc_desc *desc,
 | 
			
		|||
			      struct intc_group *groups,
 | 
			
		||||
			      int nr_groups);
 | 
			
		||||
 | 
			
		||||
int sh_intc_init(struct intc_desc *desc,
 | 
			
		||||
int sh_intc_init(MemoryRegion *sysmem,
 | 
			
		||||
                 struct intc_desc *desc,
 | 
			
		||||
		 int nr_sources,
 | 
			
		||||
		 struct intc_mask_reg *mask_regs,
 | 
			
		||||
		 int nr_mask_regs,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,10 @@
 | 
			
		|||
#include <signal.h>
 | 
			
		||||
 | 
			
		||||
#include "cpu.h"
 | 
			
		||||
 | 
			
		||||
#if !defined(CONFIG_USER_ONLY)
 | 
			
		||||
#include "hw/sh_intc.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_USER_ONLY)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue