qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] SH: Improve the interrupt controller


From: takasi-y
Subject: Re: [Qemu-devel] SH: Improve the interrupt controller
Date: Mon, 15 Dec 2008 01:46:39 +0900 (JST)

# a patch attached is not to be commit to repos, but for explanation.
Hi,

> I have tested this only with SH4A and it's desirable to test
> with 7751/R2D. However, I no longer sure I know which kernel
> to use for that. Can anybody either provide me with instructions,
> or test this patch with R2D for me?

It doesn't work at least here for me (for r2d).
It stops with CPU load 100% (and I had to power my PC off...).

BTW, I think your patch is not following to current sh_intc's design model.
# please read to the end. this will be turned over later.

I think its design model is
 - registering memory regions for each registers.
 - read/write function doesn't check address
But, you have add address check in read/write function.

Mine(which I have forgotten to send..., only to move icr) is attached at the
 end of this mail. This one is based on the recognition above.

It works, but I wonder if this model is valid or not on mmio system after #5849.
Especially here is in question,
+    cpu_register_physical_memory(P4ADDR(base), 2, io_memory);
+    cpu_register_physical_memory(A7ADDR(base), 2, io_memory);

Paul(the author of #5849) said,
> [1] It's actually the offset from the start of the first page of that region. 
> In practice this difference doesn't matter, and makes the implementation a 
> lot simpler.

I don't know why he thought it "doesn't matter", but from discussions on ML,
 I guess the model he have is
 - register one memory region for each modules.
 - read/write function check address
 - most of modules are aligned to page.

In that case, your patch is nearer to the model.
But, then, we should done with these,
        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));

Sorry for no conclusion. I'm still wondering.
/yoshii

commit 53bf0820c255aea216053e67c11ffd409b78c16d
Author: Takashi YOSHII <address@hidden>
Date:   Thu Dec 11 22:26:19 2008 +0900

    move intc.icr from sh7750.c to sh_intc.c

diff --git a/hw/sh7750.c b/hw/sh7750.c
index 4d1a806..0c49c4c 100644
--- a/hw/sh7750.c
+++ b/hw/sh7750.c
@@ -700,7 +700,7 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
     cpu_register_physical_memory(0xf0000000, 0x08000000,
                                 sh7750_mm_cache_and_tlb);
 
-    sh_intc_init(&s->intc, NR_SOURCES,
+    sh_intc_init(0x1fd00000, &s->intc, NR_SOURCES,
                 _INTC_ARRAY(mask_registers),
                 _INTC_ARRAY(prio_registers));
 
diff --git a/hw/sh_intc.c b/hw/sh_intc.c
index 136e7dd..7c66545 100644
--- a/hw/sh_intc.c
+++ b/hw/sh_intc.c
@@ -416,7 +416,26 @@ void sh_intc_register_sources(struct intc_desc *desc,
     }
 }
 
-int sh_intc_init(struct intc_desc *desc,
+static uint32_t sh_intc_icr_read(void *opaque, uint32_t offs)
+{
+    return ((struct intc_desc*)opaque)->icr;
+}
+
+static void sh_intc_icr_write(void *opaque, uint32_t offs, uint32_t value)
+{
+    ((struct intc_desc*)opaque)->icr = value;
+}
+
+static CPUReadMemoryFunc *sh_intc_icr_readfn[] = {
+    NULL, sh_intc_icr_read, NULL
+};
+
+static CPUWriteMemoryFunc *sh_intc_icr_writefn[] = {
+    NULL, sh_intc_icr_write, NULL
+};
+
+int sh_intc_init(target_phys_addr_t base,
+                struct intc_desc *desc,
                 int nr_sources,
                 struct intc_mask_reg *mask_regs,
                 int nr_mask_regs,
@@ -424,6 +443,7 @@ int sh_intc_init(struct intc_desc *desc,
                 int nr_prio_regs)
 {
     unsigned int i;
+    int io_memory;
 
     desc->pending = 0;
     desc->nr_sources = nr_sources;
@@ -465,6 +485,10 @@ int sh_intc_init(struct intc_desc *desc,
            sh_intc_register(desc, pr->clr_reg);
        }
     }
+    io_memory = cpu_register_io_memory(0, sh_intc_icr_readfn,
+                                       sh_intc_icr_writefn, desc);
+    cpu_register_physical_memory(P4ADDR(base), 2, io_memory);
+    cpu_register_physical_memory(A7ADDR(base), 2, io_memory);
 
     return 0;
 }
diff --git a/hw/sh_intc.h b/hw/sh_intc.h
index 4e36f00..e39f794 100644
--- a/hw/sh_intc.h
+++ b/hw/sh_intc.h
@@ -55,6 +55,7 @@ struct intc_desc {
     int nr_prio_regs;
     int iomemtype;
     int pending; /* number of interrupt sources that has pending set */
+    uint16_t icr;
 };
 
 int sh_intc_get_pending_vector(struct intc_desc *desc, int imask);
@@ -68,7 +69,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(target_phys_addr_t base,
+                struct intc_desc *desc,
                 int nr_sources,
                 struct intc_mask_reg *mask_regs,
                 int nr_mask_regs,




reply via email to

[Prev in Thread] Current Thread [Next in Thread]