[Qemu-devel] Help needed to run Exynos 4210 linux kernel on qemu?

2012-09-04 Thread Jean-Christophe DUBOIS

Hi,

I am trying to run linux over qemu-system-arm emulating a nuri or 
smdkc210 Exynos 4210 based board.


To do this I fetched the last qemu (from git://git.qemu.org/qemu.git) 
and built it with "./configure --target-list=arm-softmmu.


Then I fetched the latest linux image for samsung processors (from 
git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git) 
and built it using exynos4_defconfig config file.


Then I tried to run the 2 together:

$ qemu-system-arm -kernel zImage -append "console=ttySAC0,115200n8 
root=/dev/ram rw earlyprintk" -serial stdio -M smdkc210 -initrd rootfs.img

smdkc210 board supports only 2 CPU cores. Ignoring smp_cpus value.
VNC server running on `127.0.0.1:5900'
Booting Linux on physical CPU 0
Linux version 3.6.0-rc3 (jcd@jcd-P31SG) (gcc version 4.6.3 
(Ubuntu/Linaro 4.6.3-1ubuntu5) ) #1 SMP PREEMPT Mon Sep 3 22:44:05 CEST 2012

CPU: ARMv7 Processor [410fc090] revision 0 (ARMv7), cr=10c5387d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
Machine: SMDKC210
bootconsole [earlycon0] enabled
Truncating RAM at 4000-7fff to -6f7f (vmalloc region overlap).
Memory policy: ECC disabled, Data cache writealloc

The kernel hangs here because it got a data abort exception while trying 
to print the "next" message (which is "CPU EXYNOS4210 (id 0x43210211)"). 
The data abort is generated somewhere in the console_unlock() function.


I tried the same thing with some less up to date source code of qemu 
and/or linux with the same result. I even tried the linaro versions of 
qemu and linux without luck.


So there has to be something I am doing wrong. I would really appreciate 
it if you could point me in the right direction.


Thanks.

JC



Re: [Qemu-devel] Help needed to run Exynos 4210 linux kernel on qemu?

2012-09-05 Thread Jean-Christophe DUBOIS

Hello Igor,

Thanks for you reply and your time.

JC

On 09/05/2012 02:38 PM, Igor Mitsyanko wrote:

On 09/04/2012 02:13 AM, Jean-Christophe DUBOIS wrote:

Hello, Jean!

I've just tried to do the same thing you're trying to do, it works for 
me if I remove earlyprintk from append.


Yes, I found out about this in the mean time.

Probably this is due to the fact that kernel expects uart0 to be 
configured by u-boot prior to kernel start execution. Interestingly, 
if you change default exynos4_defconfig CONFIG_DEBUG_S3C_UART0 to, for 
example, CONFIG_DEBUG_S3C_UART2 in linux kernel configuration, 
everything starting to work fine even with earlyprintk.


Seems strange. It would be nice if "earlyprintk" was not hanging though 
(is it possible to work around the actual LSP expectation?).




But using ramdisks is always a pain for me, I would suggest you two 
different approaches:


Ramdisk is fine for what I need to do at this time.



1) The most convenient way is to use emulated SD card for rootfs 
storage. There is no SD card support for exynos4210 in current QEMU 
master, but you can apply SD host controller patches I attached to 
this email to get this support. These patches already have been 
thoroughly reviewed in qemu-devel mailing list and hopefully would be 
applied to QEMU master soon enough.
If you want to use SD card instead of RAMDISK, apply these patches to 
QEMU master with "git am", and enable MMC/SD support in linux kernel 
configuration (it is disabled by default in exynos4_defconfig). You 
need to check CONFIG_MMC, CONFIG_MMC_SDHC, CONFIG_MMC_SDHCI_S3C and 
ONFIG_MMC_SDHCI_S3C_DMA.
Then you can launch QEMU with -sd /path/to/your/rootfs and, for 
example, append line -append "root=/dev/mmcblk0 rootfstype=ext4 rw 
rootwait".


Thanks. That seems interesting but I don't need it right now. I can wait 
for this patch to hit mainline.




2) If you want to work only with what current QEMU master has, you can 
use network filesystem as rootfs, but only for smdkc210 board (nuri 
board doesn't have any net devices). You're gonna have to check these 
options in Linux configuration:
CONFIG_NET, CONFIG_PACKET, CONFIG_INET, CONFIG_IP_PNP, 
CONFIG_IP_PNP_DHCP, CONFIG_NETDEVICES, CONFIG_SMSC911X, CONFIG_NFS_FS, 
CONFIG_ROOT_NFS.
Then, if, for example, you have directory /mnt/nfsroot exported by NFS 
server on your host machine, you can launch QEMU guest with following 
command line:


qemu-system-arm -kernel ./zImage -M smdkc210 -append 
"console=ttySAC0,115200n8 ip=dhcp root=/dev/nfs 
nfsroot=10.0.2.2:/mnt/nfsroot/ rw" -serial stdio


Unfortunately, network will have to wait too. But it will come in a 
second step.




Also, maybe you noticed, graphic support is disabled in 
exynos4_defconfig by default. To enable it, check these options in 
Linux configuration:
CONFIG_DRM, CONFIG_DRM_EXYNOS, CONFIG_DRM_EXYNOS_DMABUF, 
CONFIG_DRM_EXYNOS_FIMD. You can also check CONFIG_LOGO to get a fancy 
penguins during guest VM startup. And if you need to start X server on 
your guest VM, you also need to enable UNIX domain sockets in linux 
kernel CONFIG_UNIX.


Thanks. I'll look at this later. No graphic is needed for now. A serial 
console is all I need.





[Qemu-devel] [PATCH] i.MX: implement a more correct version of EPIT timer.

2013-04-09 Thread Jean-Christophe DUBOIS
This patch is providing a complete version of the EPIT timer.

Note, however that the GPT timer in the same file is still not
complete.

Signed-off-by: Jean-Christophe DUBOIS 
---
 hw/timer/imx_timer.c |  250 ++
 1 file changed, 192 insertions(+), 58 deletions(-)

diff --git a/hw/timer/imx_timer.c b/hw/timer/imx_timer.c
index 03197e3..12aa376 100644
--- a/hw/timer/imx_timer.c
+++ b/hw/timer/imx_timer.c
@@ -95,6 +95,10 @@ typedef struct {
 uint32_t sr;
 uint32_t ir;
 uint32_t ocr1;
+uint32_t ocr2;
+uint32_t ocr3;
+uint32_t icr1;
+uint32_t icr2;
 uint32_t cnt;
 
 uint32_t waiting_rov;
@@ -112,6 +116,10 @@ static const VMStateDescription vmstate_imx_timerg = {
 VMSTATE_UINT32(sr, IMXTimerGState),
 VMSTATE_UINT32(ir, IMXTimerGState),
 VMSTATE_UINT32(ocr1, IMXTimerGState),
+VMSTATE_UINT32(ocr2, IMXTimerGState),
+VMSTATE_UINT32(ocr3, IMXTimerGState),
+VMSTATE_UINT32(icr1, IMXTimerGState),
+VMSTATE_UINT32(icr2, IMXTimerGState),
 VMSTATE_UINT32(cnt, IMXTimerGState),
 VMSTATE_UINT32(waiting_rov, IMXTimerGState),
 VMSTATE_PTIMER(timer, IMXTimerGState),
@@ -156,7 +164,6 @@ static void imx_timerg_update(IMXTimerGState *s)
 s->ir & GPT_SR_ROV ? "ROV" : "",
 s->cr & GPT_CR_EN ? "CR_EN" : "Not Enabled");
 
-
 qemu_set_irq(s->irq, (s->cr & GPT_CR_EN) && flags);
 }
 
@@ -221,6 +228,21 @@ static uint64_t imx_timerg_read(void *opaque, hwaddr 
offset,
 DPRINTF(" ocr1 = %x\n", s->ocr1);
 return s->ocr1;
 
+case 5: /* Output Compare Register 2 */
+DPRINTF(" ocr2 = %x\n", s->ocr2);
+return s->ocr2;
+
+case 6: /* Output Compare Register 3 */
+DPRINTF(" ocr3 = %x\n", s->ocr3);
+return s->ocr3;
+
+case 7: /* input Capture Register 1 */
+DPRINTF(" icr1 = %x\n", s->icr1);
+return s->icr1;
+
+case 8: /* input Capture Register 2 */
+DPRINTF(" icr2 = %x\n", s->icr2);
+return s->icr2;
 
 case 9: /* cnt */
 imx_timerg_update_counts(s);
@@ -230,6 +252,7 @@ static uint64_t imx_timerg_read(void *opaque, hwaddr offset,
 
 IPRINTF("imx_timerg_read: Bad offset %x\n",
 (int)offset >> 2);
+
 return 0;
 }
 
@@ -240,14 +263,19 @@ static void imx_timerg_reset(DeviceState *dev)
 /*
  * Soft reset doesn't touch some bits; hard reset clears them
  */
-s->cr &= ~(GPT_CR_EN|GPT_CR_DOZEN|GPT_CR_WAITEN|GPT_CR_DBGEN);
+s->cr &= 
~(GPT_CR_EN|GPT_CR_ENMOD|GPT_CR_STOPEN|GPT_CR_DOZEN|GPT_CR_WAITEN|GPT_CR_DBGEN);
 s->sr = 0;
 s->pr = 0;
 s->ir = 0;
 s->cnt = 0;
 s->ocr1 = TIMER_MAX;
+s->ocr2 = TIMER_MAX;
+s->ocr3 = TIMER_MAX;
+s->icr1 = 0;
+s->icr2 = 0;
 ptimer_stop(s->timer);
 ptimer_set_limit(s->timer, TIMER_MAX, 1);
+ptimer_set_count(s->timer, TIMER_MAX);
 imx_timerg_set_freq(s);
 }
 
@@ -323,6 +351,8 @@ static void imx_timerg_write(void *opaque, hwaddr offset,
 s->ocr1 = value;
 return;
 
+case 5: /* OCR2 -- output compare register */
+case 6: /* OCR3 -- output compare register */
 default:
 IPRINTF("imx_timerg_write: Bad offset %x\n",
 (int)offset >> 2);
@@ -411,7 +441,7 @@ static int imx_timerg_init(SysBusDevice *dev)
 #define CR_SWR  (1 << 16)
 #define CR_IOVW (1 << 17)
 #define CR_DBGEN(1 << 18)
-#define CR_EPIT (1 << 19)
+#define CR_WAITEN   (1 << 19)
 #define CR_DOZEN(1 << 20)
 #define CR_STOPEN   (1 << 21)
 #define CR_CLKSRC_SHIFT (24)
@@ -423,24 +453,26 @@ static int imx_timerg_init(SysBusDevice *dev)
  * These are typical.
  */
 static const IMXClk imx_timerp_clocks[] =  {
-0,/* disabled */
-IPG, /* ipg_clk, ~532MHz */
-IPG, /* ipg_clk_highfreq */
-CLK_32k,/* ipg_clk_32k -- ~32kHz */
+0,/* 00 disabled */
+IPG,  /* 01 ipg_clk, ~532MHz */
+IPG,  /* 10 ipg_clk_highfreq */
+CLK_32k,  /* 11 ipg_clk_32k -- ~32kHz */
 };
 
 typedef struct {
 SysBusDevice busdev;
-ptimer_state *timer;
+ptimer_state *timer_reload;
+ptimer_state *timer_cmp;
 MemoryRegion iomem;
 DeviceState *ccm;
 
 uint32_t cr;
+uint32_t sr;
 uint32_t lr;
 uint32_t cmp;
+uint32_t cnt;
 
 uint32_t freq;
-int int_level;
 qemu_irq irq;
 } IMXTimerPState;
 
@@ -449,23 +481,63 @@ typedef struct {
  */
 static void imx_timerp_update(IMXTimerPState *s)
 {
-if (s->int_level && (s->cr & CR_OCIEN)) {
+if (s->sr && (s->cr & CR_OCIEN)) {
 qemu_irq_raise(s->irq);
 } else {
 qemu_irq_lower(s

Re: [Qemu-devel] [PATCH] i.MX: implement a more correct version of EPIT timer.

2013-04-09 Thread Jean-Christophe DUBOIS

On 04/10/2013 01:27 AM, Peter Chubb wrote:

This patch is providing a complete version of the EPIT timer.
Note, however that the GPT timer in the same file is still not
complete.

Thanks!

Comments in=line below.


@@ -411,7 +441,7 @@ static int imx_timerg_init(SysBusDevice *dev)
  #define CR_SWR  (1 << 16)
  #define CR_IOVW (1 << 17)
  #define CR_DBGEN(1 << 18)
-#define CR_EPIT (1 << 19)
+#define CR_WAITEN   (1 << 19)


In the docs this bit is called EPIT.  Its function is to enable the
timer in wait-mode. So is conformance with the docs or the description
of the function more important?  If you *do* rename it, there should
be a comment to say it's EPIT in the i.mx31 documentation.


Well, in the i.MX25 or the i.MX6 manual, this bit is named WAITEN (like 
in the GPT).


I believe it is a typo in the i.MX31 documentation (where it is referred 
as WAITEN in the SWR bit description).


  
  

-static void set_timerp_freq(IMXTimerPState *s)
+static void imx_reload_compare_timer(IMXTimerPState *s)
{
-int clksrc;
-unsigned prescaler;
-uint32_t freq;
-
-clksrc = (s->cr & CR_CLKSRC_MASK) >> CR_CLKSRC_SHIFT;
-prescaler = 1 + ((s->cr >> CR_PRESCALE_SHIFT) & CR_PRESCALE_MASK);
-freq = imx_clock_frequency(s->ccm, imx_timerp_clocks[clksrc]) / prescaler;
-
-s->freq = freq;
-DPRINTF("Setting ptimer frequency to %u\n", freq);
-
-if (freq) {
-ptimer_set_freq(s->timer, freq);
+if ((s->cr & CR_OCIEN) && s->cmp) {
+/* it the compare feature is on */]

s/it/if/

right


+uint32_t tmp = imx_timerp_update_counts(s);
+if (tmp > s->cmp) {
+/* reinit the cmp timer if required */
+ptimer_set_count(s->timer_cmp, tmp - s->cmp);
+if ((s->cr & CR_EN)) {
+/* Restart the cmp timer if required */
+ptimer_run(s->timer_cmp, 0);
+}
+}
  }
  }
  

@@ -526,40 +599,63 @@ static void imx_timerp_write(void *opaque, hwaddr offset,

 switch (offset >> 2) {
 case 0: /* CR */
-if (value & CR_SWR) {
+s->cr = value & 0x03ff;
+if (s->cr & CR_SWR) {
+/* handle the reset */
 imx_timerp_reset(&s->busdev.qdev);
-value &= ~CR_SWR;
+} else {
+set_timerp_freq(s);
 }
-s->cr = value & 0x03ff;
-set_timerp_freq(s);
+value &= s->cr;

You're letting the reset function clear the SWR.  It's unclear to me
from the docs whether when the SWR bit is set, assignment to other
fields in the CR happens before or after the reset.  I punted on
`after' (because it seemted to work), this changes to `before'.


Well the documentation states that the SWR bit is reset to 0 at the end 
of reset. So this should be the case even when we don't call it 
explicitly in the driver (when it is called directly by Qemu).




The reset looks good --- you seem to understand the ptimer interface
better than I did when I updated this code.

Peter c
--
Dr Peter Chubb  peter.chubb AT nicta.com.au
http://www.ssrg.nicta.com.au  Software Systems Research Group/NICTA






Re: [Qemu-devel] [PATCH] i.MX: implement a more correct version of EPIT timer.

2013-04-10 Thread Jean-Christophe DUBOIS

On 04/10/2013 10:26 AM, Peter Maydell wrote:

On 9 April 2013 23:32, Jean-Christophe DUBOIS  wrote:

@@ -605,11 +735,13 @@ static const VMStateDescription vmstate_imx_timerp = {
  .minimum_version_id_old = 1,
  .fields  = (VMStateField[]) {
  VMSTATE_UINT32(cr, IMXTimerPState),
+VMSTATE_UINT32(sr, IMXTimerPState),
  VMSTATE_UINT32(lr, IMXTimerPState),
  VMSTATE_UINT32(cmp, IMXTimerPState),
+VMSTATE_UINT32(cnt, IMXTimerPState),
  VMSTATE_UINT32(freq, IMXTimerPState),
-VMSTATE_INT32(int_level, IMXTimerPState),
-VMSTATE_PTIMER(timer, IMXTimerPState),
+VMSTATE_PTIMER(timer_reload, IMXTimerPState),
+VMSTATE_PTIMER(timer_cmp, IMXTimerPState),
  VMSTATE_END_OF_LIST()
  }
  };

If you're adding/changing vmstate fields like this then you
need to increment all the version id fields too. Otherwise
cross-version migration will break oddly (rather than failing
cleanly).

OK


thanks
-- PMM






[Qemu-devel] [PATCH v2] i.MX: implement a more correct version of EPIT timer.

2013-04-10 Thread Jean-Christophe DUBOIS
This patch is providing a complete version of the EPIT timer.

Note, however that the GPT timer in the same file is still not
complete.

Signed-off-by: Jean-Christophe DUBOIS 

Change from v1:
  - bump up the version number on VMSTATE struct
  - fix comment
---
 hw/timer/imx_timer.c |  253 ++
 1 file changed, 193 insertions(+), 60 deletions(-)

diff --git a/hw/timer/imx_timer.c b/hw/timer/imx_timer.c
index 03197e3..514a907 100644
--- a/hw/timer/imx_timer.c
+++ b/hw/timer/imx_timer.c
@@ -95,6 +95,10 @@ typedef struct {
 uint32_t sr;
 uint32_t ir;
 uint32_t ocr1;
+uint32_t ocr2;
+uint32_t ocr3;
+uint32_t icr1;
+uint32_t icr2;
 uint32_t cnt;
 
 uint32_t waiting_rov;
@@ -103,7 +107,7 @@ typedef struct {
 
 static const VMStateDescription vmstate_imx_timerg = {
 .name = "imx-timerg",
-.version_id = 1,
+.version_id = 2,
 .minimum_version_id = 1,
 .minimum_version_id_old = 1,
 .fields  = (VMStateField[]) {
@@ -112,6 +116,10 @@ static const VMStateDescription vmstate_imx_timerg = {
 VMSTATE_UINT32(sr, IMXTimerGState),
 VMSTATE_UINT32(ir, IMXTimerGState),
 VMSTATE_UINT32(ocr1, IMXTimerGState),
+VMSTATE_UINT32(ocr2, IMXTimerGState),
+VMSTATE_UINT32(ocr3, IMXTimerGState),
+VMSTATE_UINT32(icr1, IMXTimerGState),
+VMSTATE_UINT32(icr2, IMXTimerGState),
 VMSTATE_UINT32(cnt, IMXTimerGState),
 VMSTATE_UINT32(waiting_rov, IMXTimerGState),
 VMSTATE_PTIMER(timer, IMXTimerGState),
@@ -156,7 +164,6 @@ static void imx_timerg_update(IMXTimerGState *s)
 s->ir & GPT_SR_ROV ? "ROV" : "",
 s->cr & GPT_CR_EN ? "CR_EN" : "Not Enabled");
 
-
 qemu_set_irq(s->irq, (s->cr & GPT_CR_EN) && flags);
 }
 
@@ -221,6 +228,21 @@ static uint64_t imx_timerg_read(void *opaque, hwaddr 
offset,
 DPRINTF(" ocr1 = %x\n", s->ocr1);
 return s->ocr1;
 
+case 5: /* Output Compare Register 2 */
+DPRINTF(" ocr2 = %x\n", s->ocr2);
+return s->ocr2;
+
+case 6: /* Output Compare Register 3 */
+DPRINTF(" ocr3 = %x\n", s->ocr3);
+return s->ocr3;
+
+case 7: /* input Capture Register 1 */
+DPRINTF(" icr1 = %x\n", s->icr1);
+return s->icr1;
+
+case 8: /* input Capture Register 2 */
+DPRINTF(" icr2 = %x\n", s->icr2);
+return s->icr2;
 
 case 9: /* cnt */
 imx_timerg_update_counts(s);
@@ -230,6 +252,7 @@ static uint64_t imx_timerg_read(void *opaque, hwaddr offset,
 
 IPRINTF("imx_timerg_read: Bad offset %x\n",
 (int)offset >> 2);
+
 return 0;
 }
 
@@ -240,14 +263,19 @@ static void imx_timerg_reset(DeviceState *dev)
 /*
  * Soft reset doesn't touch some bits; hard reset clears them
  */
-s->cr &= ~(GPT_CR_EN|GPT_CR_DOZEN|GPT_CR_WAITEN|GPT_CR_DBGEN);
+s->cr &= 
~(GPT_CR_EN|GPT_CR_ENMOD|GPT_CR_STOPEN|GPT_CR_DOZEN|GPT_CR_WAITEN|GPT_CR_DBGEN);
 s->sr = 0;
 s->pr = 0;
 s->ir = 0;
 s->cnt = 0;
 s->ocr1 = TIMER_MAX;
+s->ocr2 = TIMER_MAX;
+s->ocr3 = TIMER_MAX;
+s->icr1 = 0;
+s->icr2 = 0;
 ptimer_stop(s->timer);
 ptimer_set_limit(s->timer, TIMER_MAX, 1);
+ptimer_set_count(s->timer, TIMER_MAX);
 imx_timerg_set_freq(s);
 }
 
@@ -323,6 +351,8 @@ static void imx_timerg_write(void *opaque, hwaddr offset,
 s->ocr1 = value;
 return;
 
+case 5: /* OCR2 -- output compare register */
+case 6: /* OCR3 -- output compare register */
 default:
 IPRINTF("imx_timerg_write: Bad offset %x\n",
 (int)offset >> 2);
@@ -411,7 +441,7 @@ static int imx_timerg_init(SysBusDevice *dev)
 #define CR_SWR  (1 << 16)
 #define CR_IOVW (1 << 17)
 #define CR_DBGEN(1 << 18)
-#define CR_EPIT (1 << 19)
+#define CR_WAITEN   (1 << 19)
 #define CR_DOZEN(1 << 20)
 #define CR_STOPEN   (1 << 21)
 #define CR_CLKSRC_SHIFT (24)
@@ -423,24 +453,26 @@ static int imx_timerg_init(SysBusDevice *dev)
  * These are typical.
  */
 static const IMXClk imx_timerp_clocks[] =  {
-0,/* disabled */
-IPG, /* ipg_clk, ~532MHz */
-IPG, /* ipg_clk_highfreq */
-CLK_32k,/* ipg_clk_32k -- ~32kHz */
+0,/* 00 disabled */
+IPG,  /* 01 ipg_clk, ~532MHz */
+IPG,  /* 10 ipg_clk_highfreq */
+CLK_32k,  /* 11 ipg_clk_32k -- ~32kHz */
 };
 
 typedef struct {
 SysBusDevice busdev;
-ptimer_state *timer;
+ptimer_state *timer_reload;
+ptimer_state *timer_cmp;
 MemoryRegion iomem;
 DeviceState *ccm;
 
 uint32_t cr;
+uint32_t sr;
 uint32_t lr;
 uint32_t cmp;
+uint32_t cnt;
 
 uint32_t 

[Qemu-devel] [PATCH v3] i.MX: implement a more correct version of EPIT timer.

2013-04-10 Thread Jean-Christophe DUBOIS
This patch is providing a complete version of the EPIT timer.

Note, however that the GPT timer in the same file is still not
complete.

Signed-off-by: Jean-Christophe DUBOIS 

Change from v2:
  - change all version number in VMSTATE struct.

Change from v1:
  - bump up the version number on VMSTATE struct
  - fix comment
---
 hw/timer/imx_timer.c |  261 +-
 1 file changed, 197 insertions(+), 64 deletions(-)

diff --git a/hw/timer/imx_timer.c b/hw/timer/imx_timer.c
index 03197e3..f981684 100644
--- a/hw/timer/imx_timer.c
+++ b/hw/timer/imx_timer.c
@@ -95,6 +95,10 @@ typedef struct {
 uint32_t sr;
 uint32_t ir;
 uint32_t ocr1;
+uint32_t ocr2;
+uint32_t ocr3;
+uint32_t icr1;
+uint32_t icr2;
 uint32_t cnt;
 
 uint32_t waiting_rov;
@@ -103,15 +107,19 @@ typedef struct {
 
 static const VMStateDescription vmstate_imx_timerg = {
 .name = "imx-timerg",
-.version_id = 1,
-.minimum_version_id = 1,
-.minimum_version_id_old = 1,
+.version_id = 2,
+.minimum_version_id = 2,
+.minimum_version_id_old = 2,
 .fields  = (VMStateField[]) {
 VMSTATE_UINT32(cr, IMXTimerGState),
 VMSTATE_UINT32(pr, IMXTimerGState),
 VMSTATE_UINT32(sr, IMXTimerGState),
 VMSTATE_UINT32(ir, IMXTimerGState),
 VMSTATE_UINT32(ocr1, IMXTimerGState),
+VMSTATE_UINT32(ocr2, IMXTimerGState),
+VMSTATE_UINT32(ocr3, IMXTimerGState),
+VMSTATE_UINT32(icr1, IMXTimerGState),
+VMSTATE_UINT32(icr2, IMXTimerGState),
 VMSTATE_UINT32(cnt, IMXTimerGState),
 VMSTATE_UINT32(waiting_rov, IMXTimerGState),
 VMSTATE_PTIMER(timer, IMXTimerGState),
@@ -156,7 +164,6 @@ static void imx_timerg_update(IMXTimerGState *s)
 s->ir & GPT_SR_ROV ? "ROV" : "",
 s->cr & GPT_CR_EN ? "CR_EN" : "Not Enabled");
 
-
 qemu_set_irq(s->irq, (s->cr & GPT_CR_EN) && flags);
 }
 
@@ -221,6 +228,21 @@ static uint64_t imx_timerg_read(void *opaque, hwaddr 
offset,
 DPRINTF(" ocr1 = %x\n", s->ocr1);
 return s->ocr1;
 
+case 5: /* Output Compare Register 2 */
+DPRINTF(" ocr2 = %x\n", s->ocr2);
+return s->ocr2;
+
+case 6: /* Output Compare Register 3 */
+DPRINTF(" ocr3 = %x\n", s->ocr3);
+return s->ocr3;
+
+case 7: /* input Capture Register 1 */
+DPRINTF(" icr1 = %x\n", s->icr1);
+return s->icr1;
+
+case 8: /* input Capture Register 2 */
+DPRINTF(" icr2 = %x\n", s->icr2);
+return s->icr2;
 
 case 9: /* cnt */
 imx_timerg_update_counts(s);
@@ -230,6 +252,7 @@ static uint64_t imx_timerg_read(void *opaque, hwaddr offset,
 
 IPRINTF("imx_timerg_read: Bad offset %x\n",
 (int)offset >> 2);
+
 return 0;
 }
 
@@ -240,14 +263,19 @@ static void imx_timerg_reset(DeviceState *dev)
 /*
  * Soft reset doesn't touch some bits; hard reset clears them
  */
-s->cr &= ~(GPT_CR_EN|GPT_CR_DOZEN|GPT_CR_WAITEN|GPT_CR_DBGEN);
+s->cr &= 
~(GPT_CR_EN|GPT_CR_ENMOD|GPT_CR_STOPEN|GPT_CR_DOZEN|GPT_CR_WAITEN|GPT_CR_DBGEN);
 s->sr = 0;
 s->pr = 0;
 s->ir = 0;
 s->cnt = 0;
 s->ocr1 = TIMER_MAX;
+s->ocr2 = TIMER_MAX;
+s->ocr3 = TIMER_MAX;
+s->icr1 = 0;
+s->icr2 = 0;
 ptimer_stop(s->timer);
 ptimer_set_limit(s->timer, TIMER_MAX, 1);
+ptimer_set_count(s->timer, TIMER_MAX);
 imx_timerg_set_freq(s);
 }
 
@@ -323,6 +351,8 @@ static void imx_timerg_write(void *opaque, hwaddr offset,
 s->ocr1 = value;
 return;
 
+case 5: /* OCR2 -- output compare register */
+case 6: /* OCR3 -- output compare register */
 default:
 IPRINTF("imx_timerg_write: Bad offset %x\n",
 (int)offset >> 2);
@@ -411,7 +441,7 @@ static int imx_timerg_init(SysBusDevice *dev)
 #define CR_SWR  (1 << 16)
 #define CR_IOVW (1 << 17)
 #define CR_DBGEN(1 << 18)
-#define CR_EPIT (1 << 19)
+#define CR_WAITEN   (1 << 19)
 #define CR_DOZEN(1 << 20)
 #define CR_STOPEN   (1 << 21)
 #define CR_CLKSRC_SHIFT (24)
@@ -423,24 +453,26 @@ static int imx_timerg_init(SysBusDevice *dev)
  * These are typical.
  */
 static const IMXClk imx_timerp_clocks[] =  {
-0,/* disabled */
-IPG, /* ipg_clk, ~532MHz */
-IPG, /* ipg_clk_highfreq */
-CLK_32k,/* ipg_clk_32k -- ~32kHz */
+0,/* 00 disabled */
+IPG,  /* 01 ipg_clk, ~532MHz */
+IPG,  /* 10 ipg_clk_highfreq */
+CLK_32k,  /* 11 ipg_clk_32k -- ~32kHz */
 };
 
 typedef struct {
 SysBusDevice busdev;
-ptimer_state *timer;
+ptimer_state *timer_reload;
+ptimer_state *timer_cmp;

Re: [Qemu-devel] [PATCH v2] i.MX: implement a more correct version of EPIT timer.

2013-04-10 Thread Jean-Christophe DUBOIS

On 04/10/2013 10:07 PM, Peter Maydell wrote:

On 10 April 2013 21:02, Jean-Christophe DUBOIS  wrote:

  static const VMStateDescription vmstate_imx_timerp = {
  .name = "imx-timerp",
-.version_id = 1,
+.version_id = 2,
  .minimum_version_id = 1,
  .minimum_version_id_old = 1,

I said "all the version id fields" but you've only changed one.
(I'm assuming you don't want to try to support old-to-new
migration, which is the case where the minimum and current IDs
differ; in that case you need to annotate fields with the
version they appear in and you can't delete or rename them.)
To be honest with you Peter, I don't even know how these state 
information are used.


I never practiced VM migration with Qemu for now.

Actually if you had a few pointers to a decent explanation, I would be 
interested.


JC


thanks
-- PMM






[Qemu-devel] [PATCH] Add i.MX25 3DS evaluation board support

2013-04-18 Thread Jean-Christophe DUBOIS
This is an initial port of the Freescale i.MX25 processor.

This allow a minimally configured linux kernel to boot on Qemu.

Signed-off-by: Jean-Christophe DUBOIS 
---
 hw/arm/Makefile.objs |1 +
 hw/arm/imx25_3ds.c   |  199 ++
 2 files changed, 200 insertions(+)
 create mode 100644 hw/arm/imx25_3ds.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 9e3a06f..2f4280d 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -2,6 +2,7 @@ obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
 obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
 obj-y += omap_sx1.o palm.o pic_cpu.o realview.o spitz.o stellaris.o
 obj-y += tosa.o versatilepb.o vexpress.o xilinx_zynq.o z2.o
+obj-y += imx25_3ds.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
 obj-y += omap1.o omap2.o strongarm.o
diff --git a/hw/arm/imx25_3ds.c b/hw/arm/imx25_3ds.c
new file mode 100644
index 000..6ba0f9c
--- /dev/null
+++ b/hw/arm/imx25_3ds.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2013 Jean-Christophe Dubois
+ *
+ * 3Dstack Board System emulation.
+ *
+ * Based on hw/arm/kzm.c
+ *
+ * Copyright (c) 2008 OKL and 2011 NICTA
+ * Written by Hans at OK-Labs
+ * Updated by Peter Chubb.
+ *
+ * This code is licensed under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a i.MX25 3D-Stack PDK board
+ */
+
+#include "hw/sysbus.h"
+#include "exec/address-spaces.h"
+#include "hw/hw.h"
+#include "hw/arm.h"
+#include "hw/arm/devices.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+#include "hw/char/serial.h"
+#include "hw/arm/imx.h"
+
+/* Memory map for 3D-Stack Emulation Baseboard:
+ * 0x-0x3fff 16k secure ROM   IGNORED
+ * 0x4000-0x00403fff Reserved IGNORED
+ * 0x00404000-0x00408fff ROM  IGNORED
+ * 0x00409000-0x0fff Reserved IGNORED
+ * 0x1000-0x1fff Reserved IGNORED
+ * 0x2000-0x2fff Reserved IGNORED
+ * 0x3000-0x3fff Reserved IGNORED
+ * 0x4000-0x43ef Reserved IGNORED
+ * 0x43f0-0x6fff I.MX25 Internal Register Space
+ *   0x43f0 IO_AREA0
+ *   0x43f9 UART1 EMULATED
+ *   0x43f94000 UART2 EMULATED
+ *   0x43fb UART4 IGNORED
+ *   0x43fb4000 UART5 IGNORED
+ *   0x5000c000 UART3 IGNORED
+ *   0x53f8 CCM   EMULATED
+ *   0x53f84000 GPT 4 EMULATED
+ *   0x53f88000 GPT 3 EMULATED
+ *   0x53f8c000 GPT 2 EMULATED
+ *   0x53f9 GPT 1 EMULATED
+ *   0x53f94000 PIT 1 EMULATED
+ *   0x53f98000 PIT 2 EMULATED
+ *   0x6800 ASIC  EMULATED
+ * 0x7800-0x7801 SRAM EMULATED
+ * 0x7802-0x7fff SRAM AliasingEMULATED
+ * 0x8000-0x87ff RAM  EMULATED
+ * 0x8800-0x8fff RAM Aliasing EMULATED
+ * 0x9000-0x9fff RAM  IGNORED
+ * 0xa000-0xa7ff FlashIGNORED
+ * 0xa800-0xafff FlashIGNORED
+ * 0xb000-0xb1ff SRAM IGNORED
+ * 0xb200-0xb3ff SRAM IGNORED
+ * 0xb400-0xb5ff CS4  IGNORED
+ * 0xb600-0xb8000fff Reserved IGNORED
+ * 0xb8001000-0xb8001fff SDRM CTRL regIGNORED
+ * 0xb8002000-0xb8002fff WEIM CTRL regIGNORED
+ * 0xb8003000-0xb8003fff M3IF CTRL regIGNORED
+ * 0xb8004000-0xb8004fff EMI CTRL reg IGNORED
+ * 0xb8005000-0xbaff Reserved IGNORED
+ * 0xbb00-0xbb000fff NAND flash area buf  IGNORED
+ * 0xbb001000-0xbb0011ff NAND flash reserved  IGNORED
+ * 0xbb001200-0xbb001dff Reserved IGNORED
+ * 0xbb001e00-0xbb001fff NAN flash CTRL reg   IGNORED
+ * 0xbb012000-0xbfff Reserved IGNORED
+ * 0xc000-0x Reserved IGNORED
+ */
+
+#define IMX25_SRAM_ADDRESS (0x7800)
+#define IMX25_SRAMSIZE (128*1024)
+#define IMX25_CS_SRAMSIZE  (128*1024*1024)
+#define IMX25_3DS_ADDRESS  (0x8000)
+#define IMX25_CS_RAMSIZE   (256*1024*1024)
+
+static struct arm_boot_info imx25_3ds_binfo = {
+.loader_start = IMX25_3DS_ADDRESS,
+.board_id = 1771,
+};
+
+static void imx25_3ds_init(QEMUMachineInitArgs *args)
+{
+ram_addr_t ram_size = args->ram_size;
+const 

[Qemu-devel] [PATCH 1/2] Add i.MX FEC ethernet controller

2013-04-26 Thread Jean-Christophe DUBOIS
This port is based on the cold fire FEC emulator.

A generic PHY was added (borrowed from lan9118).

The buffer management is also modified as buffers are
slightly different between coldfire and i.MX.

Signed-off-by: Jean-Christophe DUBOIS 
---
 default-configs/arm-softmmu.mak |   1 +
 hw/net/Makefile.objs|   1 +
 hw/net/imx_fec.c| 746 
 include/hw/arm/imx.h|   1 +
 4 files changed, 749 insertions(+)
 create mode 100644 hw/net/imx_fec.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 27cbe3d..b3a0207 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -28,6 +28,7 @@ CONFIG_SSI_SD=y
 CONFIG_SSI_M25P80=y
 CONFIG_LAN9118=y
 CONFIG_SMC91C111=y
+CONFIG_IMX_FEC=y
 CONFIG_DS1338=y
 CONFIG_PFLASH_CFI01=y
 CONFIG_PFLASH_CFI02=y
diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index 951cca3..5c84727 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -18,6 +18,7 @@ common-obj-$(CONFIG_OPENCORES_ETH) += opencores_eth.o
 common-obj-$(CONFIG_XGMAC) += xgmac.o
 common-obj-$(CONFIG_MIPSNET) += mipsnet.o
 common-obj-$(CONFIG_XILINX_AXI) += xilinx_axienet.o
+common-obj-$(CONFIG_IMX_FEC) += imx_fec.o
 
 common-obj-$(CONFIG_CADENCE) += cadence_gem.o
 common-obj-$(CONFIG_STELLARIS_ENET) += stellaris_enet.o
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
new file mode 100644
index 000..7ce34b7
--- /dev/null
+++ b/hw/net/imx_fec.c
@@ -0,0 +1,746 @@
+/*
+ * i.MX Fast Ethernet Controller emulation.
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois.
+ *
+ * Based on Coldfire Fast Ethernet Controller emulation.
+ *
+ * Copyright (c) 2007 CodeSourcery.
+ *
+ * This code is licensed under the GPL
+ */
+#include "hw/sysbus.h"
+#include "net/net.h"
+#include "hw/devices.h"
+
+/* For crc32 */
+#include 
+
+#include "hw/arm/imx.h"
+
+//#define DEBUG_FEC 1
+//#define DEBUG_PHY 1
+
+#ifdef DEBUG_FEC
+#define DPRINTF(fmt, ...) \
+do { printf("imx_fec: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) do {} while(0)
+#endif
+
+#ifdef DEBUG_PHY
+#define DPPRINTF(fmt, ...) \
+do { printf("imx_fec_phy: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DPPRINTF(fmt, ...) do {} while(0)
+#endif
+
+#define FEC_MAX_FRAME_SIZE 2032
+
+typedef struct {
+SysBusDevice busdev;
+NICState *nic;
+NICConf conf;
+qemu_irq irq;
+MemoryRegion iomem;
+
+uint32_t irq_state;
+uint32_t eir;
+uint32_t eimr;
+uint32_t rx_enabled;
+uint32_t rx_descriptor;
+uint32_t tx_descriptor;
+uint32_t ecr;
+uint32_t mmfr;
+uint32_t mscr;
+uint32_t mibc;
+uint32_t rcr;
+uint32_t tcr;
+uint32_t tfwr;
+uint32_t frsr;
+uint32_t erdsr;
+uint32_t etdsr;
+uint32_t emrbr;
+uint32_t miigsk_cfgr;
+uint32_t miigsk_enr;
+
+uint32_t phy_status;
+uint32_t phy_control;
+uint32_t phy_advertise;
+uint32_t phy_int;
+uint32_t phy_int_mask;
+} imx_fec_state;
+
+static const VMStateDescription vmstate_imx_fec = {
+.name = "fec",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(irq_state, imx_fec_state),
+VMSTATE_UINT32(eir, imx_fec_state),
+VMSTATE_UINT32(eimr, imx_fec_state),
+VMSTATE_UINT32(rx_enabled, imx_fec_state),
+VMSTATE_UINT32(rx_descriptor, imx_fec_state),
+VMSTATE_UINT32(tx_descriptor, imx_fec_state),
+VMSTATE_UINT32(ecr, imx_fec_state),
+VMSTATE_UINT32(mmfr, imx_fec_state),
+VMSTATE_UINT32(mscr, imx_fec_state),
+VMSTATE_UINT32(mibc, imx_fec_state),
+VMSTATE_UINT32(rcr, imx_fec_state),
+VMSTATE_UINT32(tcr, imx_fec_state),
+VMSTATE_UINT32(tfwr, imx_fec_state),
+VMSTATE_UINT32(frsr, imx_fec_state),
+VMSTATE_UINT32(erdsr, imx_fec_state),
+VMSTATE_UINT32(etdsr, imx_fec_state),
+VMSTATE_UINT32(emrbr, imx_fec_state),
+VMSTATE_UINT32(miigsk_cfgr, imx_fec_state),
+VMSTATE_UINT32(miigsk_enr, imx_fec_state),
+
+VMSTATE_UINT32(phy_status, imx_fec_state),
+VMSTATE_UINT32(phy_control, imx_fec_state),
+VMSTATE_UINT32(phy_advertise, imx_fec_state),
+VMSTATE_UINT32(phy_int, imx_fec_state),
+VMSTATE_UINT32(phy_int_mask, imx_fec_state),
+VMSTATE_END_OF_LIST()
+}
+};
+
+#define PHY_INT_ENERGYON(1 << 7)
+#define PHY_INT_AUTONEG_COMPLETE(1 << 6)
+#define PHY_INT_FAULT   (1 << 5)
+#define PHY_INT_DOWN(1 << 4)
+#define PHY_INT_AUTONEG_LP  (1 << 3)
+#define PHY_INT_PARFAULT(1 << 2)
+#define PHY_INT_AUTONEG_PAGE(1 << 1)
+
+static void imx_fec_update(imx_fec_state *s);
+
+/*
+ * The MII phy could raise a GPIO to the processor which in turn
+ * could be handled as

[Qemu-devel] [PATCH 2/2] Add i.MX25 3DS evaluation board support

2013-04-26 Thread Jean-Christophe DUBOIS
This is an initial port of the Freescale i.MX25 processor.

This allow a minimally configured linux kernel to boot on Qemu.

It also handle the newly added FEC ethernet device.

Signed-off-by: Jean-Christophe DUBOIS 
---
 hw/arm/Makefile.objs |   1 +
 hw/arm/imx25_3ds.c   | 218 +++
 2 files changed, 219 insertions(+)
 create mode 100644 hw/arm/imx25_3ds.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 9e3a06f..2f4280d 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -2,6 +2,7 @@ obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
 obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
 obj-y += omap_sx1.o palm.o pic_cpu.o realview.o spitz.o stellaris.o
 obj-y += tosa.o versatilepb.o vexpress.o xilinx_zynq.o z2.o
+obj-y += imx25_3ds.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
 obj-y += omap1.o omap2.o strongarm.o
diff --git a/hw/arm/imx25_3ds.c b/hw/arm/imx25_3ds.c
new file mode 100644
index 000..9de4941
--- /dev/null
+++ b/hw/arm/imx25_3ds.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2013 Jean-Christophe Dubois
+ *
+ * 3Dstack Board System emulation.
+ *
+ * Based on hw/arm/kzm.c
+ *
+ * Copyright (c) 2008 OKL and 2011 NICTA
+ * Written by Hans at OK-Labs
+ * Updated by Peter Chubb.
+ *
+ * This code is licensed under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a i.MX25 3D-Stack PDK board
+ */
+
+#include "hw/sysbus.h"
+#include "exec/address-spaces.h"
+#include "hw/hw.h"
+#include "hw/arm/arm.h"
+#include "hw/devices.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+#include "hw/char/serial.h"
+#include "hw/arm/imx.h"
+
+/* Memory map for 3D-Stack Emulation Baseboard:
+ * 0x-0x3fff 16k ROM  IGNORED
+ * 0x4000-0x00403fff Reserved IGNORED
+ * 0x00404000-0x00408fff 20k ROM  IGNORED
+ * 0x00409000-0x0fff Reserved IGNORED
+ * 0x1000-0x1fff Reserved IGNORED
+ * 0x2000-0x2fff Reserved IGNORED
+ * 0x3000-0x3fff Reserved IGNORED
+ * 0x4000-0x43ef Reserved IGNORED
+ * 0x43f0-0x6fff I.MX25 Internal Register Space
+ *   0x43f0 IO_AREA0
+ *   0x43f9 UART1 EMULATED
+ *   0x43f94000 UART2 EMULATED
+ *   0x43fb UART4 IGNORED
+ *   0x43fb4000 UART5 IGNORED
+ *   0x5000c000 UART3 IGNORED
+ *   0x53f8 CCM   EMULATED
+ *   0x53f84000 GPT 4 EMULATED
+ *   0x53f88000 GPT 3 EMULATED
+ *   0x53f8c000 GPT 2 EMULATED
+ *   0x53f9 GPT 1 EMULATED
+ *   0x53f94000 PIT 1 EMULATED
+ *   0x53f98000 PIT 2 EMULATED
+ *   0x6800 ASIC  EMULATED
+ * 0x7800-0x7801 SRAM EMULATED
+ * 0x7802-0x7fff SRAM AliasingEMULATED
+ * 0x8000-0x87ff RAM + Alias  EMULATED
+ * 0x9000-0x9fff RAM + Alias  EMULATED
+ * 0xa000-0xa7ff FlashIGNORED
+ * 0xa800-0xafff FlashIGNORED
+ * 0xb000-0xb1ff SRAM IGNORED
+ * 0xb200-0xb3ff SRAM IGNORED
+ * 0xb400-0xb5ff CS4  IGNORED
+ * 0xb600-0xb8000fff Reserved IGNORED
+ * 0xb8001000-0xb8001fff SDRAM CTRL reg   IGNORED
+ * 0xb8002000-0xb8002fff WEIM CTRL regIGNORED
+ * 0xb8003000-0xb8003fff M3IF CTRL regIGNORED
+ * 0xb8004000-0xb8004fff EMI CTRL reg IGNORED
+ * 0xb8005000-0xbaff Reserved IGNORED
+ * 0xbb00-0xbb000fff NAND flash area buf  IGNORED
+ * 0xbb001000-0xbb0011ff NAND flash reserved  IGNORED
+ * 0xbb001200-0xbb001dff Reserved IGNORED
+ * 0xbb001e00-0xbb001fff NAN flash CTRL reg   IGNORED
+ * 0xbb012000-0xbfff Reserved IGNORED
+ * 0xc000-0x Reserved IGNORED
+ */
+
+#define IMX25_SRAM_ADDRESS  (0x7800)
+#define IMX25_SRAMSIZE  (128*1024)
+#define IMX25_CS_SRAMSIZE   (128*1024*1024)
+#define IMX25_3DS_ADDRESS   (0x8000)
+#define IMX25_CS_RAMSIZE(256*1024*1024)
+
+static struct arm_boot_info imx25_3ds_binfo = {
+.loader_start = IMX25_3DS_ADDRESS,
+.board_id = 1771,
+};
+
+static void imx25_3ds_init(QEMUMachineInitArgs *args)
+{
+int i;
+ram_addr_t ram_size = args->ram_size;
+const char *cpu_model = args->cpu_model;
+const char *kernel_filename = args->kernel_filename;
+const char *kernel_cmdline = args->kernel_cmdline;
+const char *initrd_filename

[Qemu-devel] [PATCH][ARM] Fix C15 FSR (C5) domain setting

2011-11-03 Thread Jean-Christophe DUBOIS

During Xvisor development, it was noted that qemu did not return
the correct domain value in the C15 [Data] FSR register (C5).

This patch is a proposal to fix it.

Signed-off-by: Jean-Christophe DUBOIS
---

--- qemu-0.15.1.org/target-arm/helper.c2011-10-12 18:41:43.0 
+0200

+++ qemu-0.15.1/target-arm/helper.c2011-11-04 00:49:03.247062518 +0100
@@ -924,12 +924,12 @@
 /* Check section/page access permissions.
Returns the page protection flags, or zero if the access is not
permitted.  */
-static inline int check_ap(CPUState *env, int ap, int domain, int 
access_type,
+static inline int check_ap(CPUState *env, int ap, int domain_prot, int 
access_type,

int is_user)
 {
   int prot_ro;

-  if (domain == 3)
+  if (domain_prot == 3)
 return PAGE_READ | PAGE_WRITE;

   if (access_type == 1)
@@ -996,6 +996,7 @@
 int type;
 int ap;
 int domain;
+int domain_prot;
 uint32_t phys_addr;

 /* Pagetable walk.  */
@@ -1003,13 +1004,14 @@
 table = get_level1_table_address(env, address);
 desc = ldl_phys(table);
 type = (desc & 3);
-domain = (env->cp15.c3 >> ((desc >> 4) & 0x1e)) & 3;
+domain = (desc >> 5) & 0x0f;
+domain_prot = (env->cp15.c3 >> (domain * 2)) & 3;
 if (type == 0) {
 /* Section translation fault.  */
 code = 5;
 goto do_fault;
 }
-if (domain == 0 || domain == 2) {
+if (domain_prot == 0 || domain_prot == 2) {
 if (type == 2)
 code = 9; /* Section domain fault.  */
 else
@@ -1067,7 +1069,7 @@
 }
 code = 15;
 }
-*prot = check_ap(env, ap, domain, access_type, is_user);
+*prot = check_ap(env, ap, domain_prot, access_type, is_user);
 if (!*prot) {
 /* Access permission fault.  */
 goto do_fault;
@@ -1090,6 +1092,7 @@
 int type;
 int ap;
 int domain;
+int domain_prot;
 uint32_t phys_addr;

 /* Pagetable walk.  */
@@ -1107,10 +1110,10 @@
 domain = 0;
 } else {
 /* Section or page.  */
-domain = (desc >> 4) & 0x1e;
+domain = (desc >> 5) & 0x0f;
 }
-domain = (env->cp15.c3 >> domain) & 3;
-if (domain == 0 || domain == 2) {
+domain_prot = (env->cp15.c3 >> (domain * 2)) & 3;
+if (domain_prot == 0 || domain_prot == 2) {
 if (type == 2)
 code = 9; /* Section domain fault.  */
 else
@@ -1155,7 +1158,7 @@
 }
 code = 15;
 }
-if (domain == 3) {
+if (domain_prot == 3) {
 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 } else {
 if (xn && access_type == 2)
@@ -1167,7 +1170,7 @@
 code = (code == 15) ? 6 : 3;
 goto do_fault;
 }
-*prot = check_ap(env, ap, domain, access_type, is_user);
+*prot = check_ap(env, ap, domain_prot, access_type, is_user);
 if (!*prot) {
 /* Access permission fault.  */
 goto do_fault;




[Qemu-devel] [PATCH] arm: Fix CP15 FSR (C5) domain setting

2011-11-04 Thread Jean-Christophe DUBOIS

During Xvisor development, it was noted that qemu did not return
the correct domain value in the Cp15 [Data] FSR register (C5).

This patch is a proposal to fix it.

Signed-off-by: Jean-Christophe DUBOIS 
---

--- qemu-0.15.1.org/target-arm/helper.c2011-10-12 18:41:43.0 
+0200

+++ qemu-0.15.1/target-arm/helper.c2011-11-04 00:49:03.247062518 +0100
@@ -924,12 +924,12 @@
 /* Check section/page access permissions.
Returns the page protection flags, or zero if the access is not
permitted.  */
-static inline int check_ap(CPUState *env, int ap, int domain, int 
access_type,
+static inline int check_ap(CPUState *env, int ap, int domain_prot, int 
access_type,

int is_user)
 {
   int prot_ro;

-  if (domain == 3)
+  if (domain_prot == 3)
 return PAGE_READ | PAGE_WRITE;

   if (access_type == 1)
@@ -996,6 +996,7 @@
 int type;
 int ap;
 int domain;
+int domain_prot;
 uint32_t phys_addr;

 /* Pagetable walk.  */
@@ -1003,13 +1004,14 @@
 table = get_level1_table_address(env, address);
 desc = ldl_phys(table);
 type = (desc & 3);
-domain = (env->cp15.c3 >> ((desc >> 4) & 0x1e)) & 3;
+domain = (desc >> 5) & 0x0f;
+domain_prot = (env->cp15.c3 >> (domain * 2)) & 3;
 if (type == 0) {
 /* Section translation fault.  */
 code = 5;
 goto do_fault;
 }
-if (domain == 0 || domain == 2) {
+if (domain_prot == 0 || domain_prot == 2) {
 if (type == 2)
 code = 9; /* Section domain fault.  */
 else
@@ -1067,7 +1069,7 @@
 }
 code = 15;
 }
-*prot = check_ap(env, ap, domain, access_type, is_user);
+*prot = check_ap(env, ap, domain_prot, access_type, is_user);
 if (!*prot) {
 /* Access permission fault.  */
 goto do_fault;
@@ -1090,6 +1092,7 @@
 int type;
 int ap;
 int domain;
+int domain_prot;
 uint32_t phys_addr;

 /* Pagetable walk.  */
@@ -1107,10 +1110,10 @@
 domain = 0;
 } else {
 /* Section or page.  */
-domain = (desc >> 4) & 0x1e;
+domain = (desc >> 5) & 0x0f;
 }
-domain = (env->cp15.c3 >> domain) & 3;
-if (domain == 0 || domain == 2) {
+domain_prot = (env->cp15.c3 >> (domain * 2)) & 3;
+if (domain_prot == 0 || domain_prot == 2) {
 if (type == 2)
 code = 9; /* Section domain fault.  */
 else
@@ -1155,7 +1158,7 @@
 }
 code = 15;
 }
-if (domain == 3) {
+if (domain_prot == 3) {
 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 } else {
 if (xn && access_type == 2)
@@ -1167,7 +1170,7 @@
 code = (code == 15) ? 6 : 3;
 goto do_fault;
 }
-*prot = check_ap(env, ap, domain, access_type, is_user);
+*prot = check_ap(env, ap, domain_prot, access_type, is_user);
 if (!*prot) {
 /* Access permission fault.  */
 goto do_fault;




[Qemu-devel] [PATCH] Fix reset bit for realview platform.

2011-11-04 Thread Jean-Christophe DUBOIS
According to realview documentation [1], the bit used to reset the board
is bit 2 and not bit 8.

This is also in sync with Linux source code [2].

[1] 
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0417d/BBACIGAD.html
[2] 
http://lxr.free-electrons.com/source/arch/arm/mach-realview/realview_pba8.c#L274

Signed-off-by: Jean-Christophe DUBOIS 
---
 hw/arm_sysctl.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
index 17cf6f7..aef271e 100644
--- a/hw/arm_sysctl.c
+++ b/hw/arm_sysctl.c
@@ -237,7 +237,7 @@ static void arm_sysctl_write(void *opaque, 
target_phys_addr_t offset,
 }
 if (s->lockval == LOCK_VALUE) {
 s->resetlevel = val;
-if (val & 0x100)
+if (val & 0x04)
 qemu_system_reset_request ();
 }
 break;
-- 
1.7.5.4




[Qemu-devel] [PATCH v2] realview: fix reset bit depending on platform

2011-11-05 Thread Jean-Christophe DUBOIS
Depending on the considered baseboard the bit used to
reset the platform is different.

Here is the list of considered Realview/Versatile platforms:

Realview/Versatile AB for ARM926EJ-S: BOARD_ID = 0x100 = BOARD_ID_PB926
http://infocenter.arm.com/help/topic/com.arm.doc.dui0225d/CACCIFGI.html

RealView Emulation Baseboard: BOARD_ID = 0x140 = BOARD_ID_EB
No reset register

RealView PB for ARM1176JZF-S: BOARD_ID = 0x147 = BOARD_ID_PB1176
http://infocenter.arm.com/help/topic/com.arm.doc.dui0425f/Caccifgi.html

RealView PB for ARM11 MPCore: BOARD_ID = 0x159 = BOARD_ID_PB11MP
http://infocenter.arm.com/help/topic/com.arm.doc.dui0351e/CACCHBFB.html

RealView PB for Cortex-A8: BOARD_ID = 0x178 = BOARD_ID_PBA8
http://infocenter.arm.com/help/topic/com.arm.doc.dui0417d/BBACIGAD.html

RealView PB for Cortex-A9: BOARD_ID = 0x182 = BOARD_ID_PBX
http://infocenter.arm.com/help/topic/com.arm.doc.dui0440b/CACCHBFB.html

Motherboard Express µATX: BOARD_ID = 0x190 = BOARD_ID_VEXPRESS
No reset register

v2:
- Add multiple boards support
- fix coding style
- Added a BOARD_ID descriptor for unsupported baseboards.

Signed-off-by: Jean-Christophe DUBOIS 
---
 hw/arm_sysctl.c |   43 ---
 1 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
index 17cf6f7..8f07fd5 100644
--- a/hw/arm_sysctl.c
+++ b/hw/arm_sysctl.c
@@ -63,6 +63,8 @@ static const VMStateDescription vmstate_arm_sysctl = {
  */
 #define BOARD_ID_PB926 0x100
 #define BOARD_ID_EB 0x140
+#define BOARD_ID_PB1176 0x147
+#define BOARD_ID_PB11MP 0x159
 #define BOARD_ID_PBA8 0x178
 #define BOARD_ID_PBX 0x182
 #define BOARD_ID_VEXPRESS 0x190
@@ -143,7 +145,8 @@ static uint64_t arm_sysctl_read(void *opaque, 
target_phys_addr_t offset,
 case 0x58: /* BOOTCS */
 return 0;
 case 0x5c: /* 24MHz */
-return muldiv64(qemu_get_clock_ns(vm_clock), 2400, 
get_ticks_per_sec());
+return muldiv64(qemu_get_clock_ns(vm_clock), 2400,
+get_ticks_per_sec());
 case 0x60: /* MISC */
 return 0;
 case 0x84: /* PROCID0 */
@@ -184,7 +187,7 @@ static uint64_t arm_sysctl_read(void *opaque, 
target_phys_addr_t offset,
 return s->sys_cfgstat;
 default:
 bad_reg:
-printf ("arm_sysctl_read: Bad register offset 0x%x\n", (int)offset);
+printf("arm_sysctl_read: Bad register offset 0x%x\n", (int)offset);
 return 0;
 }
 }
@@ -205,10 +208,11 @@ static void arm_sysctl_write(void *opaque, 
target_phys_addr_t offset,
 /* ??? */
 break;
 case 0x20: /* LOCK */
-if (val == LOCK_VALUE)
+if (val == LOCK_VALUE) {
 s->lockval = val;
-else
+} else {
 s->lockval = val & 0x7fff;
+}
 break;
 case 0x28: /* CFGDATA1 */
 /* ??? Need to implement this.  */
@@ -231,15 +235,32 @@ static void arm_sysctl_write(void *opaque, 
target_phys_addr_t offset,
 s->nvflags &= ~val;
 break;
 case 0x40: /* RESETCTL */
-if (board_id(s) == BOARD_ID_VEXPRESS) {
+switch (board_id(s)) {
+case BOARD_ID_PB926:
+case BOARD_ID_PB1176:
+if (s->lockval == LOCK_VALUE) {
+s->resetlevel = val;
+if (val & 0x100) {
+qemu_system_reset_request();
+}
+}
+break;
+case BOARD_ID_PBX:
+case BOARD_ID_PBA8:
+case BOARD_ID_PB11MP:
+if (s->lockval == LOCK_VALUE) {
+s->resetlevel = val;
+if (val & 0x04) {
+qemu_system_reset_request();
+}
+}
+break;
+case BOARD_ID_VEXPRESS:
+case BOARD_ID_EB:
+default:
 /* reserved: RAZ/WI */
 break;
 }
-if (s->lockval == LOCK_VALUE) {
-s->resetlevel = val;
-if (val & 0x100)
-qemu_system_reset_request ();
-}
 break;
 case 0x44: /* PCICTL */
 /* nothing to do.  */
@@ -324,7 +345,7 @@ static void arm_sysctl_write(void *opaque, 
target_phys_addr_t offset,
 return;
 default:
 bad_reg:
-printf ("arm_sysctl_write: Bad register offset 0x%x\n", (int)offset);
+printf("arm_sysctl_write: Bad register offset 0x%x\n", (int)offset);
 return;
 }
 }
-- 
1.7.5.4




[Qemu-devel] [PATCH v2] arm: Fix CP15 FSR (C5) domain setting

2011-11-05 Thread Jean-Christophe DUBOIS
During Xvisor development, it was noted that qemu did not return
the correct domain value in the Cp15 [Data] FSR register (C5).

This patch is a proposal to fix it.

v2:
- fix coding style
- rebase on git.

Signed-off-by: Jean-Christophe DUBOIS 
---
 target-arm/helper.c |   26 +++---
 1 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 97af4d0..8133087 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -951,13 +951,14 @@ void do_interrupt(CPUARMState *env)
 /* Check section/page access permissions.
Returns the page protection flags, or zero if the access is not
permitted.  */
-static inline int check_ap(CPUState *env, int ap, int domain, int access_type,
-   int is_user)
+static inline int check_ap(CPUState *env, int ap, int domain_prot,
+   int access_type, int is_user)
 {
   int prot_ro;
 
-  if (domain == 3)
+  if (domain_prot == 3) {
 return PAGE_READ | PAGE_WRITE;
+  }
 
   if (access_type == 1)
   prot_ro = 0;
@@ -1023,6 +1024,7 @@ static int get_phys_addr_v5(CPUState *env, uint32_t 
address, int access_type,
 int type;
 int ap;
 int domain;
+int domain_prot;
 uint32_t phys_addr;
 
 /* Pagetable walk.  */
@@ -1030,13 +1032,14 @@ static int get_phys_addr_v5(CPUState *env, uint32_t 
address, int access_type,
 table = get_level1_table_address(env, address);
 desc = ldl_phys(table);
 type = (desc & 3);
-domain = (env->cp15.c3 >> ((desc >> 4) & 0x1e)) & 3;
+domain = (desc >> 5) & 0x0f;
+domain_prot = (env->cp15.c3 >> (domain * 2)) & 3;
 if (type == 0) {
 /* Section translation fault.  */
 code = 5;
 goto do_fault;
 }
-if (domain == 0 || domain == 2) {
+if (domain_prot == 0 || domain_prot == 2) {
 if (type == 2)
 code = 9; /* Section domain fault.  */
 else
@@ -1094,7 +1097,7 @@ static int get_phys_addr_v5(CPUState *env, uint32_t 
address, int access_type,
 }
 code = 15;
 }
-*prot = check_ap(env, ap, domain, access_type, is_user);
+*prot = check_ap(env, ap, domain_prot, access_type, is_user);
 if (!*prot) {
 /* Access permission fault.  */
 goto do_fault;
@@ -1117,6 +1120,7 @@ static int get_phys_addr_v6(CPUState *env, uint32_t 
address, int access_type,
 int type;
 int ap;
 int domain;
+int domain_prot;
 uint32_t phys_addr;
 
 /* Pagetable walk.  */
@@ -1134,10 +1138,10 @@ static int get_phys_addr_v6(CPUState *env, uint32_t 
address, int access_type,
 domain = 0;
 } else {
 /* Section or page.  */
-domain = (desc >> 4) & 0x1e;
+domain = (desc >> 5) & 0x0f;
 }
-domain = (env->cp15.c3 >> domain) & 3;
-if (domain == 0 || domain == 2) {
+domain_prot = (env->cp15.c3 >> (domain * 2)) & 3;
+if (domain_prot == 0 || domain_prot == 2) {
 if (type == 2)
 code = 9; /* Section domain fault.  */
 else
@@ -1182,7 +1186,7 @@ static int get_phys_addr_v6(CPUState *env, uint32_t 
address, int access_type,
 }
 code = 15;
 }
-if (domain == 3) {
+if (domain_prot == 3) {
 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 } else {
 if (xn && access_type == 2)
@@ -1194,7 +1198,7 @@ static int get_phys_addr_v6(CPUState *env, uint32_t 
address, int access_type,
 code = (code == 15) ? 6 : 3;
 goto do_fault;
 }
-*prot = check_ap(env, ap, domain, access_type, is_user);
+*prot = check_ap(env, ap, domain_prot, access_type, is_user);
 if (!*prot) {
 /* Access permission fault.  */
 goto do_fault;
-- 
1.7.5.4




Re: [Qemu-devel] [PATCH v2] arm: Fix CP15 FSR (C5) domain setting

2011-11-06 Thread Jean-Christophe DUBOIS

On 06/11/2011 18:33, Peter Maydell wrote:

On 5 November 2011 11:42, Jean-Christophe DUBOIS  wrote:

During Xvisor development, it was noted that qemu did not return
the correct domain value in the Cp15 [Data] FSR register (C5).

This patch is a proposal to fix it.

v2:
- fix coding style
- rebase on git.

Signed-off-by: Jean-Christophe DUBOIS


Reviewed-by: Peter Maydell

NB: not going to put this into 1.0, it's a bit late and it's not
a critical bug fix IMHO. In particular, well behaved code shouldn't
be relying on this DFSR field; see the ARM ARM B3.9.7:
"From ARMv7, use of the domain field in the DFSR is deprecated. This
field might not be supported in future versions of the ARM architecture.
ARM strongly recommends that new software does not use this field."
Yes, same comment from the xvisor side of things. As xvisor targets 
mainly ARMv7 (and MIPS) for now, this was not a real issue.


Nonetheless this is worth fixing at some point in time (but this can be 
post 1.0).


JC



-- PMM






[Qemu-devel] [PATCH v3] hw/arm_sysctl: Fix RESETCTL for realview-pb-a8 and -pbx-a9

2011-11-06 Thread Jean-Christophe DUBOIS
Depending on the considered baseboard the bit used to
reset the platform is different.

Here is the list of considered Realview/Versatile platforms:

Realview/Versatile AB for ARM926EJ-S: BOARD_ID = 0x100 = BOARD_ID_PB926
http://infocenter.arm.com/help/topic/com.arm.doc.dui0225d/CACCIFGI.html

RealView Emulation Baseboard: BOARD_ID = 0x140 = BOARD_ID_EB
No reset register

RealView PB for Cortex-A8: BOARD_ID = 0x178 = BOARD_ID_PBA8
http://infocenter.arm.com/help/topic/com.arm.doc.dui0417d/BBACIGAD.html

RealView PB for Cortex-A9: BOARD_ID = 0x182 = BOARD_ID_PBX
http://infocenter.arm.com/help/topic/com.arm.doc.dui0440b/CACCHBFB.html

Motherboard Express µATX: BOARD_ID = 0x190 = BOARD_ID_VEXPRESS
No reset register

Signed-off-by: Jean-Christophe DUBOIS 
---

v3:
- change patch name to something more meaningful
- move version information after the commit message.
- remove added BOARD_ID and code for unsuported board
- remove code style fixing for unrelated code

v2:
- Add multiple boards support
- fix coding style
- Added a BOARD_ID descriptor for unsupported baseboards.

 hw/arm_sysctl.c |   27 +--
 1 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
index 17cf6f7..477fc6f 100644
--- a/hw/arm_sysctl.c
+++ b/hw/arm_sysctl.c
@@ -231,15 +231,30 @@ static void arm_sysctl_write(void *opaque, 
target_phys_addr_t offset,
 s->nvflags &= ~val;
 break;
 case 0x40: /* RESETCTL */
-if (board_id(s) == BOARD_ID_VEXPRESS) {
+switch (board_id(s)) {
+case BOARD_ID_PB926:
+if (s->lockval == LOCK_VALUE) {
+s->resetlevel = val;
+if (val & 0x100) {
+qemu_system_reset_request();
+}
+}
+break;
+case BOARD_ID_PBX:
+case BOARD_ID_PBA8:
+if (s->lockval == LOCK_VALUE) {
+s->resetlevel = val;
+if (val & 0x04) {
+qemu_system_reset_request();
+}
+}
+break;
+case BOARD_ID_VEXPRESS:
+case BOARD_ID_EB:
+default:
 /* reserved: RAZ/WI */
 break;
 }
-if (s->lockval == LOCK_VALUE) {
-s->resetlevel = val;
-if (val & 0x100)
-qemu_system_reset_request ();
-}
 break;
 case 0x44: /* PCICTL */
 /* nothing to do.  */
-- 
1.7.5.4




Re: [Qemu-devel] [PATCH v2] i.MX: implement a more correct version of EPIT timer.

2013-04-29 Thread Jean-Christophe DUBOIS

On 04/28/2013 11:29 PM, Peter Chubb wrote:

"Jean-Christophe" == Jean-Christophe DUBOIS  writes:

Jean-Christophe> This patch is providing a complete version of the
Jean-Christophe> EPIT timer.  Note, however that the GPT timer in the
Jean-Christophe> same file is still not complete.

Looks good.  You can add my

Reviewed-by: Peter Chubb 

line.
Peter (Maydel), will you pick it up as is (actually the v3  version) or 
do I need to send a new version of the patch (a v4) ?


JC


Peter C
--
Dr Peter Chubb  peter.chubb AT nicta.com.au
http://www.ssrg.nicta.com.au  Software Systems Research Group/NICTA






Re: [Qemu-devel] [PATCH v2] i.MX: implement a more correct version of EPIT timer.

2013-04-29 Thread Jean-Christophe DUBOIS

On 04/29/2013 06:49 PM, Peter Maydell wrote:

On 29 April 2013 17:39, Jean-Christophe DUBOIS  wrote:

Peter (Maydel), will you pick it up as is (actually the v3  version) or do I
need to send a new version of the patch (a v4) ?

The last on-list version still has the wrong vmstate version
fields, I think?


The last on list (v3) has all VMSTATE version numbers set to 2 (as 
opposed to 1 previously).


Am I missing something?

JC



thanks
-- PMM






[Qemu-devel] [PATCH 1/2] Add i.MX I2C device emulator.

2013-05-01 Thread Jean-Christophe DUBOIS
Signed-off-by: Jean-Christophe DUBOIS 
---
 default-configs/arm-softmmu.mak |   2 +
 hw/i2c/Makefile.objs|   1 +
 hw/i2c/imx_i2c.c| 374 
 3 files changed, 377 insertions(+)
 create mode 100644 hw/i2c/imx_i2c.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index b3a0207..a20f112 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -81,3 +81,5 @@ CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
 
 CONFIG_SDHCI=y
+
+CONFIG_IMX_I2C=y
diff --git a/hw/i2c/Makefile.objs b/hw/i2c/Makefile.objs
index 648278e..d27bbaa 100644
--- a/hw/i2c/Makefile.objs
+++ b/hw/i2c/Makefile.objs
@@ -4,4 +4,5 @@ common-obj-$(CONFIG_ACPI) += smbus_ich9.o
 common-obj-$(CONFIG_APM) += pm_smbus.o
 common-obj-$(CONFIG_BITBANG_I2C) += bitbang_i2c.o
 common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o
+common-obj-$(CONFIG_IMX_I2C) += imx_i2c.o
 obj-$(CONFIG_OMAP) += omap_i2c.o
diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c
new file mode 100644
index 000..30d3f5c
--- /dev/null
+++ b/hw/i2c/imx_i2c.c
@@ -0,0 +1,374 @@
+/*
+ *  i.MX I2C Bus Serial Interface Emulation
+ *
+ *  Copyright (C) 2013 Jean-Christophe Dubois.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "hw/sysbus.h"
+#include "hw/i2c/i2c.h"
+
+#ifndef IMX_I2C_DEBUG
+#define IMX_I2C_DEBUG 0
+#endif
+
+#define TYPE_IMX_I2C  "imx.i2c"
+#define IMX_I2C(obj)  \
+OBJECT_CHECK(imx_i2c_state, (obj), TYPE_IMX_I2C)
+
+/* i.MX I2C memory map */
+#define IMX_I2C_MEM_SIZE   0x14
+#define IADR_ADDR  0x00  /* address register */
+#define IFDR_ADDR  0x04  /* frequency divider register */
+#define I2CR_ADDR  0x08  /* control register */
+#define I2SR_ADDR  0x0c  /* status register */
+#define I2DR_ADDR  0x10  /* data register */
+
+#define IADR_MASK  0xFE
+#define IADR_RESET 0
+
+#define IFDR_MASK  0x3F
+#define IFDR_RESET 0
+
+#define I2CR_IEN   (1 << 7)
+#define I2CR_IIEN  (1 << 6)
+#define I2CR_MSTA  (1 << 5)
+#define I2CR_MTX   (1 << 4)
+#define I2CR_TXAK  (1 << 3)
+#define I2CR_RSTA  (1 << 2)
+#define I2CR_MASK  0xFC
+#define I2CR_RESET 0
+
+#define I2SR_ICF   (1 << 7)
+#define I2SR_IAAF  (1 << 6)
+#define I2SR_IBB   (1 << 5)
+#define I2SR_IAL   (1 << 4)
+#define I2SR_SRW   (1 << 2)
+#define I2SR_IIF   (1 << 1)
+#define I2SR_RXAK  (1 << 0)
+#define I2SR_MASK  0xE9
+#define I2SR_RESET 0x81
+
+#define I2DR_MASK  0xFF
+#define I2DR_RESET 0
+
+#define ADDR_RESET 0xFF00
+
+#if IMX_I2C_DEBUG
+#define DPRINT(fmt, args...)  \
+do { fprintf(stderr, "%s: "fmt, __func__, ## args); } while (0)
+
+static const char *imx_i2c_get_regname(unsigned offset)
+{
+switch (offset) {
+case IADR_ADDR:
+return "IADR";
+case IFDR_ADDR:
+return "IFDR";
+case I2CR_ADDR:
+return "I2CR";
+case I2SR_ADDR:
+return "I2SR";
+case I2DR_ADDR:
+return "I2DR";
+default:
+return "[?]";
+}
+}
+
+#else
+#define DPRINT(fmt, args...)  do { } while (0)
+#endif
+
+typedef struct imx_i2c_state {
+SysBusDevice busdev;
+MemoryRegion iomem;
+i2c_bus *bus;
+qemu_irq irq;
+
+uint16_t  address;
+
+uint16_t iadr;
+uint16_t ifdr;
+uint16_t i2cr;
+uint16_t i2sr;
+uint16_t i2dr_read;
+uint16_t i2dr_write;
+} imx_i2c_state;
+
+static inline bool imx_i2c_is_enabled(imx_i2c_state *s)
+{
+return (s->i2cr & I2CR_IEN);
+}
+
+static inline bool imx_i2c_interrupt_is_enabled(imx_i2c_state *s)
+{
+return (s->i2cr & I2CR_IIEN);
+}
+
+static inline bool imx_i2c_is_master(imx_i2c_state *s)
+{
+return (s->i2cr &am

[Qemu-devel] [PATCH 2/2] Add i.MX device to i.MX25 3DS platform.

2013-05-01 Thread Jean-Christophe DUBOIS
Signed-off-by: Jean-Christophe DUBOIS 
---
 hw/arm/imx25_3ds.c | 48 
 1 file changed, 32 insertions(+), 16 deletions(-)

diff --git a/hw/arm/imx25_3ds.c b/hw/arm/imx25_3ds.c
index 9de4941..aba9279 100644
--- a/hw/arm/imx25_3ds.c
+++ b/hw/arm/imx25_3ds.c
@@ -25,6 +25,7 @@
 #include "hw/boards.h"
 #include "hw/char/serial.h"
 #include "hw/arm/imx.h"
+#include "hw/i2c/i2c.h"
 
 /* Memory map for 3D-Stack Emulation Baseboard:
  * 0x-0x3fff 16k ROM  IGNORED
@@ -37,6 +38,9 @@
  * 0x4000-0x43ef Reserved IGNORED
  * 0x43f0-0x6fff I.MX25 Internal Register Space
  *   0x43f0 IO_AREA0
+ *   0x43f8 I2C0  EMULATED
+ *   0x43f84000 I2C2  EMULATED
+ *   0x43f98000 I2C1  EMULATED
  *   0x43f9 UART1 EMULATED
  *   0x43f94000 UART2 EMULATED
  *   0x43fb UART4 IGNORED
@@ -95,12 +99,11 @@ static void imx25_3ds_init(QEMUMachineInitArgs *args)
 ARMCPU *cpu;
 MemoryRegion *address_space_mem = get_system_memory();
 qemu_irq *cpu_pic;
-DeviceState *dev;
+DeviceState *pic_dev;
 DeviceState *ccm;
 MemoryRegion *sram = g_new(MemoryRegion, 1);
 MemoryRegion *sram_alias = g_new(MemoryRegion, 1);
 
-
 if (!cpu_model) {
 cpu_model = "arm926";
 }
@@ -169,31 +172,44 @@ static void imx25_3ds_init(QEMUMachineInitArgs *args)
 
 /* add the PIC */
 cpu_pic = arm_pic_init_cpu(cpu);
-dev = sysbus_create_varargs("imx_avic", 0x6800,
+pic_dev = sysbus_create_varargs("imx_avic", 0x6800,
 cpu_pic[ARM_PIC_CPU_IRQ],
 cpu_pic[ARM_PIC_CPU_FIQ], NULL);
 
 /* add some serial lines */
-imx_serial_create(0, 0x43f9, qdev_get_gpio_in(dev, 45));
-imx_serial_create(1, 0x43f94000, qdev_get_gpio_in(dev, 32));
+imx_serial_create(0, 0x43f9, qdev_get_gpio_in(pic_dev, 45));
+imx_serial_create(1, 0x43f94000, qdev_get_gpio_in(pic_dev, 32));
 // Qemu does not support more than 4 serial ports. Too bad.
-//imx_serial_create(3, 0x5000c000, qdev_get_gpio_in(dev, 18));
-//imx_serial_create(4, 0x43fb, qdev_get_gpio_in(dev, 46));
-//imx_serial_create(5, 0x43fb4000, qdev_get_gpio_in(dev, 47));
+//imx_serial_create(3, 0x5000c000, qdev_get_gpio_in(pic_dev, 18));
+//imx_serial_create(4, 0x43fb, qdev_get_gpio_in(pic_dev, 46));
+//imx_serial_create(5, 0x43fb4000, qdev_get_gpio_in(pic_dev, 47));
 
 ccm = sysbus_create_simple("imx_ccm", 0x53f8, NULL);
 
 /* add gpt timers */
-imx_timerg_create(0x53f84000, qdev_get_gpio_in(dev, 1), ccm);
-imx_timerg_create(0x53f88000, qdev_get_gpio_in(dev, 29), ccm);
-imx_timerg_create(0x53f8c000, qdev_get_gpio_in(dev, 53), ccm);
-imx_timerg_create(0x53f9, qdev_get_gpio_in(dev, 54), ccm);
+imx_timerg_create(0x53f84000, qdev_get_gpio_in(pic_dev, 1), ccm);
+imx_timerg_create(0x53f88000, qdev_get_gpio_in(pic_dev, 29), ccm);
+imx_timerg_create(0x53f8c000, qdev_get_gpio_in(pic_dev, 53), ccm);
+imx_timerg_create(0x53f9, qdev_get_gpio_in(pic_dev, 54), ccm);
 
 /* add epit timers */
-imx_timerp_create(0x53f94000, qdev_get_gpio_in(dev, 28), ccm);
-imx_timerp_create(0x53f98000, qdev_get_gpio_in(dev, 27), ccm);
-
-imx_fec_create(0, 0x50038000, qdev_get_gpio_in(dev, 57));
+imx_timerp_create(0x53f94000, qdev_get_gpio_in(pic_dev, 28), ccm);
+imx_timerp_create(0x53f98000, qdev_get_gpio_in(pic_dev, 27), ccm);
+
+imx_fec_create(0, 0x50038000, qdev_get_gpio_in(pic_dev, 57));
+
+/*** I2C ***/
+for (i = 0; i < 3; i++) {
+static uint32_t addr[] = {0x43F8, 0x43F98000, 0x43F84000};
+static uint32_t irq[]  = {3, 4, 10};
+SysBusDevice *busdev;
+DeviceState *i2c_dev = qdev_create(NULL, "imx.i2c");
+
+qdev_init_nofail(i2c_dev);
+busdev = SYS_BUS_DEVICE(i2c_dev);
+sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(pic_dev, irq[i]));
+sysbus_mmio_map(busdev, 0, addr[i]);
+}
 
 imx25_3ds_binfo.ram_size = ram_size;
 imx25_3ds_binfo.kernel_filename = kernel_filename;
-- 
1.8.1.2




Re: [Qemu-devel] [PATCH 2/2] Add i.MX25 3DS evaluation board support

2013-05-01 Thread Jean-Christophe DUBOIS

Peter,

I have submitted a few patch to add support to the i.MX25 processor and 
the 3DS Freescale evaluation platform.


Most of the i.MX devices present on i.MX25 can be reused on other 
Freescale processors including the i.MX6.


So far I did not get that much feedback on this.

Is this of any interest to somebody?

If so, what it the process to get it adopted in an official tree.

Thanks

JC


On 04/26/2013 04:02 PM, Jean-Christophe DUBOIS wrote:

This is an initial port of the Freescale i.MX25 processor.

This allow a minimally configured linux kernel to boot on Qemu.

It also handle the newly added FEC ethernet device.

Signed-off-by: Jean-Christophe DUBOIS 
---
  hw/arm/Makefile.objs |   1 +
  hw/arm/imx25_3ds.c   | 218 +++
  2 files changed, 219 insertions(+)
  create mode 100644 hw/arm/imx25_3ds.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 9e3a06f..2f4280d 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -2,6 +2,7 @@ obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
  obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
  obj-y += omap_sx1.o palm.o pic_cpu.o realview.o spitz.o stellaris.o
  obj-y += tosa.o versatilepb.o vexpress.o xilinx_zynq.o z2.o
+obj-y += imx25_3ds.o
  
  obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o

  obj-y += omap1.o omap2.o strongarm.o
diff --git a/hw/arm/imx25_3ds.c b/hw/arm/imx25_3ds.c
new file mode 100644
index 000..9de4941
--- /dev/null
+++ b/hw/arm/imx25_3ds.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2013 Jean-Christophe Dubois
+ *
+ * 3Dstack Board System emulation.
+ *
+ * Based on hw/arm/kzm.c
+ *
+ * Copyright (c) 2008 OKL and 2011 NICTA
+ * Written by Hans at OK-Labs
+ * Updated by Peter Chubb.
+ *
+ * This code is licensed under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a i.MX25 3D-Stack PDK board
+ */
+
+#include "hw/sysbus.h"
+#include "exec/address-spaces.h"
+#include "hw/hw.h"
+#include "hw/arm/arm.h"
+#include "hw/devices.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+#include "hw/char/serial.h"
+#include "hw/arm/imx.h"
+
+/* Memory map for 3D-Stack Emulation Baseboard:
+ * 0x-0x3fff 16k ROM  IGNORED
+ * 0x4000-0x00403fff Reserved IGNORED
+ * 0x00404000-0x00408fff 20k ROM  IGNORED
+ * 0x00409000-0x0fff Reserved IGNORED
+ * 0x1000-0x1fff Reserved IGNORED
+ * 0x2000-0x2fff Reserved IGNORED
+ * 0x3000-0x3fff Reserved IGNORED
+ * 0x4000-0x43ef Reserved IGNORED
+ * 0x43f0-0x6fff I.MX25 Internal Register Space
+ *   0x43f0 IO_AREA0
+ *   0x43f9 UART1 EMULATED
+ *   0x43f94000 UART2 EMULATED
+ *   0x43fb UART4 IGNORED
+ *   0x43fb4000 UART5 IGNORED
+ *   0x5000c000 UART3 IGNORED
+ *   0x53f8 CCM   EMULATED
+ *   0x53f84000 GPT 4 EMULATED
+ *   0x53f88000 GPT 3 EMULATED
+ *   0x53f8c000 GPT 2 EMULATED
+ *   0x53f9 GPT 1 EMULATED
+ *   0x53f94000 PIT 1 EMULATED
+ *   0x53f98000 PIT 2 EMULATED
+ *   0x6800 ASIC  EMULATED
+ * 0x7800-0x7801 SRAM EMULATED
+ * 0x7802-0x7fff SRAM AliasingEMULATED
+ * 0x8000-0x87ff RAM + Alias  EMULATED
+ * 0x9000-0x9fff RAM + Alias  EMULATED
+ * 0xa000-0xa7ff FlashIGNORED
+ * 0xa800-0xafff FlashIGNORED
+ * 0xb000-0xb1ff SRAM IGNORED
+ * 0xb200-0xb3ff SRAM IGNORED
+ * 0xb400-0xb5ff CS4  IGNORED
+ * 0xb600-0xb8000fff Reserved IGNORED
+ * 0xb8001000-0xb8001fff SDRAM CTRL reg   IGNORED
+ * 0xb8002000-0xb8002fff WEIM CTRL regIGNORED
+ * 0xb8003000-0xb8003fff M3IF CTRL regIGNORED
+ * 0xb8004000-0xb8004fff EMI CTRL reg IGNORED
+ * 0xb8005000-0xbaff Reserved IGNORED
+ * 0xbb00-0xbb000fff NAND flash area buf  IGNORED
+ * 0xbb001000-0xbb0011ff NAND flash reserved  IGNORED
+ * 0xbb001200-0xbb001dff Reserved IGNORED
+ * 0xbb001e00-0xbb001fff NAN flash CTRL reg   IGNORED
+ * 0xbb012000-0xbfff Reserved IGNORED
+ * 0xc000-0x Reserved IGNORED
+ */
+
+#define IMX25_SRAM_ADDRESS  (0x7800)
+#define IMX25_SRAMSIZE  (128*1024)
+#define IMX25_CS_SRAMSIZE   (128*1024*1024)
+#define IMX25_3DS_ADDRESS   (0x8000)
+#define 

Re: [Qemu-devel] [PATCH 1/2] Add i.MX I2C device emulator.

2013-05-02 Thread Jean-Christophe DUBOIS

Peter,

Thanks for you review.

I have a few questions below.

JC

On 05/02/2013 02:16 PM, Peter Crosthwaite wrote:

Hi Jean-Christophe,

Thanks for your contribution. Please run the patch through
scripts/checkpatch.pl to check for formatting errors.

On Thu, May 2, 2013 at 5:53 AM, Jean-Christophe DUBOIS
 wrote:
ERROR: return is not a function, parentheses are not required
#148: FILE: hw/i2c/imx_i2c.c:114:
+return (s->i2cr & I2CR_IEN);

>From checkpatch, here and below.


Will do.


+}
+
+static inline bool imx_i2c_interrupt_is_enabled(imx_i2c_state *s)
+{
+return (s->i2cr & I2CR_IIEN);
+}
+
+static inline bool imx_i2c_is_master(imx_i2c_state *s)
+{
+return (s->i2cr & I2CR_MSTA);
+}
+
+static inline bool imx_i2c_direction_is_tx(imx_i2c_state *s)
+{
+return (s->i2cr & I2CR_MTX);
+}
+
+static void imx_i2c_reset(DeviceState *d)
+{
+imx_i2c_state *s = FROM_SYSBUS(imx_i2c_state, SYS_BUS_DEVICE(d));
+

Please don't use FROM_SYSBUS in new code. Use QOM cast macros.

http://wiki.qemu.org/QOMConventions

Has useful guidelines for the rules around this for new devices.


It is not very clear what you do expect. Could you point me to a driver 
that is up to date.



+if (s->address != ADDR_RESET) {
+i2c_end_transfer(s->bus);
+}
+
+s->address= ADDR_RESET;
+s->iadr   = IADR_RESET;
+s->ifdr   = IFDR_RESET;
+s->i2cr   = I2CR_RESET;
+s->i2sr   = I2SR_RESET;
+s->i2dr_read  = I2DR_RESET;
+s->i2dr_write = I2DR_RESET;
+}
+
+static inline void imx_i2c_raise_interrupt(imx_i2c_state *s)
+{
+/*
+ * raise an interrupt if the device is enabled and it is configured
+ * to generate some interrupts.
+ */
+if (imx_i2c_is_enabled(s) && imx_i2c_interrupt_is_enabled(s)) {
+s->i2sr |= I2SR_IIF;
+qemu_irq_raise(s->irq);
+}
+}
+
+static uint64_t imx_i2c_read(void *opaque, hwaddr offset,
+ unsigned size)
+{
+imx_i2c_state *s = (imx_i2c_state *)opaque;

QOM cast macro.


Could you point me to an up to date driver using QOM cast macro?



+
+static const MemoryRegionOps imx_i2c_ops = {
+.read = imx_i2c_read,
+.write = imx_i2c_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
I think you may need a .valid definition here as it looks like you
have restrictions on access size and alignment? (looks like 4bytes
accesses only).


I'll look into this.


+};
+
+static const VMStateDescription imx_i2c_vmstate = {
+.name = TYPE_IMX_I2C,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT16(address, imx_i2c_state),
+VMSTATE_UINT16(iadr, imx_i2c_state),
+VMSTATE_UINT16(ifdr, imx_i2c_state),
+VMSTATE_UINT16(i2cr, imx_i2c_state),
+VMSTATE_UINT16(i2sr, imx_i2c_state),
+VMSTATE_UINT16(i2dr_read, imx_i2c_state),
+VMSTATE_UINT16(i2dr_write, imx_i2c_state),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static int imx_i2c_init(SysBusDevice *dev)
+{

Use of the SysBusDeviceClass::init function is deprecated. Please use
DeviceClass::realise or Object::init. With no reliance on properties I
would suggest this one can be done as just an Object::init fn.

Could you point me to the documentation or an up to date example?



Re: [Qemu-devel] [PATCH 1/2] Add i.MX I2C device emulator.

2013-05-03 Thread Jean-Christophe DUBOIS

Andreas,

On 05/02/2013 02:38 PM, Andreas Färber wrote:

Hi,

Am 01.05.2013 21:53, schrieb Jean-Christophe DUBOIS:

Signed-off-by: Jean-Christophe DUBOIS 
---
  default-configs/arm-softmmu.mak |   2 +
  hw/i2c/Makefile.objs|   1 +
  hw/i2c/imx_i2c.c| 374 
  3 files changed, 377 insertions(+)
  create mode 100644 hw/i2c/imx_i2c.c

Please thread your messages together so they can be reviewed in context.

Since you're adding a new I2C device and we have a qtest framework for
I2C, please supply an implementation for this device (which will require
some constant sharing via header file) and some simple test case for the
board you're using it on, to assure it keeps working.

What is the "target" for building qtest?

And then how to run it?

Could you point me to some documentation please? It doesn't build out of 
the box for me.


JC




Re: [Qemu-devel] [PATCH 1/2] Add i.MX I2C device emulator.

2013-05-03 Thread Jean-Christophe DUBOIS

On 05/03/2013 05:20 PM, Andreas Färber wrote:

Am 03.05.2013 17:16, schrieb Jean-Christophe DUBOIS:

Andreas,

On 05/02/2013 02:38 PM, Andreas Färber wrote:

Hi,

Am 01.05.2013 21:53, schrieb Jean-Christophe DUBOIS:

Signed-off-by: Jean-Christophe DUBOIS 
---
   default-configs/arm-softmmu.mak |   2 +
   hw/i2c/Makefile.objs|   1 +
   hw/i2c/imx_i2c.c| 374

   3 files changed, 377 insertions(+)
   create mode 100644 hw/i2c/imx_i2c.c

Please thread your messages together so they can be reviewed in context.

Since you're adding a new I2C device and we have a qtest framework for
I2C, please supply an implementation for this device (which will require
some constant sharing via header file) and some simple test case for the
board you're using it on, to assure it keeps working.

What is the "target" for building qtest?

And then how to run it?

make check


Thanks Andreas,

So I added a libi2c-imx.c file, a ds1338-test.c file ...

but when I run "make check" I get the following.

What am I missing?

JC

$ make check
GTESTER tests/check-qdict
GTESTER tests/check-qfloat
GTESTER tests/check-qint
GTESTER tests/check-qstring
GTESTER tests/check-qlist
GTESTER tests/check-qjson
GTESTER tests/test-qmp-output-visitor
GTESTER tests/test-qmp-input-visitor
GTESTER tests/test-qmp-input-strict
GTESTER tests/test-qmp-commands
GTESTER tests/test-string-input-visitor
GTESTER tests/test-string-output-visitor
GTESTER tests/test-coroutine
GTESTER tests/test-visitor-serialization
GTESTER tests/test-iov
GTESTER tests/test-aio
GTESTER tests/test-thread-pool
GTESTER tests/test-hbitmap
GTESTER tests/test-x86-cpuid
GTESTER tests/test-xbzrle
GTESTER tests/test-cutils
GTESTER tests/test-mul64
  CCtests/libi2c-imx.o
  LINK  tests/tmp105-test
  CCtests/ds1338-test.o
  LINK  tests/ds1338-test
GTESTER check-qtest-arm
Kernel image must be specified
Broken pipe
make: *** [check-qtest-arm] Error 1
$



Andreas


Could you point me to some documentation please? It doesn't build out of
the box for me.

JC








Re: [Qemu-devel] [PATCH 1/2] Add i.MX I2C device emulator.

2013-05-04 Thread Jean-Christophe DUBOIS

On 05/03/2013 06:41 PM, Andreas Färber wrote:

   CCtests/libi2c-imx.o
   LINK  tests/tmp105-test
   CCtests/ds1338-test.o
   LINK  tests/ds1338-test
GTESTER check-qtest-arm
Kernel image must be specified
Without seeing your code and since tmp105-test is working on my side, I
can only guess that your ds1338-test is starting either your own machine
or some machine that terminates with above error.

the ds1338-test.c code is very similar to the tmp105-test.c code.

The tmp105-test.c code starts a n800 machine while the ds1338-test.c 
starts a imx25_3ds machine (to get the i.MX I2C device, it seems natural).


Nowhere in the tmp105-test.c code is any kernel or initrd file 
specified. So I did the same with ds1338-test.c.


But then "make check" is complaining the kernel is missing ...

So it seems the n800 allows qemu to start even if no parameters (ram 
size, kernel file, ...) are provided (you can actually confirm this by 
running "qemu-system-arm -machine n800"). This is not the default 
behavior for most implemented platform (including imx25_3ds) that will 
refuse to start if no parameter is given.


Is there a new requirement mandating platforms to start with guessed 
parameters if not provided on the command line in order to be compatible 
with qtest?


The solution is to only mandate -kernel, -initrd, -dtb, etc. in the
machine init function if !qtest_enabled() or so.


I am calling arm_load_kernel() with a pointer to a "struct arm_boot_info".

The first thing done by arm_load_kernel() is to check for the kernel 
parameter without checking for qtest_enable() and all.


/* Load the kernel.  */
if (!info->kernel_filename) {
fprintf(stderr, "Kernel image must be specified\n");
exit(1);
}

Do you mean arm_load_kernel() should test for qtest_enable() or should I 
call arm_load_kernel() only if !qtest_enable() (there is not much 
platform checking for qtest_enable() at this time and it seems somebody 
need to set the "entry" field in the info struct).




Re: [Qemu-devel] [PATCH 1/2] Add i.MX I2C device emulator.

2013-05-04 Thread Jean-Christophe DUBOIS

On 05/04/2013 10:29 AM, Peter Maydell wrote:

On 4 May 2013 09:27, Andreas Färber  wrote:

Am 04.05.2013 10:22, schrieb Jean-Christophe DUBOIS:

Do you mean arm_load_kernel() should test for qtest_enable() or should I
call arm_load_kernel() only if !qtest_enable() (there is not much
platform checking for qtest_enable() at this time and it seems somebody
need to set the "entry" field in the info struct).

In short, qtest does not execute any code, so it does not need to load
binaries or set CPU entry addresses.

Yes, I would say there is no point calling arm_load_kernel() if
!qtest_enabled().

I'd rather we didn't end up with qtest_enabled() checks infecting
every board model, please...


Then should we put it in arm_load_kernel() so that all board model get it ?

JC



thanks
-- PMM






[Qemu-devel] [PATCH v2 0/4] Add i.MX25 support through the 3DS evaluation board

2013-05-04 Thread Jean-Christophe DUBOIS
This serie of patches add the support for the i.MX25 processor through the
Freescale 3DS evaluation board.

For now a limited set of devices are supported.
* GPT timers (from i.MX31)
* EPI timers (from i.MX31)
* Serial ports (from i.MX31)
* Ethernet FEC port
* I2C controller

Jean-Christophe DUBOIS (4):
  Add i.MX FEC Ethernet driver
  Add i.MX I2C controller driver.
  Add i.MX25 3DS evaluation board support.
  Add qtest support for i.MX I2C device emulation.

 default-configs/arm-softmmu.mak |   3 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/imx25_3ds.c  | 258 ++
 hw/i2c/Makefile.objs|   1 +
 hw/i2c/imx_i2c.c| 383 
 hw/net/Makefile.objs|   1 +
 hw/net/imx_fec.c| 748 
 include/hw/arm/imx.h|   1 +
 tests/Makefile  |   3 +
 tests/ds1338-test.c |  64 
 tests/libqos/i2c-imx.c  | 224 
 tests/libqos/i2c.h  |   3 +
 12 files changed, 1690 insertions(+)
 create mode 100644 hw/arm/imx25_3ds.c
 create mode 100644 hw/i2c/imx_i2c.c
 create mode 100644 hw/net/imx_fec.c
 create mode 100644 tests/ds1338-test.c
 create mode 100644 tests/libqos/i2c-imx.c

-- 
1.8.1.2




[Qemu-devel] [PATCH v2 3/4] Add i.MX25 3DS evaluation board support.

2013-05-04 Thread Jean-Christophe DUBOIS
For now we support:
* timers (GPT and EPIT)
* serial ports (only 2 out of 5 possible)
* ethernet (through the newly added FEC driver)
* I2C (through the newly added I2C driver)

A ds1338 I2C RTC chip was added on the first i2c bus to allow
automatic test through qtest. This RTC is not present on the real
board.

Signed-off-by: Jean-Christophe DUBOIS 
---
 hw/arm/Makefile.objs |   1 +
 hw/arm/imx25_3ds.c   | 258 +++
 2 files changed, 259 insertions(+)
 create mode 100644 hw/arm/imx25_3ds.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 9e3a06f..2f4280d 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -2,6 +2,7 @@ obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
 obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
 obj-y += omap_sx1.o palm.o pic_cpu.o realview.o spitz.o stellaris.o
 obj-y += tosa.o versatilepb.o vexpress.o xilinx_zynq.o z2.o
+obj-y += imx25_3ds.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
 obj-y += omap1.o omap2.o strongarm.o
diff --git a/hw/arm/imx25_3ds.c b/hw/arm/imx25_3ds.c
new file mode 100644
index 000..b7ff26d
--- /dev/null
+++ b/hw/arm/imx25_3ds.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2013 Jean-Christophe Dubois
+ *
+ * 3Dstack Board System emulation.
+ *
+ * Based on hw/arm/kzm.c
+ *
+ * Copyright (c) 2008 OKL and 2011 NICTA
+ * Written by Hans at OK-Labs
+ * Updated by Peter Chubb.
+ *
+ * This code is licensed under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a i.MX25 3D-Stack PDK board
+ */
+
+#include "hw/sysbus.h"
+#include "exec/address-spaces.h"
+#include "hw/hw.h"
+#include "hw/arm/arm.h"
+#include "hw/devices.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+#include "hw/char/serial.h"
+#include "hw/arm/imx.h"
+#include "hw/i2c/i2c.h"
+
+#include "sysemu/qtest.h"
+
+/* Memory map for 3D-Stack Emulation Baseboard:
+ * 0x-0x3fff 16k ROM  IGNORED
+ * 0x4000-0x00403fff Reserved IGNORED
+ * 0x00404000-0x00408fff 20k ROM  IGNORED
+ * 0x00409000-0x0fff Reserved IGNORED
+ * 0x1000-0x1fff Reserved IGNORED
+ * 0x2000-0x2fff Reserved IGNORED
+ * 0x3000-0x3fff Reserved IGNORED
+ * 0x4000-0x43ef Reserved IGNORED
+ * 0x43f0-0x6fff I.MX25 Internal Register Space
+ *   0x43f0 IO_AREA0
+ *   0x43f8 I2C0  EMULATED
+ *   0x43f84000 I2C2  EMULATED
+ *   0x43f98000 I2C1  EMULATED
+ *   0x43f9 UART1 EMULATED
+ *   0x43f94000 UART2 EMULATED
+ *   0x43fb UART4 IGNORED
+ *   0x43fb4000 UART5 IGNORED
+ *   0x5000c000 UART3 IGNORED
+ *   0x53f8 CCM   EMULATED
+ *   0x53f84000 GPT 4 EMULATED
+ *   0x53f88000 GPT 3 EMULATED
+ *   0x53f8c000 GPT 2 EMULATED
+ *   0x53f9 GPT 1 EMULATED
+ *   0x53f94000 PIT 1 EMULATED
+ *   0x53f98000 PIT 2 EMULATED
+ *   0x6800 ASIC  EMULATED
+ * 0x7800-0x7801 SRAM EMULATED
+ * 0x7802-0x7fff SRAM AliasingEMULATED
+ * 0x8000-0x87ff RAM + Alias  EMULATED
+ * 0x9000-0x9fff RAM + Alias  EMULATED
+ * 0xa000-0xa7ff FlashIGNORED
+ * 0xa800-0xafff FlashIGNORED
+ * 0xb000-0xb1ff SRAM IGNORED
+ * 0xb200-0xb3ff SRAM IGNORED
+ * 0xb400-0xb5ff CS4  IGNORED
+ * 0xb600-0xb8000fff Reserved IGNORED
+ * 0xb8001000-0xb8001fff SDRAM CTRL reg   IGNORED
+ * 0xb8002000-0xb8002fff WEIM CTRL regIGNORED
+ * 0xb8003000-0xb8003fff M3IF CTRL regIGNORED
+ * 0xb8004000-0xb8004fff EMI CTRL reg IGNORED
+ * 0xb8005000-0xbaff Reserved IGNORED
+ * 0xbb00-0xbb000fff NAND flash area buf  IGNORED
+ * 0xbb001000-0xbb0011ff NAND flash reserved  IGNORED
+ * 0xbb001200-0xbb001dff Reserved IGNORED
+ * 0xbb001e00-0xbb001fff NAN flash CTRL reg   IGNORED
+ * 0xbb012000-0xbfff Reserved IGNORED
+ * 0xc000-0x Reserved IGNORED
+ */
+
+#define IMX25_SRAM_ADDRESS  (0x7800)
+#define IMX25_SRAMSIZE  (128*1024)
+#define IMX25_CS_SRAMSIZE   (128*1024*1024)
+#define IMX25_3DS_ADDRESS   (0x8000)
+#define IMX25_CS_RAMSIZE(256*1024*1024)
+
+static struct arm_boot_info imx25_3ds_b

[Qemu-devel] [PATCH v2 1/4] Add i.MX FEC Ethernet driver

2013-05-04 Thread Jean-Christophe DUBOIS
This is based on the mcf_fec.c FEC implementation for ColdFire.

* a generic phy was added (borrowed from lan9118).
* The buffer management is also modified as buffers are
  slightly different between coldfire and i.MX.

Signed-off-by: Jean-Christophe DUBOIS 
---
 default-configs/arm-softmmu.mak |   1 +
 hw/net/Makefile.objs|   1 +
 hw/net/imx_fec.c| 748 
 3 files changed, 750 insertions(+)
 create mode 100644 hw/net/imx_fec.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 27cbe3d..b3a0207 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -28,6 +28,7 @@ CONFIG_SSI_SD=y
 CONFIG_SSI_M25P80=y
 CONFIG_LAN9118=y
 CONFIG_SMC91C111=y
+CONFIG_IMX_FEC=y
 CONFIG_DS1338=y
 CONFIG_PFLASH_CFI01=y
 CONFIG_PFLASH_CFI02=y
diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index 951cca3..5c84727 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -18,6 +18,7 @@ common-obj-$(CONFIG_OPENCORES_ETH) += opencores_eth.o
 common-obj-$(CONFIG_XGMAC) += xgmac.o
 common-obj-$(CONFIG_MIPSNET) += mipsnet.o
 common-obj-$(CONFIG_XILINX_AXI) += xilinx_axienet.o
+common-obj-$(CONFIG_IMX_FEC) += imx_fec.o
 
 common-obj-$(CONFIG_CADENCE) += cadence_gem.o
 common-obj-$(CONFIG_STELLARIS_ENET) += stellaris_enet.o
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
new file mode 100644
index 000..e894d50
--- /dev/null
+++ b/hw/net/imx_fec.c
@@ -0,0 +1,748 @@
+/*
+ * i.MX Fast Ethernet Controller emulation.
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois.
+ *
+ * Based on Coldfire Fast Ethernet Controller emulation.
+ *
+ * Copyright (c) 2007 CodeSourcery.
+ *
+ * This code is licensed under the GPL
+ */
+#include "hw/sysbus.h"
+#include "net/net.h"
+#include "hw/devices.h"
+
+/* For crc32 */
+#include 
+
+#include "hw/arm/imx.h"
+
+#ifndef IMX_FEC_DEBUG
+#define IMX_FEC_DEBUG  0
+#endif
+
+#ifndef IMX_PHY_DEBUG
+#define IMX_PHY_DEBUG  0
+#endif
+
+#if IMX_FEC_DEBUG
+#define DPRINTF(fmt, ...) \
+do { printf("imx_fec: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) do {} while (0)
+#endif
+
+#if IMX_PHY_DEBUG
+#define DPPRINTF(fmt, ...) \
+do { printf("imx_fec_phy: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DPPRINTF(fmt, ...) do {} while (0)
+#endif
+
+#define FEC_MAX_FRAME_SIZE 2032
+
+typedef struct {
+SysBusDevice busdev;
+NICState *nic;
+NICConf conf;
+qemu_irq irq;
+MemoryRegion iomem;
+
+uint32_t irq_state;
+uint32_t eir;
+uint32_t eimr;
+uint32_t rx_enabled;
+uint32_t rx_descriptor;
+uint32_t tx_descriptor;
+uint32_t ecr;
+uint32_t mmfr;
+uint32_t mscr;
+uint32_t mibc;
+uint32_t rcr;
+uint32_t tcr;
+uint32_t tfwr;
+uint32_t frsr;
+uint32_t erdsr;
+uint32_t etdsr;
+uint32_t emrbr;
+uint32_t miigsk_cfgr;
+uint32_t miigsk_enr;
+
+uint32_t phy_status;
+uint32_t phy_control;
+uint32_t phy_advertise;
+uint32_t phy_int;
+uint32_t phy_int_mask;
+} imx_fec_state;
+
+static const VMStateDescription vmstate_imx_fec = {
+.name = "fec",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(irq_state, imx_fec_state),
+VMSTATE_UINT32(eir, imx_fec_state),
+VMSTATE_UINT32(eimr, imx_fec_state),
+VMSTATE_UINT32(rx_enabled, imx_fec_state),
+VMSTATE_UINT32(rx_descriptor, imx_fec_state),
+VMSTATE_UINT32(tx_descriptor, imx_fec_state),
+VMSTATE_UINT32(ecr, imx_fec_state),
+VMSTATE_UINT32(mmfr, imx_fec_state),
+VMSTATE_UINT32(mscr, imx_fec_state),
+VMSTATE_UINT32(mibc, imx_fec_state),
+VMSTATE_UINT32(rcr, imx_fec_state),
+VMSTATE_UINT32(tcr, imx_fec_state),
+VMSTATE_UINT32(tfwr, imx_fec_state),
+VMSTATE_UINT32(frsr, imx_fec_state),
+VMSTATE_UINT32(erdsr, imx_fec_state),
+VMSTATE_UINT32(etdsr, imx_fec_state),
+VMSTATE_UINT32(emrbr, imx_fec_state),
+VMSTATE_UINT32(miigsk_cfgr, imx_fec_state),
+VMSTATE_UINT32(miigsk_enr, imx_fec_state),
+
+VMSTATE_UINT32(phy_status, imx_fec_state),
+VMSTATE_UINT32(phy_control, imx_fec_state),
+VMSTATE_UINT32(phy_advertise, imx_fec_state),
+VMSTATE_UINT32(phy_int, imx_fec_state),
+VMSTATE_UINT32(phy_int_mask, imx_fec_state),
+VMSTATE_END_OF_LIST()
+}
+};
+
+#define PHY_INT_ENERGYON(1 << 7)
+#define PHY_INT_AUTONEG_COMPLETE(1 << 6)
+#define PHY_INT_FAULT   (1 << 5)
+#define PHY_INT_DOWN(1 << 4)
+#define PHY_INT_AUTONEG_LP  (1 << 3)
+#define PHY_INT_PARFAULT(1 << 2)
+#define PHY_INT_AUTONEG_PAGE(1 << 1)
+
+static void imx_fec_update(imx_fec_state *s);
+
+/*
+ * The MII 

[Qemu-devel] [PATCH v2 4/4] Add qtest support for i.MX I2C device emulation.

2013-05-04 Thread Jean-Christophe DUBOIS
This is using a ds1338 RTC chip on the i2c bus. This RTC
chip is nop present on the real board

Signed-off-by: Jean-Christophe DUBOIS 
---
 tests/Makefile |   3 +
 tests/ds1338-test.c|  64 ++
 tests/libqos/i2c-imx.c | 224 +
 tests/libqos/i2c.h |   3 +
 4 files changed, 294 insertions(+)
 create mode 100644 tests/ds1338-test.c
 create mode 100644 tests/libqos/i2c-imx.c

diff --git a/tests/Makefile b/tests/Makefile
index bf41d10..5f7a0e0 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -64,6 +64,7 @@ gcov-files-x86_64-y = $(subst 
i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y)
 gcov-files-sparc-y += hw/m48t59.c
 gcov-files-sparc64-y += hw/m48t59.c
 check-qtest-arm-y = tests/tmp105-test$(EXESUF)
+check-qtest-arm-y += tests/ds1338-test$(EXESUF)
 gcov-files-arm-y += hw/tmp105.c
 
 GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h 
tests/test-qmp-commands.h
@@ -123,12 +124,14 @@ libqos-obj-y += tests/libqos/i2c.o
 libqos-pc-obj-y = $(libqos-obj-y) tests/libqos/pci-pc.o 
tests/libqos/fw_cfg-pc.o
 libqos-pc-obj-y += tests/libqos/malloc-pc.o
 libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o
+libqos-imx-obj-y = $(libqos-obj-y) tests/libqos/i2c-imx.o
 
 tests/rtc-test$(EXESUF): tests/rtc-test.o
 tests/m48t59-test$(EXESUF): tests/m48t59-test.o
 tests/fdc-test$(EXESUF): tests/fdc-test.o
 tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o
 tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
+tests/ds1338-test$(EXESUF): tests/ds1338-test.o $(libqos-imx-obj-y)
 tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
 tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
 
diff --git a/tests/ds1338-test.c b/tests/ds1338-test.c
new file mode 100644
index 000..3e3fa0b
--- /dev/null
+++ b/tests/ds1338-test.c
@@ -0,0 +1,64 @@
+/*
+ * QTest testcase for the DS1338 RTC
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "libqtest.h"
+#include "libqos/i2c.h"
+
+#include 
+
+#define IMX25_I2C_0_BASE 0x43F8
+
+#define DS1338_ADDR 0x68
+
+static I2CAdapter *i2c;
+static uint8_t addr;
+
+#define bcd2bin(x)(((x) & 0x0f) + ((x) >> 4) * 10)
+
+static void send_and_receive(void)
+{
+uint8_t cmd[1];
+uint8_t resp[7];
+time_t now = time(NULL);
+struct tm *tm_ptr = localtime(&now);
+
+/* reset the index in the RTC memory */
+cmd[0] = 0;
+i2c_send(i2c, addr, cmd, 1);
+
+/* retrieve the date */
+i2c_recv(i2c, addr, resp, 7);
+
+/* check retreived time againt local time */
+g_assert_cmpuint(bcd2bin(resp[4]), == , tm_ptr->tm_mday);
+g_assert_cmpuint(bcd2bin(resp[5]), == , 1 + tm_ptr->tm_mon);
+g_assert_cmpuint(2000 + bcd2bin(resp[6]), == , 1900 + tm_ptr->tm_year);
+}
+
+int main(int argc, char **argv)
+{
+QTestState *s = NULL;
+int ret;
+
+g_test_init(&argc, &argv, NULL);
+
+s = qtest_start("-display none -machine imx25_3ds");
+i2c = imx_i2c_create(IMX25_I2C_0_BASE);
+addr = DS1338_ADDR;
+
+qtest_add_func("/ds1338/tx-rx", send_and_receive);
+
+ret = g_test_run();
+
+if (s) {
+qtest_quit(s);
+}
+g_free(i2c);
+
+return ret;
+}
diff --git a/tests/libqos/i2c-imx.c b/tests/libqos/i2c-imx.c
new file mode 100644
index 000..da7316f
--- /dev/null
+++ b/tests/libqos/i2c-imx.c
@@ -0,0 +1,224 @@
+/*
+ * QTest i.MX I2C driver
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "libqos/i2c.h"
+
+#include 
+#include 
+
+#include "qemu/osdep.h"
+#include "qemu/bswap.h"
+#include "libqtest.h"
+
+enum IMXI2CRegisters {
+IMX_I2C_IADR = 0x00,
+IMX_I2C_IFDR = 0x04,
+IMX_I2C_I2CR = 0x08,
+IMX_I2C_I2SR = 0x0c,
+IMX_I2C_I2DR = 0x10,
+};
+
+enum IMXI2CCRBits {
+IMX_I2C_I2CR_IEN  = 1 << 7,
+IMX_I2C_I2CR_IIEN = 1 << 6,
+IMX_I2C_I2CR_MSTA = 1 << 5,
+IMX_I2C_I2CR_MTX  = 1 << 4,
+IMX_I2C_I2CR_TXAK = 1 << 3,
+IMX_I2C_I2CR_RSTA = 1 << 2,
+};
+
+enum IMXI2CSRBits {
+IMX_I2C_I2SR_ICF  = 1 << 7,
+IMX_I2C_I2SR_IAAF = 1 << 6,
+IMX_I2C_I2SR_IBB  = 1 << 5,
+IMX_I2C_I2SR_IAL  = 1 << 4,
+IMX_I2C_I2SR_SRW  = 1 << 2,
+IMX_I2C_I2SR_IIF  = 1 << 1,
+IMX_I2C_I2SR_RXAK = 1 << 0,
+};
+
+enum IMXI2CDirection {
+IMX_I2C_READ,
+IMX_I2C_WRITE,
+};
+
+typedef struct IMXI2C {
+I2CAdapter parent;
+
+uint64_t addr;
+} IMXI2C;
+
+
+static void imx_i2c_set_slave_addr(IMXI2C *s, uint8_t addr,
+   enum IMXI2CDirection direction)
+{
+   

[Qemu-devel] [PATCH v2 2/4] Add i.MX I2C controller driver.

2013-05-04 Thread Jean-Christophe DUBOIS
The slave mode is not implemented.

Signed-off-by: Jean-Christophe DUBOIS 
---
 default-configs/arm-softmmu.mak |   2 +
 hw/i2c/Makefile.objs|   1 +
 hw/i2c/imx_i2c.c| 383 
 include/hw/arm/imx.h|   1 +
 4 files changed, 387 insertions(+)
 create mode 100644 hw/i2c/imx_i2c.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index b3a0207..a20f112 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -81,3 +81,5 @@ CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
 
 CONFIG_SDHCI=y
+
+CONFIG_IMX_I2C=y
diff --git a/hw/i2c/Makefile.objs b/hw/i2c/Makefile.objs
index 648278e..d27bbaa 100644
--- a/hw/i2c/Makefile.objs
+++ b/hw/i2c/Makefile.objs
@@ -4,4 +4,5 @@ common-obj-$(CONFIG_ACPI) += smbus_ich9.o
 common-obj-$(CONFIG_APM) += pm_smbus.o
 common-obj-$(CONFIG_BITBANG_I2C) += bitbang_i2c.o
 common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o
+common-obj-$(CONFIG_IMX_I2C) += imx_i2c.o
 obj-$(CONFIG_OMAP) += omap_i2c.o
diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c
new file mode 100644
index 000..5b0d046
--- /dev/null
+++ b/hw/i2c/imx_i2c.c
@@ -0,0 +1,383 @@
+/*
+ *  i.MX I2C Bus Serial Interface Emulation
+ *
+ *  Copyright (C) 2013 Jean-Christophe Dubois.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "hw/sysbus.h"
+#include "hw/i2c/i2c.h"
+
+#ifndef IMX_I2C_DEBUG
+#define IMX_I2C_DEBUG 0
+#endif
+
+#define TYPE_IMX_I2C  "imx.i2c"
+#define IMX_I2C(obj)  \
+OBJECT_CHECK(imx_i2c_state, (obj), TYPE_IMX_I2C)
+
+/* i.MX I2C memory map */
+#define IMX_I2C_MEM_SIZE   0x14
+#define IADR_ADDR  0x00  /* address register */
+#define IFDR_ADDR  0x04  /* frequency divider register */
+#define I2CR_ADDR  0x08  /* control register */
+#define I2SR_ADDR  0x0c  /* status register */
+#define I2DR_ADDR  0x10  /* data register */
+
+#define IADR_MASK  0xFE
+#define IADR_RESET 0
+
+#define IFDR_MASK  0x3F
+#define IFDR_RESET 0
+
+#define I2CR_IEN   (1 << 7)
+#define I2CR_IIEN  (1 << 6)
+#define I2CR_MSTA  (1 << 5)
+#define I2CR_MTX   (1 << 4)
+#define I2CR_TXAK  (1 << 3)
+#define I2CR_RSTA  (1 << 2)
+#define I2CR_MASK  0xFC
+#define I2CR_RESET 0
+
+#define I2SR_ICF   (1 << 7)
+#define I2SR_IAAF  (1 << 6)
+#define I2SR_IBB   (1 << 5)
+#define I2SR_IAL   (1 << 4)
+#define I2SR_SRW   (1 << 2)
+#define I2SR_IIF   (1 << 1)
+#define I2SR_RXAK  (1 << 0)
+#define I2SR_MASK  0xE9
+#define I2SR_RESET 0x81
+
+#define I2DR_MASK  0xFF
+#define I2DR_RESET 0
+
+#define ADDR_RESET 0xFF00
+
+#if IMX_I2C_DEBUG
+#define DPRINT(fmt, args...)  \
+do { fprintf(stderr, "%s: "fmt, __func__, ## args); } while (0)
+
+static const char *imx_i2c_get_regname(unsigned offset)
+{
+switch (offset) {
+case IADR_ADDR:
+return "IADR";
+case IFDR_ADDR:
+return "IFDR";
+case I2CR_ADDR:
+return "I2CR";
+case I2SR_ADDR:
+return "I2SR";
+case I2DR_ADDR:
+return "I2DR";
+default:
+return "[?]";
+}
+}
+#else
+#define DPRINT(fmt, args...)  do { } while (0)
+#endif
+
+typedef struct imx_i2c_state {
+SysBusDevice parent_obj;
+MemoryRegion iomem;
+i2c_bus *bus;
+qemu_irq irq;
+
+uint16_t  address;
+
+uint16_t iadr;
+uint16_t ifdr;
+uint16_t i2cr;
+uint16_t i2sr;
+uint16_t i2dr_read;
+uint16_t i2dr_write;
+} imx_i2c_state;
+
+static inline bool imx_i2c_is_enabled(imx_i2c_state *s)
+{
+return s->i2cr & I2CR_IEN;
+}
+
+static inline bool imx_i2c_interrupt_is_enabled(imx_i2c_state *s)
+{
+return s->i2cr & I2CR_IIEN;
+}
+
+static inlin

Re: [Qemu-devel] [PATCH v2 4/4] Add qtest support for i.MX I2C device emulation.

2013-05-04 Thread Jean-Christophe DUBOIS

On 05/04/2013 06:53 PM, Andreas Färber wrote:

Am 04.05.2013 16:09, schrieb Jean-Christophe DUBOIS:


+#include "qemu/bswap.h"

Is this one needed?


No, I will remove it.


+enum IMXI2CRegisters {
+IMX_I2C_IADR = 0x00,
+IMX_I2C_IFDR = 0x04,
+IMX_I2C_I2CR = 0x08,
+IMX_I2C_I2SR = 0x0c,
+IMX_I2C_I2DR = 0x10,
+};
+
+enum IMXI2CCRBits {
+IMX_I2C_I2CR_IEN  = 1 << 7,
+IMX_I2C_I2CR_IIEN = 1 << 6,
+IMX_I2C_I2CR_MSTA = 1 << 5,
+IMX_I2C_I2CR_MTX  = 1 << 4,
+IMX_I2C_I2CR_TXAK = 1 << 3,
+IMX_I2C_I2CR_RSTA = 1 << 2,
+};
+
+enum IMXI2CSRBits {
+IMX_I2C_I2SR_ICF  = 1 << 7,
+IMX_I2C_I2SR_IAAF = 1 << 6,
+IMX_I2C_I2SR_IBB  = 1 << 5,
+IMX_I2C_I2SR_IAL  = 1 << 4,
+IMX_I2C_I2SR_SRW  = 1 << 2,
+IMX_I2C_I2SR_IIF  = 1 << 1,
+IMX_I2C_I2SR_RXAK = 1 << 0,
+};
+
+enum IMXI2CDirection {
+IMX_I2C_READ,
+IMX_I2C_WRITE,
+};

libqos/i2c-omap.c was a driver for an unmaintained legacy device.
i.MX I2C however is being added by you in 2/4, so it would be better to
put these constants in a header in 2/4 for reuse here (i2c/imx_regs.h?).

Otherwise looking fine!


Will do in next version.

Meanwhile, other comments on the series are welcome.

JC



Regards,
Andreas





Re: [Qemu-devel] [PATCH v2 2/4] Add i.MX I2C controller driver.

2013-05-04 Thread Jean-Christophe DUBOIS

On 05/05/2013 05:14 AM, Peter Crosthwaite wrote:

Hi JC,

Thanks for actioning the comments.

On Sun, May 5, 2013 at 12:09 AM, Jean-Christophe DUBOIS
 wrote:

The slave mode is not implemented.

Signed-off-by: Jean-Christophe DUBOIS 
---

As a general rule you need to indicate changes between the last
version and this version (changlog). My personal preference is to do
it here - below the line on individual patch emails, although others
do their changlogs in cover letters for entire series. Either system
is acceptable.


I'll do



  default-configs/arm-softmmu.mak |   2 +
  hw/i2c/Makefile.objs|   1 +
  hw/i2c/imx_i2c.c| 383 
  include/hw/arm/imx.h|   1 +
  4 files changed, 387 insertions(+)
  create mode 100644 hw/i2c/imx_i2c.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index b3a0207..a20f112 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -81,3 +81,5 @@ CONFIG_VERSATILE_PCI=y
  CONFIG_VERSATILE_I2C=y

  CONFIG_SDHCI=y
+
+CONFIG_IMX_I2C=y
diff --git a/hw/i2c/Makefile.objs b/hw/i2c/Makefile.objs
index 648278e..d27bbaa 100644
--- a/hw/i2c/Makefile.objs
+++ b/hw/i2c/Makefile.objs
@@ -4,4 +4,5 @@ common-obj-$(CONFIG_ACPI) += smbus_ich9.o
  common-obj-$(CONFIG_APM) += pm_smbus.o
  common-obj-$(CONFIG_BITBANG_I2C) += bitbang_i2c.o
  common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o
+common-obj-$(CONFIG_IMX_I2C) += imx_i2c.o
  obj-$(CONFIG_OMAP) += omap_i2c.o
diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c
new file mode 100644
index 000..5b0d046
--- /dev/null
+++ b/hw/i2c/imx_i2c.c
@@ -0,0 +1,383 @@
+/*
+ *  i.MX I2C Bus Serial Interface Emulation
+ *
+ *  Copyright (C) 2013 Jean-Christophe Dubois.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "hw/sysbus.h"
+#include "hw/i2c/i2c.h"
+
+#ifndef IMX_I2C_DEBUG
+#define IMX_I2C_DEBUG 0
+#endif
+
+#define TYPE_IMX_I2C  "imx.i2c"
+#define IMX_I2C(obj)  \
+OBJECT_CHECK(imx_i2c_state, (obj), TYPE_IMX_I2C)
+
+/* i.MX I2C memory map */
+#define IMX_I2C_MEM_SIZE   0x14
+#define IADR_ADDR  0x00  /* address register */
+#define IFDR_ADDR  0x04  /* frequency divider register */
+#define I2CR_ADDR  0x08  /* control register */
+#define I2SR_ADDR  0x0c  /* status register */
+#define I2DR_ADDR  0x10  /* data register */
+
+#define IADR_MASK  0xFE
+#define IADR_RESET 0
+
+#define IFDR_MASK  0x3F
+#define IFDR_RESET 0
+
+#define I2CR_IEN   (1 << 7)
+#define I2CR_IIEN  (1 << 6)
+#define I2CR_MSTA  (1 << 5)
+#define I2CR_MTX   (1 << 4)
+#define I2CR_TXAK  (1 << 3)
+#define I2CR_RSTA  (1 << 2)
+#define I2CR_MASK  0xFC
+#define I2CR_RESET 0
+
+#define I2SR_ICF   (1 << 7)
+#define I2SR_IAAF  (1 << 6)
+#define I2SR_IBB   (1 << 5)
+#define I2SR_IAL   (1 << 4)
+#define I2SR_SRW   (1 << 2)
+#define I2SR_IIF   (1 << 1)
+#define I2SR_RXAK  (1 << 0)
+#define I2SR_MASK  0xE9
+#define I2SR_RESET 0x81
+
+#define I2DR_MASK  0xFF
+#define I2DR_RESET 0
+
+#define ADDR_RESET 0xFF00
+
+#if IMX_I2C_DEBUG
+#define DPRINT(fmt, args...)  \
+do { fprintf(stderr, "%s: "fmt, __func__, ## args); } while (0)
+
+static const char *imx_i2c_get_regname(unsigned offset)
+{
+switch (offset) {
+case IADR_ADDR:
+return "IADR";
+case IFDR_ADDR:
+return "IFDR";
+case I2CR_ADDR:
+return "I2CR";
+case I2SR_ADDR:
+return "I2SR";
+case I2DR_ADDR:
+return "I2DR";
+default:
+return "[?]";
+}
+}
+#else
+#define DPRINT(fmt, args...)  do { } while (0)
+#endif
+
+typedef struct imx_i2c_state {

types should be in CamelCase IMXI2

Re: [Qemu-devel] [PATCH v2 2/4] Add i.MX I2C controller driver.

2013-05-05 Thread Jean-Christophe DUBOIS

On 05/05/2013 01:53 PM, Peter Crosthwaite wrote:

Hi Peter,

On Sun, May 5, 2013 at 9:41 PM, Peter Maydell  wrote:

On 5 May 2013 11:53, Peter Crosthwaite  wrote:

On Sun, May 5, 2013 at 8:47 PM, Peter Maydell  wrote:

On 5 May 2013 04:58, Jean-Christophe DUBOIS  wrote:

no extract16() macro spotted.
Should one be added?

There's no need for one -- just use extract32. The only
reason for having a separate extract64 is to avoid doing
64 bit arithmetic when we don't have to, I think.


perhaps a quick:

#define extract16(a, b, c) (uint16_t)extract32((uint16_t)(a), (b), (c))

would keep the 16bit device code explicit and clean? Save on
dummy casts in certain situations as well (but not this one).

Hmm, what situations would ever require a cast of the result
or the input of extract32?


The one off the top of my head:

fprintf(stderr, "your 16 field is :%" PRIx16 "\n", extract16(foo, bar, baz));

Otherwise you would have to match PRIx32 to extract 16 which is clumsy.

But aren't there there some other varargs situations that may require
casts as well?

As for the input cast, I got nothin, I just put it in there for
completeness. Meet you half way and drop the input cast and keep the
output?

Regards,
Peter


I will use extract32() for now.

JC




-- PMM






Re: [Qemu-devel] [PATCH v2 2/4] Add i.MX I2C controller driver.

2013-05-05 Thread Jean-Christophe DUBOIS

On 05/05/2013 01:34 PM, Andreas Färber wrote:

Am 05.05.2013 05:14, schrieb Peter Crosthwaite:

On Sun, May 5, 2013 at 12:09 AM, Jean-Christophe DUBOIS
 wrote:

diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c
new file mode 100644
index 000..5b0d046
--- /dev/null
+++ b/hw/i2c/imx_i2c.c

[...]

+typedef struct imx_i2c_state {

types should be in CamelCase IMXI2CState


+SysBusDevice parent_obj;

While at it, please add a white line here. Background is that this
parent field will pretty likely go away once we switch to a better
object-orientation framework - if it were in a header we would annotate
it as private and thus hidden from documentation.


Will do.




+MemoryRegion iomem;
+i2c_bus *bus;

Please rather use i2c_bus bus; and qbus_create_inline() in instance_init.


I am using i2c_init_bus() which itself uses qbus_create().

Do you mean we should not use i2c_init_bus() but instead reimplement 
locally based on qbus_create_inline()?


JC




Re: [Qemu-devel] [PATCH v2 1/4] Add i.MX FEC Ethernet driver

2013-05-05 Thread Jean-Christophe DUBOIS

On 05/05/2013 05:11 AM, Peter Crosthwaite wrote:

Hi JC,

On Sun, May 5, 2013 at 12:09 AM, Jean-Christophe DUBOIS
  wrote:

This is based on the mcf_fec.c FEC implementation for ColdFire.

 * a generic phy was added (borrowed from lan9118).
 * The buffer management is also modified as buffers are
   slightly different between coldfire and i.MX.

Signed-off-by: Jean-Christophe DUBOIS
---
  default-configs/arm-softmmu.mak |   1 +
  hw/net/Makefile.objs|   1 +
  hw/net/imx_fec.c| 748 
  3 files changed, 750 insertions(+)
  create mode 100644 hw/net/imx_fec.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 27cbe3d..b3a0207 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -28,6 +28,7 @@ CONFIG_SSI_SD=y
  CONFIG_SSI_M25P80=y
  CONFIG_LAN9118=y
  CONFIG_SMC91C111=y
+CONFIG_IMX_FEC=y
  CONFIG_DS1338=y
  CONFIG_PFLASH_CFI01=y
  CONFIG_PFLASH_CFI02=y
diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index 951cca3..5c84727 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -18,6 +18,7 @@ common-obj-$(CONFIG_OPENCORES_ETH) += opencores_eth.o
  common-obj-$(CONFIG_XGMAC) += xgmac.o
  common-obj-$(CONFIG_MIPSNET) += mipsnet.o
  common-obj-$(CONFIG_XILINX_AXI) += xilinx_axienet.o
+common-obj-$(CONFIG_IMX_FEC) += imx_fec.o

  common-obj-$(CONFIG_CADENCE) += cadence_gem.o
  common-obj-$(CONFIG_STELLARIS_ENET) += stellaris_enet.o
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
new file mode 100644
index 000..e894d50
--- /dev/null
+++ b/hw/net/imx_fec.c
@@ -0,0 +1,748 @@
+/*
+ * i.MX Fast Ethernet Controller emulation.
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois.
+ *
+ * Based on Coldfire Fast Ethernet Controller emulation.
+ *
+ * Copyright (c) 2007 CodeSourcery.
+ *
+ * This code is licensed under the GPL
+ */
+#include "hw/sysbus.h"
+#include "net/net.h"
+#include "hw/devices.h"
+

is devices.h needed? Its a collection of helper init fns for misc
devices pre QOM style.


No, I'll remove it. It was part of mcf_fec.c

+/* For crc32 */
+#include 
+
+#include "hw/arm/imx.h"
+
+#ifndef IMX_FEC_DEBUG
+#define IMX_FEC_DEBUG  0
+#endif
+
+#ifndef IMX_PHY_DEBUG
+#define IMX_PHY_DEBUG  0
+#endif
+
+#if IMX_FEC_DEBUG
+#define DPRINTF(fmt, ...) \
+do { printf("imx_fec: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) do {} while (0)
+#endif
+
+#if IMX_PHY_DEBUG
+#define DPPRINTF(fmt, ...) \
+do { printf("imx_fec_phy: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DPPRINTF(fmt, ...) do {} while (0)
+#endif
+
+#define FEC_MAX_FRAME_SIZE 2032
+
+typedef struct {
+SysBusDevice busdev;

parent_obj

OK

+NICState *nic;
+NICConf conf;
+qemu_irq irq;
+MemoryRegion iomem;
+
+uint32_t irq_state;
+uint32_t eir;
+uint32_t eimr;
+uint32_t rx_enabled;
+uint32_t rx_descriptor;
+uint32_t tx_descriptor;
+uint32_t ecr;
+uint32_t mmfr;
+uint32_t mscr;
+uint32_t mibc;
+uint32_t rcr;
+uint32_t tcr;
+uint32_t tfwr;
+uint32_t frsr;
+uint32_t erdsr;
+uint32_t etdsr;
+uint32_t emrbr;
+uint32_t miigsk_cfgr;
+uint32_t miigsk_enr;
+
+uint32_t phy_status;
+uint32_t phy_control;
+uint32_t phy_advertise;
+uint32_t phy_int;
+uint32_t phy_int_mask;
+} imx_fec_state;

types are CamelCase (IMXFECState)

OK

+
+static const VMStateDescription vmstate_imx_fec = {
+.name = "fec",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(irq_state, imx_fec_state),
+VMSTATE_UINT32(eir, imx_fec_state),
+VMSTATE_UINT32(eimr, imx_fec_state),
+VMSTATE_UINT32(rx_enabled, imx_fec_state),
+VMSTATE_UINT32(rx_descriptor, imx_fec_state),
+VMSTATE_UINT32(tx_descriptor, imx_fec_state),
+VMSTATE_UINT32(ecr, imx_fec_state),
+VMSTATE_UINT32(mmfr, imx_fec_state),
+VMSTATE_UINT32(mscr, imx_fec_state),
+VMSTATE_UINT32(mibc, imx_fec_state),
+VMSTATE_UINT32(rcr, imx_fec_state),
+VMSTATE_UINT32(tcr, imx_fec_state),
+VMSTATE_UINT32(tfwr, imx_fec_state),
+VMSTATE_UINT32(frsr, imx_fec_state),
+VMSTATE_UINT32(erdsr, imx_fec_state),
+VMSTATE_UINT32(etdsr, imx_fec_state),
+VMSTATE_UINT32(emrbr, imx_fec_state),
+VMSTATE_UINT32(miigsk_cfgr, imx_fec_state),
+VMSTATE_UINT32(miigsk_enr, imx_fec_state),
+
+VMSTATE_UINT32(phy_status, imx_fec_state),
+VMSTATE_UINT32(phy_control, imx_fec_state),
+VMSTATE_UINT32(phy_advertise, imx_fec_state),
+VMSTATE_UINT32(phy_int, imx_fec_state),
+VMSTATE_UINT32(phy_int_mask, imx_fec_state),
+VMSTATE_END_OF_LIST()
+}
+};
+
+#define PHY_INT_ENERGYON(1 << 7)
+#define PHY_INT_AUTONEG_COMPLET

Re: [Qemu-devel] [PATCH v2 1/4] Add i.MX FEC Ethernet driver

2013-05-05 Thread Jean-Christophe DUBOIS

On 05/05/2013 03:31 PM, Andreas Färber wrote:

Am 05.05.2013 15:14, schrieb Jean-Christophe DUBOIS:

On 05/05/2013 05:11 AM, Peter Crosthwaite wrote:

Hi JC,

On Sun, May 5, 2013 at 12:09 AM, Jean-Christophe DUBOIS
  wrote:

This is based on the mcf_fec.c FEC implementation for ColdFire.

Note that ColdFire is one of the least maintained targets in QEMU...


Well, that's too bad.

I actually believe the ColdFire FEC implementation would not work in 
actual QEMU (but I don't plan to build a ColdFire Kernel and RootFS to 
find out).





+static int imx_fec_can_receive(NetClientState *nc)
+{
+imx_fec_state *s = qemu_get_nic_opaque(nc);
+

Andreas, do we care about QOM casts coming from random void* opaques?

Generally no. If we ever switch to C++ or some other OO language we'll
have to touch casts anyway.

Peter, please note that I usually don't have time to read through all
patches - noticed this inline question incidentally only.


OK, I am going to do a QOM cast anyway.

You should check how frequently this function is called - the current
OBJECT_CHECK() implementation does at least one string comparison, so
I'd suggest to avoid it here. That is, if the type passed in as opaque
matches the type assigned here (thinking of interfaces).


Hum, ... you are going to be unhappy with my new patch.




+return s->rx_enabled;
+}

[snip]

Not knowing this piece of hardware, might it make sense to call it
"imx-fec" when there's another FEC for ColdFire?


I am calling it "imx.fec" in the new version of the file (to be 
equivalent to "imx.i2c" I did for I2C).



  Or are they the same
thing and should be unified?
Well, they are certainly very similar but are different on a few points. 
In particular the "buffer descriptors" are reversed between i.MX and 
Coldfire. Linux does a compile time decision about these buffer 
descriptors but I don't know how this would work with Qemu (can you make 
a different compile time decision for 2 different targets?).


We could also implement a more cumbersome run time decision but I wanted 
to keep simple.


And anyway I don't have Coldfire (cross compilers, rootfs, ...) setup 
around to test.




Regards,
Andreas






[Qemu-devel] [PATCH v3 0/4] Add i.MX25 support through the 3DS evaluation board

2013-05-05 Thread Jean-Christophe DUBOIS
This series of patches add the support for the i.MX25 processor through the
Freescale 3DS evaluation board.

For now a limited set of devices are supported.
* GPT timers (from i.MX31)
* EPIT timers (from i.MX31)
* Serial ports (from i.MX31)
* Ethernet FEC port
* I2C controller

It also adds qtest support for the I2C controller.

Jean-Christophe DUBOIS (4):
  Add i.MX FEC Ethernet emulator
  Add i.MX I2C controller emulator
  Add i.MX25 3DS evaluation board support.
  Add qtest support for i.MX I2C device emulation.

 default-configs/arm-softmmu.mak |   3 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/imx25_3ds.c  | 258 +
 hw/i2c/Makefile.objs|   1 +
 hw/i2c/imx_i2c.c| 352 ++
 hw/i2c/imx_i2c_regs.h   |  63 
 hw/net/Makefile.objs|   1 +
 hw/net/imx_fec.c| 793 
 include/hw/arm/imx.h|   1 +
 tests/Makefile  |   3 +
 tests/ds1338-test.c |  64 
 tests/libqos/i2c-imx.c  | 198 ++
 tests/libqos/i2c.h  |   3 +
 13 files changed, 1741 insertions(+)
 create mode 100644 hw/arm/imx25_3ds.c
 create mode 100644 hw/i2c/imx_i2c.c
 create mode 100644 hw/i2c/imx_i2c_regs.h
 create mode 100644 hw/net/imx_fec.c
 create mode 100644 tests/ds1338-test.c
 create mode 100644 tests/libqos/i2c-imx.c

-- 
1.8.1.2




[Qemu-devel] [PATCH v3 3/4] Add i.MX25 3DS evaluation board support.

2013-05-05 Thread Jean-Christophe DUBOIS
For now we support:
* timers (GPT and EPIT)
* serial ports (only 2 out of 5 possible)
* ethernet (through the newly added FEC driver)
* I2C (through the newly added I2C driver)

A ds1338 I2C RTC chip was added on the first i2c bus to allow
automatic test through qtest. This RTC is not present on the real
board.

Changes since v1:
* Added a ds1338 I2C device for qtest purpose.

Changes since v2:
* none

Signed-off-by: Jean-Christophe DUBOIS 
---
 default-configs/arm-softmmu.mak |   3 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/imx25_3ds.c  | 258 
 3 files changed, 262 insertions(+)
 create mode 100644 hw/arm/imx25_3ds.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 27cbe3d..a20f112 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -28,6 +28,7 @@ CONFIG_SSI_SD=y
 CONFIG_SSI_M25P80=y
 CONFIG_LAN9118=y
 CONFIG_SMC91C111=y
+CONFIG_IMX_FEC=y
 CONFIG_DS1338=y
 CONFIG_PFLASH_CFI01=y
 CONFIG_PFLASH_CFI02=y
@@ -80,3 +81,5 @@ CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
 
 CONFIG_SDHCI=y
+
+CONFIG_IMX_I2C=y
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 9e3a06f..2f4280d 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -2,6 +2,7 @@ obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
 obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
 obj-y += omap_sx1.o palm.o pic_cpu.o realview.o spitz.o stellaris.o
 obj-y += tosa.o versatilepb.o vexpress.o xilinx_zynq.o z2.o
+obj-y += imx25_3ds.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
 obj-y += omap1.o omap2.o strongarm.o
diff --git a/hw/arm/imx25_3ds.c b/hw/arm/imx25_3ds.c
new file mode 100644
index 000..b7ff26d
--- /dev/null
+++ b/hw/arm/imx25_3ds.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2013 Jean-Christophe Dubois
+ *
+ * 3Dstack Board System emulation.
+ *
+ * Based on hw/arm/kzm.c
+ *
+ * Copyright (c) 2008 OKL and 2011 NICTA
+ * Written by Hans at OK-Labs
+ * Updated by Peter Chubb.
+ *
+ * This code is licensed under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a i.MX25 3D-Stack PDK board
+ */
+
+#include "hw/sysbus.h"
+#include "exec/address-spaces.h"
+#include "hw/hw.h"
+#include "hw/arm/arm.h"
+#include "hw/devices.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+#include "hw/char/serial.h"
+#include "hw/arm/imx.h"
+#include "hw/i2c/i2c.h"
+
+#include "sysemu/qtest.h"
+
+/* Memory map for 3D-Stack Emulation Baseboard:
+ * 0x-0x3fff 16k ROM  IGNORED
+ * 0x4000-0x00403fff Reserved IGNORED
+ * 0x00404000-0x00408fff 20k ROM  IGNORED
+ * 0x00409000-0x0fff Reserved IGNORED
+ * 0x1000-0x1fff Reserved IGNORED
+ * 0x2000-0x2fff Reserved IGNORED
+ * 0x3000-0x3fff Reserved IGNORED
+ * 0x4000-0x43ef Reserved IGNORED
+ * 0x43f0-0x6fff I.MX25 Internal Register Space
+ *   0x43f0 IO_AREA0
+ *   0x43f8 I2C0  EMULATED
+ *   0x43f84000 I2C2  EMULATED
+ *   0x43f98000 I2C1  EMULATED
+ *   0x43f9 UART1 EMULATED
+ *   0x43f94000 UART2 EMULATED
+ *   0x43fb UART4 IGNORED
+ *   0x43fb4000 UART5 IGNORED
+ *   0x5000c000 UART3 IGNORED
+ *   0x53f8 CCM   EMULATED
+ *   0x53f84000 GPT 4 EMULATED
+ *   0x53f88000 GPT 3 EMULATED
+ *   0x53f8c000 GPT 2 EMULATED
+ *   0x53f9 GPT 1 EMULATED
+ *   0x53f94000 PIT 1 EMULATED
+ *   0x53f98000 PIT 2 EMULATED
+ *   0x6800 ASIC  EMULATED
+ * 0x7800-0x7801 SRAM EMULATED
+ * 0x7802-0x7fff SRAM AliasingEMULATED
+ * 0x8000-0x87ff RAM + Alias  EMULATED
+ * 0x9000-0x9fff RAM + Alias  EMULATED
+ * 0xa000-0xa7ff FlashIGNORED
+ * 0xa800-0xafff FlashIGNORED
+ * 0xb000-0xb1ff SRAM IGNORED
+ * 0xb200-0xb3ff SRAM IGNORED
+ * 0xb400-0xb5ff CS4  IGNORED
+ * 0xb600-0xb8000fff Reserved IGNORED
+ * 0xb8001000-0xb8001fff SDRAM CTRL reg   IGNORED
+ * 0xb8002000-0xb8002fff WEIM CTRL regIGNORED
+ * 0xb8003000-0xb8003fff M3IF CTRL regIGNORED
+ * 0xb8004000-0xb8004fff EMI CTRL reg IGNORED
+ * 0xb8005000-0xbaff Reserved 

[Qemu-devel] [PATCH v3 1/4] Add i.MX FEC Ethernet emulator

2013-05-05 Thread Jean-Christophe DUBOIS
This is based on the mcf_fec.c FEC implementation for ColdFire.

* a generic phy was added (borrowed from lan9118).
* The buffer management is also modified as buffers are
  slightly different between coldfire and i.MX.

Changes since V1:
* none

Changes since v2:
* use QOM cast
* reworked debug printf
* use CamelCase for state type
* warn with qemu_log_mask(LOG_GUEST_ERROR) or qemu_log_mask(LOG_UNIMP)
* move to dma_memory_read/write API
* rework interrupt handling
* use qemu_flush_queued_packets() in rx_enable()

Signed-off-by: Jean-Christophe DUBOIS 
---
 hw/net/Makefile.objs |   1 +
 hw/net/imx_fec.c | 793 +++
 include/hw/arm/imx.h |   1 +
 3 files changed, 795 insertions(+)
 create mode 100644 hw/net/imx_fec.c

diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index 951cca3..5c84727 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -18,6 +18,7 @@ common-obj-$(CONFIG_OPENCORES_ETH) += opencores_eth.o
 common-obj-$(CONFIG_XGMAC) += xgmac.o
 common-obj-$(CONFIG_MIPSNET) += mipsnet.o
 common-obj-$(CONFIG_XILINX_AXI) += xilinx_axienet.o
+common-obj-$(CONFIG_IMX_FEC) += imx_fec.o
 
 common-obj-$(CONFIG_CADENCE) += cadence_gem.o
 common-obj-$(CONFIG_STELLARIS_ENET) += stellaris_enet.o
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
new file mode 100644
index 000..aee0a4a
--- /dev/null
+++ b/hw/net/imx_fec.c
@@ -0,0 +1,793 @@
+/*
+ * i.MX Fast Ethernet Controller emulation.
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois.
+ *
+ * Based on Coldfire Fast Ethernet Controller emulation.
+ *
+ * Copyright (c) 2007 CodeSourcery.
+ *
+ * This code is licensed under the GPL
+ */
+
+#include "qemu/bitops.h"
+
+#include "sysemu/dma.h"
+
+#include "net/net.h"
+
+#include "hw/sysbus.h"
+
+/* For crc32 */
+#include 
+
+#include "hw/arm/imx.h"
+
+#ifndef IMX_FEC_DEBUG
+#define IMX_FEC_DEBUG  0
+#endif
+
+#ifndef IMX_PHY_DEBUG
+#define IMX_PHY_DEBUG  0
+#endif
+
+#if IMX_FEC_DEBUG
+#define FEC_PRINTF(fmt, ...) \
+do { fprintf(stderr, "imx_fec[%s]: " fmt , __func__, ## __VA_ARGS__); \
+   } while (0)
+#else
+#define FEC_PRINTF(fmt, ...) do {} while (0)
+#endif
+
+#if IMX_PHY_DEBUG
+#define PHY_PRINTF(fmt, ...) \
+do { fprintf(stderr, "imx_fec_phy[%s]: " fmt , __func__, ## __VA_ARGS__); \
+   } while (0)
+#else
+#define PHY_PRINTF(fmt, ...) do {} while (0)
+#endif
+
+#define TYPE_IMX_FEC  "imx.fec"
+#define IMX_FEC(obj)  \
+OBJECT_CHECK(IMXFECState, (obj), TYPE_IMX_FEC)
+
+#define FEC_MAX_FRAME_SIZE 2032
+
+typedef struct {
+SysBusDevice parent_obj;
+
+NICState *nic;
+NICConf conf;
+qemu_irq irq;
+MemoryRegion iomem;
+
+uint32_t irq_state;
+uint32_t eir;
+uint32_t eimr;
+uint32_t rx_enabled;
+uint32_t rx_descriptor;
+uint32_t tx_descriptor;
+uint32_t ecr;
+uint32_t mmfr;
+uint32_t mscr;
+uint32_t mibc;
+uint32_t rcr;
+uint32_t tcr;
+uint32_t tfwr;
+uint32_t frsr;
+uint32_t erdsr;
+uint32_t etdsr;
+uint32_t emrbr;
+uint32_t miigsk_cfgr;
+uint32_t miigsk_enr;
+
+uint32_t phy_status;
+uint32_t phy_control;
+uint32_t phy_advertise;
+uint32_t phy_int;
+uint32_t phy_int_mask;
+} IMXFECState;
+
+static const VMStateDescription vmstate_imx_fec = {
+.name = TYPE_IMX_FEC,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(irq_state, IMXFECState),
+VMSTATE_UINT32(eir, IMXFECState),
+VMSTATE_UINT32(eimr, IMXFECState),
+VMSTATE_UINT32(rx_enabled, IMXFECState),
+VMSTATE_UINT32(rx_descriptor, IMXFECState),
+VMSTATE_UINT32(tx_descriptor, IMXFECState),
+VMSTATE_UINT32(ecr, IMXFECState),
+VMSTATE_UINT32(mmfr, IMXFECState),
+VMSTATE_UINT32(mscr, IMXFECState),
+VMSTATE_UINT32(mibc, IMXFECState),
+VMSTATE_UINT32(rcr, IMXFECState),
+VMSTATE_UINT32(tcr, IMXFECState),
+VMSTATE_UINT32(tfwr, IMXFECState),
+VMSTATE_UINT32(frsr, IMXFECState),
+VMSTATE_UINT32(erdsr, IMXFECState),
+VMSTATE_UINT32(etdsr, IMXFECState),
+VMSTATE_UINT32(emrbr, IMXFECState),
+VMSTATE_UINT32(miigsk_cfgr, IMXFECState),
+VMSTATE_UINT32(miigsk_enr, IMXFECState),
+
+VMSTATE_UINT32(phy_status, IMXFECState),
+VMSTATE_UINT32(phy_control, IMXFECState),
+VMSTATE_UINT32(phy_advertise, IMXFECState),
+VMSTATE_UINT32(phy_int, IMXFECState),
+VMSTATE_UINT32(phy_int_mask, IMXFECState),
+
+VMSTATE_END_OF_LIST()
+}
+};
+
+#define PHY_INT_ENERGYON(1 << 7)
+#define PHY_INT_AUTONEG_COMPLETE(1 << 6)
+#define PHY_INT_FAULT   (1 << 5)
+#define PHY_INT_DOWN(1 << 4)
+#define PHY_INT_AUTONEG_LP 

[Qemu-devel] [PATCH v3 2/4] Add i.MX I2C controller emulator

2013-05-05 Thread Jean-Christophe DUBOIS
The slave mode is not implemented.

Changes since v1:
* use QOM cast
* run checkpatch on code
* added restrictin on MemoryRegionOps
* use DeviceClass::realise as init function

Changes since v2:
* use CamelCase for state type
* use extrac32() for bit manipilation.
* improve QOM cast
* separate regs definition in its own file (to be reused by qtest)

Signed-off-by: Jean-Christophe DUBOIS 
---
 hw/i2c/Makefile.objs  |   1 +
 hw/i2c/imx_i2c.c  | 352 ++
 hw/i2c/imx_i2c_regs.h |  63 +
 3 files changed, 416 insertions(+)
 create mode 100644 hw/i2c/imx_i2c.c
 create mode 100644 hw/i2c/imx_i2c_regs.h

diff --git a/hw/i2c/Makefile.objs b/hw/i2c/Makefile.objs
index 648278e..d27bbaa 100644
--- a/hw/i2c/Makefile.objs
+++ b/hw/i2c/Makefile.objs
@@ -4,4 +4,5 @@ common-obj-$(CONFIG_ACPI) += smbus_ich9.o
 common-obj-$(CONFIG_APM) += pm_smbus.o
 common-obj-$(CONFIG_BITBANG_I2C) += bitbang_i2c.o
 common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o
+common-obj-$(CONFIG_IMX_I2C) += imx_i2c.o
 obj-$(CONFIG_OMAP) += omap_i2c.o
diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c
new file mode 100644
index 000..9debcce
--- /dev/null
+++ b/hw/i2c/imx_i2c.c
@@ -0,0 +1,352 @@
+/*
+ *  i.MX I2C Bus Serial Interface Emulation
+ *
+ *  Copyright (C) 2013 Jean-Christophe Dubois.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "qemu/bitops.h"
+
+#include "hw/sysbus.h"
+#include "hw/i2c/i2c.h"
+
+#include "hw/i2c/imx_i2c_regs.h"
+
+#ifndef IMX_I2C_DEBUG
+#define IMX_I2C_DEBUG 0
+#endif
+
+#if IMX_I2C_DEBUG
+#define DPRINT(fmt, ...)  \
+do { fprintf(stderr, "imx_i2c[%s]: " fmt, __func__, ## __VA_ARGS__); \
+   } while (0)
+
+static const char *imx_i2c_get_regname(unsigned offset)
+{
+switch (offset) {
+case IADR_ADDR:
+return "IADR";
+case IFDR_ADDR:
+return "IFDR";
+case I2CR_ADDR:
+return "I2CR";
+case I2SR_ADDR:
+return "I2SR";
+case I2DR_ADDR:
+return "I2DR";
+default:
+return "[?]";
+}
+}
+#else
+#define DPRINT(fmt, args...)  do { } while (0)
+#endif
+
+#define TYPE_IMX_I2C  "imx.i2c"
+#define IMX_I2C(obj)  \
+OBJECT_CHECK(IMXI2CState, (obj), TYPE_IMX_I2C)
+
+typedef struct IMXI2CState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+i2c_bus *bus;
+qemu_irq irq;
+
+uint16_t  address;
+
+uint16_t iadr;
+uint16_t ifdr;
+uint16_t i2cr;
+uint16_t i2sr;
+uint16_t i2dr_read;
+uint16_t i2dr_write;
+} IMXI2CState;
+
+static inline bool imx_i2c_is_enabled(IMXI2CState *s)
+{
+return s->i2cr & I2CR_IEN;
+}
+
+static inline bool imx_i2c_interrupt_is_enabled(IMXI2CState *s)
+{
+return s->i2cr & I2CR_IIEN;
+}
+
+static inline bool imx_i2c_is_master(IMXI2CState *s)
+{
+return s->i2cr & I2CR_MSTA;
+}
+
+static inline bool imx_i2c_direction_is_tx(IMXI2CState *s)
+{
+return s->i2cr & I2CR_MTX;
+}
+
+static void imx_i2c_reset(DeviceState *dev)
+{
+IMXI2CState *s = IMX_I2C(dev);
+
+if (s->address != ADDR_RESET) {
+i2c_end_transfer(s->bus);
+}
+
+s->address= ADDR_RESET;
+s->iadr   = IADR_RESET;
+s->ifdr   = IFDR_RESET;
+s->i2cr   = I2CR_RESET;
+s->i2sr   = I2SR_RESET;
+s->i2dr_read  = I2DR_RESET;
+s->i2dr_write = I2DR_RESET;
+}
+
+static inline void imx_i2c_raise_interrupt(IMXI2CState *s)
+{
+/*
+ * raise an interrupt if the device is enabled and it is configured
+ * to generate some interrupts.
+ */
+if (imx_i2c_is_enabled(s) && imx_i2c_interrupt_is_enabled(s)) {
+s->i2sr |= I2SR_IIF;
+qemu_irq_raise(s->irq);
+}
+}
+
+static uint64_t imx_i2c_read(void *opaque, hwaddr offset,
+ unsigned size)
+{
+uint16_t value;
+IMXI2CState *s = IMX_I2C(opaque);
+
+switch (offset) {
+case IADR_ADDR:
+value = s->iadr;
+break;
+case IFDR_ADDR:
+value = s->ifdr;
+break;
+case I2CR_ADDR:
+value = s->i2cr;
+break;
+case I2SR

[Qemu-devel] [PATCH v3 4/4] Add qtest support for i.MX I2C device emulation.

2013-05-05 Thread Jean-Christophe DUBOIS
This is using a ds1338 RTC chip on the i2c bus. This RTC
chip is not present on the real board.

Changes since v1:
* not present on v1

Changes since v2:
* use a common header file for I2C regs definition

Signed-off-by: Jean-Christophe DUBOIS 
---
 tests/Makefile |   3 +
 tests/ds1338-test.c|  64 
 tests/libqos/i2c-imx.c | 198 +
 tests/libqos/i2c.h |   3 +
 4 files changed, 268 insertions(+)
 create mode 100644 tests/ds1338-test.c
 create mode 100644 tests/libqos/i2c-imx.c

diff --git a/tests/Makefile b/tests/Makefile
index bf41d10..5f7a0e0 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -64,6 +64,7 @@ gcov-files-x86_64-y = $(subst 
i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y)
 gcov-files-sparc-y += hw/m48t59.c
 gcov-files-sparc64-y += hw/m48t59.c
 check-qtest-arm-y = tests/tmp105-test$(EXESUF)
+check-qtest-arm-y += tests/ds1338-test$(EXESUF)
 gcov-files-arm-y += hw/tmp105.c
 
 GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h 
tests/test-qmp-commands.h
@@ -123,12 +124,14 @@ libqos-obj-y += tests/libqos/i2c.o
 libqos-pc-obj-y = $(libqos-obj-y) tests/libqos/pci-pc.o 
tests/libqos/fw_cfg-pc.o
 libqos-pc-obj-y += tests/libqos/malloc-pc.o
 libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o
+libqos-imx-obj-y = $(libqos-obj-y) tests/libqos/i2c-imx.o
 
 tests/rtc-test$(EXESUF): tests/rtc-test.o
 tests/m48t59-test$(EXESUF): tests/m48t59-test.o
 tests/fdc-test$(EXESUF): tests/fdc-test.o
 tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o
 tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
+tests/ds1338-test$(EXESUF): tests/ds1338-test.o $(libqos-imx-obj-y)
 tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
 tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
 
diff --git a/tests/ds1338-test.c b/tests/ds1338-test.c
new file mode 100644
index 000..3e3fa0b
--- /dev/null
+++ b/tests/ds1338-test.c
@@ -0,0 +1,64 @@
+/*
+ * QTest testcase for the DS1338 RTC
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "libqtest.h"
+#include "libqos/i2c.h"
+
+#include 
+
+#define IMX25_I2C_0_BASE 0x43F8
+
+#define DS1338_ADDR 0x68
+
+static I2CAdapter *i2c;
+static uint8_t addr;
+
+#define bcd2bin(x)(((x) & 0x0f) + ((x) >> 4) * 10)
+
+static void send_and_receive(void)
+{
+uint8_t cmd[1];
+uint8_t resp[7];
+time_t now = time(NULL);
+struct tm *tm_ptr = localtime(&now);
+
+/* reset the index in the RTC memory */
+cmd[0] = 0;
+i2c_send(i2c, addr, cmd, 1);
+
+/* retrieve the date */
+i2c_recv(i2c, addr, resp, 7);
+
+/* check retreived time againt local time */
+g_assert_cmpuint(bcd2bin(resp[4]), == , tm_ptr->tm_mday);
+g_assert_cmpuint(bcd2bin(resp[5]), == , 1 + tm_ptr->tm_mon);
+g_assert_cmpuint(2000 + bcd2bin(resp[6]), == , 1900 + tm_ptr->tm_year);
+}
+
+int main(int argc, char **argv)
+{
+QTestState *s = NULL;
+int ret;
+
+g_test_init(&argc, &argv, NULL);
+
+s = qtest_start("-display none -machine imx25_3ds");
+i2c = imx_i2c_create(IMX25_I2C_0_BASE);
+addr = DS1338_ADDR;
+
+qtest_add_func("/ds1338/tx-rx", send_and_receive);
+
+ret = g_test_run();
+
+if (s) {
+qtest_quit(s);
+}
+g_free(i2c);
+
+return ret;
+}
diff --git a/tests/libqos/i2c-imx.c b/tests/libqos/i2c-imx.c
new file mode 100644
index 000..173bfc5
--- /dev/null
+++ b/tests/libqos/i2c-imx.c
@@ -0,0 +1,198 @@
+/*
+ * QTest i.MX I2C driver
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "libqos/i2c.h"
+
+#include 
+#include 
+
+#include "qemu/osdep.h"
+#include "libqtest.h"
+
+#include "hw/i2c/imx_i2c_regs.h"
+
+enum IMXI2CDirection {
+IMX_I2C_READ,
+IMX_I2C_WRITE,
+};
+
+typedef struct IMXI2C {
+I2CAdapter parent;
+
+uint64_t addr;
+} IMXI2C;
+
+
+static void imx_i2c_set_slave_addr(IMXI2C *s, uint8_t addr,
+   enum IMXI2CDirection direction)
+{
+writeb(s->addr + I2DR_ADDR, (addr << 1) |
+   (direction == IMX_I2C_READ ? 1 : 0));
+}
+
+static void imx_i2c_send(I2CAdapter *i2c, uint8_t addr,
+ const uint8_t *buf, uint16_t len)
+{
+IMXI2C *s = (IMXI2C *)i2c;
+uint8_t data;
+uint8_t status;
+uint16_t size = 0;
+
+if (!len) {
+return;
+}
+
+/* set the bus for write */
+data = I2CR_IEN |
+   I2CR_IIEN |
+   I2CR_MSTA |
+   I2CR_MTX |
+   I2CR_TXAK;
+
+writeb(s->addr + I2CR_ADDR, data);
+status = readb(s-&g

Re: [Qemu-devel] [PATCH v3 2/4] Add i.MX I2C controller emulator

2013-05-05 Thread Jean-Christophe DUBOIS

On 05/06/2013 04:19 AM, Peter Crosthwaite wrote:

Hi JC,

On Mon, May 6, 2013 at 12:28 AM, Jean-Christophe DUBOIS
 wrote:

The slave mode is not implemented.

Changes since v1:
 * use QOM cast
 * run checkpatch on code
 * added restrictin on MemoryRegionOps
 * use DeviceClass::realise as init function

Changes since v2:
 * use CamelCase for state type
 * use extrac32() for bit manipilation.
 * improve QOM cast
 * separate regs definition in its own file (to be reused by qtest)


Per-patch change logs need to go below the line ...


Signed-off-by: Jean-Christophe DUBOIS 
---

... here. Otherwise it will go into the mainline git log on merge.

The edit can be done by hand edit before the send-email. But I use a
scripted approach personally to move my changelogs out of commit
message pre send (and my working tree has commits formatted similar to
what you have sent here). Others using the manual flow tend to just
use cover letter change logs I think.

OK



  hw/i2c/Makefile.objs  |   1 +
  hw/i2c/imx_i2c.c  | 352 ++
  hw/i2c/imx_i2c_regs.h |  63 +
  3 files changed, 416 insertions(+)
  create mode 100644 hw/i2c/imx_i2c.c
  create mode 100644 hw/i2c/imx_i2c_regs.h

diff --git a/hw/i2c/Makefile.objs b/hw/i2c/Makefile.objs
index 648278e..d27bbaa 100644
--- a/hw/i2c/Makefile.objs
+++ b/hw/i2c/Makefile.objs
@@ -4,4 +4,5 @@ common-obj-$(CONFIG_ACPI) += smbus_ich9.o
  common-obj-$(CONFIG_APM) += pm_smbus.o
  common-obj-$(CONFIG_BITBANG_I2C) += bitbang_i2c.o
  common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o
+common-obj-$(CONFIG_IMX_I2C) += imx_i2c.o
  obj-$(CONFIG_OMAP) += omap_i2c.o
diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c
new file mode 100644
index 000..9debcce
--- /dev/null
+++ b/hw/i2c/imx_i2c.c
@@ -0,0 +1,352 @@
+/*
+ *  i.MX I2C Bus Serial Interface Emulation
+ *
+ *  Copyright (C) 2013 Jean-Christophe Dubois.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "qemu/bitops.h"
+
+#include "hw/sysbus.h"
+#include "hw/i2c/i2c.h"
+
+#include "hw/i2c/imx_i2c_regs.h"
+
+#ifndef IMX_I2C_DEBUG
+#define IMX_I2C_DEBUG 0
+#endif
+
+#if IMX_I2C_DEBUG
+#define DPRINT(fmt, ...)  \
+do { fprintf(stderr, "imx_i2c[%s]: " fmt, __func__, ## __VA_ARGS__); \
+   } while (0)
+
+static const char *imx_i2c_get_regname(unsigned offset)
+{
+switch (offset) {
+case IADR_ADDR:
+return "IADR";
+case IFDR_ADDR:
+return "IFDR";
+case I2CR_ADDR:
+return "I2CR";
+case I2SR_ADDR:
+return "I2SR";
+case I2DR_ADDR:
+return "I2DR";
+default:
+return "[?]";
+}
+}
+#else
+#define DPRINT(fmt, args...)  do { } while (0)
+#endif
+
+#define TYPE_IMX_I2C  "imx.i2c"
+#define IMX_I2C(obj)  \
+OBJECT_CHECK(IMXI2CState, (obj), TYPE_IMX_I2C)
+
+typedef struct IMXI2CState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+i2c_bus *bus;
+qemu_irq irq;
+
+uint16_t  address;
+
+uint16_t iadr;
+uint16_t ifdr;
+uint16_t i2cr;
+uint16_t i2sr;
+uint16_t i2dr_read;
+uint16_t i2dr_write;
+} IMXI2CState;
+
+static inline bool imx_i2c_is_enabled(IMXI2CState *s)
+{
+return s->i2cr & I2CR_IEN;
+}
+
+static inline bool imx_i2c_interrupt_is_enabled(IMXI2CState *s)
+{
+return s->i2cr & I2CR_IIEN;
+}
+
+static inline bool imx_i2c_is_master(IMXI2CState *s)
+{
+return s->i2cr & I2CR_MSTA;
+}
+
+static inline bool imx_i2c_direction_is_tx(IMXI2CState *s)
+{
+return s->i2cr & I2CR_MTX;
+}
+
+static void imx_i2c_reset(DeviceState *dev)
+{
+IMXI2CState *s = IMX_I2C(dev);
+
+if (s->address != ADDR_RESET) {
+i2c_end_transfer(s->bus);
+}

I don't think this is right, unless your device has actual logic that
cleans up the I2C bus on hard reset (which would be very strange). The
I2C bus should be responsible for its own reset as a reset (if needed
at all). As an I2C bus is stateless, cleanup of an inflight
transaction should happen naturally when a reset happens both master
and slave side. Did this manifest for you as a bug at any stage? If so
I t

[Qemu-devel] [PATCH v4 0/4] Add i.MX25 support through the 3DS evaluation board

2013-05-07 Thread Jean-Christophe DUBOIS
This series of patches add the support for the i.MX25 processor through the
Freescale 3DS evaluation board.

For now a limited set of devices are supported.
* GPT timers (from i.MX31)
* EPIT timers (from i.MX31)
* Serial ports (from i.MX31)
* Ethernet FEC port
* I2C controller

It also adds qtest support for the I2C controller.

Jean-Christophe DUBOIS (4):
  Add i.MX FEC Ethernet emulator
  Add i.MX I2C controller emulator
  Add i.MX25 3DS evaluation board support.
  Add qtest support for i.MX I2C device emulation.

 default-configs/arm-softmmu.mak |   3 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/imx25_3ds.c  | 251 
 hw/i2c/Makefile.objs|   1 +
 hw/i2c/imx_i2c.c| 371 ++
 hw/i2c/imx_i2c_regs.h   |  63 
 hw/net/Makefile.objs|   1 +
 hw/net/imx_fec.c| 818 
 include/hw/arm/imx.h|  12 +-
 tests/Makefile  |   3 +
 tests/ds1338-test.c |  75 
 tests/libqos/i2c-imx.c  | 209 ++
 tests/libqos/i2c.h  |   3 +
 13 files changed, 1805 insertions(+), 6 deletions(-)
 create mode 100644 hw/arm/imx25_3ds.c
 create mode 100644 hw/i2c/imx_i2c.c
 create mode 100644 hw/i2c/imx_i2c_regs.h
 create mode 100644 hw/net/imx_fec.c
 create mode 100644 tests/ds1338-test.c
 create mode 100644 tests/libqos/i2c-imx.c

-- 
1.8.1.2




[Qemu-devel] [PATCH v4 1/4] Add i.MX FEC Ethernet emulator

2013-05-07 Thread Jean-Christophe DUBOIS
This is based on the mcf_fec.c FEC implementation for ColdFire.

* a generic phy was added (borrowed from lan9118).
* The buffer management is also modified as buffers are
  slightly different between coldfire and i.MX.

Signed-off-by: Jean-Christophe DUBOIS 
---

Changes since V1:
* none

Changes since v2:
* use QOM cast
* reworked debug printf
* use CamelCase for state type
* warn with qemu_log_mask(LOG_GUEST_ERROR) or qemu_log_mask(LOG_UNIMP)
* move to dma_memory_read/write API
* rework interrupt handling
* use qemu_flush_queued_packets() in rx_enable()

Changes since v3:
* use realise for device initialization
* More QOM cast
* reworked debug printf some more
* standardise GPL header
* use CamelCase for buffer descriptor type

 default-configs/arm-softmmu.mak |   1 +
 hw/net/Makefile.objs|   1 +
 hw/net/imx_fec.c| 818 
 include/hw/arm/imx.h|  10 +-
 4 files changed, 824 insertions(+), 6 deletions(-)
 create mode 100644 hw/net/imx_fec.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 27cbe3d..b3a0207 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -28,6 +28,7 @@ CONFIG_SSI_SD=y
 CONFIG_SSI_M25P80=y
 CONFIG_LAN9118=y
 CONFIG_SMC91C111=y
+CONFIG_IMX_FEC=y
 CONFIG_DS1338=y
 CONFIG_PFLASH_CFI01=y
 CONFIG_PFLASH_CFI02=y
diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index 951cca3..5c84727 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -18,6 +18,7 @@ common-obj-$(CONFIG_OPENCORES_ETH) += opencores_eth.o
 common-obj-$(CONFIG_XGMAC) += xgmac.o
 common-obj-$(CONFIG_MIPSNET) += mipsnet.o
 common-obj-$(CONFIG_XILINX_AXI) += xilinx_axienet.o
+common-obj-$(CONFIG_IMX_FEC) += imx_fec.o
 
 common-obj-$(CONFIG_CADENCE) += cadence_gem.o
 common-obj-$(CONFIG_STELLARIS_ENET) += stellaris_enet.o
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
new file mode 100644
index 000..e25d6cd
--- /dev/null
+++ b/hw/net/imx_fec.c
@@ -0,0 +1,818 @@
+/*
+ * i.MX Fast Ethernet Controller emulation.
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois.
+ *
+ * Based on Coldfire Fast Ethernet Controller emulation.
+ *
+ * Copyright (c) 2007 CodeSourcery.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/bitops.h"
+
+#include "sysemu/dma.h"
+
+#include "net/net.h"
+
+#include "hw/sysbus.h"
+
+/* For crc32 */
+#include 
+
+#include "hw/arm/imx.h"
+
+#ifndef IMX_FEC_DEBUG
+#define IMX_FEC_DEBUG  0
+#endif
+
+#ifndef IMX_PHY_DEBUG
+#define IMX_PHY_DEBUG  0
+#endif
+
+#define TYPE_IMX_FEC  "imx.fec"
+
+#if IMX_FEC_DEBUG
+#define FEC_PRINTF(fmt, ...) \
+do { fprintf(stderr, "%s[%s]: " fmt , TYPE_IMX_FEC, __func__, \
+ ## __VA_ARGS__); \
+} while (0)
+#else
+#define FEC_PRINTF(fmt, ...) do {} while (0)
+#endif
+
+#if IMX_PHY_DEBUG
+#define PHY_PRINTF(fmt, ...) \
+do { fprintf(stderr, "%s.phy[%s]: " fmt , TYPE_IMX_FEC, __func__, \
+ ## __VA_ARGS__); \
+} while (0)
+#else
+#define PHY_PRINTF(fmt, ...) do {} while (0)
+#endif
+
+#define IMX_FEC(obj)  \
+OBJECT_CHECK(IMXFECState, (obj), TYPE_IMX_FEC)
+
+#define FEC_MAX_FRAME_SIZE 2032
+
+typedef struct {
+SysBusDevice parent_obj;
+
+NICState *nic;
+NICConf conf;
+qemu_irq irq;
+MemoryRegion iomem;
+
+uint32_t irq_state;
+uint32_t eir;
+uint32_t eimr;
+uint32_t rx_enabled;
+uint32_t rx_descriptor;
+uint32_t tx_descriptor;
+uint32_t ecr;
+uint32_t mmfr;
+uint32_t mscr;
+uint32_t mibc;
+uint32_t rcr;
+uint32_t tcr;
+uint32_t tfwr;
+uint32_t frsr;
+uint32_t erdsr;
+uint32_t etdsr;
+uint32_t emrbr;
+uint32_t miigsk_cfgr;
+uint32_t miigsk_enr;
+
+uint32_t phy_status;
+uint32_t phy_control;
+uint32_t phy_advertise;
+uint32_t phy_int;
+uint32_t phy_int_mask;
+} IMXFECState;
+
+static const VMStateDescription vmstate_imx_fec = {
+.name = TYPE_IMX_FEC,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(irq_state, IMXFECState),
+VMSTATE_UINT32(eir, IMXFEC

[Qemu-devel] [PATCH v4 4/4] Add qtest support for i.MX I2C device emulation.

2013-05-07 Thread Jean-Christophe DUBOIS
This is using a ds1338 RTC chip on the i2c bus. This RTC
chip is not present on the real board.

Signed-off-by: Jean-Christophe DUBOIS 
---

Changes since v1:
* not present on v1

Changes since v2:
* use a common header file for I2C regs definition

Changes since v3:
* rework GPL headers.

 tests/Makefile |   3 +
 tests/ds1338-test.c|  75 ++
 tests/libqos/i2c-imx.c | 209 +
 tests/libqos/i2c.h |   3 +
 4 files changed, 290 insertions(+)
 create mode 100644 tests/ds1338-test.c
 create mode 100644 tests/libqos/i2c-imx.c

diff --git a/tests/Makefile b/tests/Makefile
index bf41d10..5f7a0e0 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -64,6 +64,7 @@ gcov-files-x86_64-y = $(subst 
i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y)
 gcov-files-sparc-y += hw/m48t59.c
 gcov-files-sparc64-y += hw/m48t59.c
 check-qtest-arm-y = tests/tmp105-test$(EXESUF)
+check-qtest-arm-y += tests/ds1338-test$(EXESUF)
 gcov-files-arm-y += hw/tmp105.c
 
 GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h 
tests/test-qmp-commands.h
@@ -123,12 +124,14 @@ libqos-obj-y += tests/libqos/i2c.o
 libqos-pc-obj-y = $(libqos-obj-y) tests/libqos/pci-pc.o 
tests/libqos/fw_cfg-pc.o
 libqos-pc-obj-y += tests/libqos/malloc-pc.o
 libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o
+libqos-imx-obj-y = $(libqos-obj-y) tests/libqos/i2c-imx.o
 
 tests/rtc-test$(EXESUF): tests/rtc-test.o
 tests/m48t59-test$(EXESUF): tests/m48t59-test.o
 tests/fdc-test$(EXESUF): tests/fdc-test.o
 tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o
 tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
+tests/ds1338-test$(EXESUF): tests/ds1338-test.o $(libqos-imx-obj-y)
 tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
 tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
 
diff --git a/tests/ds1338-test.c b/tests/ds1338-test.c
new file mode 100644
index 000..fbc989b
--- /dev/null
+++ b/tests/ds1338-test.c
@@ -0,0 +1,75 @@
+/*
+ * QTest testcase for the DS1338 RTC
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "libqtest.h"
+#include "libqos/i2c.h"
+
+#include 
+
+#define IMX25_I2C_0_BASE 0x43F8
+
+#define DS1338_ADDR 0x68
+
+static I2CAdapter *i2c;
+static uint8_t addr;
+
+#define bcd2bin(x)(((x) & 0x0f) + ((x) >> 4) * 10)
+
+static void send_and_receive(void)
+{
+uint8_t cmd[1];
+uint8_t resp[7];
+time_t now = time(NULL);
+struct tm *tm_ptr = gmtime(&now);
+
+/* reset the index in the RTC memory */
+cmd[0] = 0;
+i2c_send(i2c, addr, cmd, 1);
+
+/* retrieve the date */
+i2c_recv(i2c, addr, resp, 7);
+
+/* check retreived time againt local time */
+g_assert_cmpuint(bcd2bin(resp[4]), == , tm_ptr->tm_mday);
+g_assert_cmpuint(bcd2bin(resp[5]), == , 1 + tm_ptr->tm_mon);
+g_assert_cmpuint(2000 + bcd2bin(resp[6]), == , 1900 + tm_ptr->tm_year);
+}
+
+int main(int argc, char **argv)
+{
+QTestState *s = NULL;
+int ret;
+
+g_test_init(&argc, &argv, NULL);
+
+s = qtest_start("-display none -machine imx25_3ds");
+i2c = imx_i2c_create(IMX25_I2C_0_BASE);
+addr = DS1338_ADDR;
+
+qtest_add_func("/ds1338/tx-rx", send_and_receive);
+
+ret = g_test_run();
+
+if (s) {
+qtest_quit(s);
+}
+g_free(i2c);
+
+return ret;
+}
diff --git a/tests/libqos/i2c-imx.c b/tests/libqos/i2c-imx.c
new file mode 100644
index 000..2b18581
--- /dev/null
+++ b/tests/libqos/i2c-imx.c
@@ -0,0 +1,209 @@
+/*
+ * QTest i.MX I2C driver
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  wi

[Qemu-devel] [PATCH v4 3/4] Add i.MX25 3DS evaluation board support.

2013-05-07 Thread Jean-Christophe DUBOIS
For now we support:
* timers (GPT and EPIT)
* serial ports (only 2 out of 5 possible)
* ethernet (through the newly added FEC driver)
* I2C (through the newly added I2C driver)

A ds1338 I2C RTC chip was added on the first i2c bus to allow
automatic test through qtest. This RTC is not present on the real
board.

Signed-off-by: Jean-Christophe DUBOIS 
---

Changes since v1:
* Added a ds1338 I2C device for qtest purpose.

Changes since v2:
* none

Changes since v3:
* Rework GPL header
* use I2C constructor helper.

 hw/arm/Makefile.objs |   1 +
 hw/arm/imx25_3ds.c   | 251 +++
 2 files changed, 252 insertions(+)
 create mode 100644 hw/arm/imx25_3ds.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 9e3a06f..2f4280d 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -2,6 +2,7 @@ obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
 obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
 obj-y += omap_sx1.o palm.o pic_cpu.o realview.o spitz.o stellaris.o
 obj-y += tosa.o versatilepb.o vexpress.o xilinx_zynq.o z2.o
+obj-y += imx25_3ds.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
 obj-y += omap1.o omap2.o strongarm.o
diff --git a/hw/arm/imx25_3ds.c b/hw/arm/imx25_3ds.c
new file mode 100644
index 000..92f7179
--- /dev/null
+++ b/hw/arm/imx25_3ds.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2013 Jean-Christophe Dubois
+ *
+ * 3Dstack Board System emulation.
+ *
+ * Based on hw/arm/kzm.c
+ *
+ * Copyright (c) 2008 OKL and 2011 NICTA
+ * Written by Hans at OK-Labs
+ * Updated by Peter Chubb.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw/sysbus.h"
+#include "exec/address-spaces.h"
+#include "hw/hw.h"
+#include "hw/arm/arm.h"
+#include "hw/devices.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+#include "hw/char/serial.h"
+#include "hw/arm/imx.h"
+#include "hw/i2c/i2c.h"
+
+#include "sysemu/qtest.h"
+
+/* Memory map for 3D-Stack Emulation Baseboard:
+ * 0x-0x3fff 16k ROM  IGNORED
+ * 0x4000-0x00403fff Reserved IGNORED
+ * 0x00404000-0x00408fff 20k ROM  IGNORED
+ * 0x00409000-0x0fff Reserved IGNORED
+ * 0x1000-0x1fff Reserved IGNORED
+ * 0x2000-0x2fff Reserved IGNORED
+ * 0x3000-0x3fff Reserved IGNORED
+ * 0x4000-0x43ef Reserved IGNORED
+ * 0x43f0-0x6fff I.MX25 Internal Register Space
+ *   0x43f0 IO_AREA0
+ *   0x43f8 I2C0  EMULATED
+ *   0x43f84000 I2C2  EMULATED
+ *   0x43f98000 I2C1  EMULATED
+ *   0x43f9 UART1 EMULATED
+ *   0x43f94000 UART2 EMULATED
+ *   0x5000c000 UART3 EMULATED
+ *   0x53f8 CCM   EMULATED
+ *   0x53f84000 GPT 4 EMULATED
+ *   0x53f88000 GPT 3 EMULATED
+ *   0x53f8c000 GPT 2 EMULATED
+ *   0x53f9 GPT 1 EMULATED
+ *   0x53f94000 PIT 1 EMULATED
+ *   0x53f98000 PIT 2 EMULATED
+ *   0x6800 ASIC  EMULATED
+ * 0x7800-0x7801 SRAM EMULATED
+ * 0x7802-0x7fff SRAM AliasingEMULATED
+ * 0x8000-0x87ff RAM + Alias  EMULATED
+ * 0x9000-0x9fff RAM + Alias  EMULATED
+ * 0xa000-0xa7ff FlashIGNORED
+ * 0xa800-0xafff FlashIGNORED
+ * 0xb000-0xb1ff SRAM IGNORED
+ * 0xb200-0xb3ff SRAM IGNORED
+ * 0xb400-0xb5ff CS4  IGNORED
+ * 0xb600-0xb8000fff Reserved IGNORED
+ * 0xb8001000-0xb8001fff SDRAM CTRL reg   IGNORED
+ * 0xb8002000-0xb8002fff WEIM CTRL regIGNORED
+ * 0xb8003000-0xb8003fff M3IF CTRL regIGNORED
+ * 0xb8004000-0xb8004fff EMI CTRL reg IGNORED
+ * 0xb8005000-0xbaff Reserved IGNORED
+ * 0xbb00-0xbb000fff NAND flash a

[Qemu-devel] [PATCH v4 2/4] Add i.MX I2C controller emulator

2013-05-07 Thread Jean-Christophe DUBOIS
The slave mode is not implemented.

Signed-off-by: Jean-Christophe DUBOIS 
---

Changes since v1:
* use QOM cast
* run checkpatch on code
* added restrictin on MemoryRegionOps
* use DeviceClass::realise as init function

Changes since v2:
* use CamelCase for state type
* use extrac32() for bit manipilation.
* improve QOM cast
* separate regs definition in its own file (to be reused by qtest)

Changes since v3:
* More QOM cast.
* Rework GPL headers
* Add a constructor helper.
* fix reset()
* rework debug printf

 default-configs/arm-softmmu.mak |   2 +
 hw/i2c/Makefile.objs|   1 +
 hw/i2c/imx_i2c.c| 371 
 hw/i2c/imx_i2c_regs.h   |  63 +++
 include/hw/arm/imx.h|   2 +
 5 files changed, 439 insertions(+)
 create mode 100644 hw/i2c/imx_i2c.c
 create mode 100644 hw/i2c/imx_i2c_regs.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index b3a0207..a20f112 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -81,3 +81,5 @@ CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
 
 CONFIG_SDHCI=y
+
+CONFIG_IMX_I2C=y
diff --git a/hw/i2c/Makefile.objs b/hw/i2c/Makefile.objs
index 648278e..d27bbaa 100644
--- a/hw/i2c/Makefile.objs
+++ b/hw/i2c/Makefile.objs
@@ -4,4 +4,5 @@ common-obj-$(CONFIG_ACPI) += smbus_ich9.o
 common-obj-$(CONFIG_APM) += pm_smbus.o
 common-obj-$(CONFIG_BITBANG_I2C) += bitbang_i2c.o
 common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o
+common-obj-$(CONFIG_IMX_I2C) += imx_i2c.o
 obj-$(CONFIG_OMAP) += omap_i2c.o
diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c
new file mode 100644
index 000..03eef62
--- /dev/null
+++ b/hw/i2c/imx_i2c.c
@@ -0,0 +1,371 @@
+/*
+ *  i.MX I2C Bus Serial Interface Emulation
+ *
+ *  Copyright (C) 2013 Jean-Christophe Dubois.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "qemu/bitops.h"
+
+#include "hw/sysbus.h"
+#include "hw/i2c/i2c.h"
+
+#include "hw/arm/imx.h"
+
+#include "hw/i2c/imx_i2c_regs.h"
+
+#ifndef IMX_I2C_DEBUG
+#define IMX_I2C_DEBUG 0
+#endif
+
+#define TYPE_IMX_I2C  "imx.i2c"
+
+#if IMX_I2C_DEBUG
+#define DPRINT(fmt, ...)  \
+do { fprintf(stderr, "%s[%s]: " fmt, TYPE_IMX_I2C, __func__, \
+ ## __VA_ARGS__); \
+} while (0)
+
+static const char *imx_i2c_get_regname(unsigned offset)
+{
+switch (offset) {
+case IADR_ADDR:
+return "IADR";
+case IFDR_ADDR:
+return "IFDR";
+case I2CR_ADDR:
+return "I2CR";
+case I2SR_ADDR:
+return "I2SR";
+case I2DR_ADDR:
+return "I2DR";
+default:
+return "[?]";
+}
+}
+#else
+#define DPRINT(fmt, args...)  do { } while (0)
+#endif
+
+#define IMX_I2C(obj)  \
+OBJECT_CHECK(IMXI2CState, (obj), TYPE_IMX_I2C)
+
+typedef struct IMXI2CState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+i2c_bus *bus;
+qemu_irq irq;
+
+uint16_t  address;
+
+uint16_t iadr;
+uint16_t ifdr;
+uint16_t i2cr;
+uint16_t i2sr;
+uint16_t i2dr_read;
+uint16_t i2dr_write;
+} IMXI2CState;
+
+static inline bool imx_i2c_is_enabled(IMXI2CState *s)
+{
+return s->i2cr & I2CR_IEN;
+}
+
+static inline bool imx_i2c_interrupt_is_enabled(IMXI2CState *s)
+{
+return s->i2cr & I2CR_IIEN;
+}
+
+static inline bool imx_i2c_is_master(IMXI2CState *s)
+{
+return s->i2cr & I2CR_MSTA;
+}
+
+static inline bool imx_i2c_direction_is_tx(IMXI2CState *s)
+{
+return s->i2cr & I2CR_MTX;
+}
+
+static void imx_i2c_reset(DeviceState *dev)
+{
+IMXI2CState *s = IMX_I2C(dev);
+
+s->address= ADDR_RESET;
+s->iadr   = IADR_RESET;
+s->ifdr   = IFDR_RESET;
+s->i2cr   = I2CR_RESET;
+s->i2sr   = I2SR_RESET;
+s->i2dr_read  = I2DR_RESET;
+s->i2dr_write = I2DR_RESET;
+}
+
+static inline void imx_i2c_raise_interrupt(IMXI2CState *s)
+{
+/*
+ * raise an interrupt if the device is enabled and it is configured
+ * to generate some interrupts.
+ */
+if (imx_i2c

[Qemu-devel] [PATCH 14/14] [ARM] i.MX25: Fix DTS tree for real hardware.

2013-05-07 Thread Jean-Christophe DUBOIS
i.MX25 PDK only has 64 MB DDR

Signed-off-by: Jean-Christophe DUBOIS 
---
 arch/arm/board/imx25/dts/3dstack/3dstack.dtsi| 3 ++-
 arch/arm/board/imx25/dts/3dstack/one_guest_versatile.dts | 5 +
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/arm/board/imx25/dts/3dstack/3dstack.dtsi 
b/arch/arm/board/imx25/dts/3dstack/3dstack.dtsi
index 29ff746..9c59d93 100644
--- a/arch/arm/board/imx25/dts/3dstack/3dstack.dtsi
+++ b/arch/arm/board/imx25/dts/3dstack/3dstack.dtsi
@@ -27,9 +27,10 @@
 * unless specified by "-m" option. If you have
 * X MB then we will be able to access only first
 * X MB starting at physical_addr.
+ * Note: the 3Dstack board only has 64 MB DDR.
 */
physical_addr = <0x8000>;
-   physical_size = <0x0800>; /* 128 MB */
+   physical_size = <0x0400>; /* 64 MB */
};
 
soc {
diff --git a/arch/arm/board/imx25/dts/3dstack/one_guest_versatile.dts 
b/arch/arm/board/imx25/dts/3dstack/one_guest_versatile.dts
index e6ec7ea..7d5e2d6 100644
--- a/arch/arm/board/imx25/dts/3dstack/one_guest_versatile.dts
+++ b/arch/arm/board/imx25/dts/3dstack/one_guest_versatile.dts
@@ -10,10 +10,7 @@
 
  /* Update guest0 memory regions */
  "devtree attr set /guests/guest0/aspace/mem0 
host_physical_addr physaddr 0x8200",
- "devtree attr set /guests/guest0/aspace/mem0 
physical_size physsize 0x0600",
-
- /* Connect guest0/virtio-net0 netport to netbridge0 */
- "devtree attr set /guests/guest0/aspace/virtio-net0 
switch string netbridge0",
+ "devtree attr set /guests/guest0/aspace/mem0 
physical_size physsize 0x0200",
 
  /* Update guest0 flash region */
  "devtree attr set /guests/guest0/aspace/nor_flash 
host_physical_addr physaddr 0x8100",
-- 
1.8.1.2




Re: [Qemu-devel] [PATCH 14/14] [ARM] i.MX25: Fix DTS tree for real hardware.

2013-05-07 Thread Jean-Christophe DUBOIS

Sorry for the 14/14 in the subject.

JC

On 05/07/2013 11:29 AM, Jean-Christophe DUBOIS wrote:

i.MX25 PDK only has 64 MB DDR

Signed-off-by: Jean-Christophe DUBOIS 
---
  arch/arm/board/imx25/dts/3dstack/3dstack.dtsi| 3 ++-
  arch/arm/board/imx25/dts/3dstack/one_guest_versatile.dts | 5 +
  2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/arm/board/imx25/dts/3dstack/3dstack.dtsi 
b/arch/arm/board/imx25/dts/3dstack/3dstack.dtsi
index 29ff746..9c59d93 100644
--- a/arch/arm/board/imx25/dts/3dstack/3dstack.dtsi
+++ b/arch/arm/board/imx25/dts/3dstack/3dstack.dtsi
@@ -27,9 +27,10 @@
 * unless specified by "-m" option. If you have
 * X MB then we will be able to access only first
 * X MB starting at physical_addr.
+ * Note: the 3Dstack board only has 64 MB DDR.
 */
physical_addr = <0x8000>;
-   physical_size = <0x0800>; /* 128 MB */
+   physical_size = <0x0400>; /* 64 MB */
};
  
  		soc {

diff --git a/arch/arm/board/imx25/dts/3dstack/one_guest_versatile.dts 
b/arch/arm/board/imx25/dts/3dstack/one_guest_versatile.dts
index e6ec7ea..7d5e2d6 100644
--- a/arch/arm/board/imx25/dts/3dstack/one_guest_versatile.dts
+++ b/arch/arm/board/imx25/dts/3dstack/one_guest_versatile.dts
@@ -10,10 +10,7 @@
  
  			  /* Update guest0 memory regions */

  "devtree attr set /guests/guest0/aspace/mem0 
host_physical_addr physaddr 0x8200",
- "devtree attr set /guests/guest0/aspace/mem0 physical_size 
physsize 0x0600",
-
- /* Connect guest0/virtio-net0 netport to netbridge0 */
- "devtree attr set /guests/guest0/aspace/virtio-net0 switch 
string netbridge0",
+ "devtree attr set /guests/guest0/aspace/mem0 physical_size 
physsize 0x0200",
  
  			  /* Update guest0 flash region */

  "devtree attr set /guests/guest0/aspace/nor_flash 
host_physical_addr physaddr 0x8100",





Re: [Qemu-devel] [PATCH v4 2/4] Add i.MX I2C controller emulator

2013-05-07 Thread Jean-Christophe DUBOIS

On 05/07/2013 09:35 AM, Jean-Christophe DUBOIS wrote:

The slave mode is not implemented.

Signed-off-by: Jean-Christophe DUBOIS 
---

Changes since v1:
 * use QOM cast
 * run checkpatch on code
 * added restrictin on MemoryRegionOps
 * use DeviceClass::realise as init function

Changes since v2:
 * use CamelCase for state type
 * use extrac32() for bit manipilation.
 * improve QOM cast
 * separate regs definition in its own file (to be reused by qtest)

Changes since v3:
 * More QOM cast.
 * Rework GPL headers
 * Add a constructor helper.


Before you spot it 

The helper is unnecessary. I will use sysbus_create_simple() instead.


 * fix reset()
 * rework debug printf

  default-configs/arm-softmmu.mak |   2 +
  hw/i2c/Makefile.objs|   1 +
  hw/i2c/imx_i2c.c| 371 
  hw/i2c/imx_i2c_regs.h   |  63 +++
  include/hw/arm/imx.h|   2 +
  5 files changed, 439 insertions(+)
  create mode 100644 hw/i2c/imx_i2c.c
  create mode 100644 hw/i2c/imx_i2c_regs.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index b3a0207..a20f112 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -81,3 +81,5 @@ CONFIG_VERSATILE_PCI=y
  CONFIG_VERSATILE_I2C=y
  
  CONFIG_SDHCI=y

+
+CONFIG_IMX_I2C=y
diff --git a/hw/i2c/Makefile.objs b/hw/i2c/Makefile.objs
index 648278e..d27bbaa 100644
--- a/hw/i2c/Makefile.objs
+++ b/hw/i2c/Makefile.objs
@@ -4,4 +4,5 @@ common-obj-$(CONFIG_ACPI) += smbus_ich9.o
  common-obj-$(CONFIG_APM) += pm_smbus.o
  common-obj-$(CONFIG_BITBANG_I2C) += bitbang_i2c.o
  common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o
+common-obj-$(CONFIG_IMX_I2C) += imx_i2c.o
  obj-$(CONFIG_OMAP) += omap_i2c.o
diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c
new file mode 100644
index 000..03eef62
--- /dev/null
+++ b/hw/i2c/imx_i2c.c
@@ -0,0 +1,371 @@
+/*
+ *  i.MX I2C Bus Serial Interface Emulation
+ *
+ *  Copyright (C) 2013 Jean-Christophe Dubois.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "qemu/bitops.h"
+
+#include "hw/sysbus.h"
+#include "hw/i2c/i2c.h"
+
+#include "hw/arm/imx.h"
+
+#include "hw/i2c/imx_i2c_regs.h"
+
+#ifndef IMX_I2C_DEBUG
+#define IMX_I2C_DEBUG 0
+#endif
+
+#define TYPE_IMX_I2C  "imx.i2c"
+
+#if IMX_I2C_DEBUG
+#define DPRINT(fmt, ...)  \
+do { fprintf(stderr, "%s[%s]: " fmt, TYPE_IMX_I2C, __func__, \
+ ## __VA_ARGS__); \
+} while (0)
+
+static const char *imx_i2c_get_regname(unsigned offset)
+{
+switch (offset) {
+case IADR_ADDR:
+return "IADR";
+case IFDR_ADDR:
+return "IFDR";
+case I2CR_ADDR:
+return "I2CR";
+case I2SR_ADDR:
+return "I2SR";
+case I2DR_ADDR:
+return "I2DR";
+default:
+return "[?]";
+}
+}
+#else
+#define DPRINT(fmt, args...)  do { } while (0)
+#endif
+
+#define IMX_I2C(obj)  \
+OBJECT_CHECK(IMXI2CState, (obj), TYPE_IMX_I2C)
+
+typedef struct IMXI2CState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+i2c_bus *bus;
+qemu_irq irq;
+
+uint16_t  address;
+
+uint16_t iadr;
+uint16_t ifdr;
+uint16_t i2cr;
+uint16_t i2sr;
+uint16_t i2dr_read;
+uint16_t i2dr_write;
+} IMXI2CState;
+
+static inline bool imx_i2c_is_enabled(IMXI2CState *s)
+{
+return s->i2cr & I2CR_IEN;
+}
+
+static inline bool imx_i2c_interrupt_is_enabled(IMXI2CState *s)
+{
+return s->i2cr & I2CR_IIEN;
+}
+
+static inline bool imx_i2c_is_master(IMXI2CState *s)
+{
+return s->i2cr & I2CR_MSTA;
+}
+
+static inline bool imx_i2c_direction_is_tx(IMXI2CState *s)
+{
+return s->i2cr & I2CR_MTX;
+}
+
+static void imx_i2c_reset(DeviceState *dev)
+{
+IMXI2CState *s = IMX_I2C(dev);
+
+s->address= ADDR_RESET;
+s->iadr   = IADR_RESET;
+s->ifdr   = IFDR_RESET;
+s->i2cr   = I2CR_RESET;
+s->i2sr   = I2SR_RESET;
+s->i2dr_read  = I2DR_RESET;
+s->i2dr_write = I2DR_RESET;
+}
+
+static inline void imx_i2c_raise_

[Qemu-devel] [PATCH] [ARM] i.MX25: Fix DTS tree for real hardware.

2013-05-08 Thread Jean-Christophe DUBOIS
i.MX25 PDK only has 64 MB DDR

Signed-off-by: Jean-Christophe DUBOIS 
---
 arch/arm/board/imx25/dts/3dstack/3dstack.dtsi| 3 ++-
 arch/arm/board/imx25/dts/3dstack/one_guest_versatile.dts | 5 +
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/arm/board/imx25/dts/3dstack/3dstack.dtsi 
b/arch/arm/board/imx25/dts/3dstack/3dstack.dtsi
index 29ff746..9c59d93 100644
--- a/arch/arm/board/imx25/dts/3dstack/3dstack.dtsi
+++ b/arch/arm/board/imx25/dts/3dstack/3dstack.dtsi
@@ -27,9 +27,10 @@
 * unless specified by "-m" option. If you have
 * X MB then we will be able to access only first
 * X MB starting at physical_addr.
+ * Note: the 3Dstack board only has 64 MB DDR.
 */
physical_addr = <0x8000>;
-   physical_size = <0x0800>; /* 128 MB */
+   physical_size = <0x0400>; /* 64 MB */
};
 
soc {
diff --git a/arch/arm/board/imx25/dts/3dstack/one_guest_versatile.dts 
b/arch/arm/board/imx25/dts/3dstack/one_guest_versatile.dts
index e6ec7ea..7d5e2d6 100644
--- a/arch/arm/board/imx25/dts/3dstack/one_guest_versatile.dts
+++ b/arch/arm/board/imx25/dts/3dstack/one_guest_versatile.dts
@@ -10,10 +10,7 @@
 
  /* Update guest0 memory regions */
  "devtree attr set /guests/guest0/aspace/mem0 
host_physical_addr physaddr 0x8200",
- "devtree attr set /guests/guest0/aspace/mem0 
physical_size physsize 0x0600",
-
- /* Connect guest0/virtio-net0 netport to netbridge0 */
- "devtree attr set /guests/guest0/aspace/virtio-net0 
switch string netbridge0",
+ "devtree attr set /guests/guest0/aspace/mem0 
physical_size physsize 0x0200",
 
  /* Update guest0 flash region */
  "devtree attr set /guests/guest0/aspace/nor_flash 
host_physical_addr physaddr 0x8100",
-- 
1.8.1.2




[Qemu-devel] [PATCH v5 4/4] Add qtest support for i.MX I2C device emulation.

2013-05-08 Thread Jean-Christophe DUBOIS
This is using a ds1338 RTC chip on the i2c bus. This RTC
chip is not present on the real board.

Signed-off-by: Jean-Christophe DUBOIS 
---

Changes since v1:
* not present on v1

Changes since v2:
* use a common header file for I2C regs definition

Changes since v3:
* rework GPL headers.

Changes since v4:
* none

 tests/Makefile |   3 +
 tests/ds1338-test.c|  75 ++
 tests/libqos/i2c-imx.c | 209 +
 tests/libqos/i2c.h |   3 +
 4 files changed, 290 insertions(+)
 create mode 100644 tests/ds1338-test.c
 create mode 100644 tests/libqos/i2c-imx.c

diff --git a/tests/Makefile b/tests/Makefile
index bf41d10..5f7a0e0 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -64,6 +64,7 @@ gcov-files-x86_64-y = $(subst 
i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y)
 gcov-files-sparc-y += hw/m48t59.c
 gcov-files-sparc64-y += hw/m48t59.c
 check-qtest-arm-y = tests/tmp105-test$(EXESUF)
+check-qtest-arm-y += tests/ds1338-test$(EXESUF)
 gcov-files-arm-y += hw/tmp105.c
 
 GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h 
tests/test-qmp-commands.h
@@ -123,12 +124,14 @@ libqos-obj-y += tests/libqos/i2c.o
 libqos-pc-obj-y = $(libqos-obj-y) tests/libqos/pci-pc.o 
tests/libqos/fw_cfg-pc.o
 libqos-pc-obj-y += tests/libqos/malloc-pc.o
 libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o
+libqos-imx-obj-y = $(libqos-obj-y) tests/libqos/i2c-imx.o
 
 tests/rtc-test$(EXESUF): tests/rtc-test.o
 tests/m48t59-test$(EXESUF): tests/m48t59-test.o
 tests/fdc-test$(EXESUF): tests/fdc-test.o
 tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o
 tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
+tests/ds1338-test$(EXESUF): tests/ds1338-test.o $(libqos-imx-obj-y)
 tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
 tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
 
diff --git a/tests/ds1338-test.c b/tests/ds1338-test.c
new file mode 100644
index 000..fbc989b
--- /dev/null
+++ b/tests/ds1338-test.c
@@ -0,0 +1,75 @@
+/*
+ * QTest testcase for the DS1338 RTC
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "libqtest.h"
+#include "libqos/i2c.h"
+
+#include 
+
+#define IMX25_I2C_0_BASE 0x43F8
+
+#define DS1338_ADDR 0x68
+
+static I2CAdapter *i2c;
+static uint8_t addr;
+
+#define bcd2bin(x)(((x) & 0x0f) + ((x) >> 4) * 10)
+
+static void send_and_receive(void)
+{
+uint8_t cmd[1];
+uint8_t resp[7];
+time_t now = time(NULL);
+struct tm *tm_ptr = gmtime(&now);
+
+/* reset the index in the RTC memory */
+cmd[0] = 0;
+i2c_send(i2c, addr, cmd, 1);
+
+/* retrieve the date */
+i2c_recv(i2c, addr, resp, 7);
+
+/* check retreived time againt local time */
+g_assert_cmpuint(bcd2bin(resp[4]), == , tm_ptr->tm_mday);
+g_assert_cmpuint(bcd2bin(resp[5]), == , 1 + tm_ptr->tm_mon);
+g_assert_cmpuint(2000 + bcd2bin(resp[6]), == , 1900 + tm_ptr->tm_year);
+}
+
+int main(int argc, char **argv)
+{
+QTestState *s = NULL;
+int ret;
+
+g_test_init(&argc, &argv, NULL);
+
+s = qtest_start("-display none -machine imx25_3ds");
+i2c = imx_i2c_create(IMX25_I2C_0_BASE);
+addr = DS1338_ADDR;
+
+qtest_add_func("/ds1338/tx-rx", send_and_receive);
+
+ret = g_test_run();
+
+if (s) {
+qtest_quit(s);
+}
+g_free(i2c);
+
+return ret;
+}
diff --git a/tests/libqos/i2c-imx.c b/tests/libqos/i2c-imx.c
new file mode 100644
index 000..2b18581
--- /dev/null
+++ b/tests/libqos/i2c-imx.c
@@ -0,0 +1,209 @@
+/*
+ * QTest i.MX I2C driver
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General

[Qemu-devel] [PATCH v5 3/4] Add i.MX25 3DS evaluation board support.

2013-05-08 Thread Jean-Christophe DUBOIS
For now we support:
* timers (GPT and EPIT)
* serial ports
* ethernet (through the newly added FEC emulator)
* I2C (through the newly added I2C emulator)

Signed-off-by: Jean-Christophe DUBOIS 
---

Changes since v1:
* Added a ds1338 I2C device for qtest purpose.

Changes since v2:
* none
 
Changes since v3:
* Rework GPL header  
* use I2C constructor helper.

Changes since v4:
* use sysbus_create_simple() instead of I2C constructor helper

 hw/arm/Makefile.objs |   1 +
 hw/arm/imx25_3ds.c   | 250 +++
 2 files changed, 251 insertions(+)
 create mode 100644 hw/arm/imx25_3ds.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 9e3a06f..2f4280d 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -2,6 +2,7 @@ obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
 obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
 obj-y += omap_sx1.o palm.o pic_cpu.o realview.o spitz.o stellaris.o
 obj-y += tosa.o versatilepb.o vexpress.o xilinx_zynq.o z2.o
+obj-y += imx25_3ds.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
 obj-y += omap1.o omap2.o strongarm.o
diff --git a/hw/arm/imx25_3ds.c b/hw/arm/imx25_3ds.c
new file mode 100644
index 000..c845195
--- /dev/null
+++ b/hw/arm/imx25_3ds.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2013 Jean-Christophe Dubois
+ *
+ * 3Dstack Board System emulation.
+ *
+ * Based on hw/arm/kzm.c
+ *
+ * Copyright (c) 2008 OKL and 2011 NICTA
+ * Written by Hans at OK-Labs
+ * Updated by Peter Chubb.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw/sysbus.h"
+#include "exec/address-spaces.h"
+#include "hw/hw.h"
+#include "hw/arm/arm.h"
+#include "hw/devices.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+#include "hw/char/serial.h"
+#include "hw/arm/imx.h"
+#include "hw/i2c/i2c.h"
+
+#include "sysemu/qtest.h"
+
+/* Memory map for 3D-Stack Emulation Baseboard:
+ * 0x-0x3fff 16k ROM  IGNORED
+ * 0x4000-0x00403fff Reserved IGNORED
+ * 0x00404000-0x00408fff 20k ROM  IGNORED
+ * 0x00409000-0x0fff Reserved IGNORED
+ * 0x1000-0x1fff Reserved IGNORED
+ * 0x2000-0x2fff Reserved IGNORED
+ * 0x3000-0x3fff Reserved IGNORED
+ * 0x4000-0x43ef Reserved IGNORED
+ * 0x43f0-0x6fff I.MX25 Internal Register Space
+ *   0x43f0 IO_AREA0
+ *   0x43f8 I2C0  EMULATED
+ *   0x43f84000 I2C2  EMULATED
+ *   0x43f98000 I2C1  EMULATED
+ *   0x43f9 UART1 EMULATED
+ *   0x43f94000 UART2 EMULATED
+ *   0x5000c000 UART3 EMULATED
+ *   0x53f8 CCM   EMULATED
+ *   0x53f84000 GPT 4 EMULATED
+ *   0x53f88000 GPT 3 EMULATED
+ *   0x53f8c000 GPT 2 EMULATED
+ *   0x53f9 GPT 1 EMULATED
+ *   0x53f94000 PIT 1 EMULATED
+ *   0x53f98000 PIT 2 EMULATED
+ *   0x6800 ASIC  EMULATED
+ * 0x7800-0x7801 SRAM EMULATED
+ * 0x7802-0x7fff SRAM AliasingEMULATED
+ * 0x8000-0x87ff RAM + Alias  EMULATED
+ * 0x9000-0x9fff RAM + Alias  EMULATED
+ * 0xa000-0xa7ff FlashIGNORED
+ * 0xa800-0xafff FlashIGNORED
+ * 0xb000-0xb1ff SRAM IGNORED
+ * 0xb200-0xb3ff SRAM IGNORED
+ * 0xb400-0xb5ff CS4  IGNORED
+ * 0xb600-0xb8000fff Reserved IGNORED
+ * 0xb8001000-0xb8001fff SDRAM CTRL reg   IGNORED
+ * 0xb8002000-0xb8002fff WEIM CTRL regIGNORED
+ * 0xb8003000-0xb8003fff M3IF CTRL regIGNORED
+ * 0xb8004000-0xb8004fff EMI CTRL reg IGNORED
+ * 0xb8005000-0xbaff Reserved IGNORED
+ * 0xbb00-0xbb000fff NAND flash area buf  IGNORED
+ * 0xbb001000-0xbb0011ff NAND flash r

[Qemu-devel] [PATCH v5 2/4] Add i.MX I2C controller emulator

2013-05-08 Thread Jean-Christophe DUBOIS
The slave mode is not implemented.

Signed-off-by: Jean-Christophe DUBOIS 
---

Changes since v1: 
* use QOM cast
* run checkpatch on code
* added restrictin on MemoryRegionOps
* use DeviceClass::realise as init function

Changes since v2:
* use CamelCase for state type   
* use extrac32() for bit manipilation.
* improve QOM cast   
* separate regs definition in its own file (to be reused by qtest)
 
Changes since v3:
* More QOM cast.
* Rework GPL headers
* Add a constructor helper.
* fix reset()
* rework debug printf

Changes since v4:
* remove the constructor helper

 default-configs/arm-softmmu.mak |   2 +
 hw/i2c/Makefile.objs|   1 +
 hw/i2c/imx_i2c.c| 357 
 hw/i2c/imx_i2c_regs.h   |  63 +++
 4 files changed, 423 insertions(+)
 create mode 100644 hw/i2c/imx_i2c.c
 create mode 100644 hw/i2c/imx_i2c_regs.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index b3a0207..a20f112 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -81,3 +81,5 @@ CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
 
 CONFIG_SDHCI=y
+
+CONFIG_IMX_I2C=y
diff --git a/hw/i2c/Makefile.objs b/hw/i2c/Makefile.objs
index 648278e..d27bbaa 100644
--- a/hw/i2c/Makefile.objs
+++ b/hw/i2c/Makefile.objs
@@ -4,4 +4,5 @@ common-obj-$(CONFIG_ACPI) += smbus_ich9.o
 common-obj-$(CONFIG_APM) += pm_smbus.o
 common-obj-$(CONFIG_BITBANG_I2C) += bitbang_i2c.o
 common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o
+common-obj-$(CONFIG_IMX_I2C) += imx_i2c.o
 obj-$(CONFIG_OMAP) += omap_i2c.o
diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c
new file mode 100644
index 000..292c07b
--- /dev/null
+++ b/hw/i2c/imx_i2c.c
@@ -0,0 +1,357 @@
+/*
+ *  i.MX I2C Bus Serial Interface Emulation
+ *
+ *  Copyright (C) 2013 Jean-Christophe Dubois.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "qemu/bitops.h"
+
+#include "hw/sysbus.h"
+#include "hw/i2c/i2c.h"
+
+#include "hw/arm/imx.h"
+
+#include "hw/i2c/imx_i2c_regs.h"
+
+#ifndef IMX_I2C_DEBUG
+#define IMX_I2C_DEBUG 0
+#endif
+
+#define TYPE_IMX_I2C  "imx.i2c"
+
+#if IMX_I2C_DEBUG
+#define DPRINT(fmt, ...)  \
+do { fprintf(stderr, "%s[%s]: " fmt, TYPE_IMX_I2C, __func__, \
+ ## __VA_ARGS__); \
+} while (0)
+
+static const char *imx_i2c_get_regname(unsigned offset)
+{
+switch (offset) {
+case IADR_ADDR:
+return "IADR";
+case IFDR_ADDR:
+return "IFDR";
+case I2CR_ADDR:
+return "I2CR";
+case I2SR_ADDR:
+return "I2SR";
+case I2DR_ADDR:
+return "I2DR";
+default:
+return "[?]";
+}
+}
+#else
+#define DPRINT(fmt, args...)  do { } while (0)
+#endif
+
+#define IMX_I2C(obj)  \
+OBJECT_CHECK(IMXI2CState, (obj), TYPE_IMX_I2C)
+
+typedef struct IMXI2CState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+i2c_bus *bus;
+qemu_irq irq;
+
+uint16_t  address;
+
+uint16_t iadr;
+uint16_t ifdr;
+uint16_t i2cr;
+uint16_t i2sr;
+uint16_t i2dr_read;
+uint16_t i2dr_write;
+} IMXI2CState;
+
+static inline bool imx_i2c_is_enabled(IMXI2CState *s)
+{
+return s->i2cr & I2CR_IEN;
+}
+
+static inline bool imx_i2c_interrupt_is_enabled(IMXI2CState *s)
+{
+return s->i2cr & I2CR_IIEN;
+}
+
+static inline bool imx_i2c_is_master(IMXI2CState *s)
+{
+return s->i2cr & I2CR_MSTA;
+}
+
+static inline bool imx_i2c_direction_is_tx(IMXI2CState *s)
+{
+return s->i2cr & I2CR_MTX;
+}
+
+static void imx_i2c_reset(DeviceState *dev)
+{
+IMXI2CState *s = IMX_I2C(dev);
+
+s->address= ADDR_RESET;
+s->iadr   = IADR_RESET;
+s->ifdr   = IFDR_RESET;
+s->i2cr   = I2CR_RESET;
+s->i2sr   = I2SR_RESET;
+s->i2dr_read  = I2DR_RESET;
+s->i2dr_write = I2DR_RESET;
+}
+
+static inline void imx_i2c_raise_interrupt(IMXI2CState *s)
+{
+/*
+ * raise an interrupt if the device is enabled and it is configured
+ * to generate some interrupts.
+ */
+if (imx_i2c

[Qemu-devel] [PATCH v5 1/4] Add i.MX FEC Ethernet emulator

2013-05-08 Thread Jean-Christophe DUBOIS
This is based on the mcf_fec.c FEC implementation for ColdFire.

* a generic phy was added (borrowed from lan9118).
* The buffer management is also modified as buffers are
  slightly different between coldfire and i.MX.

Signed-off-by: Jean-Christophe DUBOIS 
---

Changes since V1:
* none 
  
Changes since v2:
* use QOM cast
* reworked debug printf
* use CamelCase for state type   
* warn with qemu_log_mask(LOG_GUEST_ERROR) or qemu_log_mask(LOG_UNIMP)
* move to dma_memory_read/write API
* rework interrupt handling  
* use qemu_flush_queued_packets() in rx_enable()
 
Changes since v3:
* use realise for device initialization
* More QOM cast
* reworked debug printf some more
* standardise GPL header
* use CamelCase for buffer descriptor type

Changes since v4:
* none

 default-configs/arm-softmmu.mak |   1 +
 hw/net/Makefile.objs|   1 +
 hw/net/imx_fec.c| 818 
 include/hw/arm/imx.h|  10 +-
 4 files changed, 824 insertions(+), 6 deletions(-)
 create mode 100644 hw/net/imx_fec.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 27cbe3d..b3a0207 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -28,6 +28,7 @@ CONFIG_SSI_SD=y
 CONFIG_SSI_M25P80=y
 CONFIG_LAN9118=y
 CONFIG_SMC91C111=y
+CONFIG_IMX_FEC=y
 CONFIG_DS1338=y
 CONFIG_PFLASH_CFI01=y
 CONFIG_PFLASH_CFI02=y
diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index 951cca3..5c84727 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -18,6 +18,7 @@ common-obj-$(CONFIG_OPENCORES_ETH) += opencores_eth.o
 common-obj-$(CONFIG_XGMAC) += xgmac.o
 common-obj-$(CONFIG_MIPSNET) += mipsnet.o
 common-obj-$(CONFIG_XILINX_AXI) += xilinx_axienet.o
+common-obj-$(CONFIG_IMX_FEC) += imx_fec.o
 
 common-obj-$(CONFIG_CADENCE) += cadence_gem.o
 common-obj-$(CONFIG_STELLARIS_ENET) += stellaris_enet.o
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
new file mode 100644
index 000..e25d6cd
--- /dev/null
+++ b/hw/net/imx_fec.c
@@ -0,0 +1,818 @@
+/*
+ * i.MX Fast Ethernet Controller emulation.
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois.
+ *
+ * Based on Coldfire Fast Ethernet Controller emulation.
+ *
+ * Copyright (c) 2007 CodeSourcery.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/bitops.h"
+
+#include "sysemu/dma.h"
+
+#include "net/net.h"
+
+#include "hw/sysbus.h"
+
+/* For crc32 */
+#include 
+
+#include "hw/arm/imx.h"
+
+#ifndef IMX_FEC_DEBUG
+#define IMX_FEC_DEBUG  0
+#endif
+
+#ifndef IMX_PHY_DEBUG
+#define IMX_PHY_DEBUG  0
+#endif
+
+#define TYPE_IMX_FEC  "imx.fec"
+
+#if IMX_FEC_DEBUG
+#define FEC_PRINTF(fmt, ...) \
+do { fprintf(stderr, "%s[%s]: " fmt , TYPE_IMX_FEC, __func__, \
+ ## __VA_ARGS__); \
+} while (0)
+#else
+#define FEC_PRINTF(fmt, ...) do {} while (0)
+#endif
+
+#if IMX_PHY_DEBUG
+#define PHY_PRINTF(fmt, ...) \
+do { fprintf(stderr, "%s.phy[%s]: " fmt , TYPE_IMX_FEC, __func__, \
+ ## __VA_ARGS__); \
+} while (0)
+#else
+#define PHY_PRINTF(fmt, ...) do {} while (0)
+#endif
+
+#define IMX_FEC(obj)  \
+OBJECT_CHECK(IMXFECState, (obj), TYPE_IMX_FEC)
+
+#define FEC_MAX_FRAME_SIZE 2032
+
+typedef struct {
+SysBusDevice parent_obj;
+
+NICState *nic;
+NICConf conf;
+qemu_irq irq;
+MemoryRegion iomem;
+
+uint32_t irq_state;
+uint32_t eir;
+uint32_t eimr;
+uint32_t rx_enabled;
+uint32_t rx_descriptor;
+uint32_t tx_descriptor;
+uint32_t ecr;
+uint32_t mmfr;
+uint32_t mscr;
+uint32_t mibc;
+uint32_t rcr;
+uint32_t tcr;
+uint32_t tfwr;
+uint32_t frsr;
+uint32_t erdsr;
+uint32_t etdsr;
+uint32_t emrbr;
+uint32_t miigsk_cfgr;
+uint32_t miigsk_enr;
+
+uint32_t phy_status;
+uint32_t phy_control;
+uint32_t phy_advertise;
+uint32_t phy_int;
+uint32_t phy_int_mask;
+} IMXFECState;
+
+static const VMStateDescription vmstate_imx_fec = {
+.name = TYPE_IMX_FEC,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(irq_state, IMXFECState)

[Qemu-devel] [PATCH v5 0/4] Add i.MX25 support through the 3DS evaluation board

2013-05-08 Thread Jean-Christophe DUBOIS
This series of patches add the support for the i.MX25 processor through the
Freescale 3DS evaluation board.

For now a limited set of devices are supported.
* GPT timers (from i.MX31)
* EPIT timers (from i.MX31)
* Serial ports (from i.MX31)
* Ethernet FEC port
* I2C controller

It also adds qtest support for the I2C controller.

Jean-Christophe DUBOIS (4):
  Add i.MX FEC Ethernet emulator
  Add i.MX I2C controller emulator
  Add i.MX25 3DS evaluation board support.
  Add qtest support for i.MX I2C device emulation.

 default-configs/arm-softmmu.mak |   3 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/imx25_3ds.c  | 250 
 hw/i2c/Makefile.objs|   1 +
 hw/i2c/imx_i2c.c| 357 ++
 hw/i2c/imx_i2c_regs.h   |  63 
 hw/net/Makefile.objs|   1 +
 hw/net/imx_fec.c| 818 
 include/hw/arm/imx.h|  10 +-
 tests/Makefile  |   3 +
 tests/ds1338-test.c |  75 
 tests/libqos/i2c-imx.c  | 209 ++
 tests/libqos/i2c.h  |   3 +
 13 files changed, 1788 insertions(+), 6 deletions(-)
 create mode 100644 hw/arm/imx25_3ds.c
 create mode 100644 hw/i2c/imx_i2c.c
 create mode 100644 hw/i2c/imx_i2c_regs.h
 create mode 100644 hw/net/imx_fec.c
 create mode 100644 tests/ds1338-test.c
 create mode 100644 tests/libqos/i2c-imx.c

-- 
1.8.1.2




Re: [Qemu-devel] [PATCH v5 0/4] Add i.MX25 support through the 3DS evaluation board

2013-05-12 Thread Jean-Christophe DUBOIS

Peter (and all),

In your opinion, is this patch set good enough in its actual state for 
inclusion?


Are you expecting anything else from me (beside maybe adding more i.MX 
devices in the future)?


Thanks

JC

On 05/08/2013 10:28 AM, Jean-Christophe DUBOIS wrote:

This series of patches add the support for the i.MX25 processor through the
Freescale 3DS evaluation board.

For now a limited set of devices are supported.
 * GPT timers (from i.MX31)
 * EPIT timers (from i.MX31)
 * Serial ports (from i.MX31)
 * Ethernet FEC port
 * I2C controller

It also adds qtest support for the I2C controller.

Jean-Christophe DUBOIS (4):
   Add i.MX FEC Ethernet emulator
   Add i.MX I2C controller emulator
   Add i.MX25 3DS evaluation board support.
   Add qtest support for i.MX I2C device emulation.

  default-configs/arm-softmmu.mak |   3 +
  hw/arm/Makefile.objs|   1 +
  hw/arm/imx25_3ds.c  | 250 
  hw/i2c/Makefile.objs|   1 +
  hw/i2c/imx_i2c.c| 357 ++
  hw/i2c/imx_i2c_regs.h   |  63 
  hw/net/Makefile.objs|   1 +
  hw/net/imx_fec.c| 818 
  include/hw/arm/imx.h|  10 +-
  tests/Makefile  |   3 +
  tests/ds1338-test.c |  75 
  tests/libqos/i2c-imx.c  | 209 ++
  tests/libqos/i2c.h  |   3 +
  13 files changed, 1788 insertions(+), 6 deletions(-)
  create mode 100644 hw/arm/imx25_3ds.c
  create mode 100644 hw/i2c/imx_i2c.c
  create mode 100644 hw/i2c/imx_i2c_regs.h
  create mode 100644 hw/net/imx_fec.c
  create mode 100644 tests/ds1338-test.c
  create mode 100644 tests/libqos/i2c-imx.c






[Qemu-devel] [PATCH] i.MX: split GPT and EPIT timer implementation

2013-05-19 Thread Jean-Christophe DUBOIS
There is no common code between these 2 timer implementation.
So it is better to split them.

Signed-off-by: Jean-Christophe DUBOIS 
---
 hw/timer/Makefile.objs |   3 +-
 hw/timer/imx_epit.c| 404 
 hw/timer/imx_gpt.c | 465 
 hw/timer/imx_timer.c   | 823 -
 4 files changed, 871 insertions(+), 824 deletions(-)
 create mode 100644 hw/timer/imx_epit.c
 create mode 100644 hw/timer/imx_gpt.c
 delete mode 100644 hw/timer/imx_timer.c

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index e4bd17f..32b5c1a 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -11,7 +11,8 @@ common-obj-$(CONFIG_XILINX) += xilinx_timer.o
 common-obj-$(CONFIG_SLAVIO) += slavio_timer.o
 common-obj-$(CONFIG_ETRAXFS) += etraxfs_timer.o
 common-obj-$(CONFIG_GRLIB) += grlib_gptimer.o
-common-obj-$(CONFIG_IMX) += imx_timer.o
+common-obj-$(CONFIG_IMX) += imx_epit.o
+common-obj-$(CONFIG_IMX) += imx_gpt.o
 common-obj-$(CONFIG_LM32) += lm32_timer.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o
 
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
new file mode 100644
index 000..451e646
--- /dev/null
+++ b/hw/timer/imx_epit.c
@@ -0,0 +1,404 @@
+/*
+ * IMX EPIT Timer
+ *
+ * Copyright (c) 2008 OK Labs
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally written by Hans Jiang
+ * Updated by Peter Chubb
+ *
+ * This code is licensed under GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw/hw.h"
+#include "qemu/bitops.h"
+#include "qemu/timer.h"
+#include "hw/ptimer.h"
+#include "hw/sysbus.h"
+#include "hw/arm/imx.h"
+
+//#define DEBUG_TIMER 1
+#ifdef DEBUG_TIMER
+#  define DPRINTF(fmt, args...) \
+  do { printf("imx_timer: " fmt , ##args); } while (0)
+#else
+#  define DPRINTF(fmt, args...) do {} while (0)
+#endif
+
+/*
+ * Define to 1 for messages about attempts to
+ * access unimplemented registers or similar.
+ */
+#define DEBUG_IMPLEMENTATION 1
+#if DEBUG_IMPLEMENTATION
+#  define IPRINTF(fmt, args...) \
+do  { fprintf(stderr, "imx_timer: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+/*
+ * EPIT: Enhanced periodic interrupt timer
+ */
+
+#define CR_EN   (1 << 0)
+#define CR_ENMOD(1 << 1)
+#define CR_OCIEN(1 << 2)
+#define CR_RLD  (1 << 3)
+#define CR_PRESCALE_SHIFT (4)
+#define CR_PRESCALE_MASK  (0xfff)
+#define CR_SWR  (1 << 16)
+#define CR_IOVW (1 << 17)
+#define CR_DBGEN(1 << 18)
+#define CR_WAITEN   (1 << 19)
+#define CR_DOZEN(1 << 20)
+#define CR_STOPEN   (1 << 21)
+#define CR_CLKSRC_SHIFT (24)
+#define CR_CLKSRC_MASK  (0x3 << CR_CLKSRC_SHIFT)
+
+#define TIMER_MAX  0XUL
+
+/*
+ * Exact clock frequencies vary from board to board.
+ * These are typical.
+ */
+static const IMXClk imx_timerp_clocks[] =  {
+0,/* 00 disabled */
+IPG,  /* 01 ipg_clk, ~532MHz */
+IPG,  /* 10 ipg_clk_highfreq */
+CLK_32k,  /* 11 ipg_clk_32k -- ~32kHz */
+};
+
+typedef struct {
+SysBusDevice busdev;
+ptimer_state *timer_reload;
+ptimer_state *timer_cmp;
+MemoryRegion iomem;
+DeviceState *ccm;
+
+uint32_t cr;
+uint32_t sr;
+uint32_t lr;
+uint32_t cmp;
+uint32_t cnt;
+
+uint32_t freq;
+qemu_irq irq;
+} IMXTimerPState;
+
+/*
+ * Update interrupt status
+ */
+static void imx_timerp_update(IMXTimerPState *s)
+{
+if (s->sr && (s->cr & CR_OCIEN)) {
+qemu_irq_raise(s->irq);
+} else {
+qemu_irq_lower(s->irq);
+}
+}
+
+static void set_timerp_freq(IMXTimerPState *s)
+{
+unsigned clksrc;
+unsigned prescaler;
+uint32_t freq;
+
+clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, 2);
+prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, 12);
+
+freq = imx_clock_frequency(s->ccm, imx_timerp_clocks[clksrc]) / prescaler;
+
+s->freq = freq;
+DPRINTF("Setting ptimer frequency to %u\n", freq);
+
+if (freq) {
+ptimer_set_freq(s->timer_reload, freq);
+ptimer_set_freq(s->timer_cmp, freq);
+}
+}
+
+static void imx_timerp_reset(DeviceState *dev)
+{
+IMXTimerPState *s = container_of(dev, IMXTimerPState, busdev.qdev);
+
+/*
+ * Soft reset doesn't touch some bits; hard reset clears them
+ */
+s->cr &= ~(CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
+s->sr = 0;
+s->lr = TIMER_MAX;
+s->cmp = 0;
+s->cnt = 0;
+/* stop both timers */
+ptimer_stop(s->timer_cmp);
+ptimer_stop(s->timer_reload);
+/* compute new frequency */
+set_timerp_freq(s);
+/* init both timers to TIMER_MAX */
+ptimer_set_limit(s->timer_cmp, TIM

[Qemu-devel] [PATCH 0/2] i.MX: Add an i.MX25 specific CCM driver

2015-10-27 Thread Jean-Christophe Dubois
i.MX25 SOC has a different CCM device than i.MX31.

Qemu i.MX25 emulation was built with i.MX31 CCM driver. This allows
Linux to work on top of the i.MX25 emultion but this is not correct.

Furthermore, other SOC we could emulate like i.MX6 have yet a different
implementation of the CCM device.

We then add an i.MX25 specific CCM Device and have the i.MX25 SOC use it.

Jean-Christophe Dubois (2):
  i.MX: rework CCM driver.
  i.MX: Add i.MX25 CCM driver

 hw/arm/fsl-imx25.c  |   6 +-
 hw/arm/fsl-imx31.c  |   6 +-
 hw/misc/Makefile.objs   |   2 +
 hw/misc/imx25_ccm.c | 224 +++
 hw/misc/imx31_ccm.c | 240 ++
 hw/misc/imx_ccm.c   | 249 +++-
 hw/timer/imx_epit.c |   8 +-
 hw/timer/imx_gpt.c  |  12 +--
 include/hw/arm/fsl-imx25.h  |   4 +-
 include/hw/arm/fsl-imx31.h  |   4 +-
 include/hw/misc/imx25_ccm.h |  61 +++
 include/hw/misc/imx31_ccm.h |  68 
 include/hw/misc/imx_ccm.h   |  73 +++--
 include/hw/timer/imx_epit.h |   1 -
 include/hw/timer/imx_gpt.h  |   1 -
 15 files changed, 640 insertions(+), 319 deletions(-)
 create mode 100644 hw/misc/imx25_ccm.c
 create mode 100644 hw/misc/imx31_ccm.c
 create mode 100644 include/hw/misc/imx25_ccm.h
 create mode 100644 include/hw/misc/imx31_ccm.h

-- 
2.5.0




[Qemu-devel] [PATCH 2/2] i.MX: Add i.MX25 CCM driver

2015-10-27 Thread Jean-Christophe Dubois
The i.MX25 CCM device is different from the i.MX31 one.

So for now the emulation was not correct even if linux was working OK
on top of the i.MX25 emulation.

We add an i.MX25 specific CCM driver and use it in the i.MX25 SOC
emulation.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx25.c  |   2 +-
 hw/misc/Makefile.objs   |   1 +
 hw/misc/imx25_ccm.c | 224 
 include/hw/arm/fsl-imx25.h  |   4 +-
 include/hw/misc/imx25_ccm.h |  61 
 5 files changed, 289 insertions(+), 3 deletions(-)
 create mode 100644 hw/misc/imx25_ccm.c
 create mode 100644 include/hw/misc/imx25_ccm.h

diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index 620c5c6..5301c1c 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -38,7 +38,7 @@ static void fsl_imx25_init(Object *obj)
 object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
 qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());
 
-object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX31_CCM);
+object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX25_CCM);
 qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
 
 for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 79b3487..e8dc22d 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -27,6 +27,7 @@ obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o
 obj-$(CONFIG_IMX) += imx_ccm.o
 obj-$(CONFIG_IMX) += imx31_ccm.o
+obj-$(CONFIG_IMX) += imx25_ccm.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx25_ccm.c b/hw/misc/imx25_ccm.c
new file mode 100644
index 000..6cb4c6f
--- /dev/null
+++ b/hw/misc/imx25_ccm.c
@@ -0,0 +1,224 @@
+/*
+ * IMX25 Clock Control Module
+ *
+ * Copyright (C) 2012 NICTA
+ * Updated by Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * To get the timer frequencies right, we need to emulate at least part of
+ * the CCM.
+ */
+
+#include "hw/misc/imx25_ccm.h"
+
+#define CKIH_FREQ 2400 /* 24MHz crystal input */
+
+//#define DEBUG_CCM 1
+#ifdef DEBUG_CCM
+#define DPRINTF(fmt, args...) \
+do { printf("%s: " fmt , TYPE_IMX25_CCM, ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...) do {} while (0)
+#endif
+
+static int imx25_ccm_post_load(void *opaque, int version_id);
+
+static const VMStateDescription vmstate_imx25_ccm = {
+.name = TYPE_IMX25_CCM,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(mpctl, IMX25CCMState),
+VMSTATE_UINT32(upctl, IMX25CCMState),
+VMSTATE_UINT32(cctl, IMX25CCMState),
+VMSTATE_UINT32_ARRAY(cgcr, IMX25CCMState, 3),
+VMSTATE_UINT32_ARRAY(pcdr, IMX25CCMState, 4),
+VMSTATE_UINT32(rcsr, IMX25CCMState),
+VMSTATE_UINT32(crdr, IMX25CCMState),
+VMSTATE_UINT32_ARRAY(dcvr, IMX25CCMState, 4),
+VMSTATE_UINT32_ARRAY(ltr, IMX25CCMState, 4),
+VMSTATE_UINT32_ARRAY(ltbr, IMX25CCMState, 2),
+VMSTATE_UINT32_ARRAY(pmcr, IMX25CCMState, 3),
+VMSTATE_UINT32(mcr, IMX25CCMState),
+VMSTATE_UINT32_ARRAY(lpimr, IMX25CCMState, 2),
+VMSTATE_UINT32(pll_refclk_freq, IMX25CCMState),
+VMSTATE_END_OF_LIST()
+},
+.post_load = imx25_ccm_post_load,
+};
+
+static void imx25_ccm_update_clocks(IMX25CCMState *s)
+{
+DPRINTF("%s()\n", __func__);
+/*
+ * If we ever emulate more clocks, this should switch to a data-driven
+ * approach
+ */
+
+/* Our input CLK */
+s->pll_refclk_freq = CKIH_FREQ;
+
+/* Set MCU PLL CLK */
+if (EXTRACT(s->cctl, MPLL_BYPASS)) {
+imx_ccm_set_clock_frequency(CLK_MPLL, s->pll_refclk_freq);
+} else {
+imx_ccm_set_clock_frequency(CLK_MPLL,
+imx_ccm_calc_pll(s->mpctl,
+ s->pll_refclk_freq));
+}
+
+/* Set USB PLL CLK */
+imx_ccm_set_clock_frequency(CLK_UPLL,
+imx_ccm_calc_pll(s->upctl,
+ s->pll_refclk_freq));
+
+/* Set Processor clock */
+if (EXTRACT(s->cctl, ARM_SRC)) {
+imx_ccm_set_clock_frequency(CLK_MCU,
+(imx_ccm_get_clock_frequency(CLK_MPLL) * 3
+ / 4)
+ / (1 + EXTRACT(s->cctl, ARM_CLK_DIV)));
+} else {
+imx_ccm_set_clock_frequency(CLK_MCU,
+imx_ccm_get_clock_frequency(CLK_MPLL) /
+(1 + EXTRACT(s->cctl, ARM_CLK_DIV)));
+ 

[Qemu-devel] [PATCH] i.MX: add support for lower and upper interrupt in GPIO.

2015-10-27 Thread Jean-Christophe Dubois
The i.MX6 GPIO device supports 2 interrupts instead of one.

* 1 for the lower 16 GPIOs.
* 1 for the upper 16 GPIOs.

i.MX31 and i.MX25 only support 1 interrupt for the 32 GPIOs.

So we add a property to turn the behavior on when required.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/gpio/imx_gpio.c | 12 ++--
 include/hw/gpio/imx_gpio.h |  3 ++-
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/hw/gpio/imx_gpio.c b/hw/gpio/imx_gpio.c
index 3170585..a6d7cab 100644
--- a/hw/gpio/imx_gpio.c
+++ b/hw/gpio/imx_gpio.c
@@ -62,7 +62,12 @@ static const char *imx_gpio_reg_name(uint32_t reg)
 
 static void imx_gpio_update_int(IMXGPIOState *s)
 {
-qemu_set_irq(s->irq, (s->isr & s->imr) ? 1 : 0);
+if (s->has_upper_pin_irq) {
+qemu_set_irq(s->irq[0], (s->isr & s->imr & 0x) ? 1 : 0);
+qemu_set_irq(s->irq[1], (s->isr & s->imr & 0x) ? 1 : 0);
+} else {
+qemu_set_irq(s->irq[0], (s->isr & s->imr) ? 1 : 0);
+}
 }
 
 static void imx_gpio_set_int_line(IMXGPIOState *s, int line, IMXGPIOLevel 
level)
@@ -282,6 +287,8 @@ static const VMStateDescription vmstate_imx_gpio = {
 
 static Property imx_gpio_properties[] = {
 DEFINE_PROP_BOOL("has-edge-sel", IMXGPIOState, has_edge_sel, true),
+DEFINE_PROP_BOOL("has-upper-pin-irq", IMXGPIOState, has_upper_pin_irq,
+ false),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -311,7 +318,8 @@ static void imx_gpio_realize(DeviceState *dev, Error **errp)
 qdev_init_gpio_in(DEVICE(s), imx_gpio_set, IMX_GPIO_PIN_COUNT);
 qdev_init_gpio_out(DEVICE(s), s->output, IMX_GPIO_PIN_COUNT);
 
-sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
+sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[0]);
+sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[1]);
 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
 }
 
diff --git a/include/hw/gpio/imx_gpio.h b/include/hw/gpio/imx_gpio.h
index 517b261..b15a09f 100644
--- a/include/hw/gpio/imx_gpio.h
+++ b/include/hw/gpio/imx_gpio.h
@@ -54,8 +54,9 @@ typedef struct IMXGPIOState {
 uint32_t isr;
 bool has_edge_sel;
 uint32_t edge_sel;
+bool has_upper_pin_irq;
 
-qemu_irq irq;
+qemu_irq irq[2];
 qemu_irq output[IMX_GPIO_PIN_COUNT];
 } IMXGPIOState;
 
-- 
2.5.0




[Qemu-devel] [PATCH 1/2] i.MX: rework CCM driver.

2015-10-27 Thread Jean-Christophe Dubois
The CCM driver is in fact specific to the i.MX31. We need to add an i.MX25
CCM driver.

As a first step, we split the CCM driver into 2 parts:
1) A common/utility part that allow to compute an manipulate clock freq for
   any CCM driver
2) The i.MX31 CCM specifc driver.

We also remove EPIT/GPT timer reference to CCM. These objects now use the
utility function we added in 1) instead of direct reference to CCM object.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/fsl-imx25.c  |   6 +-
 hw/arm/fsl-imx31.c  |   6 +-
 hw/misc/Makefile.objs   |   1 +
 hw/misc/imx31_ccm.c | 240 ++
 hw/misc/imx_ccm.c   | 249 +++-
 hw/timer/imx_epit.c |   8 +-
 hw/timer/imx_gpt.c  |  12 +--
 include/hw/arm/fsl-imx25.h  |   4 +-
 include/hw/arm/fsl-imx31.h  |   4 +-
 include/hw/misc/imx31_ccm.h |  68 
 include/hw/misc/imx_ccm.h   |  73 +++--
 include/hw/timer/imx_epit.h |   1 -
 include/hw/timer/imx_gpt.h  |   1 -
 13 files changed, 354 insertions(+), 319 deletions(-)
 create mode 100644 hw/misc/imx31_ccm.c
 create mode 100644 include/hw/misc/imx31_ccm.h

diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index e1cadac..620c5c6 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -38,7 +38,7 @@ static void fsl_imx25_init(Object *obj)
 object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
 qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());
 
-object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX_CCM);
+object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX31_CCM);
 qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
 
 for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
@@ -150,8 +150,6 @@ static void fsl_imx25_realize(DeviceState *dev, Error 
**errp)
 { FSL_IMX25_GPT4_ADDR, FSL_IMX25_GPT4_IRQ }
 };
 
-s->gpt[i].ccm = DEVICE(&s->ccm);
-
 object_property_set_bool(OBJECT(&s->gpt[i]), true, "realized", &err);
 if (err) {
 error_propagate(errp, err);
@@ -173,8 +171,6 @@ static void fsl_imx25_realize(DeviceState *dev, Error 
**errp)
 { FSL_IMX25_EPIT2_ADDR, FSL_IMX25_EPIT2_IRQ }
 };
 
-s->epit[i].ccm = DEVICE(&s->ccm);
-
 object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err);
 if (err) {
 error_propagate(errp, err);
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
index 53d4473..7ae23d5 100644
--- a/hw/arm/fsl-imx31.c
+++ b/hw/arm/fsl-imx31.c
@@ -35,7 +35,7 @@ static void fsl_imx31_init(Object *obj)
 object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
 qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());
 
-object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX_CCM);
+object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX31_CCM);
 qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
 
 for (i = 0; i < FSL_IMX31_NUM_UARTS; i++) {
@@ -128,8 +128,6 @@ static void fsl_imx31_realize(DeviceState *dev, Error 
**errp)
 serial_table[i].irq));
 }
 
-s->gpt.ccm = DEVICE(&s->ccm);
-
 object_property_set_bool(OBJECT(&s->gpt), true, "realized", &err);
 if (err) {
 error_propagate(errp, err);
@@ -150,8 +148,6 @@ static void fsl_imx31_realize(DeviceState *dev, Error 
**errp)
 { FSL_IMX31_EPIT2_ADDR, FSL_IMX31_EPIT2_IRQ },
 };
 
-s->epit[i].ccm = DEVICE(&s->ccm);
-
 object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err);
 if (err) {
 error_propagate(errp, err);
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 4aa76ff..79b3487 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -26,6 +26,7 @@ obj-$(CONFIG_NSERIES) += cbus.o
 obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o
 obj-$(CONFIG_IMX) += imx_ccm.o
+obj-$(CONFIG_IMX) += imx31_ccm.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
new file mode 100644
index 000..1ef34f4
--- /dev/null
+++ b/hw/misc/imx31_ccm.c
@@ -0,0 +1,240 @@
+/*
+ * IMX31 Clock Control Module
+ *
+ * Copyright (C) 2012 NICTA
+ * Updated by Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * To get the timer frequencies right, we need to emulate at least part of
+ * the CCM.
+ */
+
+#include "hw/misc/imx31_ccm.h"
+
+#ifndef DEBUG_IMX31_CCM
+#define DEBUG_IMX31_CCM 0
+#endif
+
+#define D

Re: [Qemu-devel] [PATCH] i.MX: add support for lower and upper interrupt in GPIO.

2015-10-28 Thread Jean-Christophe DUBOIS

Le 27/10/2015 23:41, Peter Crosthwaite a écrit :



On Tue, Oct 27, 2015 at 3:32 PM, Jean-Christophe Dubois 
mailto:j...@tribudubois.net>> wrote:


The i.MX6 GPIO device supports 2 interrupts instead of one.

* 1 for the lower 16 GPIOs.
* 1 for the upper 16 GPIOs.

i.MX31 and i.MX25 only support 1 interrupt for the 32 GPIOs.


So an architectural question, is it the case that the IP always has 
two outbound interrupt lines but MX31 and 25 always OR together on the 
SoC level?


Well, I am not part of Freescale so I just don't know anything about 
internal implementation details of this IP and its use inside the SOC.


What we can say is that the dual interrupt version (i.MX6) is newer than 
the single one (i.MX31, i.MX25). So my guess is that this is an 
evolution of the IP and the goal was to make GPIO interrupt handling 
easier, faster and prioritisable.




If that is the case I think it would be cleaner to do on the board level.


At the SOC level I was planning to set (or not) the new property and to 
assign 1 (or 2) IRQ to the device.


Regards

JC



Regards,
Peter

So we add a property to turn the behavior on when required.

Signed-off-by: Jean-Christophe Dubois mailto:j...@tribudubois.net>>
---
 hw/gpio/imx_gpio.c | 12 ++--
 include/hw/gpio/imx_gpio.h |  3 ++-
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/hw/gpio/imx_gpio.c b/hw/gpio/imx_gpio.c
index 3170585..a6d7cab 100644
--- a/hw/gpio/imx_gpio.c
+++ b/hw/gpio/imx_gpio.c
@@ -62,7 +62,12 @@ static const char *imx_gpio_reg_name(uint32_t reg)

 static void imx_gpio_update_int(IMXGPIOState *s)
 {
-qemu_set_irq(s->irq, (s->isr & s->imr) ? 1 : 0);
+if (s->has_upper_pin_irq) {
+qemu_set_irq(s->irq[0], (s->isr & s->imr & 0x) ?
1 : 0);
+qemu_set_irq(s->irq[1], (s->isr & s->imr & 0x) ?
1 : 0);
+} else {
+qemu_set_irq(s->irq[0], (s->isr & s->imr) ? 1 : 0);
+}
 }

 static void imx_gpio_set_int_line(IMXGPIOState *s, int line,
IMXGPIOLevel level)
@@ -282,6 +287,8 @@ static const VMStateDescription
vmstate_imx_gpio = {

 static Property imx_gpio_properties[] = {
 DEFINE_PROP_BOOL("has-edge-sel", IMXGPIOState, has_edge_sel,
true),
+DEFINE_PROP_BOOL("has-upper-pin-irq", IMXGPIOState,
has_upper_pin_irq,
+ false),
 DEFINE_PROP_END_OF_LIST(),
 };

@@ -311,7 +318,8 @@ static void imx_gpio_realize(DeviceState *dev,
Error **errp)
 qdev_init_gpio_in(DEVICE(s), imx_gpio_set, IMX_GPIO_PIN_COUNT);
 qdev_init_gpio_out(DEVICE(s), s->output, IMX_GPIO_PIN_COUNT);

-sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
+sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[0]);
+sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[1]);
 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
 }

diff --git a/include/hw/gpio/imx_gpio.h b/include/hw/gpio/imx_gpio.h
index 517b261..b15a09f 100644
--- a/include/hw/gpio/imx_gpio.h
+++ b/include/hw/gpio/imx_gpio.h
@@ -54,8 +54,9 @@ typedef struct IMXGPIOState {
 uint32_t isr;
 bool has_edge_sel;
 uint32_t edge_sel;
+bool has_upper_pin_irq;

-qemu_irq irq;
+qemu_irq irq[2];
 qemu_irq output[IMX_GPIO_PIN_COUNT];
 } IMXGPIOState;

--
2.5.0






[Qemu-devel] [PATCH v2 0/2] Add an i.MX25 specific CCM driver

2015-10-28 Thread Jean-Christophe Dubois
i.MX25 SOC has a different CCM device than i.MX31.

Qemu i.MX25 emulation was built with i.MX31 CCM driver. This allows
Linux to work on top of the i.MX25 emultion but this is not correct.

Furthermore, other SOC we could emulate like i.MX6 have yet a different
implementation of the CCM device.

We then add an i.MX25 specific CCM Device and have the i.MX25 SOC use it.

Jean-Christophe Dubois (2):
  i.MX: rework CCM driver.
  i.MX: Add i.MX25 CCM driver

 hw/arm/fsl-imx25.c  |   6 +-
 hw/arm/fsl-imx31.c  |   6 +-
 hw/misc/Makefile.objs   |   2 +
 hw/misc/imx25_ccm.c | 228 
 hw/misc/imx31_ccm.c | 240 ++
 hw/misc/imx_ccm.c   | 249 +++-
 hw/timer/imx_epit.c |   8 +-
 hw/timer/imx_gpt.c  |  12 +--
 include/hw/arm/fsl-imx25.h  |   4 +-
 include/hw/arm/fsl-imx31.h  |   4 +-
 include/hw/misc/imx25_ccm.h |  61 +++
 include/hw/misc/imx31_ccm.h |  68 
 include/hw/misc/imx_ccm.h   |  73 +++--
 include/hw/timer/imx_epit.h |   1 -
 include/hw/timer/imx_gpt.h  |   1 -
 15 files changed, 644 insertions(+), 319 deletions(-)
 create mode 100644 hw/misc/imx25_ccm.c
 create mode 100644 hw/misc/imx31_ccm.c
 create mode 100644 include/hw/misc/imx25_ccm.h
 create mode 100644 include/hw/misc/imx31_ccm.h

-- 
2.5.0




[Qemu-devel] [PATCH v2 1/2] i.MX: rework CCM driver.

2015-10-28 Thread Jean-Christophe Dubois
The CCM drive is in fact specific to the i.MX31. We need to add an i.MX25
CCM driver.

As a first step, we split the CCM driver into 2 parts:
1) A common/utility part that allow to compute an manipulate clock freq for
   any CCM driver
2) The i.MX31 CCM specifc driver.

We also remove EPIT/GPT timer reference to CCM. These objects now use the
utility function we added in 1) instead of direct reference to CCM object.

Signed-off-by: Jean-Christophe Dubois 
---

Changes since v1:
 * None

 hw/arm/fsl-imx25.c  |   6 +-
 hw/arm/fsl-imx31.c  |   6 +-
 hw/misc/Makefile.objs   |   1 +
 hw/misc/imx31_ccm.c | 240 ++
 hw/misc/imx_ccm.c   | 249 +++-
 hw/timer/imx_epit.c |   8 +-
 hw/timer/imx_gpt.c  |  12 +--
 include/hw/arm/fsl-imx25.h  |   4 +-
 include/hw/arm/fsl-imx31.h  |   4 +-
 include/hw/misc/imx31_ccm.h |  68 
 include/hw/misc/imx_ccm.h   |  73 +++--
 include/hw/timer/imx_epit.h |   1 -
 include/hw/timer/imx_gpt.h  |   1 -
 13 files changed, 354 insertions(+), 319 deletions(-)
 create mode 100644 hw/misc/imx31_ccm.c
 create mode 100644 include/hw/misc/imx31_ccm.h

diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index e1cadac..620c5c6 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -38,7 +38,7 @@ static void fsl_imx25_init(Object *obj)
 object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
 qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());
 
-object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX_CCM);
+object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX31_CCM);
 qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
 
 for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
@@ -150,8 +150,6 @@ static void fsl_imx25_realize(DeviceState *dev, Error 
**errp)
 { FSL_IMX25_GPT4_ADDR, FSL_IMX25_GPT4_IRQ }
 };
 
-s->gpt[i].ccm = DEVICE(&s->ccm);
-
 object_property_set_bool(OBJECT(&s->gpt[i]), true, "realized", &err);
 if (err) {
 error_propagate(errp, err);
@@ -173,8 +171,6 @@ static void fsl_imx25_realize(DeviceState *dev, Error 
**errp)
 { FSL_IMX25_EPIT2_ADDR, FSL_IMX25_EPIT2_IRQ }
 };
 
-s->epit[i].ccm = DEVICE(&s->ccm);
-
 object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err);
 if (err) {
 error_propagate(errp, err);
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
index 53d4473..7ae23d5 100644
--- a/hw/arm/fsl-imx31.c
+++ b/hw/arm/fsl-imx31.c
@@ -35,7 +35,7 @@ static void fsl_imx31_init(Object *obj)
 object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
 qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());
 
-object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX_CCM);
+object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX31_CCM);
 qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
 
 for (i = 0; i < FSL_IMX31_NUM_UARTS; i++) {
@@ -128,8 +128,6 @@ static void fsl_imx31_realize(DeviceState *dev, Error 
**errp)
 serial_table[i].irq));
 }
 
-s->gpt.ccm = DEVICE(&s->ccm);
-
 object_property_set_bool(OBJECT(&s->gpt), true, "realized", &err);
 if (err) {
 error_propagate(errp, err);
@@ -150,8 +148,6 @@ static void fsl_imx31_realize(DeviceState *dev, Error 
**errp)
 { FSL_IMX31_EPIT2_ADDR, FSL_IMX31_EPIT2_IRQ },
 };
 
-s->epit[i].ccm = DEVICE(&s->ccm);
-
 object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err);
 if (err) {
 error_propagate(errp, err);
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 4aa76ff..79b3487 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -26,6 +26,7 @@ obj-$(CONFIG_NSERIES) += cbus.o
 obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o
 obj-$(CONFIG_IMX) += imx_ccm.o
+obj-$(CONFIG_IMX) += imx31_ccm.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
new file mode 100644
index 000..1ef34f4
--- /dev/null
+++ b/hw/misc/imx31_ccm.c
@@ -0,0 +1,240 @@
+/*
+ * IMX31 Clock Control Module
+ *
+ * Copyright (C) 2012 NICTA
+ * Updated by Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * To get the timer frequencies right, we need to emulate at least part of
+ * the CCM.
+ */
+
+#include "hw/misc/imx31_ccm.h"
+
+#ifndef DEBUG_IMX31_CCM
+#define DEBUG

[Qemu-devel] [PATCH v2 2/2] i.MX: Add i.MX25 CCM driver

2015-10-28 Thread Jean-Christophe Dubois
The i.MX25 CCM device is different from the i.MX31 one.

So for now the emulation was not correct even if linux was working OK
on top of the i.MX25 emulation.

We add an i.MX25 specific CCM driver and use it in the i.MX25 SOC
emulation.

Signed-off-by: Jean-Christophe Dubois 
---

Changes since v1:
 * rework loging to match other i.MX drivers

 hw/arm/fsl-imx25.c  |   2 +-
 hw/misc/Makefile.objs   |   1 +
 hw/misc/imx25_ccm.c | 228 
 include/hw/arm/fsl-imx25.h  |   4 +-
 include/hw/misc/imx25_ccm.h |  61 
 5 files changed, 293 insertions(+), 3 deletions(-)
 create mode 100644 hw/misc/imx25_ccm.c
 create mode 100644 include/hw/misc/imx25_ccm.h

diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index 620c5c6..5301c1c 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -38,7 +38,7 @@ static void fsl_imx25_init(Object *obj)
 object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
 qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());
 
-object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX31_CCM);
+object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX25_CCM);
 qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
 
 for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 79b3487..e8dc22d 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -27,6 +27,7 @@ obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o
 obj-$(CONFIG_IMX) += imx_ccm.o
 obj-$(CONFIG_IMX) += imx31_ccm.o
+obj-$(CONFIG_IMX) += imx25_ccm.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx25_ccm.c b/hw/misc/imx25_ccm.c
new file mode 100644
index 000..e76292d
--- /dev/null
+++ b/hw/misc/imx25_ccm.c
@@ -0,0 +1,228 @@
+/*
+ * IMX25 Clock Control Module
+ *
+ * Copyright (C) 2012 NICTA
+ * Updated by Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * To get the timer frequencies right, we need to emulate at least part of
+ * the CCM.
+ */
+
+#include "hw/misc/imx25_ccm.h"
+
+#ifndef DEBUG_IMX25_CCM
+#define DEBUG_IMX25_CCM 0
+#endif
+
+#define DPRINTF(fmt, args...) \
+do { \
+if (DEBUG_IMX25_CCM) { \
+fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX25_CCM, \
+ __func__, ##args); \
+} \
+} while (0)
+
+#define CKIH_FREQ 2400 /* 24MHz crystal input */
+
+static int imx25_ccm_post_load(void *opaque, int version_id);
+
+static const VMStateDescription vmstate_imx25_ccm = {
+.name = TYPE_IMX25_CCM,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(mpctl, IMX25CCMState),
+VMSTATE_UINT32(upctl, IMX25CCMState),
+VMSTATE_UINT32(cctl, IMX25CCMState),
+VMSTATE_UINT32_ARRAY(cgcr, IMX25CCMState, 3),
+VMSTATE_UINT32_ARRAY(pcdr, IMX25CCMState, 4),
+VMSTATE_UINT32(rcsr, IMX25CCMState),
+VMSTATE_UINT32(crdr, IMX25CCMState),
+VMSTATE_UINT32_ARRAY(dcvr, IMX25CCMState, 4),
+VMSTATE_UINT32_ARRAY(ltr, IMX25CCMState, 4),
+VMSTATE_UINT32_ARRAY(ltbr, IMX25CCMState, 2),
+VMSTATE_UINT32_ARRAY(pmcr, IMX25CCMState, 3),
+VMSTATE_UINT32(mcr, IMX25CCMState),
+VMSTATE_UINT32_ARRAY(lpimr, IMX25CCMState, 2),
+VMSTATE_UINT32(pll_refclk_freq, IMX25CCMState),
+VMSTATE_END_OF_LIST()
+},
+.post_load = imx25_ccm_post_load,
+};
+
+static void imx25_ccm_update_clocks(IMX25CCMState *s)
+{
+DPRINTF("\n");
+/*
+ * If we ever emulate more clocks, this should switch to a data-driven
+ * approach
+ */
+
+/* Our input CLK */
+s->pll_refclk_freq = CKIH_FREQ;
+
+/* Set MCU PLL CLK */
+if (EXTRACT(s->cctl, MPLL_BYPASS)) {
+imx_ccm_set_clock_frequency(CLK_MPLL, s->pll_refclk_freq);
+} else {
+imx_ccm_set_clock_frequency(CLK_MPLL,
+imx_ccm_calc_pll(s->mpctl,
+ s->pll_refclk_freq));
+}
+
+/* Set USB PLL CLK */
+imx_ccm_set_clock_frequency(CLK_UPLL,
+imx_ccm_calc_pll(s->upctl,
+ s->pll_refclk_freq));
+
+/* Set Processor clock */
+if (EXTRACT(s->cctl, ARM_SRC)) {
+imx_ccm_set_clock_frequency(CLK_MCU,
+(imx_ccm_get_clock_frequency(CLK_MPLL) * 3
+ / 4)
+ / (1 + EXTRACT(s->cctl, ARM_CLK_DIV)));
+} else {
+imx_cc

Re: [Qemu-devel] [PATCH v2 0/2] Add an i.MX25 specific CCM driver

2015-10-30 Thread Jean-Christophe DUBOIS

Le 30/10/2015 21:50, Peter Crosthwaite a écrit :

On Fri, Oct 30, 2015 at 1:24 PM, Peter Maydell  wrote:

On 28 October 2015 at 23:02, Jean-Christophe Dubois  
wrote:

i.MX25 SOC has a different CCM device than i.MX31.

Qemu i.MX25 emulation was built with i.MX31 CCM driver. This allows
Linux to work on top of the i.MX25 emultion but this is not correct.

Furthermore, other SOC we could emulate like i.MX6 have yet a different
implementation of the CCM device.

We then add an i.MX25 specific CCM Device and have the i.MX25 SOC use it.

Jean-Christophe Dubois (2):
   i.MX: rework CCM driver.
   i.MX: Add i.MX25 CCM driver

Just to let you know, as this is a new feature and we're
in softfreeze I'm not intending to put it in target-arm
for 2.5. It is still on my to-review list though (though
I'm hoping Peter C will get to it first ;-))


I'm prioritising for-2.5 stuffs for the next few days, there's still
one or two more series I need to look at. Probably get to this next
week.

Regards,
Peter

No problem, Whenever you have time.

JC




thanks
-- PMM





[Qemu-devel] [PATCH 0/6] Add i.MX6 (Single/Dual/Quad) support

2016-01-26 Thread Jean-Christophe Dubois
This patch series adds support for the Freescale i.MX6 processor.

For now we only support the following devices:
* up to 4 Cortex A9 cores
* A9 MPCORE (SCU, GIC, TWD)
* 5 i.MX UARTs
* 2 EPIT timers
* 1 GPT timer
* 7 GPIO controllers
* 6 SDHC controllers
* 1 CCM device
* 1 SRC device
* various ROM/RAM areas.

This also adds the sabrelite board as a an actual platform for i.MX6.

This series was tested by booting a 4.4 linux kernel (using the
imx_v6_v7_defconfig file as kernel configuration).

Note: In order for Linux to work I had to customize a bit the 
arch/arm/boot/dts/imx6qdl-sabrelite.dtsi device tree file.

Jean-Christophe Dubois (6):
  i.MX: Allow GPT timer to rollover.
  i.MX: simplify CCM to only handle clock required by timers.
  i.MX: Add i.MX6 CCM and ANALOG device.
  i.MX: Add i.MX6 System Reset Controller device.
  i.MX: Add i.MX6 SOC implementation.
  i.MX: Add sabrelite i.MX6 emulation.

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/fsl-imx6.c   | 402 +
 hw/arm/sabrelite.c  |  93 +
 hw/misc/Makefile.objs   |   2 +
 hw/misc/imx25_ccm.c |  35 +-
 hw/misc/imx31_ccm.c |  38 +-
 hw/misc/imx6_ccm.c  | 764 
 hw/misc/imx6_src.c  | 353 +++
 hw/timer/imx_epit.c |   8 +-
 hw/timer/imx_gpt.c  |  43 +--
 include/hw/arm/fsl-imx6.h   | 447 +++
 include/hw/misc/imx6_ccm.h  | 195 ++
 include/hw/misc/imx6_src.h  |  72 
 include/hw/misc/imx_ccm.h   |  10 +-
 15 files changed, 2368 insertions(+), 96 deletions(-)
 create mode 100644 hw/arm/fsl-imx6.c
 create mode 100644 hw/arm/sabrelite.c
 create mode 100644 hw/misc/imx6_ccm.c
 create mode 100644 hw/misc/imx6_src.c
 create mode 100644 include/hw/arm/fsl-imx6.h
 create mode 100644 include/hw/misc/imx6_ccm.h
 create mode 100644 include/hw/misc/imx6_src.h

-- 
2.5.0




[Qemu-devel] [PATCH 3/6] i.MX: Add i.MX6 CCM and ANALOG device.

2016-01-26 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---
 hw/misc/Makefile.objs  |   1 +
 hw/misc/imx6_ccm.c | 764 +
 include/hw/misc/imx6_ccm.h | 195 
 3 files changed, 960 insertions(+)
 create mode 100644 hw/misc/imx6_ccm.c
 create mode 100644 include/hw/misc/imx6_ccm.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index d4765c2..a2a8e91 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -28,6 +28,7 @@ obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o
 obj-$(CONFIG_IMX) += imx_ccm.o
 obj-$(CONFIG_IMX) += imx31_ccm.o
 obj-$(CONFIG_IMX) += imx25_ccm.o
+obj-$(CONFIG_IMX) += imx6_ccm.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx6_ccm.c b/hw/misc/imx6_ccm.c
new file mode 100644
index 000..05dfe2d
--- /dev/null
+++ b/hw/misc/imx6_ccm.c
@@ -0,0 +1,764 @@
+/*
+ * IMX6 Clock Control Module
+ *
+ * Copyright (c) 2015 Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * To get the timer frequencies right, we need to emulate at least part of
+ * the CCM.
+ */
+
+#include "hw/misc/imx6_ccm.h"
+
+#ifndef DEBUG_IMX6_CCM
+#define DEBUG_IMX6_CCM 0
+#endif
+
+#define DPRINTF(fmt, args...) \
+do { \
+if (DEBUG_IMX6_CCM) { \
+fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX6_CCM, \
+ __func__, ##args); \
+} \
+} while (0)
+
+static char const *imx6_ccm_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case CCM_CCR:
+return "CCR";
+case CCM_CCDR:
+return "CCDR";
+case CCM_CSR:
+return "CSR";
+case CCM_CCSR:
+return "CCSR";
+case CCM_CACRR:
+return "CACRR";
+case CCM_CBCDR:
+return "CBCDR";
+case CCM_CBCMR:
+return "CBCMR";
+case CCM_CSCMR1:
+return "CSCMR1";
+case CCM_CSCMR2:
+return "CSCMR2";
+case CCM_CSCDR1:
+return "CSCDR1";
+case CCM_CS1CDR:
+return "CS1CDR";
+case CCM_CS2CDR:
+return "CS2CDR";
+case CCM_CDCDR:
+return "CDCDR";
+case CCM_CHSCCDR:
+return "CHSCCDR";
+case CCM_CSCDR2:
+return "CSCDR2";
+case CCM_CSCDR3:
+return "CSCDR3";
+case CCM_CDHIPR:
+return "CDHIPR";
+case CCM_CTOR:
+return "CTOR";
+case CCM_CLPCR:
+return "CLPCR";
+case CCM_CISR:
+return "CISR";
+case CCM_CIMR:
+return "CIMR";
+case CCM_CCOSR:
+return "CCOSR";
+case CCM_CGPR:
+return "CGPR";
+case CCM_CCGR0:
+return "CCGR0";
+case CCM_CCGR1:
+return "CCGR1";
+case CCM_CCGR2:
+return "CCGR2";
+case CCM_CCGR3:
+return "CCGR3";
+case CCM_CCGR4:
+return "CCGR4";
+case CCM_CCGR5:
+return "CCGR5";
+case CCM_CCGR6:
+return "CCGR6";
+case CCM_CMEOR:
+return "CMEOR";
+default:
+sprintf(unknown, "%d ?", reg);
+return unknown;
+}
+}
+
+static char const *imx6_analog_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case CCM_ANALOG_PLL_ARM:
+return "PLL_ARM";
+case CCM_ANALOG_PLL_ARM_SET:
+return "PLL_ARM_SET";
+case CCM_ANALOG_PLL_ARM_CLR:
+return "PLL_ARM_CLR";
+case CCM_ANALOG_PLL_ARM_TOG:
+return "PLL_ARM_TOG";
+case CCM_ANALOG_PLL_USB1:
+return "PLL_USB1";
+case CCM_ANALOG_PLL_USB1_SET:
+return "PLL_USB1_SET";
+case CCM_ANALOG_PLL_USB1_CLR:
+return "PLL_USB1_CLR";
+case CCM_ANALOG_PLL_USB1_TOG:
+return "PLL_USB1_TOG";
+case CCM_ANALOG_PLL_USB2:
+return "PLL_USB2";
+case CCM_ANALOG_PLL_USB2_SET:
+return "PLL_USB2_SET";
+case CCM_ANALOG_PLL_USB2_CLR:
+return "PLL_USB2_CLR";
+case CCM_ANALOG_PLL_USB2_TOG:
+return "PLL_USB2_TOG";
+case CCM_ANALOG_PLL_SYS:
+return "PLL_SYS";
+case CCM_ANALOG_PLL_SYS_SET:
+return "PLL_SYS_SET";
+case CCM_ANALOG_PLL_SYS_CLR:
+return "PLL_SYS_CLR";
+case CCM_ANALOG_PLL_SYS_TOG:
+return "PLL_SYS_TOG";
+case CCM_ANALOG_PLL_SYS_SS:
+return "PLL_SYS_SS";
+case CCM_ANALOG_PLL_SYS_NUM:
+

[Qemu-devel] [PATCH 2/6] i.MX: simplify CCM to only handle clock required by timers.

2016-01-26 Thread Jean-Christophe Dubois
Various i.MX timers (GPT, EPIT, PWM, ...) are only requesting 4 clocks
from the system.
* CLK_NONE,
* CLK_IPG,
* CLK_IPG_HIGH,
* CLK_32k

Other "clocks" are not required by the qemu framework so far.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/misc/imx25_ccm.c   | 35 +--
 hw/misc/imx31_ccm.c   | 38 --
 hw/timer/imx_epit.c   |  8 
 hw/timer/imx_gpt.c| 16 
 include/hw/misc/imx_ccm.h | 10 ++
 5 files changed, 23 insertions(+), 84 deletions(-)

diff --git a/hw/misc/imx25_ccm.c b/hw/misc/imx25_ccm.c
index 23759ca..38599f2 100644
--- a/hw/misc/imx25_ccm.c
+++ b/hw/misc/imx25_ccm.c
@@ -119,20 +119,6 @@ static uint32_t imx25_ccm_get_mpll_clk(IMXCCMState *dev)
 return freq;
 }
 
-static uint32_t imx25_ccm_get_upll_clk(IMXCCMState *dev)
-{
-uint32_t freq = 0;
-IMX25CCMState *s = IMX25_CCM(dev);
-
-if (!EXTRACT(s->reg[IMX25_CCM_CCTL_REG], UPLL_DIS)) {
-freq = imx_ccm_calc_pll(s->reg[IMX25_CCM_UPCTL_REG], CKIH_FREQ);
-}
-
-DPRINTF("freq = %d\n", freq);
-
-return freq;
-}
-
 static uint32_t imx25_ccm_get_mcu_clk(IMXCCMState *dev)
 {
 uint32_t freq;
@@ -181,21 +167,10 @@ static uint32_t imx25_ccm_get_clock_frequency(IMXCCMState 
*dev, IMXClk clock)
 DPRINTF("Clock = %d)\n", clock);
 
 switch (clock) {
-case NOCLK:
-break;
-case CLK_MPLL:
-freq = imx25_ccm_get_mpll_clk(dev);
-break;
-case CLK_UPLL:
-freq = imx25_ccm_get_upll_clk(dev);
-break;
-case CLK_MCU:
-freq = imx25_ccm_get_mcu_clk(dev);
-break;
-case CLK_AHB:
-freq = imx25_ccm_get_ahb_clk(dev);
+case CLK_NONE:
 break;
 case CLK_IPG:
+case CLK_IPG_HIGH:
 freq = imx25_ccm_get_ipg_clk(dev);
 break;
 case CLK_32k:
@@ -221,9 +196,9 @@ static void imx25_ccm_reset(DeviceState *dev)
 memset(s->reg, 0, IMX25_CCM_MAX_REG * sizeof(uint32_t));
 s->reg[IMX25_CCM_MPCTL_REG] = 0x800b2c01;
 s->reg[IMX25_CCM_UPCTL_REG] = 0x84042800;
-/* 
+/*
  * The value below gives:
- * CPU = 133 MHz, AHB = 66,5 MHz, IPG = 33 MHz. 
+ * CPU = 133 MHz, AHB = 66,5 MHz, IPG = 33 MHz.
  */
 s->reg[IMX25_CCM_CCTL_REG]  = 0xd003;
 s->reg[IMX25_CCM_CGCR0_REG] = 0x028A0100;
@@ -240,7 +215,7 @@ static void imx25_ccm_reset(DeviceState *dev)
 
 /*
  * default boot will change the reset values to allow:
- * CPU = 399 MHz, AHB = 133 MHz, IPG = 66,5 MHz. 
+ * CPU = 399 MHz, AHB = 133 MHz, IPG = 66,5 MHz.
  * For some reason, this doesn't work. With the value below, linux
  * detects a 88 MHz IPG CLK instead of 66,5 MHz.
 s->reg[IMX25_CCM_CCTL_REG]  = 0x20032000;
diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
index 47d6ead..3876cc2 100644
--- a/hw/misc/imx31_ccm.c
+++ b/hw/misc/imx31_ccm.c
@@ -111,7 +111,7 @@ static uint32_t imx31_ccm_get_pll_ref_clk(IMXCCMState *dev)
 if (s->reg[IMX31_CCM_CCMR_REG] & CCMR_FPMF) {
 freq *= 1024;
 }
-} 
+}
 } else {
 freq = CKIH_FREQ;
 }
@@ -134,6 +134,7 @@ static uint32_t imx31_ccm_get_mpll_clk(IMXCCMState *dev)
 return freq;
 }
 
+
 static uint32_t imx31_ccm_get_mcu_main_clk(IMXCCMState *dev)
 {
 uint32_t freq;
@@ -151,32 +152,6 @@ static uint32_t imx31_ccm_get_mcu_main_clk(IMXCCMState 
*dev)
 return freq;
 }
 
-static uint32_t imx31_ccm_get_mcu_clk(IMXCCMState *dev)
-{
-uint32_t freq;
-IMX31CCMState *s = IMX31_CCM(dev);
-
-freq = imx31_ccm_get_mcu_main_clk(dev)
-   / (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], MCU));
-
-DPRINTF("freq = %d\n", freq);
-
-return freq;
-}
-
-static uint32_t imx31_ccm_get_hsp_clk(IMXCCMState *dev)
-{
-uint32_t freq;
-IMX31CCMState *s = IMX31_CCM(dev);
-
-freq = imx31_ccm_get_mcu_main_clk(dev)
-   / (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], HSP));
-
-DPRINTF("freq = %d\n", freq);
-
-return freq;
-}
-
 static uint32_t imx31_ccm_get_hclk_clk(IMXCCMState *dev)
 {
 uint32_t freq;
@@ -208,15 +183,10 @@ static uint32_t imx31_ccm_get_clock_frequency(IMXCCMState 
*dev, IMXClk clock)
 uint32_t freq = 0;
 
 switch (clock) {
-case NOCLK:
-break;
-case CLK_MCU:
-freq = imx31_ccm_get_mcu_clk(dev);
-break;
-case CLK_HSP:
-freq = imx31_ccm_get_hsp_clk(dev);
+case CLK_NONE:
 break;
 case CLK_IPG:
+case CLK_IPG_HIGH:
 freq = imx31_ccm_get_ipg_clk(dev);
 break;
 case CLK_32k:
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 50bf83c..a67bcb5 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -51,10 +51,10 @@ static char const *imx_epit_reg_name(uint32_t reg)
  * These are typical.
  */
 static const IMXClk imx_epit_clocks[] =  {
-NOCLK,/* 0

[Qemu-devel] [PATCH 1/6] i.MX: Allow GPT timer to rollover.

2016-01-26 Thread Jean-Christophe Dubois
GPT timer need to rolloever when it reaches 0x.

It also need to reset to 0 when in "retart mode" and crossing the
compare 1 register.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/timer/imx_gpt.c | 27 +++
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index b1893b8..b227256 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -133,7 +133,7 @@ static inline uint32_t imx_gpt_find_limit(uint32_t count, 
uint32_t reg,
 static void imx_gpt_compute_next_timeout(IMXGPTState *s, bool event)
 {
 uint32_t timeout = GPT_TIMER_MAX;
-uint32_t count = 0;
+uint32_t count;
 long long limit;
 
 if (!(s->cr & GPT_CR_EN)) {
@@ -141,20 +141,23 @@ static void imx_gpt_compute_next_timeout(IMXGPTState *s, 
bool event)
 return;
 }
 
-if (event) {
-/* This is a timer event  */
+/* update the count */
+count = imx_gpt_update_count(s);
 
-if ((s->cr & GPT_CR_FRR)  && (s->next_timeout != GPT_TIMER_MAX)) {
-/*
- * if we are in free running mode and we have not reached
- * the GPT_TIMER_MAX limit, then update the count
+if (event) {
+/*
+ * This is an event (the ptimer reached 0 and stopped), and the
+ * timer counter is now equal to s->next_timeout.
+ */
+if (!(s->cr & GPT_CR_FRR) && (count == s->ocr1)) {
+/* We are in restart mode and we crossed the compare channel 1
+ * value. We need to reset the counter to 0.
  */
-count = imx_gpt_update_count(s);
+count = s->cnt = s->next_timeout = 0;
+} else if (count == GPT_TIMER_MAX) {
+/* We reached GPT_TIMER_MAX so we need to rollover */
+count = s->cnt = s->next_timeout = 0;
 }
-} else {
-/* not a timer event, then just update the count */
-
-count = imx_gpt_update_count(s);
 }
 
 /* now, find the next timeout related to count */
-- 
2.5.0




[Qemu-devel] [PATCH 4/6] i.MX: Add i.MX6 System Reset Controller device.

2016-01-26 Thread Jean-Christophe Dubois
This controller is also present in i.MX5X devices but they are not
yet emulated by Qemu.

Signed-off-by: Jean-Christophe Dubois 
---
 hw/misc/Makefile.objs  |   1 +
 hw/misc/imx6_src.c | 353 +
 include/hw/misc/imx6_src.h |  72 +
 3 files changed, 426 insertions(+)
 create mode 100644 hw/misc/imx6_src.c
 create mode 100644 include/hw/misc/imx6_src.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index a2a8e91..6bac654 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -29,6 +29,7 @@ obj-$(CONFIG_IMX) += imx_ccm.o
 obj-$(CONFIG_IMX) += imx31_ccm.o
 obj-$(CONFIG_IMX) += imx25_ccm.o
 obj-$(CONFIG_IMX) += imx6_ccm.o
+obj-$(CONFIG_IMX) += imx6_src.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx6_src.c b/hw/misc/imx6_src.c
new file mode 100644
index 000..d1be7c1
--- /dev/null
+++ b/hw/misc/imx6_src.c
@@ -0,0 +1,353 @@
+/*
+ * IMX6 System Reset Controller
+ *
+ * Copyright (c) 2015 Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw/misc/imx6_src.h"
+#include "sysemu/sysemu.h"
+#include "qemu/bitops.h"
+
+#ifndef DEBUG_IMX6_SRC
+#define DEBUG_IMX6_SRC 0
+#endif
+
+#define DPRINTF(fmt, args...) \
+do { \
+if (DEBUG_IMX6_SRC) { \
+fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX6_SRC, \
+ __func__, ##args); \
+} \
+} while (0)
+
+static char const *imx6_src_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case SRC_SCR:
+return "SRC_SCR";
+case SRC_SBMR1:
+return "SRC_SBMR1";
+case SRC_SRSR:
+return "SRC_SRSR";
+case SRC_SISR:
+return "SRC_SISR";
+case SRC_SIMR:
+return "SRC_SIMR";
+case SRC_SBMR2:
+return "SRC_SBMR2";
+case SRC_GPR1:
+return "SRC_GPR1";
+case SRC_GPR2:
+return "SRC_GPR2";
+case SRC_GPR3:
+return "SRC_GPR3";
+case SRC_GPR4:
+return "SRC_GPR4";
+case SRC_GPR5:
+return "SRC_GPR5";
+case SRC_GPR6:
+return "SRC_GPR6";
+case SRC_GPR7:
+return "SRC_GPR7";
+case SRC_GPR8:
+return "SRC_GPR8";
+case SRC_GPR9:
+return "SRC_GPR9";
+case SRC_GPR10:
+return "SRC_GPR10";
+default:
+sprintf(unknown, "%d ?", reg);
+return unknown;
+}
+}
+
+static const VMStateDescription vmstate_imx6_src = {
+.name = TYPE_IMX6_SRC,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32_ARRAY(regs, IMX6SRCState, SRC_MAX),
+VMSTATE_END_OF_LIST()
+},
+};
+
+static void imx6_src_reset(DeviceState *dev)
+{
+IMX6SRCState *s = IMX6_SRC(dev);
+
+DPRINTF("\n");
+
+/*
+ * We only clear the first registers as all GPR registers are preserved
+ * over resets
+ */
+memset(s->regs, 0, SRC_GPR1 * sizeof(uint32_t));
+
+/* Set reset values */
+s->regs[SRC_SCR] = 0x521;
+s->regs[SRC_SRSR] = 0x1;
+s->regs[SRC_SIMR] = 0x1F;
+}
+
+static CPUState *imx6_src_get_cpu_by_id(uint32_t id)
+{
+CPUState *cpu;
+
+DPRINTF("cpu %d\n", id);
+
+CPU_FOREACH(cpu) {
+ARMCPU *armcpu = ARM_CPU(cpu);
+
+if (armcpu->mp_affinity == id) {
+return cpu;
+}
+}
+
+qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Resquesting unknown CPU %d\n",
+  TYPE_IMX6_SRC, __func__, id);
+
+return NULL;
+}
+
+static void imx6_src_cpu_on(uint32_t cpuid, uint32_t entry, uint32_t 
context_id)
+{
+CPUState *target_cpu_state;
+ARMCPU *target_cpu;
+CPUClass *target_cpu_class;
+
+DPRINTF("cpu %d @ 0x%08x with R0 = 0x%08x\n", cpuid, entry, context_id);
+
+/* change to the cpu we are powering up */
+target_cpu_state = imx6_src_get_cpu_by_id(cpuid);
+if (!target_cpu_state) {
+return;
+}
+target_cpu = ARM_CPU(target_cpu_state);
+if (!target_cpu->powered_off) {
+qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: CPU %d is already running\n",
+  TYPE_IMX6_SRC, __func__, cpuid);
+return;
+}
+target_cpu_class = CPU_GET_CLASS(target_cpu);
+
+/* Initialize the cpu we are turning on */
+cpu_reset(target_cpu_state);
+target_cpu->powered_off = false;
+target_cpu_state->halted = 0;
+
+target_cpu->env.regs[0] = context_id;
+target_cpu->env.thumb = entry & 1;
+
+target_cpu_class->set_pc(target_

[Qemu-devel] [PATCH 6/6] i.MX: Add sabrelite i.MX6 emulation.

2016-01-26 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---
 hw/arm/Makefile.objs |  2 +-
 hw/arm/sabrelite.c   | 93 
 2 files changed, 94 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/sabrelite.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index ac383df..fc1df45 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -15,4 +15,4 @@ obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
 obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
-obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o
+obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
new file mode 100644
index 000..4e0c3fb
--- /dev/null
+++ b/hw/arm/sabrelite.c
@@ -0,0 +1,93 @@
+/*
+ * SABRELITE Board System emulation.
+ *
+ * Copyright (c) 2015 Jean-Christophe Dubois 
+ *
+ * This code is licensed under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a sabrelite board, with a Freescale
+ * i.MX6 SoC
+ */
+
+#include "hw/arm/fsl-imx6.h"
+#include "hw/boards.h"
+#include "qemu/error-report.h"
+#include "exec/address-spaces.h"
+#include "net/net.h"
+#include "hw/devices.h"
+#include "hw/char/serial.h"
+#include "sysemu/qtest.h"
+
+typedef struct IMX6Sabrelite {
+FslIMX6State soc;
+MemoryRegion ram;
+} IMX6Sabrelite;
+
+static struct arm_boot_info sabrelite_binfo = {
+/* DDR memory start */
+.loader_start = FSL_IMX6_MMDC_ADDR,
+/* No board ID, we boot from DT tree */
+.board_id = -1,
+};
+
+/* No need to do any particulat setup for secondary boot */
+static void sabrelite_write_secondary(ARMCPU *cpu,
+  const struct arm_boot_info *info)
+{
+}
+
+/* Secondary cores are reseted through SRC device */
+static void sabrelite_reset_secondary(ARMCPU *cpu,
+  const struct arm_boot_info *info)
+{
+}
+
+static void sabrelite_init(MachineState *machine)
+{
+IMX6Sabrelite *s = g_new0(IMX6Sabrelite, 1);
+Error *err = NULL;
+
+object_initialize(&s->soc, sizeof(s->soc), TYPE_FSL_IMX6);
+object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
+  &error_abort);
+
+object_property_set_bool(OBJECT(&s->soc), true, "realized", &err);
+if (err != NULL) {
+error_report("%s", error_get_pretty(err));
+exit(1);
+}
+
+/* Check the amount of memory is compatible with the SOC */
+if (machine->ram_size > FSL_IMX6_MMDC_SIZE) {
+error_report("WARNING: RAM size " RAM_ADDR_FMT " above max supported, "
+ "reduced to %x", machine->ram_size, FSL_IMX6_MMDC_SIZE);
+machine->ram_size = FSL_IMX6_MMDC_SIZE;
+}
+
+memory_region_allocate_system_memory(&s->ram, NULL, "sabrelite.ram",
+ machine->ram_size);
+memory_region_add_subregion(get_system_memory(), FSL_IMX6_MMDC_ADDR,
+&s->ram);
+
+sabrelite_binfo.ram_size = machine->ram_size;
+sabrelite_binfo.kernel_filename = machine->kernel_filename;
+sabrelite_binfo.kernel_cmdline = machine->kernel_cmdline;
+sabrelite_binfo.initrd_filename = machine->initrd_filename;
+sabrelite_binfo.nb_cpus = smp_cpus;
+sabrelite_binfo.write_secondary_boot = sabrelite_write_secondary;
+sabrelite_binfo.secondary_cpu_reset_hook = sabrelite_reset_secondary;
+
+if (!qtest_enabled()) {
+arm_load_kernel(&s->soc.cpu[0], &sabrelite_binfo);
+}
+}
+
+static void sabrelite_machine_init(MachineClass *mc)
+{
+mc->desc = "Freescale i.MX6 Quad SABRE Lite Board (Cortex A9)";
+mc->init = sabrelite_init;
+mc->max_cpus = FSL_IMX6_NUM_CPUS;
+}
+
+DEFINE_MACHINE("sabrelite", sabrelite_machine_init)
-- 
2.5.0




[Qemu-devel] [PATCH 5/6] i.MX: Add i.MX6 SOC implementation.

2016-01-26 Thread Jean-Christophe Dubois
For now we only support the following devices:
* up to 4 Cortex A9 cores
* A9 MPCORE (SCU, GIC, TWD)
* 5 i.MX UARTs
* 2 EPIT timers
* 1 GPT timer
* 7 GPIO controllers
* 6 SDHC controllers
* 1 CCM device
* 1 SRC device
* various ROM/RAM areas.

Signed-off-by: Jean-Christophe Dubois 
---
 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/fsl-imx6.c   | 402 
 include/hw/arm/fsl-imx6.h   | 447 
 4 files changed, 851 insertions(+)
 create mode 100644 hw/arm/fsl-imx6.c
 create mode 100644 include/hw/arm/fsl-imx6.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index d9b90a5..ba3a380 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -99,6 +99,7 @@ CONFIG_ALLWINNER_A10_PIT=y
 CONFIG_ALLWINNER_A10_PIC=y
 CONFIG_ALLWINNER_A10=y
 
+CONFIG_FSL_IMX6=y
 CONFIG_FSL_IMX31=y
 CONFIG_FSL_IMX25=y
 
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 2195b60..ac383df 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -15,3 +15,4 @@ obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
 obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
+obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
new file mode 100644
index 000..9167392
--- /dev/null
+++ b/hw/arm/fsl-imx6.c
@@ -0,0 +1,402 @@
+/*
+ * Copyright (c) 2015 Jean-Christophe Dubois 
+ *
+ * i.MX6 SOC emulation.
+ *
+ * Based on hw/arm/fsl-imx31.c
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw/arm/fsl-imx6.h"
+#include "sysemu/sysemu.h"
+#include "exec/address-spaces.h"
+#include "hw/boards.h"
+#include "sysemu/char.h"
+
+static void fsl_imx6_init(Object *obj)
+{
+FslIMX6State *s = FSL_IMX6(obj);
+int i;
+
+if (smp_cpus > FSL_IMX6_NUM_CPUS) {
+exit(1);
+}
+
+for (i = 0; i < smp_cpus; i++) {
+object_initialize(&s->cpu[i], sizeof(s->cpu[i]),
+  "cortex-a9-" TYPE_ARM_CPU);
+}
+
+object_initialize(&s->a9mpcore, sizeof(s->a9mpcore), TYPE_A9MPCORE_PRIV);
+qdev_set_parent_bus(DEVICE(&s->a9mpcore), sysbus_get_default());
+
+object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX6_CCM);
+qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
+
+object_initialize(&s->src, sizeof(s->src), TYPE_IMX6_SRC);
+qdev_set_parent_bus(DEVICE(&s->src), sysbus_get_default());
+
+for (i = 0; i < FSL_IMX6_NUM_UARTS; i++) {
+object_initialize(&s->uart[i], sizeof(s->uart[i]), TYPE_IMX_SERIAL);
+qdev_set_parent_bus(DEVICE(&s->uart[i]), sysbus_get_default());
+}
+
+object_initialize(&s->gpt, sizeof(s->gpt), TYPE_IMX_GPT);
+qdev_set_parent_bus(DEVICE(&s->gpt), sysbus_get_default());
+
+for (i = 0; i < FSL_IMX6_NUM_EPITS; i++) {
+object_initialize(&s->epit[i], sizeof(s->epit[i]), TYPE_IMX_EPIT);
+qdev_set_parent_bus(DEVICE(&s->epit[i]), sysbus_get_default());
+}
+
+for (i = 0; i < FSL_IMX6_NUM_I2CS; i++) {
+object_initialize(&s->i2c[i], sizeof(s->i2c[i]), TYPE_IMX_I2C);
+qdev_set_parent_bus(DEVICE(&s->i2c[i]), sysbus_get_default());
+}
+
+for (i = 0; i < FSL_IMX6_NUM_GPIOS; i++) {
+object_initialize(&s->gpio[i], sizeof(s->gpio[i]), TYPE_IMX_GPIO);
+qdev_set_parent_bus(DEVICE(&s->gpio[i]), sysbus_get_default());
+}
+
+for (i = 0; i < FSL_IMX6_NUM_ESDHCS; i++) {
+object_initialize(&s->esdhc[i], sizeof(s->esdhc[i]), 
TYPE_SYSBUS_SDHCI);
+qdev_set_parent_bus(DEVICE(&s->esdhc[i]), sysbus_get_default());
+}
+}
+
+static void fsl_imx6_realize(DeviceState *dev, Error **errp)
+{
+FslIMX6State *s = FSL_IMX6(dev);
+uint16_t i;
+Error *err = NULL;
+
+for (i = 0; i < smp_cpus; i++) {
+
+if (smp_cpus == 1) {
+/* On uniprocessor, the CBAR is set to 0 */
+object_property_set_int(OBJECT(&s->cpu[i]), 0,
+ 

Re: [Qemu-devel] [PATCH 1/6] i.MX: Allow GPT timer to rollover.

2016-01-26 Thread Jean-Christophe DUBOIS

Le 26/01/2016 22:54, Eric Blake a écrit :

On 01/26/2016 02:44 PM, Jean-Christophe Dubois wrote:

[meta-reply]
Make sure your git settings properly thread your messages. Your 1/6 came
through as a top-level thread, rather than in-reply-to the 0/6 cover
letter (likewise for the rest of the series).


Yes, sorry about that, I forgot to set the "threaded" option.




GPT timer need to rolloever when it reaches 0x.

s/rolloever/rollover/


It also need to reset to 0 when in "retart mode" and crossing the

s/retart/restart/


compare 1 register.







Re: [Qemu-devel] [PATCH 0/6] Add i.MX6 (Single/Dual/Quad) support

2016-01-28 Thread Jean-Christophe DUBOIS

Hello Peter,

Le 28/01/2016 15:57, Peter Maydell a écrit :

On 26 January 2016 at 21:44, Jean-Christophe Dubois  
wrote:

This patch series adds support for the Freescale i.MX6 processor.

For now we only support the following devices:
* up to 4 Cortex A9 cores
* A9 MPCORE (SCU, GIC, TWD)
* 5 i.MX UARTs
* 2 EPIT timers
* 1 GPT timer
* 7 GPIO controllers
* 6 SDHC controllers
* 1 CCM device
* 1 SRC device
* various ROM/RAM areas.

This also adds the sabrelite board as a an actual platform for i.MX6.

This series was tested by booting a 4.4 linux kernel (using the
imx_v6_v7_defconfig file as kernel configuration).

Note: In order for Linux to work I had to customize a bit the
arch/arm/boot/dts/imx6qdl-sabrelite.dtsi device tree file.

What changes did you have to make to the dt, and why?


Please find attached the diff file for the linux imx6qdl-sabrelite.dtsi 
file.


Basically, it boils down to the following:

 * Sabrelite uses uart2 for console but on qemu, this is uart1 that is
   wired to the default stdout. Consequently, I changed stdout-path in
   "chosen" to uart1.
 * For now i.MX6 SOC code does not emulate SPI controller. During the
   boot Linux was getting stuck trying to access a SPI device that is
   supposed to be there. Therefore I disabled the SPI controller in the
   device tree.
 * The sabrelite is supposed to have a bunch of push buttons (home,
   power, back, vol up, vol down) wired to various GPIOs. I guess these
   buttons might have pull up or pull down resistors on the real
   hardware but obviously on qemu we have no such things. As a results
   the GPIOs were triggering a lot of interrupts for nothing. So I
   commented out the GPIO sections were the buttons were defined.

Regards

JC



thanks
-- PMM



diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
index 1a69a34..760020e 100644
--- a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
@@ -44,7 +44,8 @@
 
 / {
 	chosen {
-		stdout-path = &uart2;
+bootargs = "console=ttymxc0,115200";
+		stdout-path = &uart1;
 	};
 
 	memory {
@@ -96,6 +97,7 @@
 		};
 	};
 
+/*
 	gpio-keys {
 		compatible = "gpio-keys";
 		pinctrl-names = "default";
@@ -138,6 +140,7 @@
 			linux,code = ;
 		};
 	};
+*/
 
 	sound {
 		compatible = "fsl,imx6q-sabrelite-sgtl5000",
@@ -245,7 +248,7 @@
 	cs-gpios = <&gpio3 19 0>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_ecspi1>;
-	status = "okay";
+	/* status = "okay"; */
 
 	flash: m25p80@0 {
 		compatible = "sst,sst25vf016b", "jedec,spi-nor";


Re: [Qemu-devel] [PATCH 2/6] i.MX: simplify CCM to only handle clock required by timers.

2016-02-02 Thread Jean-Christophe DUBOIS

Le 02/02/2016 17:22, Peter Maydell a écrit :

On 26 January 2016 at 21:44, Jean-Christophe Dubois  
wrote:

Various i.MX timers (GPT, EPIT, PWM, ...) are only requesting 4 clocks
from the system.
* CLK_NONE,
* CLK_IPG,
* CLK_IPG_HIGH,
* CLK_32k

Other "clocks" are not required by the qemu framework so far.

This patch confuses me. You don't say why we're removing a bunch
of code or why it's OK to do that.


I added these other clocks in a previous patch but I believe it was a 
mistake I made.


These additional clocks (MCU, AHB, PER, ...) will likely never be user 
inside QEMU. And each new version of SOC will just continue to add to 
this list of clocks making things always more confusing.


In fact, the only interesting clocks are the ones that are used by timer 
devices. And timer devices don't directly use SOC named clocks (PER, 
AHB, ...), but they use only (for now) the 4 abstract clocks listed 
above. Each SOC seems then free to map these abstract clocks (generally 
mostly IPG and IPG_HIGH) to any of its real clocks.


So I decided to just remove the useless code in relation with SOC clocks 
that are not otherwise used in the rest of the QEMU code.


I added this mess so I should clean it. And this is really what this 
patch is: A cleanup of something that should not have been added in the 
first place because it has no use.


Sorry about that.




Signed-off-by: Jean-Christophe Dubois 
---
  hw/misc/imx25_ccm.c   | 35 +--
  hw/misc/imx31_ccm.c   | 38 --
  hw/timer/imx_epit.c   |  8 
  hw/timer/imx_gpt.c| 16 
  include/hw/misc/imx_ccm.h | 10 ++
  5 files changed, 23 insertions(+), 84 deletions(-)

diff --git a/hw/misc/imx25_ccm.c b/hw/misc/imx25_ccm.c
index 23759ca..38599f2 100644
--- a/hw/misc/imx25_ccm.c
+++ b/hw/misc/imx25_ccm.c
@@ -119,20 +119,6 @@ static uint32_t imx25_ccm_get_mpll_clk(IMXCCMState *dev)
  return freq;
  }

-static uint32_t imx25_ccm_get_upll_clk(IMXCCMState *dev)
-{
-uint32_t freq = 0;
-IMX25CCMState *s = IMX25_CCM(dev);
-
-if (!EXTRACT(s->reg[IMX25_CCM_CCTL_REG], UPLL_DIS)) {
-freq = imx_ccm_calc_pll(s->reg[IMX25_CCM_UPCTL_REG], CKIH_FREQ);
-}
-
-DPRINTF("freq = %d\n", freq);
-
-return freq;
-}
-
  static uint32_t imx25_ccm_get_mcu_clk(IMXCCMState *dev)
  {
  uint32_t freq;
@@ -181,21 +167,10 @@ static uint32_t imx25_ccm_get_clock_frequency(IMXCCMState 
*dev, IMXClk clock)
  DPRINTF("Clock = %d)\n", clock);

  switch (clock) {
-case NOCLK:
-break;
-case CLK_MPLL:
-freq = imx25_ccm_get_mpll_clk(dev);
-break;
-case CLK_UPLL:
-freq = imx25_ccm_get_upll_clk(dev);
-break;
-case CLK_MCU:
-freq = imx25_ccm_get_mcu_clk(dev);
-break;
-case CLK_AHB:
-freq = imx25_ccm_get_ahb_clk(dev);
+case CLK_NONE:
  break;
  case CLK_IPG:
+case CLK_IPG_HIGH:
  freq = imx25_ccm_get_ipg_clk(dev);
  break;
  case CLK_32k:
@@ -221,9 +196,9 @@ static void imx25_ccm_reset(DeviceState *dev)
  memset(s->reg, 0, IMX25_CCM_MAX_REG * sizeof(uint32_t));
  s->reg[IMX25_CCM_MPCTL_REG] = 0x800b2c01;
  s->reg[IMX25_CCM_UPCTL_REG] = 0x84042800;
-/*
+/*
   * The value below gives:
- * CPU = 133 MHz, AHB = 66,5 MHz, IPG = 33 MHz.
+ * CPU = 133 MHz, AHB = 66,5 MHz, IPG = 33 MHz.
   */
  s->reg[IMX25_CCM_CCTL_REG]  = 0xd003;
  s->reg[IMX25_CCM_CGCR0_REG] = 0x028A0100;
@@ -240,7 +215,7 @@ static void imx25_ccm_reset(DeviceState *dev)

  /*
   * default boot will change the reset values to allow:
- * CPU = 399 MHz, AHB = 133 MHz, IPG = 66,5 MHz.
+ * CPU = 399 MHz, AHB = 133 MHz, IPG = 66,5 MHz.
   * For some reason, this doesn't work. With the value below, linux
   * detects a 88 MHz IPG CLK instead of 66,5 MHz.
  s->reg[IMX25_CCM_CCTL_REG]  = 0x20032000;
diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
index 47d6ead..3876cc2 100644
--- a/hw/misc/imx31_ccm.c
+++ b/hw/misc/imx31_ccm.c
@@ -111,7 +111,7 @@ static uint32_t imx31_ccm_get_pll_ref_clk(IMXCCMState *dev)
  if (s->reg[IMX31_CCM_CCMR_REG] & CCMR_FPMF) {
  freq *= 1024;
  }
-}
+}


What are all these whitespace only changes? If you need to do a
whitespace cleanup please put it in its own patch.

OK



  case CLK_32k:
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 50bf83c..a67bcb5 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -51,10 +51,10 @@ static char const *imx_epit_reg_name(uint32_t reg)
   * These are typical.
   */
  static const IMXClk imx_epit_clocks[] =  {
-NOCLK,/* 00 disabled */
-CLK_IPG,  /* 01 ipg_clk, ~532MHz */
-CLK_IPG,  /* 10 ipg_clk_highfreq */
-CLK_32k,  /* 11 ipg_clk_32k -- ~3

[Qemu-devel] [PATCH v2] i.MX: add support for lower and upper interrupt in GPIO.

2015-11-14 Thread Jean-Christophe Dubois
The i.MX6 GPIO device supports 2 interrupts instead of one.

* 1 for the lower 16 GPIOs.
* 1 for the upper 16 GPIOs.

i.MX31 and i.MX25 only support 1 interrupt for the 32 GPIOs.

So we add a property to turn the behavior on when required.

Signed-off-by: Jean-Christophe Dubois 
Reviewed-by: Peter Crosthwaite 
---

Changes since v1:
 * None.

 hw/gpio/imx_gpio.c | 12 ++--
 include/hw/gpio/imx_gpio.h |  3 ++-
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/hw/gpio/imx_gpio.c b/hw/gpio/imx_gpio.c
index 3170585..a6d7cab 100644
--- a/hw/gpio/imx_gpio.c
+++ b/hw/gpio/imx_gpio.c
@@ -62,7 +62,12 @@ static const char *imx_gpio_reg_name(uint32_t reg)
 
 static void imx_gpio_update_int(IMXGPIOState *s)
 {
-qemu_set_irq(s->irq, (s->isr & s->imr) ? 1 : 0);
+if (s->has_upper_pin_irq) {
+qemu_set_irq(s->irq[0], (s->isr & s->imr & 0x) ? 1 : 0);
+qemu_set_irq(s->irq[1], (s->isr & s->imr & 0x) ? 1 : 0);
+} else {
+qemu_set_irq(s->irq[0], (s->isr & s->imr) ? 1 : 0);
+}
 }
 
 static void imx_gpio_set_int_line(IMXGPIOState *s, int line, IMXGPIOLevel 
level)
@@ -282,6 +287,8 @@ static const VMStateDescription vmstate_imx_gpio = {
 
 static Property imx_gpio_properties[] = {
 DEFINE_PROP_BOOL("has-edge-sel", IMXGPIOState, has_edge_sel, true),
+DEFINE_PROP_BOOL("has-upper-pin-irq", IMXGPIOState, has_upper_pin_irq,
+ false),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -311,7 +318,8 @@ static void imx_gpio_realize(DeviceState *dev, Error **errp)
 qdev_init_gpio_in(DEVICE(s), imx_gpio_set, IMX_GPIO_PIN_COUNT);
 qdev_init_gpio_out(DEVICE(s), s->output, IMX_GPIO_PIN_COUNT);
 
-sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
+sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[0]);
+sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[1]);
 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
 }
 
diff --git a/include/hw/gpio/imx_gpio.h b/include/hw/gpio/imx_gpio.h
index 517b261..b15a09f 100644
--- a/include/hw/gpio/imx_gpio.h
+++ b/include/hw/gpio/imx_gpio.h
@@ -54,8 +54,9 @@ typedef struct IMXGPIOState {
 uint32_t isr;
 bool has_edge_sel;
 uint32_t edge_sel;
+bool has_upper_pin_irq;
 
-qemu_irq irq;
+qemu_irq irq[2];
 qemu_irq output[IMX_GPIO_PIN_COUNT];
 } IMXGPIOState;
 
-- 
2.5.0




[Qemu-devel] [PATCH v3 0/3] Add an i.MX25 specific CCM driver

2015-11-19 Thread Jean-Christophe Dubois
i.MX25 SOC has a different CCM device than i.MX31.

Qemu i.MX25 emulation was built with i.MX31 CCM driver. This allows
Linux to work on top of the i.MX25 emultion but this is not correct.

Furthermore, other SOC we could emulate like i.MX6 have yet a different
implementation of the CCM device.

So we split the i.MX31 into a generic base class and a specific i.MX31
class.

We then add an i.MX25 specific CCM Device and have the i.MX25 SOC use it.

Jean-Christophe Dubois (3):
  i.MX: rename i.MX CCM get_clock() function and CLK ID enum names
  i.MX: Split the CCM class into an abstact base class and a concrete
class.
  i.MX: Add an i.MX25 specific CCM class/instance.

 hw/arm/fsl-imx25.c  |   2 +-
 hw/arm/fsl-imx31.c  |   2 +-
 hw/misc/Makefile.objs   |   2 +
 hw/misc/imx25_ccm.c | 243 ++
 hw/misc/imx31_ccm.c | 252 
 hw/misc/imx_ccm.c   | 226 +++
 hw/timer/imx_epit.c |  20 ++--
 hw/timer/imx_gpt.c  |  16 +--
 include/hw/arm/fsl-imx25.h  |   4 +-
 include/hw/arm/fsl-imx31.h  |   4 +-
 include/hw/misc/imx25_ccm.h |  59 +++
 include/hw/misc/imx31_ccm.h |  64 +++
 include/hw/misc/imx_ccm.h   |  78 ++
 13 files changed, 690 insertions(+), 282 deletions(-)
 create mode 100644 hw/misc/imx25_ccm.c
 create mode 100644 hw/misc/imx31_ccm.c
 create mode 100644 include/hw/misc/imx25_ccm.h
 create mode 100644 include/hw/misc/imx31_ccm.h

-- 
2.5.0




[Qemu-devel] [PATCH v3 1/3] i.MX: rename i.MX CCM get_clock() function and CLK ID enum names

2015-11-19 Thread Jean-Christophe Dubois
This is to prepare for CCM code refactoring.

This is just a bit of function and enum values renaming.

We also remove some useless intermediate variables.

Signed-off-by: Jean-Christophe Dubois 
---

Changes since v1:
 * Not present 
  
Changes since v2:
 * Not present 

 hw/misc/imx_ccm.c |  8 
 hw/timer/imx_epit.c   | 20 +---
 hw/timer/imx_gpt.c| 16 
 include/hw/misc/imx_ccm.h |  8 
 4 files changed, 25 insertions(+), 27 deletions(-)

diff --git a/hw/misc/imx_ccm.c b/hw/misc/imx_ccm.c
index 4cc2bbc..415937f 100644
--- a/hw/misc/imx_ccm.c
+++ b/hw/misc/imx_ccm.c
@@ -49,18 +49,18 @@ static const VMStateDescription vmstate_imx_ccm = {
 .post_load = imx_ccm_post_load,
 };
 
-uint32_t imx_clock_frequency(DeviceState *dev, IMXClk clock)
+uint32_t imx_ccm_get_clock_frequency(DeviceState *dev, IMXClk clock)
 {
 IMXCCMState *s = IMX_CCM(dev);
 
 switch (clock) {
 case NOCLK:
 return 0;
-case MCU:
+case CLK_MCU:
 return s->mcu_clk_freq;
-case HSP:
+case CLK_HSP:
 return s->hsp_clk_freq;
-case IPG:
+case CLK_IPG:
 return s->ipg_clk_freq;
 case CLK_32k:
 return CKIL_FREQ;
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 967be4a..50bf83c 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -51,9 +51,9 @@ static char const *imx_epit_reg_name(uint32_t reg)
  * These are typical.
  */
 static const IMXClk imx_epit_clocks[] =  {
-0,/* 00 disabled */
-IPG,  /* 01 ipg_clk, ~532MHz */
-IPG,  /* 10 ipg_clk_highfreq */
+NOCLK,/* 00 disabled */
+CLK_IPG,  /* 01 ipg_clk, ~532MHz */
+CLK_IPG,  /* 10 ipg_clk_highfreq */
 CLK_32k,  /* 11 ipg_clk_32k -- ~32kHz */
 };
 
@@ -73,20 +73,18 @@ static void imx_epit_set_freq(IMXEPITState *s)
 {
 uint32_t clksrc;
 uint32_t prescaler;
-uint32_t freq;
 
 clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, 2);
 prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, 12);
 
-freq = imx_clock_frequency(s->ccm, imx_epit_clocks[clksrc]) / prescaler;
+s->freq = imx_ccm_get_clock_frequency(s->ccm,
+imx_epit_clocks[clksrc]) / prescaler;
 
-s->freq = freq;
+DPRINTF("Setting ptimer frequency to %u\n", s->freq);
 
-DPRINTF("Setting ptimer frequency to %u\n", freq);
-
-if (freq) {
-ptimer_set_freq(s->timer_reload, freq);
-ptimer_set_freq(s->timer_cmp, freq);
+if (s->freq) {
+ptimer_set_freq(s->timer_reload, s->freq);
+ptimer_set_freq(s->timer_cmp, s->freq);
 }
 }
 
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index 7257f42..b1893b8 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -81,8 +81,8 @@ static const VMStateDescription vmstate_imx_timer_gpt = {
 
 static const IMXClk imx_gpt_clocks[] = {
 NOCLK,/* 000 No clock source */
-IPG,  /* 001 ipg_clk, 532MHz*/
-IPG,  /* 010 ipg_clk_highfreq */
+CLK_IPG,  /* 001 ipg_clk, 532MHz*/
+CLK_IPG,  /* 010 ipg_clk_highfreq */
 NOCLK,/* 011 not defined */
 CLK_32k,  /* 100 ipg_clk_32k */
 NOCLK,/* 101 not defined */
@@ -93,14 +93,14 @@ static const IMXClk imx_gpt_clocks[] = {
 static void imx_gpt_set_freq(IMXGPTState *s)
 {
 uint32_t clksrc = extract32(s->cr, GPT_CR_CLKSRC_SHIFT, 3);
-uint32_t freq = imx_clock_frequency(s->ccm, imx_gpt_clocks[clksrc])
-/ (1 + s->pr);
-s->freq = freq;
 
-DPRINTF("Setting clksrc %d to frequency %d\n", clksrc, freq);
+s->freq = imx_ccm_get_clock_frequency(s->ccm,
+imx_gpt_clocks[clksrc]) / (1 + s->pr);
 
-if (freq) {
-ptimer_set_freq(s->timer, freq);
+DPRINTF("Setting clksrc %d to frequency %d\n", clksrc, s->freq);
+
+if (s->freq) {
+ptimer_set_freq(s->timer, s->freq);
 }
 }
 
diff --git a/include/hw/misc/imx_ccm.h b/include/hw/misc/imx_ccm.h
index 0f2e469..09f6248 100644
--- a/include/hw/misc/imx_ccm.h
+++ b/include/hw/misc/imx_ccm.h
@@ -80,12 +80,12 @@ typedef struct IMXCCMState {
 
 typedef enum  {
 NOCLK,
-MCU,
-HSP,
-IPG,
+CLK_MCU,
+CLK_HSP,
+CLK_IPG,
 CLK_32k
 } IMXClk;
 
-uint32_t imx_clock_frequency(DeviceState *s, IMXClk clock);
+uint32_t imx_ccm_get_clock_frequency(DeviceState *s, IMXClk clock);
 
 #endif /* IMX_CCM_H */
-- 
2.5.0




[Qemu-devel] [PATCH v3 2/3] i.MX: Split the CCM class into an abstact base class and a concrete class.

2015-11-19 Thread Jean-Christophe Dubois
The IMX_CCM class is now the base abstract class that is used by EPIT and GPT
timer implementation.

IMX31_CCM class is the concrete class implementing CCM for i.MX31 SOC.

For now the i.MX25 continues to use the i.MX31 CCM implementation.

An i.MX25 specific CCM will be introduced in a later patch.

We also rework initialization to stop using deprecated sysbus device init

Signed-off-by: Jean-Christophe Dubois 
---

Changes since v1:
 * None

Changes since v2:
 * We moved to an inheritance QOM scheme

 hw/arm/fsl-imx25.c  |   2 +-
 hw/arm/fsl-imx31.c  |   2 +-
 hw/misc/Makefile.objs   |   1 +
 hw/misc/imx31_ccm.c | 252 
 hw/misc/imx_ccm.c   | 224 +++
 include/hw/arm/fsl-imx25.h  |   4 +-
 include/hw/arm/fsl-imx31.h  |   4 +-
 include/hw/misc/imx31_ccm.h |  64 +++
 include/hw/misc/imx_ccm.h   |  70 +---
 9 files changed, 365 insertions(+), 258 deletions(-)
 create mode 100644 hw/misc/imx31_ccm.c
 create mode 100644 include/hw/misc/imx31_ccm.h

diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index e1cadac..5526c22 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -38,7 +38,7 @@ static void fsl_imx25_init(Object *obj)
 object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
 qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());
 
-object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX_CCM);
+object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX31_CCM);
 qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
 
 for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
index 53d4473..bcc71dc 100644
--- a/hw/arm/fsl-imx31.c
+++ b/hw/arm/fsl-imx31.c
@@ -35,7 +35,7 @@ static void fsl_imx31_init(Object *obj)
 object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
 qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());
 
-object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX_CCM);
+object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX31_CCM);
 qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
 
 for (i = 0; i < FSL_IMX31_NUM_UARTS; i++) {
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index aeb6b7d..c77f3e3 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -26,6 +26,7 @@ obj-$(CONFIG_NSERIES) += cbus.o
 obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o
 obj-$(CONFIG_IMX) += imx_ccm.o
+obj-$(CONFIG_IMX) += imx31_ccm.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
new file mode 100644
index 000..f56fa77
--- /dev/null
+++ b/hw/misc/imx31_ccm.c
@@ -0,0 +1,252 @@
+/*
+ * IMX31 Clock Control Module
+ *
+ * Copyright (C) 2012 NICTA
+ * Updated by Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * To get the timer frequencies right, we need to emulate at least part of
+ * the i.MX31 CCM.
+ */
+
+#include "hw/misc/imx31_ccm.h"
+
+#define CKIH_FREQ 2600 /* 26MHz crystal input */
+
+#ifndef DEBUG_IMX31_CCM
+#define DEBUG_IMX31_CCM 0
+#endif
+
+#define DPRINTF(fmt, args...) \
+do { \
+if (DEBUG_IMX31_CCM) { \
+fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX31_CCM, \
+ __func__, ##args); \
+} \
+} while (0)
+
+static const VMStateDescription vmstate_imx31_ccm = {
+.name = TYPE_IMX31_CCM,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(ccmr, IMX31CCMState),
+VMSTATE_UINT32(pdr0, IMX31CCMState),
+VMSTATE_UINT32(pdr1, IMX31CCMState),
+VMSTATE_UINT32(mpctl, IMX31CCMState),
+VMSTATE_UINT32(spctl, IMX31CCMState),
+VMSTATE_UINT32_ARRAY(cgr, IMX31CCMState, 3),
+VMSTATE_UINT32(pmcr0, IMX31CCMState),
+VMSTATE_UINT32(pmcr1, IMX31CCMState),
+VMSTATE_END_OF_LIST()
+},
+};
+
+static uint32_t imx31_ccm_get_ref_clk(DeviceState *dev)
+{
+IMX31CCMState *s = IMX31_CCM(dev);
+
+DPRINTF("()\n");
+
+if ((s->ccmr & CCMR_PRCS) == 2) {
+return CKIL_FREQ * 1024;
+} else {
+return CKIH_FREQ;
+}
+}
+
+static uint32_t imx31_ccm_get_mcu_clk(DeviceState *dev)
+{
+IMX31CCMState *s = IMX31_CCM(dev);
+
+DPRINTF("()\n");
+
+if ((s->ccmr & CCMR_MDS) || !(s->ccmr & CCMR_MPE)) {
+return imx31_ccm_get_ref_clk(dev);
+} else {
+return imx_ccm_calc_pll(s->mpctl, imx31_ccm_get_ref_clk(dev));
+}
+}
+
+static uint32_t imx31_ccm_get_hsp_clk(DeviceState *dev)
+{

[Qemu-devel] [PATCH v3 3/3] i.MX: Add an i.MX25 specific CCM class/instance.

2015-11-19 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---

Changes since v1:
 * rework loging to match other i.MX drivers

Changes since v2:
 * We moved to an inheritance QOM scheme

 hw/arm/fsl-imx25.c  |   2 +-
 hw/misc/Makefile.objs   |   1 +
 hw/misc/imx25_ccm.c | 243 
 include/hw/arm/fsl-imx25.h  |   4 +-
 include/hw/misc/imx25_ccm.h |  59 +++
 5 files changed, 306 insertions(+), 3 deletions(-)
 create mode 100644 hw/misc/imx25_ccm.c
 create mode 100644 include/hw/misc/imx25_ccm.h

diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index 5526c22..0aacc91 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -38,7 +38,7 @@ static void fsl_imx25_init(Object *obj)
 object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
 qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());
 
-object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX31_CCM);
+object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX25_CCM);
 qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
 
 for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index c77f3e3..8a235df 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -27,6 +27,7 @@ obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o
 obj-$(CONFIG_IMX) += imx_ccm.o
 obj-$(CONFIG_IMX) += imx31_ccm.o
+obj-$(CONFIG_IMX) += imx25_ccm.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx25_ccm.c b/hw/misc/imx25_ccm.c
new file mode 100644
index 000..a6c9bff
--- /dev/null
+++ b/hw/misc/imx25_ccm.c
@@ -0,0 +1,243 @@
+/*
+ * IMX25 Clock Control Module
+ *
+ * Copyright (C) 2012 NICTA
+ * Updated by Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * To get the timer frequencies right, we need to emulate at least part of
+ * the CCM.
+ */
+
+#include "hw/misc/imx25_ccm.h"
+
+#ifndef DEBUG_IMX25_CCM
+#define DEBUG_IMX25_CCM 0
+#endif
+
+#define DPRINTF(fmt, args...) \
+do { \
+if (DEBUG_IMX25_CCM) { \
+fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX25_CCM, \
+ __func__, ##args); \
+} \
+} while (0)
+
+#define CKIH_FREQ 2400 /* 24MHz crystal input */
+
+static const VMStateDescription vmstate_imx25_ccm = {
+.name = TYPE_IMX25_CCM,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(mpctl, IMX25CCMState),
+VMSTATE_UINT32(upctl, IMX25CCMState),
+VMSTATE_UINT32(cctl, IMX25CCMState),
+VMSTATE_UINT32_ARRAY(cgcr, IMX25CCMState, 3),
+VMSTATE_UINT32_ARRAY(pcdr, IMX25CCMState, 4),
+VMSTATE_UINT32(rcsr, IMX25CCMState),
+VMSTATE_UINT32(crdr, IMX25CCMState),
+VMSTATE_UINT32_ARRAY(dcvr, IMX25CCMState, 4),
+VMSTATE_UINT32_ARRAY(ltr, IMX25CCMState, 4),
+VMSTATE_UINT32_ARRAY(ltbr, IMX25CCMState, 2),
+VMSTATE_UINT32_ARRAY(pmcr, IMX25CCMState, 3),
+VMSTATE_UINT32(mcr, IMX25CCMState),
+VMSTATE_UINT32_ARRAY(lpimr, IMX25CCMState, 2),
+VMSTATE_END_OF_LIST()
+},
+};
+
+static uint32_t imx25_ccm_get_mpll_clk(DeviceState *dev)
+{
+IMX25CCMState *s = IMX25_CCM(dev);
+
+DPRINTF("()\n");
+
+if (EXTRACT(s->cctl, MPLL_BYPASS)) {
+return CKIH_FREQ;
+} else {
+return imx_ccm_calc_pll(s->mpctl, CKIH_FREQ);
+}
+}
+
+static uint32_t imx25_ccm_get_upll_clk(DeviceState *dev)
+{
+IMX25CCMState *s = IMX25_CCM(dev);
+
+DPRINTF("()\n");
+
+return imx_ccm_calc_pll(s->upctl, CKIH_FREQ);
+}
+
+static uint32_t imx25_ccm_get_mcu_clk(DeviceState *dev)
+{
+IMX25CCMState *s = IMX25_CCM(dev);
+
+DPRINTF("()\n");
+
+if (EXTRACT(s->cctl, ARM_SRC)) {
+return (imx25_ccm_get_mpll_clk(dev) * 3 / 4) /
+   (1 + EXTRACT(s->cctl, ARM_CLK_DIV));
+} else {
+return imx25_ccm_get_mpll_clk(dev) /
+   (1 + EXTRACT(s->cctl, ARM_CLK_DIV));
+}
+}
+
+static uint32_t imx25_ccm_get_ahb_clk(DeviceState *dev)
+{
+IMX25CCMState *s = IMX25_CCM(dev);
+
+DPRINTF("()\n");
+
+return imx25_ccm_get_mcu_clk(dev) / (1 + EXTRACT(s->cctl, AHB_CLK_DIV));
+}
+
+static uint32_t imx25_ccm_get_ipg_clk(DeviceState *dev)
+{
+DPRINTF("()\n");
+
+return imx25_ccm_get_ahb_clk(dev) / 2;
+}
+
+static uint32_t imx25_ccm_get_clock_frequency(DeviceState *dev, IMXClk clock)
+{
+DPRINTF("Clock = %d)\n", clock);
+
+switch (clock) {
+case NOCLK:
+return 0;
+case CLK_MPLL:
+return imx25_ccm_get_mpll_clk(dev);
+case CLK_UPLL:
+return imx2

Re: [Qemu-devel] [PATCH v3 2/3] i.MX: Split the CCM class into an abstact base class and a concrete class.

2015-11-24 Thread Jean-Christophe DUBOIS

Le 24/11/2015 23:04, Peter Crosthwaite a écrit :

On Thu, Nov 19, 2015 at 12:40 PM, Jean-Christophe Dubois
 wrote:

The IMX_CCM class is now the base abstract class that is used by EPIT and GPT
timer implementation.

IMX31_CCM class is the concrete class implementing CCM for i.MX31 SOC.

For now the i.MX25 continues to use the i.MX31 CCM implementation.

An i.MX25 specific CCM will be introduced in a later patch.

We also rework initialization to stop using deprecated sysbus device init

Signed-off-by: Jean-Christophe Dubois 
---

Changes since v1:
  * None

Changes since v2:
  * We moved to an inheritance QOM scheme

  hw/arm/fsl-imx25.c  |   2 +-
  hw/arm/fsl-imx31.c  |   2 +-
  hw/misc/Makefile.objs   |   1 +
  hw/misc/imx31_ccm.c | 252 
  hw/misc/imx_ccm.c   | 224 +++
  include/hw/arm/fsl-imx25.h  |   4 +-
  include/hw/arm/fsl-imx31.h  |   4 +-
  include/hw/misc/imx31_ccm.h |  64 +++
  include/hw/misc/imx_ccm.h   |  70 +---
  9 files changed, 365 insertions(+), 258 deletions(-)
  create mode 100644 hw/misc/imx31_ccm.c
  create mode 100644 include/hw/misc/imx31_ccm.h

diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index e1cadac..5526c22 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -38,7 +38,7 @@ static void fsl_imx25_init(Object *obj)
  object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
  qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());

-object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX_CCM);
+object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX31_CCM);
  qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());

  for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
index 53d4473..bcc71dc 100644
--- a/hw/arm/fsl-imx31.c
+++ b/hw/arm/fsl-imx31.c
@@ -35,7 +35,7 @@ static void fsl_imx31_init(Object *obj)
  object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
  qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());

-object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX_CCM);
+object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX31_CCM);
  qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());

  for (i = 0; i < FSL_IMX31_NUM_UARTS; i++) {
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index aeb6b7d..c77f3e3 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -26,6 +26,7 @@ obj-$(CONFIG_NSERIES) += cbus.o
  obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o
  obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o
  obj-$(CONFIG_IMX) += imx_ccm.o
+obj-$(CONFIG_IMX) += imx31_ccm.o
  obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
  obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
  obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
new file mode 100644
index 000..f56fa77
--- /dev/null
+++ b/hw/misc/imx31_ccm.c
@@ -0,0 +1,252 @@
+/*
+ * IMX31 Clock Control Module
+ *
+ * Copyright (C) 2012 NICTA
+ * Updated by Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * To get the timer frequencies right, we need to emulate at least part of
+ * the i.MX31 CCM.
+ */
+
+#include "hw/misc/imx31_ccm.h"
+
+#define CKIH_FREQ 2600 /* 26MHz crystal input */
+
+#ifndef DEBUG_IMX31_CCM
+#define DEBUG_IMX31_CCM 0
+#endif
+
+#define DPRINTF(fmt, args...) \
+do { \
+if (DEBUG_IMX31_CCM) { \
+fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX31_CCM, \
+ __func__, ##args); \
+} \
+} while (0)
+
+static const VMStateDescription vmstate_imx31_ccm = {
+.name = TYPE_IMX31_CCM,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(ccmr, IMX31CCMState),
+VMSTATE_UINT32(pdr0, IMX31CCMState),
+VMSTATE_UINT32(pdr1, IMX31CCMState),
+VMSTATE_UINT32(mpctl, IMX31CCMState),
+VMSTATE_UINT32(spctl, IMX31CCMState),
+VMSTATE_UINT32_ARRAY(cgr, IMX31CCMState, 3),
+VMSTATE_UINT32(pmcr0, IMX31CCMState),
+VMSTATE_UINT32(pmcr1, IMX31CCMState),
+VMSTATE_END_OF_LIST()
+},
+};
+
+static uint32_t imx31_ccm_get_ref_clk(DeviceState *dev)
+{
+IMX31CCMState *s = IMX31_CCM(dev);
+
+DPRINTF("()\n");
+
+if ((s->ccmr & CCMR_PRCS) == 2) {
+return CKIL_FREQ * 1024;
+} else {
+return CKIH_FREQ;
+}
+}
+
+static uint32_t imx31_ccm_get_mcu_clk(DeviceState *dev)
+{
+IMX31CCMState *s = IMX31_CCM(dev);
+
+DPRINTF("()\n");
+
+if ((s->ccmr & CCMR_MDS) || !(s->ccmr & CCMR_MPE)) {
+return imx31_ccm_get_ref_clk(dev);
+} else {
+r

Re: [Qemu-devel] [PATCH 4/6] i.MX: Add i.MX6 System Reset Controller device.

2016-02-06 Thread Jean-Christophe DUBOIS

Le 02/02/2016 17:46, Peter Maydell a écrit :

On 26 January 2016 at 21:45, Jean-Christophe Dubois  
wrote:

This controller is also present in i.MX5X devices but they are not
yet emulated by Qemu.

QEMU is all-caps.


Signed-off-by: Jean-Christophe Dubois 
---
  hw/misc/Makefile.objs  |   1 +
  hw/misc/imx6_src.c | 353 +
  include/hw/misc/imx6_src.h |  72 +
  3 files changed, 426 insertions(+)
  create mode 100644 hw/misc/imx6_src.c
  create mode 100644 include/hw/misc/imx6_src.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index a2a8e91..6bac654 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -29,6 +29,7 @@ obj-$(CONFIG_IMX) += imx_ccm.o
  obj-$(CONFIG_IMX) += imx31_ccm.o
  obj-$(CONFIG_IMX) += imx25_ccm.o
  obj-$(CONFIG_IMX) += imx6_ccm.o
+obj-$(CONFIG_IMX) += imx6_src.o
  obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
  obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
  obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx6_src.c b/hw/misc/imx6_src.c
new file mode 100644
index 000..d1be7c1
--- /dev/null
+++ b/hw/misc/imx6_src.c
@@ -0,0 +1,353 @@
+/*
+ * IMX6 System Reset Controller
+ *
+ * Copyright (c) 2015 Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw/misc/imx6_src.h"
+#include "sysemu/sysemu.h"
+#include "qemu/bitops.h"
+
+#ifndef DEBUG_IMX6_SRC
+#define DEBUG_IMX6_SRC 0
+#endif
+
+#define DPRINTF(fmt, args...) \
+do { \
+if (DEBUG_IMX6_SRC) { \
+fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX6_SRC, \
+ __func__, ##args); \
+} \
+} while (0)
+
+static char const *imx6_src_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case SRC_SCR:
+return "SRC_SCR";
+case SRC_SBMR1:
+return "SRC_SBMR1";
+case SRC_SRSR:
+return "SRC_SRSR";
+case SRC_SISR:
+return "SRC_SISR";
+case SRC_SIMR:
+return "SRC_SIMR";
+case SRC_SBMR2:
+return "SRC_SBMR2";
+case SRC_GPR1:
+return "SRC_GPR1";
+case SRC_GPR2:
+return "SRC_GPR2";
+case SRC_GPR3:
+return "SRC_GPR3";
+case SRC_GPR4:
+return "SRC_GPR4";
+case SRC_GPR5:
+return "SRC_GPR5";
+case SRC_GPR6:
+return "SRC_GPR6";
+case SRC_GPR7:
+return "SRC_GPR7";
+case SRC_GPR8:
+return "SRC_GPR8";
+case SRC_GPR9:
+return "SRC_GPR9";
+case SRC_GPR10:
+return "SRC_GPR10";
+default:
+sprintf(unknown, "%d ?", reg);
+return unknown;
+}
+}
+
+static const VMStateDescription vmstate_imx6_src = {
+.name = TYPE_IMX6_SRC,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32_ARRAY(regs, IMX6SRCState, SRC_MAX),
+VMSTATE_END_OF_LIST()
+},
+};
+
+static void imx6_src_reset(DeviceState *dev)
+{
+IMX6SRCState *s = IMX6_SRC(dev);
+
+DPRINTF("\n");
+
+/*
+ * We only clear the first registers as all GPR registers are preserved
+ * over resets
+ */
+memset(s->regs, 0, SRC_GPR1 * sizeof(uint32_t));

Reset for a QEMU device means "full power cycle reset", so we should
return the state to the same as if QEMU had just been started.


Is there any way to support the warm reset then?


+
+/* Set reset values */
+s->regs[SRC_SCR] = 0x521;
+s->regs[SRC_SRSR] = 0x1;
+s->regs[SRC_SIMR] = 0x1F;
+}
+
+static CPUState *imx6_src_get_cpu_by_id(uint32_t id)
+{
+CPUState *cpu;
+
+DPRINTF("cpu %d\n", id);
+
+CPU_FOREACH(cpu) {
+ARMCPU *armcpu = ARM_CPU(cpu);
+
+if (armcpu->mp_affinity == id) {
+return cpu;
+}
+}
+
+qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Resquesting unknown CPU %d\n",
+  TYPE_IMX6_SRC, __func__, id);
+
+return NULL;
+}
+
+static void imx6_src_cpu_on(uint32_t cpuid, uint32_t entry, uint32_t 
context_id)
+{
+CPUState *target_cpu_state;
+ARMCPU *target_cpu;
+CPUClass *target_cpu_class;
+
+DPRINTF("cpu %d @ 0x%08x with R0 = 0x%08x\n", cpuid, entry, context_id);
+
+/* change to the cpu we are powering up */
+target_cpu_state = imx6_src_get_cpu_by_id(cpuid);
+if (!target_cpu_state) {
+return;
+}
+target_cpu = ARM_CPU(target_cpu_state);
+if (!target_cpu->powered_off) {
+qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: CPU %d is already running\n",
+  TYPE_IMX6_SRC, __func__, cpuid);
+return;
+}
+  

Re: [Qemu-devel] [PATCH 0/6] Add i.MX6 (Single/Dual/Quad) support

2016-02-07 Thread Jean-Christophe DUBOIS

Le 02/02/2016 18:01, Peter Maydell a écrit :

On 28 January 2016 at 19:22, Jean-Christophe DUBOIS  
wrote:

Sabrelite uses uart2 for console but on qemu, this is uart1 that is wired to
the default stdout. Consequently, I changed stdout-path in "chosen" to
uart1.

This I find a bit awkward: we'd like to get eventually to the point
where you can run the stock device tree unedited. The other items
on your list are just "we don't emulate something yet", so the path
forward is to (eventually) emulate the missing things. But it's not
clear to me what we need to do to be able to stop editing stdout-path
in the future.

Perhaps the answer is just to use QEMU command line arguments to make
stdout be the uart2 rather than uart1?


I'll send a new version where the platform (sabrelite) can chose 
(through properties) which uart of the SOC (i.MX6) it wants to use as 
default output.





For now i.MX6 SOC code does not emulate SPI controller. During the boot
Linux was getting stuck trying to access a SPI device that is supposed to be
there. Therefore I disabled the SPI controller in the device tree.

This is OK for now, though I guess it means the SPI controller is
worth emulating to at least some extent.


I'll see what I can do next.




The sabrelite is supposed to have a bunch of push buttons (home, power,
back, vol up, vol down) wired to various GPIOs. I guess these buttons might
have pull up or pull down resistors on the real hardware but obviously on
qemu we have no such things. As a results the GPIOs were triggering a lot of
interrupts for nothing. So I commented out the GPIO sections were the
buttons were defined.

This is OK for now, though it would be nice to wire all the GPIOs to 0 or
something if that helps avoid the problem without editing the DT.


Ditto.



thanks
--- PMM






Re: [Qemu-devel] [PATCH 3/6] i.MX: Add i.MX6 CCM and ANALOG device.

2016-02-07 Thread Jean-Christophe DUBOIS

Le 02/02/2016 17:41, Peter Maydell a écrit :

On 26 January 2016 at 21:45, Jean-Christophe Dubois  
wrote:

Signed-off-by: Jean-Christophe Dubois 
+static uint32_t imx6_analog_get_pll2_clk(IMX6CCMState *dev)
+{
+uint32_t freq = 2400;
+
+if (EXTRACT(dev->analog[CCM_ANALOG_PLL_SYS], DIV_SELECT)) {
+freq *= 22;
+} else {
+freq *= 20;
+}
+
+DPRINTF("freq = %d\n", freq);
+
+return freq;
+}
+
+static uint32_t imx6_analog_get_pll2_pfd0_clk(IMX6CCMState *dev)
+{
+uint32_t freq = 0;
+
+freq = imx6_analog_get_pll2_clk(dev) * 18
+   / EXTRACT(dev->analog[CCM_ANALOG_PFD_528], PFD0_FRAC);

I think this multiplication can overflow. Are you sure you want
to do it at 32 bits?

(2400 == 0x16E3600. 2400 * 22 * 18 == 0x2367B8800.)


+
+DPRINTF("freq = %d\n", freq);
+
+return freq;
+}
+
+static uint32_t imx6_analog_get_pll2_pfd2_clk(IMX6CCMState *dev)
+{
+uint32_t freq = 0;
+
+freq = imx6_analog_get_pll2_clk(dev) * 18
+   / EXTRACT(dev->analog[CCM_ANALOG_PFD_528], PFD2_FRAC);

Ditto.


+
+DPRINTF("freq = %d\n", freq);

All these debug printfs are identical, which seems to me like
it would make them not terribly useful, but I'm not the one that
would be debugging this :-)


+
+return freq;
+}
+
+static uint32_t imx6_analog_get_periph_clk(IMX6CCMState *dev)
+{
+uint32_t freq = 0;
+
+switch (EXTRACT(dev->ccm[CCM_CBCMR], PRE_PERIPH_CLK_SEL)) {
+case 0:
+freq = imx6_analog_get_pll2_clk(dev);
+break;
+case 1:
+freq = imx6_analog_get_pll2_pfd2_clk(dev);
+break;
+case 2:
+freq = imx6_analog_get_pll2_pfd0_clk(dev);
+break;
+case 3:
+freq = imx6_analog_get_pll2_pfd2_clk(dev) / 2;
+break;
+default:
+/* We should never get there */
+qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unexpected clock selector\n",
+  TYPE_IMX6_CCM, __func__);

PRE_PERIPH_CLK_SEL is a two bit field, right? So this is actually
unreachable, not just "only reachable if guest misprograms a register".
That should be g_assert_not_reached().


+break;
+}
+
+DPRINTF("freq = %d\n", freq);
+
+return freq;
+}
+
+static uint32_t imx6_ccm_get_ahb_clk(IMX6CCMState *dev)
+{
+uint32_t freq = 0;
+
+freq = imx6_analog_get_periph_clk(dev)
+   / (1 + EXTRACT(dev->ccm[CCM_CBCDR], AHB_PODF));;

Stray extra ';'.


+
+DPRINTF("freq = %d\n", freq);
+
+return freq;
+}
+
+static uint32_t imx6_ccm_get_ipg_clk(IMX6CCMState *dev)
+{
+uint32_t freq = 0;
+
+freq = imx6_ccm_get_ahb_clk(dev)
+   / (1 + EXTRACT(dev->ccm[CCM_CBCDR], IPG_PODF));;
+
+DPRINTF("freq = %d\n", freq);
+
+return freq;
+}
+
+static uint32_t imx6_ccm_get_per_clk(IMX6CCMState *dev)
+{
+uint32_t freq = 0;
+
+freq = imx6_ccm_get_ipg_clk(dev)
+   / (1 + EXTRACT(dev->ccm[CCM_CSCMR1], PERCLK_PODF));
+
+DPRINTF("freq = %d\n", freq);
+
+return freq;
+}
+
+static uint32_t imx6_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
+{
+uint32_t freq = 0;
+IMX6CCMState *s = IMX6_CCM(dev);
+
+switch (clock) {
+case CLK_NONE:
+break;
+case CLK_IPG:
+freq = imx6_ccm_get_ipg_clk(s);
+break;
+case CLK_IPG_HIGH:
+freq = imx6_ccm_get_per_clk(s);
+break;
+case CLK_32k:
+freq = CKIL_FREQ;
+break;
+default:
+qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
+  TYPE_IMX6_CCM, __func__, clock);
+break;
+}
+
+DPRINTF("Clock = %d) = %d\n", clock, freq);
+
+return freq;
+}
+
+static void imx6_ccm_reset(DeviceState *dev)
+{
+IMX6CCMState *s = IMX6_CCM(dev);
+
+DPRINTF("\n");

What's this for?


+
+s->ccm[CCM_CCR] = 0x040116FF;
+s->ccm[CCM_CCDR] = 0x;
+s->ccm[CCM_CSR] = 0x0010;
+s->ccm[CCM_CCSR] = 0x0100;
+s->ccm[CCM_CACRR] = 0x;
+s->ccm[CCM_CBCDR] = 0x00018D40;
+s->ccm[CCM_CBCMR] = 0x00022324;
+s->ccm[CCM_CSCMR1] = 0x00F0;
+s->ccm[CCM_CSCMR2] = 0x02B92F06;
+s->ccm[CCM_CSCDR1] = 0x00490B00;
+s->ccm[CCM_CS1CDR] = 0x0EC102C1;
+s->ccm[CCM_CS2CDR] = 0x000736C1;
+s->ccm[CCM_CDCDR] = 0x33F71F92;
+s->ccm[CCM_CHSCCDR] = 0x0002A150;
+s->ccm[CCM_CSCDR2] = 0x0002A150;
+s->ccm[CCM_CSCDR3] = 0x00014841;
+s->ccm[CCM_CDHIPR] = 0x;
+s->ccm[CCM_CTOR] = 0x;
+s->ccm[CCM_CLPCR] = 0x0079;
+s->ccm[CCM_CISR] = 0x;
+s->ccm[CCM_CIMR] = 0x;
+s->ccm[CCM_CCOSR] = 0x000A0001;
+s->ccm[CCM_CGPR] = 0xFE62;
+s->ccm[CCM_CCGR0] = 0x;
+s->ccm[CCM_CCGR1] = 0x;
+s->ccm[CCM_CCGR2] = 0xFC3F;
+  

[Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support

2016-02-08 Thread Jean-Christophe Dubois
This patch series adds support for the Freescale i.MX6 processor.

For now we only support the following devices:
* up to 4 Cortex A9 cores
* A9 MPCORE (SCU, GIC, TWD)
* 5 i.MX UARTs
* 2 EPIT timers
* 1 GPT timer
* 7 GPIO controllers
* 6 SDHC controllers
* 1 CCM device
* 1 SRC device
* 3 I2C devices
* various ROM/RAM areas.

This also adds the sabrelite board as a an actual platform for i.MX6.

This series was tested by booting a 4.4 linux kernel (using the
imx_v6_v7_defconfig file as kernel configuration).

Note1: as sabrelite uses uart2 as console, you have to redirect the second
QEMU serial port to stdout.
qemu-system-arm -M sabrelite -display none ... -serial null -serial stdio

Note2: as the SPI controller is not yet supported in QEMU for i.MX you need
to disable SPI controllers in Linux DTS tree. Otherwise Linux would hang
during the boot waiting for a SPI device to respond.

Note3: You need to disable the GPIO section related to physical push buttons
in the Linux DTS tree in order to avoid excecive interrupt triggering on 
GPIO devices for non existant buttons.

Jean-Christophe Dubois (9):
  i.MX: Allow GPT timer to rollover.
  i.MX: Rename CCM NOCLK to CLK_NONE for naming consistency.
  i.MX: Remove CCM useless clock computation handling.
  i.MX: Add the CLK_IPG_HIGH clock
  i.MX: Add i.MX6 CCM and ANALOG device.
  i.MX: Add i.MX6 System Reset Controller device.
  i.MX: Add i.MX6 SOC implementation.
  i.MX: Add sabrelite i.MX6 emulation.
  i.MX: Add missing descriptions in devices.

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/fsl-imx25.c  |   1 +
 hw/arm/fsl-imx31.c  |   1 +
 hw/arm/fsl-imx6.c   | 407 +
 hw/arm/sabrelite.c  |  93 +
 hw/i2c/imx_i2c.c|   1 +
 hw/misc/Makefile.objs   |   2 +
 hw/misc/imx25_ccm.c |  29 +-
 hw/misc/imx31_ccm.c |  35 +-
 hw/misc/imx6_ccm.c  | 773 
 hw/misc/imx6_src.c  | 353 ++
 hw/net/imx_fec.c|   1 +
 hw/timer/imx_epit.c |   8 +-
 hw/timer/imx_gpt.c  |  43 +--
 include/hw/arm/fsl-imx6.h   | 447 +++
 include/hw/misc/imx6_ccm.h  | 197 ++
 include/hw/misc/imx6_src.h  |  73 
 include/hw/misc/imx_ccm.h   |  10 +-
 19 files changed, 2384 insertions(+), 92 deletions(-)
 create mode 100644 hw/arm/fsl-imx6.c
 create mode 100644 hw/arm/sabrelite.c
 create mode 100644 hw/misc/imx6_ccm.c
 create mode 100644 hw/misc/imx6_src.c
 create mode 100644 include/hw/arm/fsl-imx6.h
 create mode 100644 include/hw/misc/imx6_ccm.h
 create mode 100644 include/hw/misc/imx6_src.h

-- 
2.5.0




[Qemu-devel] [PATCH v2 1/9] i.MX: Allow GPT timer to rollover.

2016-02-08 Thread Jean-Christophe Dubois
GPT timer need to rollover when it reaches 0x.

It also need to reset to 0 when in "restart mode" and crossing the
compare 1 register.

Signed-off-by: Jean-Christophe Dubois 
---

Changes since V1:
 * None

 hw/timer/imx_gpt.c | 27 +++
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index b1893b8..b227256 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -133,7 +133,7 @@ static inline uint32_t imx_gpt_find_limit(uint32_t count, 
uint32_t reg,
 static void imx_gpt_compute_next_timeout(IMXGPTState *s, bool event)
 {
 uint32_t timeout = GPT_TIMER_MAX;
-uint32_t count = 0;
+uint32_t count;
 long long limit;
 
 if (!(s->cr & GPT_CR_EN)) {
@@ -141,20 +141,23 @@ static void imx_gpt_compute_next_timeout(IMXGPTState *s, 
bool event)
 return;
 }
 
-if (event) {
-/* This is a timer event  */
+/* update the count */
+count = imx_gpt_update_count(s);
 
-if ((s->cr & GPT_CR_FRR)  && (s->next_timeout != GPT_TIMER_MAX)) {
-/*
- * if we are in free running mode and we have not reached
- * the GPT_TIMER_MAX limit, then update the count
+if (event) {
+/*
+ * This is an event (the ptimer reached 0 and stopped), and the
+ * timer counter is now equal to s->next_timeout.
+ */
+if (!(s->cr & GPT_CR_FRR) && (count == s->ocr1)) {
+/* We are in restart mode and we crossed the compare channel 1
+ * value. We need to reset the counter to 0.
  */
-count = imx_gpt_update_count(s);
+count = s->cnt = s->next_timeout = 0;
+} else if (count == GPT_TIMER_MAX) {
+/* We reached GPT_TIMER_MAX so we need to rollover */
+count = s->cnt = s->next_timeout = 0;
 }
-} else {
-/* not a timer event, then just update the count */
-
-count = imx_gpt_update_count(s);
 }
 
 /* now, find the next timeout related to count */
-- 
2.5.0




[Qemu-devel] [PATCH v2 4/9] i.MX: Add the CLK_IPG_HIGH clock

2016-02-08 Thread Jean-Christophe Dubois
EPIT, GPT and other i.MX timers are using "abstract" clocks among which
a CLK_IPG_HIGH clock.

On i.MX25 and i.MX31 CLK_IPG and CLK_IPG_HIGH are mapped to the same clock
but on other SOC like i.MX6 they are mapped to distinct clocks.

This patch add the CLK_IPG_HIGH to prepare for SOC where these 2 clocks are
different.

Signed-off-by: Jean-Christophe Dubois 
---

Changes since V1:
 * Not present on V1 

 hw/misc/imx25_ccm.c   |  1 +
 hw/misc/imx31_ccm.c   |  1 +
 hw/timer/imx_epit.c   |  8 
 hw/timer/imx_gpt.c| 16 
 include/hw/misc/imx_ccm.h |  1 +
 5 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/hw/misc/imx25_ccm.c b/hw/misc/imx25_ccm.c
index e74486f..caceb0e 100644
--- a/hw/misc/imx25_ccm.c
+++ b/hw/misc/imx25_ccm.c
@@ -170,6 +170,7 @@ static uint32_t imx25_ccm_get_clock_frequency(IMXCCMState 
*dev, IMXClk clock)
 case CLK_NONE:
 break;
 case CLK_IPG:
+case CLK_IPG_HIGH:
 freq = imx25_ccm_get_ipg_clk(dev);
 break;
 case CLK_32k:
diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
index dee0b11..96ba2cb 100644
--- a/hw/misc/imx31_ccm.c
+++ b/hw/misc/imx31_ccm.c
@@ -185,6 +185,7 @@ static uint32_t imx31_ccm_get_clock_frequency(IMXCCMState 
*dev, IMXClk clock)
 case CLK_NONE:
 break;
 case CLK_IPG:
+case CLK_IPG_HIGH:
 freq = imx31_ccm_get_ipg_clk(dev);
 break;
 case CLK_32k:
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index f7772cc..ecd2e5a 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -51,10 +51,10 @@ static char const *imx_epit_reg_name(uint32_t reg)
  * These are typical.
  */
 static const IMXClk imx_epit_clocks[] =  {
-CLK_NONE, /* 00 disabled */
-CLK_IPG,  /* 01 ipg_clk, ~532MHz */
-CLK_IPG,  /* 10 ipg_clk_highfreq */
-CLK_32k,  /* 11 ipg_clk_32k -- ~32kHz */
+CLK_NONE,  /* 00 disabled */
+CLK_IPG,   /* 01 ipg_clk, ~532MHz */
+CLK_IPG_HIGH,  /* 10 ipg_clk_highfreq */
+CLK_32k,   /* 11 ipg_clk_32k -- ~32kHz */
 };
 
 /*
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index d1c0294..e69456d 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -80,14 +80,14 @@ static const VMStateDescription vmstate_imx_timer_gpt = {
 };
 
 static const IMXClk imx_gpt_clocks[] = {
-CLK_NONE, /* 000 No clock source */
-CLK_IPG,  /* 001 ipg_clk, 532MHz*/
-CLK_IPG,  /* 010 ipg_clk_highfreq */
-CLK_NONE, /* 011 not defined */
-CLK_32k,  /* 100 ipg_clk_32k */
-CLK_NONE, /* 101 not defined */
-CLK_NONE, /* 110 not defined */
-CLK_NONE, /* 111 not defined */
+CLK_NONE,  /* 000 No clock source */
+CLK_IPG,   /* 001 ipg_clk, 532MHz*/
+CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
+CLK_NONE,  /* 011 not defined */
+CLK_32k,   /* 100 ipg_clk_32k */
+CLK_NONE,  /* 101 not defined */
+CLK_NONE,  /* 110 not defined */
+CLK_NONE,  /* 111 not defined */
 };
 
 static void imx_gpt_set_freq(IMXGPTState *s)
diff --git a/include/hw/misc/imx_ccm.h b/include/hw/misc/imx_ccm.h
index 378b78d..48a7afa 100644
--- a/include/hw/misc/imx_ccm.h
+++ b/include/hw/misc/imx_ccm.h
@@ -45,6 +45,7 @@ typedef struct IMXCCMState {
 typedef enum  {
 CLK_NONE,
 CLK_IPG,
+CLK_IPG_HIGH,
 CLK_32k
 } IMXClk;
 
-- 
2.5.0




[Qemu-devel] [PATCH v2 3/9] i.MX: Remove CCM useless clock computation handling.

2016-02-08 Thread Jean-Christophe Dubois
Most clocks supported by the CCM are useless to the qemu framework.

Only clocks related to timers (EPIT, GPT, PWM, WATCHDOG, ...) are usefull
to QEMU code.

Therefore this patch removes clock computation handling for all clocks but:
* CLK_NONE,
* CLK_IPG,
* CLK_32k

Signed-off-by: Jean-Christophe Dubois 
---

Changes since V1:
 * move NOCLK renaming in its own patch
 * move CLK_IPG_HIGH addition in its own patch

 hw/misc/imx25_ccm.c   | 26 --
 hw/misc/imx31_ccm.c   | 32 
 include/hw/misc/imx_ccm.h |  7 ---
 3 files changed, 65 deletions(-)

diff --git a/hw/misc/imx25_ccm.c b/hw/misc/imx25_ccm.c
index cc0e893..e74486f 100644
--- a/hw/misc/imx25_ccm.c
+++ b/hw/misc/imx25_ccm.c
@@ -119,20 +119,6 @@ static uint32_t imx25_ccm_get_mpll_clk(IMXCCMState *dev)
 return freq;
 }
 
-static uint32_t imx25_ccm_get_upll_clk(IMXCCMState *dev)
-{
-uint32_t freq = 0;
-IMX25CCMState *s = IMX25_CCM(dev);
-
-if (!EXTRACT(s->reg[IMX25_CCM_CCTL_REG], UPLL_DIS)) {
-freq = imx_ccm_calc_pll(s->reg[IMX25_CCM_UPCTL_REG], CKIH_FREQ);
-}
-
-DPRINTF("freq = %d\n", freq);
-
-return freq;
-}
-
 static uint32_t imx25_ccm_get_mcu_clk(IMXCCMState *dev)
 {
 uint32_t freq;
@@ -183,18 +169,6 @@ static uint32_t imx25_ccm_get_clock_frequency(IMXCCMState 
*dev, IMXClk clock)
 switch (clock) {
 case CLK_NONE:
 break;
-case CLK_MPLL:
-freq = imx25_ccm_get_mpll_clk(dev);
-break;
-case CLK_UPLL:
-freq = imx25_ccm_get_upll_clk(dev);
-break;
-case CLK_MCU:
-freq = imx25_ccm_get_mcu_clk(dev);
-break;
-case CLK_AHB:
-freq = imx25_ccm_get_ahb_clk(dev);
-break;
 case CLK_IPG:
 freq = imx25_ccm_get_ipg_clk(dev);
 break;
diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
index 10c78f3..dee0b11 100644
--- a/hw/misc/imx31_ccm.c
+++ b/hw/misc/imx31_ccm.c
@@ -151,32 +151,6 @@ static uint32_t imx31_ccm_get_mcu_main_clk(IMXCCMState 
*dev)
 return freq;
 }
 
-static uint32_t imx31_ccm_get_mcu_clk(IMXCCMState *dev)
-{
-uint32_t freq;
-IMX31CCMState *s = IMX31_CCM(dev);
-
-freq = imx31_ccm_get_mcu_main_clk(dev)
-   / (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], MCU));
-
-DPRINTF("freq = %d\n", freq);
-
-return freq;
-}
-
-static uint32_t imx31_ccm_get_hsp_clk(IMXCCMState *dev)
-{
-uint32_t freq;
-IMX31CCMState *s = IMX31_CCM(dev);
-
-freq = imx31_ccm_get_mcu_main_clk(dev)
-   / (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], HSP));
-
-DPRINTF("freq = %d\n", freq);
-
-return freq;
-}
-
 static uint32_t imx31_ccm_get_hclk_clk(IMXCCMState *dev)
 {
 uint32_t freq;
@@ -210,12 +184,6 @@ static uint32_t imx31_ccm_get_clock_frequency(IMXCCMState 
*dev, IMXClk clock)
 switch (clock) {
 case CLK_NONE:
 break;
-case CLK_MCU:
-freq = imx31_ccm_get_mcu_clk(dev);
-break;
-case CLK_HSP:
-freq = imx31_ccm_get_hsp_clk(dev);
-break;
 case CLK_IPG:
 freq = imx31_ccm_get_ipg_clk(dev);
 break;
diff --git a/include/hw/misc/imx_ccm.h b/include/hw/misc/imx_ccm.h
index 74e2705..378b78d 100644
--- a/include/hw/misc/imx_ccm.h
+++ b/include/hw/misc/imx_ccm.h
@@ -44,14 +44,7 @@ typedef struct IMXCCMState {
 
 typedef enum  {
 CLK_NONE,
-CLK_MPLL,
-CLK_UPLL,
-CLK_MCU,
-CLK_HSP,
-CLK_MAX,
-CLK_AHB,
 CLK_IPG,
-CLK_PER,
 CLK_32k
 } IMXClk;
 
-- 
2.5.0




[Qemu-devel] [PATCH v2 2/9] i.MX: Rename CCM NOCLK to CLK_NONE for naming consistency.

2016-02-08 Thread Jean-Christophe Dubois
This way all CCM clock defines/enums are named CLK_XXX

Signed-off-by: Jean-Christophe Dubois 
---

Changes since V1:
 * Not present on V1

 hw/misc/imx25_ccm.c   |  2 +-
 hw/misc/imx31_ccm.c   |  2 +-
 hw/timer/imx_epit.c   |  2 +-
 hw/timer/imx_gpt.c| 10 +-
 include/hw/misc/imx_ccm.h |  2 +-
 5 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/misc/imx25_ccm.c b/hw/misc/imx25_ccm.c
index 23759ca..cc0e893 100644
--- a/hw/misc/imx25_ccm.c
+++ b/hw/misc/imx25_ccm.c
@@ -181,7 +181,7 @@ static uint32_t imx25_ccm_get_clock_frequency(IMXCCMState 
*dev, IMXClk clock)
 DPRINTF("Clock = %d)\n", clock);
 
 switch (clock) {
-case NOCLK:
+case CLK_NONE:
 break;
 case CLK_MPLL:
 freq = imx25_ccm_get_mpll_clk(dev);
diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
index 47d6ead..10c78f3 100644
--- a/hw/misc/imx31_ccm.c
+++ b/hw/misc/imx31_ccm.c
@@ -208,7 +208,7 @@ static uint32_t imx31_ccm_get_clock_frequency(IMXCCMState 
*dev, IMXClk clock)
 uint32_t freq = 0;
 
 switch (clock) {
-case NOCLK:
+case CLK_NONE:
 break;
 case CLK_MCU:
 freq = imx31_ccm_get_mcu_clk(dev);
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 50bf83c..f7772cc 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -51,7 +51,7 @@ static char const *imx_epit_reg_name(uint32_t reg)
  * These are typical.
  */
 static const IMXClk imx_epit_clocks[] =  {
-NOCLK,/* 00 disabled */
+CLK_NONE, /* 00 disabled */
 CLK_IPG,  /* 01 ipg_clk, ~532MHz */
 CLK_IPG,  /* 10 ipg_clk_highfreq */
 CLK_32k,  /* 11 ipg_clk_32k -- ~32kHz */
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index b227256..d1c0294 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -80,14 +80,14 @@ static const VMStateDescription vmstate_imx_timer_gpt = {
 };
 
 static const IMXClk imx_gpt_clocks[] = {
-NOCLK,/* 000 No clock source */
+CLK_NONE, /* 000 No clock source */
 CLK_IPG,  /* 001 ipg_clk, 532MHz*/
 CLK_IPG,  /* 010 ipg_clk_highfreq */
-NOCLK,/* 011 not defined */
+CLK_NONE, /* 011 not defined */
 CLK_32k,  /* 100 ipg_clk_32k */
-NOCLK,/* 101 not defined */
-NOCLK,/* 110 not defined */
-NOCLK,/* 111 not defined */
+CLK_NONE, /* 101 not defined */
+CLK_NONE, /* 110 not defined */
+CLK_NONE, /* 111 not defined */
 };
 
 static void imx_gpt_set_freq(IMXGPTState *s)
diff --git a/include/hw/misc/imx_ccm.h b/include/hw/misc/imx_ccm.h
index 5c4b795..74e2705 100644
--- a/include/hw/misc/imx_ccm.h
+++ b/include/hw/misc/imx_ccm.h
@@ -43,7 +43,7 @@ typedef struct IMXCCMState {
 } IMXCCMState;
 
 typedef enum  {
-NOCLK,
+CLK_NONE,
 CLK_MPLL,
 CLK_UPLL,
 CLK_MCU,
-- 
2.5.0




[Qemu-devel] [PATCH v2 6/9] i.MX: Add i.MX6 System Reset Controller device.

2016-02-08 Thread Jean-Christophe Dubois
This controller is also present in i.MX5X devices but they are not
yet emulated by QEMU.

Signed-off-by: Jean-Christophe Dubois 
---

Changes since V1:
 * Change "reset" sematic to mean full power cyvle.

 hw/misc/Makefile.objs  |   1 +
 hw/misc/imx6_src.c | 353 +
 include/hw/misc/imx6_src.h |  73 ++
 3 files changed, 427 insertions(+)
 create mode 100644 hw/misc/imx6_src.c
 create mode 100644 include/hw/misc/imx6_src.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index a2a8e91..6bac654 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -29,6 +29,7 @@ obj-$(CONFIG_IMX) += imx_ccm.o
 obj-$(CONFIG_IMX) += imx31_ccm.o
 obj-$(CONFIG_IMX) += imx25_ccm.o
 obj-$(CONFIG_IMX) += imx6_ccm.o
+obj-$(CONFIG_IMX) += imx6_src.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx6_src.c b/hw/misc/imx6_src.c
new file mode 100644
index 000..2cf97ef
--- /dev/null
+++ b/hw/misc/imx6_src.c
@@ -0,0 +1,353 @@
+/*
+ * IMX6 System Reset Controller
+ *
+ * Copyright (c) 2015 Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw/misc/imx6_src.h"
+#include "sysemu/sysemu.h"
+#include "qemu/bitops.h"
+
+#ifndef DEBUG_IMX6_SRC
+#define DEBUG_IMX6_SRC 0
+#endif
+
+#define DPRINTF(fmt, args...) \
+do { \
+if (DEBUG_IMX6_SRC) { \
+fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX6_SRC, \
+ __func__, ##args); \
+} \
+} while (0)
+
+static char const *imx6_src_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case SRC_SCR:
+return "SRC_SCR";
+case SRC_SBMR1:
+return "SRC_SBMR1";
+case SRC_SRSR:
+return "SRC_SRSR";
+case SRC_SISR:
+return "SRC_SISR";
+case SRC_SIMR:
+return "SRC_SIMR";
+case SRC_SBMR2:
+return "SRC_SBMR2";
+case SRC_GPR1:
+return "SRC_GPR1";
+case SRC_GPR2:
+return "SRC_GPR2";
+case SRC_GPR3:
+return "SRC_GPR3";
+case SRC_GPR4:
+return "SRC_GPR4";
+case SRC_GPR5:
+return "SRC_GPR5";
+case SRC_GPR6:
+return "SRC_GPR6";
+case SRC_GPR7:
+return "SRC_GPR7";
+case SRC_GPR8:
+return "SRC_GPR8";
+case SRC_GPR9:
+return "SRC_GPR9";
+case SRC_GPR10:
+return "SRC_GPR10";
+default:
+sprintf(unknown, "%d ?", reg);
+return unknown;
+}
+}
+
+static const VMStateDescription vmstate_imx6_src = {
+.name = TYPE_IMX6_SRC,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32_ARRAY(regs, IMX6SRCState, SRC_MAX),
+VMSTATE_END_OF_LIST()
+},
+};
+
+static void imx6_src_reset(DeviceState *dev)
+{
+IMX6SRCState *s = IMX6_SRC(dev);
+
+DPRINTF("\n");
+
+/*
+ * We only clear the first registers as all GPR registers are preserved
+ * over resets
+ */
+memset(s->regs, 0, SRC_MAX * sizeof(uint32_t));
+
+/* Set reset values */
+s->regs[SRC_SCR] = 0x521;
+s->regs[SRC_SRSR] = 0x1;
+s->regs[SRC_SIMR] = 0x1F;
+}
+
+static CPUState *imx6_src_get_cpu_by_id(uint32_t id)
+{
+CPUState *cpu;
+
+DPRINTF("cpu %d\n", id);
+
+CPU_FOREACH(cpu) {
+ARMCPU *armcpu = ARM_CPU(cpu);
+
+if (armcpu->mp_affinity == id) {
+return cpu;
+}
+}
+
+qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Resquesting unknown CPU %d\n",
+  TYPE_IMX6_SRC, __func__, id);
+
+return NULL;
+}
+
+static void imx6_src_cpu_on(uint32_t cpuid, uint32_t entry, uint32_t 
context_id)
+{
+CPUState *target_cpu_state;
+ARMCPU *target_cpu;
+CPUClass *target_cpu_class;
+
+DPRINTF("cpu %d @ 0x%08x with R0 = 0x%08x\n", cpuid, entry, context_id);
+
+/* change to the cpu we are powering up */
+target_cpu_state = imx6_src_get_cpu_by_id(cpuid);
+if (!target_cpu_state) {
+return;
+}
+target_cpu = ARM_CPU(target_cpu_state);
+if (!target_cpu->powered_off) {
+qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: CPU %d is already running\n",
+  TYPE_IMX6_SRC, __func__, cpuid);
+return;
+}
+target_cpu_class = CPU_GET_CLASS(target_cpu);
+
+/* Initialize the cpu we are turning on */
+cpu_reset(target_cpu_state);
+target_cpu->powered_off = false;
+target_cpu_state->halted = 0;
+
+target_cpu->env.regs[0] = contex

[Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.

2016-02-08 Thread Jean-Christophe Dubois
For now we only support the following devices:
* up to 4 Cortex A9 cores
* A9 MPCORE (SCU, GIC, TWD)
* 5 i.MX UARTs
* 2 EPIT timers
* 1 GPT timer
* 3 I2C controllers
* 7 GPIO controllers
* 6 SDHC controllers
* 1 CCM device
* 1 SRC device
* various ROM/RAM areas.

Signed-off-by: Jean-Christophe Dubois 
---

Changes since V1:
 * use g_strdup_printf/g_free instead of local char array.
 * output a message on exit for unsupported number of cores.

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/fsl-imx6.c   | 407 
 include/hw/arm/fsl-imx6.h   | 447 
 4 files changed, 856 insertions(+)
 create mode 100644 hw/arm/fsl-imx6.c
 create mode 100644 include/hw/arm/fsl-imx6.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index d9b90a5..ba3a380 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -99,6 +99,7 @@ CONFIG_ALLWINNER_A10_PIT=y
 CONFIG_ALLWINNER_A10_PIC=y
 CONFIG_ALLWINNER_A10=y
 
+CONFIG_FSL_IMX6=y
 CONFIG_FSL_IMX31=y
 CONFIG_FSL_IMX25=y
 
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 2195b60..ac383df 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -15,3 +15,4 @@ obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
 obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
+obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
new file mode 100644
index 000..0faae27
--- /dev/null
+++ b/hw/arm/fsl-imx6.c
@@ -0,0 +1,407 @@
+/*
+ * Copyright (c) 2015 Jean-Christophe Dubois 
+ *
+ * i.MX6 SOC emulation.
+ *
+ * Based on hw/arm/fsl-imx31.c
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw/arm/fsl-imx6.h"
+#include "sysemu/sysemu.h"
+#include "exec/address-spaces.h"
+#include "hw/boards.h"
+#include "sysemu/char.h"
+#include "qemu/error-report.h"
+
+static void fsl_imx6_init(Object *obj)
+{
+FslIMX6State *s = FSL_IMX6(obj);
+int i;
+
+if (smp_cpus > FSL_IMX6_NUM_CPUS) {
+error_report("%s: Only %d CPUs are supported (%d requested)\n",
+ TYPE_FSL_IMX6, FSL_IMX6_NUM_CPUS, smp_cpus);
+exit(1);
+}
+
+for (i = 0; i < smp_cpus; i++) {
+object_initialize(&s->cpu[i], sizeof(s->cpu[i]),
+  "cortex-a9-" TYPE_ARM_CPU);
+}
+
+object_initialize(&s->a9mpcore, sizeof(s->a9mpcore), TYPE_A9MPCORE_PRIV);
+qdev_set_parent_bus(DEVICE(&s->a9mpcore), sysbus_get_default());
+
+object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX6_CCM);
+qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
+
+object_initialize(&s->src, sizeof(s->src), TYPE_IMX6_SRC);
+qdev_set_parent_bus(DEVICE(&s->src), sysbus_get_default());
+
+for (i = 0; i < FSL_IMX6_NUM_UARTS; i++) {
+object_initialize(&s->uart[i], sizeof(s->uart[i]), TYPE_IMX_SERIAL);
+qdev_set_parent_bus(DEVICE(&s->uart[i]), sysbus_get_default());
+}
+
+object_initialize(&s->gpt, sizeof(s->gpt), TYPE_IMX_GPT);
+qdev_set_parent_bus(DEVICE(&s->gpt), sysbus_get_default());
+
+for (i = 0; i < FSL_IMX6_NUM_EPITS; i++) {
+object_initialize(&s->epit[i], sizeof(s->epit[i]), TYPE_IMX_EPIT);
+qdev_set_parent_bus(DEVICE(&s->epit[i]), sysbus_get_default());
+}
+
+for (i = 0; i < FSL_IMX6_NUM_I2CS; i++) {
+object_initialize(&s->i2c[i], sizeof(s->i2c[i]), TYPE_IMX_I2C);
+qdev_set_parent_bus(DEVICE(&s->i2c[i]), sysbus_get_default());
+}
+
+for (i = 0; i < FSL_IMX6_NUM_GPIOS; i++) {
+object_initialize(&s->gpio[i], sizeof(s->gpio[i]), TYPE_IMX_GPIO);
+qdev_set_parent_bus(DEVICE(&s->gpio[i]), sysbus_get_default());
+}
+
+for (i = 0; i < FSL_IMX6_NUM_ESDHCS; i++) {
+object_initialize(&s->esdhc[i], sizeof(s->esdhc[i]), 
TYPE_SYSBUS_SDHCI);
+qdev_set_parent_bus(DEVICE(&s->esdhc[i]), sysbus_get_default());
+}
+}
+

[Qemu-devel] [PATCH v2 5/9] i.MX: Add i.MX6 CCM and ANALOG device.

2016-02-08 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---

Changes since V1:
 * move clk computation to uint64_t to avoid overflow
 * added explanation on _SET, _CLR and _TOG registers
 * move CCM and ANALOG handling in sub memory regions.

 hw/misc/Makefile.objs  |   1 +
 hw/misc/imx6_ccm.c | 773 +
 include/hw/misc/imx6_ccm.h | 197 
 3 files changed, 971 insertions(+)
 create mode 100644 hw/misc/imx6_ccm.c
 create mode 100644 include/hw/misc/imx6_ccm.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index d4765c2..a2a8e91 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -28,6 +28,7 @@ obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o
 obj-$(CONFIG_IMX) += imx_ccm.o
 obj-$(CONFIG_IMX) += imx31_ccm.o
 obj-$(CONFIG_IMX) += imx25_ccm.o
+obj-$(CONFIG_IMX) += imx6_ccm.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx6_ccm.c b/hw/misc/imx6_ccm.c
new file mode 100644
index 000..8b76c0e
--- /dev/null
+++ b/hw/misc/imx6_ccm.c
@@ -0,0 +1,773 @@
+/*
+ * IMX6 Clock Control Module
+ *
+ * Copyright (c) 2015 Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * To get the timer frequencies right, we need to emulate at least part of
+ * the CCM.
+ */
+
+#include "hw/misc/imx6_ccm.h"
+
+#ifndef DEBUG_IMX6_CCM
+#define DEBUG_IMX6_CCM 0
+#endif
+
+#define DPRINTF(fmt, args...) \
+do { \
+if (DEBUG_IMX6_CCM) { \
+fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX6_CCM, \
+ __func__, ##args); \
+} \
+} while (0)
+
+static char const *imx6_ccm_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case CCM_CCR:
+return "CCR";
+case CCM_CCDR:
+return "CCDR";
+case CCM_CSR:
+return "CSR";
+case CCM_CCSR:
+return "CCSR";
+case CCM_CACRR:
+return "CACRR";
+case CCM_CBCDR:
+return "CBCDR";
+case CCM_CBCMR:
+return "CBCMR";
+case CCM_CSCMR1:
+return "CSCMR1";
+case CCM_CSCMR2:
+return "CSCMR2";
+case CCM_CSCDR1:
+return "CSCDR1";
+case CCM_CS1CDR:
+return "CS1CDR";
+case CCM_CS2CDR:
+return "CS2CDR";
+case CCM_CDCDR:
+return "CDCDR";
+case CCM_CHSCCDR:
+return "CHSCCDR";
+case CCM_CSCDR2:
+return "CSCDR2";
+case CCM_CSCDR3:
+return "CSCDR3";
+case CCM_CDHIPR:
+return "CDHIPR";
+case CCM_CTOR:
+return "CTOR";
+case CCM_CLPCR:
+return "CLPCR";
+case CCM_CISR:
+return "CISR";
+case CCM_CIMR:
+return "CIMR";
+case CCM_CCOSR:
+return "CCOSR";
+case CCM_CGPR:
+return "CGPR";
+case CCM_CCGR0:
+return "CCGR0";
+case CCM_CCGR1:
+return "CCGR1";
+case CCM_CCGR2:
+return "CCGR2";
+case CCM_CCGR3:
+return "CCGR3";
+case CCM_CCGR4:
+return "CCGR4";
+case CCM_CCGR5:
+return "CCGR5";
+case CCM_CCGR6:
+return "CCGR6";
+case CCM_CMEOR:
+return "CMEOR";
+default:
+sprintf(unknown, "%d ?", reg);
+return unknown;
+}
+}
+
+static char const *imx6_analog_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case CCM_ANALOG_PLL_ARM:
+return "PLL_ARM";
+case CCM_ANALOG_PLL_ARM_SET:
+return "PLL_ARM_SET";
+case CCM_ANALOG_PLL_ARM_CLR:
+return "PLL_ARM_CLR";
+case CCM_ANALOG_PLL_ARM_TOG:
+return "PLL_ARM_TOG";
+case CCM_ANALOG_PLL_USB1:
+return "PLL_USB1";
+case CCM_ANALOG_PLL_USB1_SET:
+return "PLL_USB1_SET";
+case CCM_ANALOG_PLL_USB1_CLR:
+return "PLL_USB1_CLR";
+case CCM_ANALOG_PLL_USB1_TOG:
+return "PLL_USB1_TOG";
+case CCM_ANALOG_PLL_USB2:
+return "PLL_USB2";
+case CCM_ANALOG_PLL_USB2_SET:
+return "PLL_USB2_SET";
+case CCM_ANALOG_PLL_USB2_CLR:
+return "PLL_USB2_CLR";
+case CCM_ANALOG_PLL_USB2_TOG:
+return "PLL_USB2_TOG";
+case CCM_ANALOG_PLL_SYS:
+return "PLL_SYS";
+case CCM_ANALOG_PLL_SYS_SET:
+return "PLL_SYS_SET";
+case CCM_ANALOG_PLL_SYS_CLR:
+return "PLL_SYS_CLR";
+case CCM_ANALOG_P

[Qemu-devel] [PATCH v2 8/9] i.MX: Add sabrelite i.MX6 emulation.

2016-02-08 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---

Changes since v1:
 * output a message and exit if RAM size is unsupported.

 hw/arm/Makefile.objs |  2 +-
 hw/arm/sabrelite.c   | 93 
 2 files changed, 94 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/sabrelite.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index ac383df..fc1df45 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -15,4 +15,4 @@ obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
 obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
-obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o
+obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
new file mode 100644
index 000..8db9bbc
--- /dev/null
+++ b/hw/arm/sabrelite.c
@@ -0,0 +1,93 @@
+/*
+ * SABRELITE Board System emulation.
+ *
+ * Copyright (c) 2015 Jean-Christophe Dubois 
+ *
+ * This code is licensed under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a sabrelite board, with a Freescale
+ * i.MX6 SoC
+ */
+
+#include "hw/arm/fsl-imx6.h"
+#include "hw/boards.h"
+#include "qemu/error-report.h"
+#include "exec/address-spaces.h"
+#include "net/net.h"
+#include "hw/devices.h"
+#include "hw/char/serial.h"
+#include "sysemu/qtest.h"
+
+typedef struct IMX6Sabrelite {
+FslIMX6State soc;
+MemoryRegion ram;
+} IMX6Sabrelite;
+
+static struct arm_boot_info sabrelite_binfo = {
+/* DDR memory start */
+.loader_start = FSL_IMX6_MMDC_ADDR,
+/* No board ID, we boot from DT tree */
+.board_id = -1,
+};
+
+/* No need to do any particular setup for secondary boot */
+static void sabrelite_write_secondary(ARMCPU *cpu,
+  const struct arm_boot_info *info)
+{
+}
+
+/* Secondary cores are reset through SRC device */
+static void sabrelite_reset_secondary(ARMCPU *cpu,
+  const struct arm_boot_info *info)
+{
+}
+
+static void sabrelite_init(MachineState *machine)
+{
+IMX6Sabrelite *s = g_new0(IMX6Sabrelite, 1);
+Error *err = NULL;
+
+object_initialize(&s->soc, sizeof(s->soc), TYPE_FSL_IMX6);
+object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
+  &error_abort);
+
+object_property_set_bool(OBJECT(&s->soc), true, "realized", &err);
+if (err != NULL) {
+error_report("%s", error_get_pretty(err));
+exit(1);
+}
+
+/* Check the amount of memory is compatible with the SOC */
+if (machine->ram_size > FSL_IMX6_MMDC_SIZE) {
+error_report("RAM size " RAM_ADDR_FMT " above max supported (%08x)\n",
+ machine->ram_size, FSL_IMX6_MMDC_SIZE);
+exit(1);
+}
+
+memory_region_allocate_system_memory(&s->ram, NULL, "sabrelite.ram",
+ machine->ram_size);
+memory_region_add_subregion(get_system_memory(), FSL_IMX6_MMDC_ADDR,
+&s->ram);
+
+sabrelite_binfo.ram_size = machine->ram_size;
+sabrelite_binfo.kernel_filename = machine->kernel_filename;
+sabrelite_binfo.kernel_cmdline = machine->kernel_cmdline;
+sabrelite_binfo.initrd_filename = machine->initrd_filename;
+sabrelite_binfo.nb_cpus = smp_cpus;
+sabrelite_binfo.write_secondary_boot = sabrelite_write_secondary;
+sabrelite_binfo.secondary_cpu_reset_hook = sabrelite_reset_secondary;
+
+if (!qtest_enabled()) {
+arm_load_kernel(&s->soc.cpu[0], &sabrelite_binfo);
+}
+}
+
+static void sabrelite_machine_init(MachineClass *mc)
+{
+mc->desc = "Freescale i.MX6 Quad SABRE Lite Board (Cortex A9)";
+mc->init = sabrelite_init;
+mc->max_cpus = FSL_IMX6_NUM_CPUS;
+}
+
+DEFINE_MACHINE("sabrelite", sabrelite_machine_init)
-- 
2.5.0




[Qemu-devel] [PATCH v2 9/9] i.MX: Add missing descriptions in devices.

2016-02-08 Thread Jean-Christophe Dubois
Signed-off-by: Jean-Christophe Dubois 
---

Changes since V1:
 * Not present on V1

 hw/arm/fsl-imx25.c | 1 +
 hw/arm/fsl-imx31.c | 1 +
 hw/i2c/imx_i2c.c   | 1 +
 hw/net/imx_fec.c   | 1 +
 4 files changed, 4 insertions(+)

diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index fb743bf..1fbc317 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -291,6 +291,7 @@ static void fsl_imx25_class_init(ObjectClass *oc, void 
*data)
  * arm_cpu_class_init()
  */
 dc->cannot_destroy_with_object_finalize_yet = true;
+dc->desc = "i.MX25 SOC";
 }
 
 static const TypeInfo fsl_imx25_type_info = {
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
index f2c2ce5..0d69a2c 100644
--- a/hw/arm/fsl-imx31.c
+++ b/hw/arm/fsl-imx31.c
@@ -265,6 +265,7 @@ static void fsl_imx31_class_init(ObjectClass *oc, void 
*data)
  * arm_cpu_class_init()
  */
 dc->cannot_destroy_with_object_finalize_yet = true;
+dc->desc = "i.MX31 SOC";
 }
 
 static const TypeInfo fsl_imx31_type_info = {
diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c
index cb62c7a..aa47a63 100644
--- a/hw/i2c/imx_i2c.c
+++ b/hw/i2c/imx_i2c.c
@@ -318,6 +318,7 @@ static void imx_i2c_class_init(ObjectClass *klass, void 
*data)
 dc->vmsd = &imx_i2c_vmstate;
 dc->reset = imx_i2c_reset;
 dc->realize = imx_i2c_realize;
+dc->desc = "i.MX I2C controller";
 }
 
 static const TypeInfo imx_i2c_type_info = {
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index c50bf7f..789a0c1 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -692,6 +692,7 @@ static void imx_fec_class_init(ObjectClass *klass, void 
*data)
 dc->reset = imx_fec_reset;
 dc->props = imx_fec_properties;
 dc->realize = imx_fec_realize;
+dc->desc = "i.MX FEC Ethernet ccontroller";
 }
 
 static const TypeInfo imx_fec_info = {
-- 
2.5.0




[Qemu-devel] [PATCH 1/3] FIFO: Add a FIFO32 implementation

2016-02-13 Thread Jean-Christophe Dubois
This one is build on top of the existing FIFO8

Signed-off-by: Jean-Christophe Dubois 
---
 include/qemu/fifo32.h | 206 ++
 1 file changed, 206 insertions(+)
 create mode 100644 include/qemu/fifo32.h

diff --git a/include/qemu/fifo32.h b/include/qemu/fifo32.h
new file mode 100644
index 000..d934516
--- /dev/null
+++ b/include/qemu/fifo32.h
@@ -0,0 +1,206 @@
+#ifndef FIFO32_H
+#define FIFO32_H
+
+#include "qemu/fifo8.h"
+
+typedef Fifo8 Fifo32;
+
+/**
+ * fifo32_create:
+ * @fifo: struct Fifo32 to initialise with new FIFO
+ * @capacity: capacity of the newly created FIFO
+ *
+ * Create a FIFO of the specified size. Clients should call fifo32_destroy()
+ * when finished using the fifo. The FIFO is initially empty.
+ */
+
+static inline void fifo32_create(Fifo32 *fifo, uint32_t capacity)
+{
+fifo8_create(fifo, capacity * sizeof(uint32_t));
+}
+
+/**
+ * fifo32_destroy:
+ * @fifo: FIFO to cleanup
+ *
+ * Cleanup a FIFO created with fifo32_create(). Frees memory created for FIFO
+  *storage. The FIFO is no longer usable after this has been called.
+ */
+
+static inline void fifo32_destroy(Fifo32 *fifo)
+{
+fifo8_destroy(fifo);
+}
+
+/**
+ * fifo32_num_free:
+ * @fifo: FIFO to check
+ *
+ * Return the number of free uint32_t slots in the FIFO.
+ *
+ * Returns: Number of free bytes.
+ */
+
+static inline uint32_t fifo32_num_free(Fifo32 *fifo)
+{
+return (fifo8_num_free(fifo) + sizeof(uint32_t) - 1) / sizeof(uint32_t);
+}
+
+/**
+ * fifo32_num_used:
+ * @fifo: FIFO to check
+ *
+ * Return the number of used uint32_t slots in the FIFO.
+ *
+ * Returns: Number of used bytes.
+ */
+
+static inline uint32_t fifo32_num_used(Fifo32 *fifo)
+{
+return (fifo8_num_used(fifo) + sizeof(uint32_t) - 1) / sizeof(uint32_t);
+}
+
+/**
+ * fifo32_push:
+ * @fifo: FIFO to push to
+ * @data: data byte to push
+ *
+ * Push a data byte to the FIFO. Behaviour is undefined if the FIFO is full.
+ * Clients are responsible for checking for fullness using fifo32_is_full().
+ */
+
+static inline void fifo32_push(Fifo32 *fifo, uint32_t data)
+{
+uint8_t *ptr = (uint8_t *)&data;
+int i;
+
+if (fifo32_num_free(fifo) == 0) {
+abort();
+}
+
+for (i=0; i < sizeof(data); i++) {
+fifo8_push(fifo, ptr[i]);
+}
+}
+
+/**
+ * fifo32_push_all:
+ * @fifo: FIFO to push to
+ * @data: data to push
+ * @size: number of bytes to push
+ *
+ * Push a byte array to the FIFO. Behaviour is undefined if the FIFO is full.
+ * Clients are responsible for checking the space left in the FIFO using
+ * fifo32_num_free().
+ */
+
+static inline void fifo32_push_all(Fifo32 *fifo, const uint32_t *data,
+   uint32_t num)
+{
+fifo8_push_all(fifo, (const uint8_t *)data, num * sizeof(uint32_t));
+}
+
+/**
+ * fifo32_pop:
+ * @fifo: fifo to pop from
+ *
+ * Pop a data byte from the FIFO. Behaviour is undefined if the FIFO is empty.
+ * Clients are responsible for checking for emptyness using fifo32_is_empty().
+ *
+ * Returns: The popped data byte.
+ */
+
+static inline uint32_t fifo32_pop(Fifo32 *fifo)
+{
+uint32_t ret = 0;
+uint8_t *ptr = (uint8_t *)&ret;
+int i;
+
+for (i=0; i < sizeof(uint32_t); i++) {
+if (fifo8_is_empty(fifo)) {
+break;
+}
+ptr[i] = fifo8_pop(fifo);
+}
+
+return ret;
+}
+
+/**
+ * fifo32_pop_buf:
+ * @fifo: FIFO to pop from
+ * @max: maximum number of bytes to pop
+ * @num: actual number of returned bytes
+ *
+ * Pop a number of elements from the FIFO up to a maximum of max. The buffer
+ * containing the popped data is returned. This buffer points directly into
+ * the FIFO backing store and data is invalidated once any of the fifo32_* APIs
+ * are called on the FIFO.
+ *
+ * The function may return fewer bytes than requested when the data wraps
+ * around in the ring buffer; in this case only a contiguous part of the data
+ * is returned.
+ *
+ * The number of valid bytes returned is populated in *num; will always return
+ * at least 1 byte. max must not be 0 or greater than the number of bytes in
+ * the FIFO.
+ *
+ * Clients are responsible for checking the availability of requested data
+ * using fifo32_num_used().
+ *
+ * Returns: A pointer to popped data.
+ */
+
+static inline const uint32_t *fifo32_pop_buf(Fifo32 *fifo, uint32_t max,
+ uint32_t *num)
+{
+const uint8_t *ptr = fifo8_pop_buf(fifo, max * sizeof(uint32_t), num);
+
+*num /= sizeof(uint32_t);
+
+return (const uint32_t *)ptr;
+}
+
+/**
+ * fifo32_reset:
+ * @fifo: FIFO to reset
+ *
+ * Reset a FIFO. All data is discarded and the FIFO is emptied.
+ */
+
+static inline void fifo32_reset(Fifo32 *fifo)
+{
+fifo8_reset(fifo);
+}
+
+/**
+ * fifo32_is_empty:
+ * @fifo: FIFO to check
+ *
+ * Check if a FIFO is empty.
+ *
+ * Returns: True if the fifo is empty, false otherwise.
+ */
+
+static inline bool fifo

  1   2   3   4   5   6   7   >