[Qemu-devel] [Bug 1324724] Re: make install fails if running strip

2014-05-30 Thread Peter Chubb
The libexec case doesn't actually work, which is why IO switched to a
separate variable.  One of the reasons I said the patch is probably
wrong.

I suspect we need something like
$(STRIP) $(addprefix $(DESTDIR)/$(BINDIR), $(notdir ${TOOLS)))

And I didn't see the problem on x86_64, only on armhf. I think x86_64
doesn't need the fsdev helper.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1324724

Title:
  make install fails if running strip

Status in QEMU:
  New

Bug description:
  I do:
 ./configure --target-list=arm-softmmu
 make
sudo make install

  and see:
  install -d -m 0755 "/usr/local/bin"
  libtool --quiet --mode=install install -c -m 0755 qemu-ga qemu-nbd qemu-img 
qemu-io  fsdev/virtfs-proxy-helper "/usr/local/bin"
  strip "/usr/local/bin/qemu-ga" "/usr/local/bin/qemu-nbd" 
"/usr/local/bin/qemu-img" "/usr/local/bin/qemu-io" 
"/usr/local/bin/fsdev/virtfs-proxy-helper"
  strip: '/usr/local/bin/fsdev/virtfs-proxy-helper': No such file
  Makefile:379: recipe for target 'install' failed
  make: *** [install] Error 1

  
  Host is Odroid-XU running Debian Jessie.
  Source is at d7d3d6092cb7edc75dc49fb90c86dd5425ab4805 Merge remote-tracking 
branch 'remotes/afaerber/tags/qom-devices-for-peter'
   
  libtool version 2.4.2-1.7 armhf

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1324724/+subscriptions



[Qemu-devel] [Bug 1324727] [NEW] qemu-system-arm segfaults without KVM on ARM

2014-05-29 Thread Peter Chubb
Public bug reported:

I'm running on Odroid-XU, Debian Jessie armhf
qemu built from today's head d7d3d6092cb7edc75dc49fb90c86dd5425ab4805

sudo  qemu-system-arm -M vexpress-a15 -drive 
if=none,file=arm.img,cache=writeback,id=foo -device virtio-blk-device,drive=foo 
-netdev user,id=user.0 -device virtio-net-device,netdev=user.0 -nographic 
-append 'root=/dev/vda rw console=ttyAMA0 rootwait' -kernel 
/usr/src/build/arm/linux-guest/arch/arm/boot/zImage -dtb a15x2.dtb
audio: Could not init `oss' audio driver
Uncompressing Linux... done, booting the kernel.
Segmentation fault

If I run under GDB, the linux guest instance panics or hangs -- the
behaviour is variable run to run.

If I do:
sudo  qemu-system-arm --enable-kvm -M vexpress-a15 -drive 
if=none,file=arm.img,cache=writeback,id=foo -device virtio-blk-device,drive=foo 
-netdev user,id=user.0 -device virtio-net-device,netdev=user.0 -nographic 
-append 'root=/dev/vda rw console=ttyAMA0 rootwait' -kernel 
/usr/src/build/arm/linux-guest/arch/arm/boot/zImage -dtb a15x2.dtb

then the guest boots as expected.

I tried to get a backtrace by allowinghte SEGV to dump core, and using gdb to 
inspect it:
Core was generated by `qemu-system-arm -M vexpress-a15 -drive 
if=none,file=arm.img,cache=writeback,id='.
Program terminated with signal 11, Segmentation fault.
#0  0xb53399c0 in ?? ()
(gdb) bt
#0  0xb53399c0 in ?? ()
Cannot access memory at address 0x28
#1  0x0016d87e in cpu_tb_exec (
tb_ptr=0xc786fe90 , cpu=0x24450d8)
at /mnt/qemu/cpu-exec.c:67
#2  cpu_arm_exec (env=) at /mnt/qemu/cpu-exec.c:642
#3  0x in ?? ()

** Affects: qemu
 Importance: Undecided
 Status: New

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1324727

Title:
  qemu-system-arm segfaults without KVM on ARM

Status in QEMU:
  New

Bug description:
  I'm running on Odroid-XU, Debian Jessie armhf
  qemu built from today's head d7d3d6092cb7edc75dc49fb90c86dd5425ab4805

  sudo  qemu-system-arm -M vexpress-a15 -drive 
if=none,file=arm.img,cache=writeback,id=foo -device virtio-blk-device,drive=foo 
-netdev user,id=user.0 -device virtio-net-device,netdev=user.0 -nographic 
-append 'root=/dev/vda rw console=ttyAMA0 rootwait' -kernel 
/usr/src/build/arm/linux-guest/arch/arm/boot/zImage -dtb a15x2.dtb
  audio: Could not init `oss' audio driver
  Uncompressing Linux... done, booting the kernel.
  Segmentation fault

  If I run under GDB, the linux guest instance panics or hangs -- the
  behaviour is variable run to run.

  If I do:
  sudo  qemu-system-arm --enable-kvm -M vexpress-a15 -drive 
if=none,file=arm.img,cache=writeback,id=foo -device virtio-blk-device,drive=foo 
-netdev user,id=user.0 -device virtio-net-device,netdev=user.0 -nographic 
-append 'root=/dev/vda rw console=ttyAMA0 rootwait' -kernel 
/usr/src/build/arm/linux-guest/arch/arm/boot/zImage -dtb a15x2.dtb

  then the guest boots as expected.

  I tried to get a backtrace by allowinghte SEGV to dump core, and using gdb to 
inspect it:
  Core was generated by `qemu-system-arm -M vexpress-a15 -drive 
if=none,file=arm.img,cache=writeback,id='.
  Program terminated with signal 11, Segmentation fault.
  #0  0xb53399c0 in ?? ()
  (gdb) bt
  #0  0xb53399c0 in ?? ()
  Cannot access memory at address 0x28
  #1  0x0016d87e in cpu_tb_exec (
  tb_ptr=0xc786fe90 , cpu=0x24450d8)
  at /mnt/qemu/cpu-exec.c:67
  #2  cpu_arm_exec (env=) at /mnt/qemu/cpu-exec.c:642
  #3  0x in ?? ()

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1324727/+subscriptions



[Qemu-devel] [Bug 1324724] [NEW] make install fails on arm host

2014-05-29 Thread Peter Chubb
Public bug reported:

I do:
   ./configure --target-list=arm-softmmu
   make
  sudo make install

and see:
install -d -m 0755 "/usr/local/bin"
libtool --quiet --mode=install install -c -m 0755 qemu-ga qemu-nbd qemu-img 
qemu-io  fsdev/virtfs-proxy-helper "/usr/local/bin"
strip "/usr/local/bin/qemu-ga" "/usr/local/bin/qemu-nbd" 
"/usr/local/bin/qemu-img" "/usr/local/bin/qemu-io" 
"/usr/local/bin/fsdev/virtfs-proxy-helper"
strip: '/usr/local/bin/fsdev/virtfs-proxy-helper': No such file
Makefile:379: recipe for target 'install' failed
make: *** [install] Error 1


Host is Odroid-XU running Debian Jessie.
Source is at d7d3d6092cb7edc75dc49fb90c86dd5425ab4805 Merge remote-tracking 
branch 'remotes/afaerber/tags/qom-devices-for-peter'
 
libtool version 2.4.2-1.7 armhf

** Affects: qemu
 Importance: Undecided
 Status: New

** Patch added: "Probably wrong fix."
   https://bugs.launchpad.net/bugs/1324724/+attachment/4122442/+files/fix.patch

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1324724

Title:
  make install fails on arm host

Status in QEMU:
  New

Bug description:
  I do:
 ./configure --target-list=arm-softmmu
 make
sudo make install

  and see:
  install -d -m 0755 "/usr/local/bin"
  libtool --quiet --mode=install install -c -m 0755 qemu-ga qemu-nbd qemu-img 
qemu-io  fsdev/virtfs-proxy-helper "/usr/local/bin"
  strip "/usr/local/bin/qemu-ga" "/usr/local/bin/qemu-nbd" 
"/usr/local/bin/qemu-img" "/usr/local/bin/qemu-io" 
"/usr/local/bin/fsdev/virtfs-proxy-helper"
  strip: '/usr/local/bin/fsdev/virtfs-proxy-helper': No such file
  Makefile:379: recipe for target 'install' failed
  make: *** [install] Error 1

  
  Host is Odroid-XU running Debian Jessie.
  Source is at d7d3d6092cb7edc75dc49fb90c86dd5425ab4805 Merge remote-tracking 
branch 'remotes/afaerber/tags/qom-devices-for-peter'
   
  libtool version 2.4.2-1.7 armhf

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1324724/+subscriptions



Re: [Qemu-devel] [Bug 1273944] Re: multiboot header has 0 in mem_upper field

2014-01-29 Thread Peter Chubb
>>>>> "Peter" == Peter Chubb  writes:
This change fixes it.

> diff --git a/exec.c b/exec.c
> index 2435d9e..b387d28 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -1070,7 +1070,7 @@ static void *file_ram_alloc(RAMBlock *block,
>  }
> 
>  /* MAP_POPULATE silently ignores failures */
> -for (i = 0; i < (memory/hpagesize); i++) {
> +for (i = 0; i < (memory/hpagesize)-1; i++) {
>  memset(area + (hpagesize*i), 0, 1);
>  }

I don't know why this fixes the issue.  Hence, no signed-off-by line, etc.

My guess is that the memset zeros something it shouldn't off the end of
the array (but that doesn't make sense to me!)

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



[Qemu-devel] [Bug 1273944] Re: multiboot header has 0 in mem_upper field

2014-01-28 Thread Peter Chubb
This change fixes it.

diff --git a/exec.c b/exec.c
index 2435d9e..b387d28 100644
--- a/exec.c
+++ b/exec.c
@@ -1070,7 +1070,7 @@ static void *file_ram_alloc(RAMBlock *block,
 }
 
 /* MAP_POPULATE silently ignores failures */
-for (i = 0; i < (memory/hpagesize); i++) {
+for (i = 0; i < (memory/hpagesize)-1; i++) {
 memset(area + (hpagesize*i), 0, 1);
 }
 
peterc@Diprotodon:/usr/src/qemu/tests/m

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1273944

Title:
  multiboot header has 0 in mem_upper field

Status in QEMU:
  New

Bug description:
  When booting a multiboot image,. mem_upper is now always zero.

  To test, build qemu from current git head, then do
cd tests/multiboot
./run_test.sh

  You will see the test fail.  In each case mem_upper is 0k.

  git-bisect says the bad commit is
  0169c511554cb0014a00290b0d3d26c31a49818f in qemu.git

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1273944/+subscriptions



[Qemu-devel] [Bug 1273944] [NEW] multiboot header has 0 in mem_upper field

2014-01-28 Thread Peter Chubb
Public bug reported:

When booting a multiboot image,. mem_upper is now always zero.

To test, build qemu from current git head, then do
  cd tests/multiboot
  ./run_test.sh

You will see the test fail.  In each case mem_upper is 0k.

git-bisect says the bad commit is
0169c511554cb0014a00290b0d3d26c31a49818f in qemu.git

** Affects: qemu
 Importance: Undecided
 Status: New

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1273944

Title:
  multiboot header has 0 in mem_upper field

Status in QEMU:
  New

Bug description:
  When booting a multiboot image,. mem_upper is now always zero.

  To test, build qemu from current git head, then do
cd tests/multiboot
./run_test.sh

  You will see the test fail.  In each case mem_upper is 0k.

  git-bisect says the bad commit is
  0169c511554cb0014a00290b0d3d26c31a49818f in qemu.git

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1273944/+subscriptions



[Qemu-devel] [Patch] Fix typo in qom/object.h

2013-08-06 Thread peter . chubb

There's been a cut-and-paste error, it looks like, in the documentation
in qom/object.h.  

Signed-off-by: Peter Chubb 

---
 include/qom/object.h |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: qemu/include/qom/object.h
===
--- qemu.orig/include/qom/object.h  2013-08-06 09:59:30.064467951 +1000
+++ qemu/include/qom/object.h   2013-08-07 12:29:46.678911807 +1000
@@ -249,7 +249,7 @@ typedef struct InterfaceInfo InterfaceIn
  * MyClass parent_class;
  *
  * MyDoSomething parent_do_something;
- * } MyClass;
+ * } DerivedClass;
  *
  * static void derived_do_something(MyState *obj)
  * {

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




Re: [Qemu-devel] [Patch] ARM: Add an L2 cache controller to KZM

2013-08-06 Thread Peter Chubb
OK, this is what I've come up with.  Dunno whether it's right or not
-- the object model is decoupled from the memory model, so  there's no
straightforward way to override just a few of the registers.

At this stage this is just for comment, as I don't really have that
much of a clue about how the object/class hierarchy is meant to work.

---
 hw/arm/kzm.c   |3 +
 hw/misc/arm_l2x0.c |  129 ++---
 2 files changed, 96 insertions(+), 36 deletions(-)

Index: qemu/hw/arm/kzm.c
===
--- qemu.orig/hw/arm/kzm.c  2013-08-07 11:21:48.864692846 +1000
+++ qemu/hw/arm/kzm.c   2013-08-07 11:22:40.292983604 +1000
@@ -33,6 +33,7 @@
  * 0x1fffc000-0x1fff RAM  EMULATED
  * 0x2000-0x2fff Reserved IGNORED
  * 0x3000-0x7fff I.MX31 Internal Register Space
+ *   0x3000-0x3fff L2 Cache Controller PARTIALLY EMULATED
  *   0x43f0 IO_AREA0
  *   0x43f9 UART1 EMULATED
  *   0x43f94000 UART2 EMULATED
@@ -134,6 +135,8 @@ static void kzm_init(QEMUMachineInitArgs
DEVICE_NATIVE_ENDIAN);
 }
 
+sysbus_create_varargs("imx_l2cc", 0x3000, NULL);
+
 kzm_binfo.ram_size = ram_size;
 kzm_binfo.kernel_filename = kernel_filename;
 kzm_binfo.kernel_cmdline = kernel_cmdline;
Index: qemu/hw/misc/arm_l2x0.c
===
--- qemu.orig/hw/misc/arm_l2x0.c2013-08-07 11:21:48.864692846 +1000
+++ qemu/hw/misc/arm_l2x0.c 2013-08-07 11:21:48.860692824 +1000
@@ -21,7 +21,9 @@
 #include "hw/sysbus.h"
 
 /* L2C-310 r3p2 */
-#define CACHE_ID 0x41c8
+#define PL310_CACHE_ID 0x41c8
+/* L2CC from Freescale */
+#define IMX_PL2CC_CACHE_ID 0xD541
 
 #define TYPE_ARM_L2X0 "l2x0"
 #define ARM_L2X0(obj) OBJECT_CHECK(L2x0State, (obj), TYPE_ARM_L2X0)
@@ -30,6 +32,7 @@ typedef struct L2x0State {
 SysBusDevice parent_obj;
 
 MemoryRegion iomem;
+uint32_t cache_id;
 uint32_t cache_type;
 uint32_t ctrl;
 uint32_t aux_ctrl;
@@ -66,7 +69,7 @@ static uint64_t l2x0_priv_read(void *opa
 }
 switch (offset) {
 case 0:
-return CACHE_ID;
+return s->cache_id;
 case 0x4:
 /* aux_ctrl values affect cache_type values */
 cache_data = (s->aux_ctrl & (7 << 17)) >> 15;
@@ -78,23 +81,25 @@ static uint64_t l2x0_priv_read(void *opa
 return s->aux_ctrl;
 case 0x108:
 return s->tag_ctrl;
-case 0x10C:
-return s->data_ctrl;
-case 0xC00:
-return s->filter_start;
-case 0xC04:
-return s->filter_end;
 case 0xF40:
 return 0;
-case 0xF60:
-return 0;
-case 0xF80:
-return 0;
-default:
-qemu_log_mask(LOG_GUEST_ERROR,
-  "l2x0_priv_read: Bad offset %x\n", (int)offset);
-break;
 }
+if (s->cache_id == PL310_CACHE_ID) {
+switch (offset) {
+case 0x10C:
+return s->data_ctrl;
+case 0xC00:
+return s->filter_start;
+case 0xC04:
+return s->filter_end;
+case 0xF60:
+return 0;
+case 0xF80:
+return 0;
+}
+}
+qemu_log_mask(LOG_GUEST_ERROR,
+  "l2x0_priv_read: Bad offset %x\n", (int)offset);
 return 0;
 }
 
@@ -107,6 +112,7 @@ static void l2x0_priv_write(void *opaque
 /* ignore */
 return;
 }
+
 switch (offset) {
 case 0x100:
 s->ctrl = value & 1;
@@ -114,29 +120,32 @@ static void l2x0_priv_write(void *opaque
 case 0x104:
 s->aux_ctrl = value;
 break;
-case 0x108:
-s->tag_ctrl = value;
-break;
-case 0x10C:
-s->data_ctrl = value;
-break;
-case 0xC00:
-s->filter_start = value;
-break;
-case 0xC04:
-s->filter_end = value;
-break;
 case 0xF40:
 return;
-case 0xF60:
-return;
-case 0xF80:
-return;
-default:
-qemu_log_mask(LOG_GUEST_ERROR,
-  "l2x0_priv_write: Bad offset %x\n", (int)offset);
-break;
 }
+
+if (s->cache_id == PL310_CACHE_ID) {
+switch (offset) {
+case 0x108:
+s->tag_ctrl = value;
+break;
+case 0x10C:
+s->data_ctrl = value;
+break;
+case 0xC00:
+s->filter_start = value;
+break;
+case 0xC04:
+s->filter_end = value;
+break;
+case 0xF60:
+return;
+case 0xF80:
+return;
+}
+}
+qemu_log_mask(LOG_GUEST_ERROR,
+  "l2x0_priv_write: Bad offset %x\n", (int)offset);
 }
 
 static void l2x0_priv_reset(DeviceState *dev)
@@ -184,16 +193,64 @@ static void l2x0_class_init(Object

Re: [Qemu-devel] [Patch] ARM: Add an L2 cache controller to KZM

2013-08-05 Thread Peter Chubb
>>>>> "Andreas" == Andreas Färber  writes:


Andreas> Peter Ch., if you know the exact differences, why don't you
Andreas> just derive an imx-l2cc type (or so) derived from ARM's type,
Andreas> overriding the values mentioned above? Sounds trivial to me.

For what it's worth, here's a diff between the arm_l2x0.c
implementation and a working imx_l2cc.c implementation.

Most of the diffs are name change; but there are substantive
differences to the initial values, and to which registers are
supported.  This makes the State variable smaller.

So it's a bit more than just overriding a few constants.

--- arm_l2x0.c  2013-08-06 09:59:30.008468028 +1000
+++ imx-l2cc-indep.c2013-08-06 10:49:38.021514073 +1000
@@ -1,7 +1,10 @@
 /*
- * ARM dummy L210, L220, PL310 cache controller.
+ * IMX dummy level 2 cache controller
  *
- * Copyright (c) 2010-2012 Calxeda
+ * Copyright (c) 2013 NICTA Peter Chubb
+ *
+ * Based on the PL210 implementation in arm_l2x0.c
+ * Differences: different Cache ID and aux control register values.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -20,46 +23,40 @@
 
 #include "hw/sysbus.h"
 
-/* L2C-310 r3p2 */
-#define CACHE_ID 0x41c8
 
-#define TYPE_ARM_L2X0 "l2x0"
-#define ARM_L2X0(obj) OBJECT_CHECK(L2x0State, (obj), TYPE_ARM_L2X0)
+#define CACHE_ID 0xd541
+#define CACHE_TYPE_DEFAULT 0x1C100100 
+
+#define TYPE_IMX_L2CC "imx_l2cc"
+#define IMX_L2CC(obj) OBJECT_CHECK(L2ccState, (obj), TYPE_IMX_L2CC)
 
-typedef struct L2x0State {
+typedef struct L2ccState {
 SysBusDevice parent_obj;
 
 MemoryRegion iomem;
 uint32_t cache_type;
 uint32_t ctrl;
 uint32_t aux_ctrl;
-uint32_t data_ctrl;
-uint32_t tag_ctrl;
-uint32_t filter_start;
-uint32_t filter_end;
-} L2x0State;
+} L2ccState;
 
-static const VMStateDescription vmstate_l2x0 = {
-.name = "l2x0",
+static const VMStateDescription vmstate_l2cc = {
+.name = "imx_l2cc",
 .version_id = 1,
 .minimum_version_id = 1,
 .fields = (VMStateField[]) {
-VMSTATE_UINT32(ctrl, L2x0State),
-VMSTATE_UINT32(aux_ctrl, L2x0State),
-VMSTATE_UINT32(data_ctrl, L2x0State),
-VMSTATE_UINT32(tag_ctrl, L2x0State),
-VMSTATE_UINT32(filter_start, L2x0State),
-VMSTATE_UINT32(filter_end, L2x0State),
+VMSTATE_UINT32(ctrl, L2ccState),
+VMSTATE_UINT32(cache_type, L2ccState),
+VMSTATE_UINT32(aux_ctrl, L2ccState),
 VMSTATE_END_OF_LIST()
 }
 };
 
 
-static uint64_t l2x0_priv_read(void *opaque, hwaddr offset,
+static uint64_t l2cc_priv_read(void *opaque, hwaddr offset,
unsigned size)
 {
 uint32_t cache_data;
-L2x0State *s = (L2x0State *)opaque;
+L2ccState *s = (L2ccState *)opaque;
 offset &= 0xfff;
 if (offset >= 0x730 && offset < 0x800) {
 return 0; /* cache ops complete */
@@ -76,32 +73,20 @@
 return s->ctrl;
 case 0x104:
 return s->aux_ctrl;
-case 0x108:
-return s->tag_ctrl;
-case 0x10C:
-return s->data_ctrl;
-case 0xC00:
-return s->filter_start;
-case 0xC04:
-return s->filter_end;
 case 0xF40:
 return 0;
-case 0xF60:
-return 0;
-case 0xF80:
-return 0;
 default:
 qemu_log_mask(LOG_GUEST_ERROR,
-  "l2x0_priv_read: Bad offset %x\n", (int)offset);
+  "l2cc_priv_read: Bad offset %x\n", (int)offset);
 break;
 }
 return 0;
 }
 
-static void l2x0_priv_write(void *opaque, hwaddr offset,
+static void l2cc_priv_write(void *opaque, hwaddr offset,
 uint64_t value, unsigned size)
 {
-L2x0State *s = (L2x0State *)opaque;
+L2ccState *s = (L2ccState *)opaque;
 offset &= 0xfff;
 if (offset >= 0x730 && offset < 0x800) {
 /* ignore */
@@ -114,86 +99,61 @@
 case 0x104:
 s->aux_ctrl = value;
 break;
-case 0x108:
-s->tag_ctrl = value;
-break;
-case 0x10C:
-s->data_ctrl = value;
-break;
-case 0xC00:
-s->filter_start = value;
-break;
-case 0xC04:
-s->filter_end = value;
-break;
 case 0xF40:
 return;
-case 0xF60:
-return;
-case 0xF80:
-return;
 default:
 qemu_log_mask(LOG_GUEST_ERROR,
-  "l2x0_priv_write: Bad offset %x\n", (int)offset);
+  "l2cc_priv_write: Bad offset %x\n", (int)offset);
 break;
 }
 }
 
-static void l2x0_priv_reset(DeviceState *dev)
+static void l2cc_priv_reset(DeviceState *dev)
 {
-L2x0State *s = ARM_L2X0(dev);
+L2ccState *s = IMX_L2CC(dev

Re: [Qemu-devel] [Patch] ARM: Add an L2 cache controller to KZM

2013-08-05 Thread Peter Chubb
>>>>> "Peter" == Peter Maydell  writes:

Peter> On 5 August 2013 02:21, Peter Chubb 
Peter> wrote:
>> Reads to unassigned memory now return non-zero (since patch
>> 9b8c69243585). This breaks guests runnong on i.MX31 that use the
>> cache controller --- they poll forever waiting for the L2CC cache
>> invalidate regsiter to be zero.

Peter> That commit claims it was just restoring the previous
Peter> behaviour, so it shouldn't break guests, surely?

The behaviour was introduced in 2008 in commit e18231a3 --- The KZM
port only went in last year and assumed the then-current behaviour.

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



[Qemu-devel] [Patch] ARM: Simplify and fix imx_epit implementation.

2013-08-04 Thread Peter Chubb

When imx_epit.c was last refactored, a common usecase (comparison
register zero) broke.  This patch fixes that, and simplifies the code
yet more.  It also fixes a major thinko in the reset path --- the
wrong bits in the control register were being cleared.

Signed-off-by: Peter Chubb 
Reviewed-by: Jean-Christophe DUBOIS 

---
 hw/timer/imx_epit.c |   94 +++-
 1 file changed, 36 insertions(+), 58 deletions(-)

Index: qemu/hw/timer/imx_epit.c
===
--- qemu.orig/hw/timer/imx_epit.c   2013-08-02 14:07:06.598276595 +1000
+++ qemu/hw/timer/imx_epit.c2013-08-02 14:31:28.494031219 +1000
@@ -43,7 +43,7 @@ static char const *imx_epit_reg_name(uin
 }
 
 #  define DPRINTF(fmt, args...) \
-  do { printf("%s: " fmt , __func__, ##args); } while (0)
+do { fprintf(stderr, "%s: " fmt , __func__, ##args); } while (0)
 #else
 #  define DPRINTF(fmt, args...) do {} while (0)
 #endif
@@ -152,7 +152,7 @@ static void imx_epit_reset(DeviceState *
 /*
  * 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->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
 s->sr = 0;
 s->lr = TIMER_MAX;
 s->cmp = 0;
@@ -167,7 +167,7 @@ static void imx_epit_reset(DeviceState *
 ptimer_set_limit(s->timer_reload, TIMER_MAX, 1);
 if (s->freq && (s->cr & CR_EN)) {
 /* if the timer is still enabled, restart it */
-ptimer_run(s->timer_reload, 1);
+ptimer_run(s->timer_reload, 0);
 }
 }
 
@@ -218,17 +218,17 @@ static uint64_t imx_epit_read(void *opaq
 
 static void imx_epit_reload_compare_timer(IMXEPITState *s)
 {
-if ((s->cr & CR_OCIEN) && s->cmp) {
-/* if the compare feature is on */
+if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN))  {
+/* if the compare feature is on and timers are running */
 uint32_t tmp = imx_epit_update_count(s);
+uint64_t next;
 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);
-}
+/* It'll fire in this round of the timer */
+next = tmp - s->cmp;
+} else { /* catch it next time around */
+next = tmp - s->cmp + ((s->cr & CR_RLD) ? TIMER_MAX : s->lr);
 }
+ptimer_set_count(s->timer_cmp, next);
 }
 }
 
@@ -237,11 +237,14 @@ static void imx_epit_write(void *opaque,
 {
 IMXEPITState *s = IMX_EPIT(opaque);
 uint32_t reg = offset >> 2;
+uint64_t oldcr;
 
 DPRINTF("(%s, value = 0x%08x)\n", imx_epit_reg_name(reg), (uint32_t)value);
 
 switch (reg) {
 case 0: /* CR */
+
+oldcr = s->cr;
 s->cr = value & 0x03ff;
 if (s->cr & CR_SWR) {
 /* handle the reset */
@@ -250,22 +253,35 @@ static void imx_epit_write(void *opaque,
 imx_epit_set_freq(s);
 }
 
-if (s->freq && (s->cr & CR_EN)) {
+if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
 if (s->cr & CR_ENMOD) {
 if (s->cr & CR_RLD) {
 ptimer_set_limit(s->timer_reload, s->lr, 1);
+ptimer_set_limit(s->timer_cmp, s->lr, 1);
 } else {
 ptimer_set_limit(s->timer_reload, TIMER_MAX, 1);
+ptimer_set_limit(s->timer_cmp, TIMER_MAX, 1);
 }
 }
 
 imx_epit_reload_compare_timer(s);
-
-ptimer_run(s->timer_reload, 1);
-} else {
+ptimer_run(s->timer_reload, 0);
+if (s->cr & CR_OCIEN) {
+ptimer_run(s->timer_cmp, 0);
+} else {
+ptimer_stop(s->timer_cmp);
+}
+} else if (!(s->cr & CR_EN)) {
 /* stop both timers */
 ptimer_stop(s->timer_reload);
 ptimer_stop(s->timer_cmp);
+} else  if (s->cr & CR_OCIEN) {
+if (!(oldcr & CR_OCIEN)) {
+imx_epit_reload_compare_timer(s);
+ptimer_run(s->timer_cmp, 0);
+}
+} else {
+ptimer_stop(s->timer_cmp);
 }
 break;
 
@@ -284,13 +300,13 @@ static void imx_epit_write(void *opaque,
 /* Also set the limit if the LRD bit is set */
 /* If IOVW bit is set then set the timer value */
 ptimer_set_limit(s->timer_reload

[Qemu-devel] [Patch] ARM: Add an L2 cache controller to KZM

2013-08-04 Thread Peter Chubb

Reads to unassigned memory now return non-zero (since patch
9b8c69243585).  This breaks guests runnong on i.MX31 that use the
cache controller --- they poll forever waiting for the L2CC cache
invalidate regsiter to be zero.

This patch adds in an L2 cache controller.  It's not quite right ---
it reuses the PL2x0 implementation that  is already in QEMU.  The
differences however are minor --- a different ID, a different initial
value for the aux control register (because Freescale have used
some of the reserved bits), and the pl2x0 implements registers that
are not present in the Freescale cache controller.

Signed-off-by: Peter Chubb 

diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
index bd6c05c..018fc81 100644
--- a/hw/arm/kzm.c
+++ b/hw/arm/kzm.c
@@ -33,6 +33,7 @@
  * 0x1fffc000-0x1fff RAM  EMULATED
  * 0x2000-0x2fff Reserved IGNORED
  * 0x3000-0x7fff I.MX31 Internal Register Space
+ *   0x3000-0x3fff L2 Cache Controller PARTIALLY EMULATED
  *   0x43f0 IO_AREA0
  *   0x43f9 UART1 EMULATED
  *   0x43f94000 UART2 EMULATED
@@ -134,6 +135,15 @@ static void kzm_init(QEMUMachineInitArgs *args)
DEVICE_NATIVE_ENDIAN);
 }
 
+/*
+ * The i.MX L2CC  is almost the same as the PL210
+ * except for a different ID (the implementor bits are different)
+ * and the `reserved' bits in the auxilliary control register
+ * are implemented.  The l2x0 qemu implementation is for a superset
+ * of the PL210.
+ */
+sysbus_create_varargs("l2x0", 0x3000, NULL);
+
 kzm_binfo.ram_size = ram_size;
 kzm_binfo.kernel_filename = kernel_filename;
 kzm_binfo.kernel_cmdline = kernel_cmdline;


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



Re: [Qemu-devel] [PATCH qom-next for-1.6 06/14] imx_ccm: QOM cast cleanup

2013-07-28 Thread Peter Chubb
>>>>> "Andreas" == Andreas Färber  writes:

Andreas> Signed-off-by: Andreas Färber  ---

Acked-by: Peter Chubb 

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



Re: [Qemu-devel] [PATCH qom-next for-1.6 07/15] imx_avic: QOM cast cleanup

2013-07-28 Thread Peter Chubb
>>>>> "Andreas" == Andreas Färber  writes:

Andreas> Signed-off-by: Andreas Färber  ---

Acked-by: Peter Chubb 

--
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.MX31: Fix PRCS bit test

2013-06-09 Thread Peter Chubb
>>>>> "Stefan" == Stefan Weil  writes:

Stefan> cppcheck detected a condition which was always false.
Stefan> According to the MCIMX31 Reference Manual, the PRCS bits have
Stefan> to be 01 to select the Frequency Pre-Multiplier (FPM). PRCS
Stefan> uses bits 1 and 2, so we have to test for 2.

Good catch.  I hate hard coded constants, they're so easy to get wrong!

Stefan> Signed-off-by: Stefan Weil  

Signed-off-by: Peter Chubb 

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



[Qemu-devel] [PATCH] [ARM] Fix rfe instruction

2013-05-30 Thread Peter Chubb

The rfe instruction has been broken since patch
5a839c0d54fac9db0516904db873a4fe01f50f4b because of a typo.

Signed-off-by: Peter Chubb 

diff --git a/target-arm/translate.c b/target-arm/translate.c
index e5a2e4c..29e8f27 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6798,7 +6798,7 @@ static void disas_arm_insn(CPUARMState * env, 
DisasContext *s)
 tcg_gen_qemu_ld32u(tmp, addr, 0);
 tcg_gen_addi_i32(addr, addr, 4);
 tmp2 = tcg_temp_new_i32();
-tcg_gen_qemu_ld32u(tmp, addr, 0);
+tcg_gen_qemu_ld32u(tmp2, addr, 0);
 if (insn & (1 << 21)) {
 /* Base writeback.  */
 switch (i) {

--
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 2/2] i.MX: unify all function and variale name convention in GPT

2013-05-29 Thread Peter Chubb

>  
> -static char const *imx_timerg_reg_name(uint32_t reg)
> +static char const *imx_timer_gpt_reg_name(uint32_t reg)

You could just use imc_gpt_xxx in line with the imx_epit_xxx naming
from your other patch series.


Otherwise this looks good.

--
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 complete version of the GPT timer.

2013-05-27 Thread Peter Chubb
>>>>> "Jean-Christophe" == Jean-Christophe DUBOIS  writes:

Jean-Christophe> * implement compare 1 2 and 3 registers * Unify
Jean-Christophe> function and type naming * use dynamic cast whenever
Jean-Christophe> possible * simplify Debug printf.  * use new style
Jean-Christophe> device intialization.

Can you split this patch into two patches: one that just does the changes to
support the comparison registers, and one that adapts to the newstyle
device initialisation and has the cosmetic renamings and code
reorganisaiton, please? 

I'd much rather review them separately, and keep functional and
non-functional changes separate.

--
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: Improve EPIT timer code.

2013-05-27 Thread Peter Chubb
Hi Jean,
   Thanks for this.  Most of it appears cosmetic and an improvement.
   Comments in-line below.

>  
>  /*
>   * Update interrupt status
>   */
> -static void imx_timerp_update(IMXTimerPState *s)
> +static void imx_timer_epit_update(IMXTimerEPITState *s)
>  {
> -if (s->sr && (s->cr & CR_OCIEN)) {
> +if (s->sr && (s->cr & CR_OCIEN) && (s->cr & CR_EN)) {

Why not
   if (s->sr && (s->cr & (CR_OCIEN|CR_EN) == (CR_OCIEN|CR_EN)))

>  qemu_irq_raise(s->irq);
>  } else {
>  qemu_irq_lower(s->irq);
>  }
>  }
>  
> -static void set_timerp_freq(IMXTimerPState *s)
> +static void imx_timer_epit_set_freq(IMXTimerEPITState *s)
>  {
>  unsigned clksrc;
>  unsigned prescaler;
> -uint32_t freq;

getting rid of this variable means a pointer dereference every time
below.  That's OK at some optimisation levels and for some compilers
as they'll cache the variable.  But I prefer making this explicit so
less competent compilers can avoid the pointer dereference.

>  
>  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 = imx_clock_frequency(s->ccm,
> +  imx_timer_epit_clocks[clksrc]) / prescaler;
>  
> -s->freq = freq;
>  DPRINTF("Setting ptimer frequency to %u\n", freq);

And here it's inconsistent --- s/freq/s->freq/ and as you've renamed,
maybe s/ptimer/epit/

The rest looks OK.

I'm not that keen on the longer names, though.
Maybe s/timer_epit/epit/  throughout.

--
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-28 Thread Peter Chubb
>>>>> "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 C
--
Dr Peter Chubb  peter.chubb AT nicta.com.au
http://www.ssrg.nicta.com.au  Software Systems Research Group/NICTA



[Qemu-devel] [PATCH v2] target-arm: Reinsert SRS missing return statement.

2013-04-15 Thread Peter Chubb

Since patch
   81465888c5306cd94abb9847e560796fd13d3c2f
   target-arm: factor out handling of SRS instruction
the SRS instruction has not worked in QEMU.

The problem is a missing return directive that was removed in the
refactoring, so after decoding the instruction, qemu would do all the
generic stuff that it should do for most instructions -- but not SRS.

Signed-off-by: Peter Chubb 
---
 target-arm/translate.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 35a21be..a1b7b8c 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6762,6 +6762,7 @@ static void disas_arm_insn(CPUARMState * env, 
DisasContext *s)
 }
 ARCH(6);
 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
+return;
 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
 /* rfe */
 int32_t offset;
-- 
1.7.10.4


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



Re: [Qemu-devel] [PATCH] target-arm: Reinsert SRS missing return statements.

2013-04-15 Thread Peter Chubb
>>>>> "Peter" == Peter Maydell  writes:

Peter> On 15 April 2013 05:50, Peter Chubb 
Peter> wrote:
>> 
>> 
>> Since patch 81465888c5306cd94abb9847e560796fd13d3c2f target-arm:
>> factor out handling of SRS instruction the SRS instruction has not
>> worked in QEMU.
>> 
>> The problem is a return directive that was removed in the
>> refactoring, so after decoding the instruction, qemu would fall
>> through to do stuff that it should not have done.

Peter> Nice catch for the ARM decoder, but not needed for thumb2 I
Peter> think?

It was there in the code that was removed.
I didn't analyse too deeply, as nothing we do uses the thumb version.

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



[Qemu-devel] [PATCH] target-arm: Reinsert SRS missing return statements.

2013-04-14 Thread Peter Chubb


Since patch
   81465888c5306cd94abb9847e560796fd13d3c2f
   target-arm: factor out handling of SRS instruction
the SRS instruction has not worked in QEMU.

The problem is a return directive that was removed in the
refactoring, so after decoding the instruction, qemu would fall
through to do stuff that it should not have done.

Signed-off-by: Peter Chubb 

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 35a21be..c870246 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6762,6 +6762,7 @@ static void disas_arm_insn(CPUARMState * env, 
DisasContext *s)
 }
 ARCH(6);
 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
+return;
 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
 /* rfe */
 int32_t offset;
@@ -8209,6 +8210,7 @@ static int disas_thumb2_insn(CPUARMState *env, 
DisasContext *s, uint16_t insn_hw
 /* srs */
 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
 insn & (1 << 21));
+return;
 }
 } else {
     int i, loaded_base = 0;
-- 
1.7.10.4



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-09 Thread Peter Chubb

> 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.
 
 
>-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/

+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'.

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] hw/imx_avic.c: Avoid format error when target_phys_addr_t is 64 bits

2012-07-10 Thread Peter Chubb
>>>>> "Peter" == Peter Maydell  writes:

Peter> Add a missing cast to avoid gcc complaining about format string
Peter> errors when printing an expression based on a
Peter> target_phys_addr_t.

Peter> Signed-off-by: Peter Maydell  

Reviewed-by: Peter Chubb 

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



[Qemu-devel] [Patch V10 3/5] i.MX31: Timers

2012-06-19 Thread Peter Chubb
Implement the timers on the Freescale i.MX31 SoC.
This is not a complete implementation, but gives enough for 
Linux to boot and run. In particular external triggers, which are 
not useful under QEMU, are not implemented.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
---
 hw/arm/Makefile.objs |2 
 hw/imx.h |8 
 hw/imx_timer.c   |  689 +++
 3 files changed, 698 insertions(+), 1 deletion(-)
 create mode 100644 hw/imx_timer.c

Index: qemu-working/hw/arm/Makefile.objs
===
--- qemu-working.orig/hw/arm/Makefile.objs  2012-06-20 09:14:01.040588473 
+1000
+++ qemu-working/hw/arm/Makefile.objs   2012-06-20 09:14:01.796592451 +1000
@@ -34,7 +34,7 @@ obj-y += framebuffer.o
 obj-y += vexpress.o
 obj-y += strongarm.o
 obj-y += collie.o
-obj-y += imx_serial.o imx_ccm.o
+obj-y += imx_serial.o imx_ccm.o imx_timer.o
 obj-y += pl041.o lm4549.o
 obj-$(CONFIG_FDT) += ../device_tree.o
 
Index: qemu-working/hw/imx.h
===
--- qemu-working.orig/hw/imx.h  2012-06-20 09:14:01.040588473 +1000
+++ qemu-working/hw/imx.h   2012-06-20 09:14:01.796592451 +1000
@@ -23,4 +23,12 @@ typedef enum  {
 
 uint32_t imx_clock_frequency(DeviceState *s, IMXClk clock);
 
+void imx_timerp_create(const target_phys_addr_t addr,
+  qemu_irq irq,
+  DeviceState *ccm);
+void imx_timerg_create(const target_phys_addr_t addr,
+  qemu_irq irq,
+  DeviceState *ccm);
+
+
 #endif /* IMX_H */
Index: qemu-working/hw/imx_timer.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_timer.c 2012-06-20 09:14:01.800592472 +1000
@@ -0,0 +1,689 @@
+/*
+ * IMX31 Timer
+ *
+ * Copyright (c) 2008 OK Labs
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally Written by Hans Jiang
+ * Updated by Peter Chubb
+ *
+ * This code is licenced under GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw.h"
+#include "qemu-timer.h"
+#include "ptimer.h"
+#include "sysbus.h"
+#include "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
+
+/*
+ * GPT : General purpose timer
+ *
+ * This timer counts up continuously while it is enabled, resetting itself
+ * to 0 when it reaches TIMER_MAX (in freerun mode) or when it
+ * reaches the value of ocr1 (in periodic mode).  WE simulate this using a
+ * QEMU ptimer counting down from ocr1 and reloading from ocr1 in
+ * periodic mode, or counting from ocr1 to zero, then TIMER_MAX - ocr1.
+ * waiting_rov is set when counting from TIMER_MAX.
+ *
+ * In the real hardware, there are three comparison registers that can
+ * trigger interrupts, and compare channel 1 can be used to
+ * force-reset the timer. However, this is a `bare-bones'
+ * implementation: only what Linux 3.x uses has been implemented
+ * (free-running timer from 0 to OCR1 or TIMER_MAX) .
+ */
+
+
+#define TIMER_MAX  0XUL
+
+/* Control register.  Not all of these bits have any effect (yet) */
+#define GPT_CR_EN (1 << 0)  /* GPT Enable */
+#define GPT_CR_ENMOD  (1 << 1)  /* GPT Enable Mode */
+#define GPT_CR_DBGEN  (1 << 2)  /* GPT Debug mode enable */
+#define GPT_CR_WAITEN (1 << 3)  /* GPT Wait Mode Enable  */
+#define GPT_CR_DOZEN  (1 << 4)  /* GPT Doze mode enable */
+#define GPT_CR_STOPEN (1 << 5)  /* GPT Stop Mode Enable */
+#define GPT_CR_CLKSRC_SHIFT (6)
+#define GPT_CR_CLKSRC_MASK  (0x7)
+
+#define GPT_CR_FRR(1 << 9)  /* Freerun or Restart */
+#define GPT_CR_SWR(1 << 15) /* Software Reset */
+#define GPT_CR_IM1(3 << 16) /* Input capture channel 1 mode (2 bits) */
+#define GPT_CR_IM2(3 << 18) /* Input capture channel 2 mode (2 bits) */
+#define GPT_CR_OM1(7 << 20) /* Output Compare Channel 1 Mode (3 bits) */
+#define GPT_CR_OM2(7 << 23) /* Output Compare Channel 2 Mode (3 bits) */
+#define GPT_CR_OM3(7 << 26) /* Output Compare Channel 3 Mode (3 bits) */
+#define GPT_CR_FO1(1 << 29) /* Force Output Compare Channel 1 */
+#define GPT_CR_FO2(1 << 30) /* Force Output Compare Channel 2 */
+#define GPT_CR_FO3(1 

[Qemu-devel] [Patch V10 4/5] i.MX31: Interrupt Controller

2012-06-19 Thread Peter Chubb
Implement the Freescale i.MX31 advanced vectored interrupt controller, at least
to the extent it is used by Linux 3.x

Vectors are not implemented.

Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
Reviewed-by: Peter Maydell 

---
 hw/arm/Makefile.objs |2 
 hw/imx_avic.c|  408 +++
 2 files changed, 409 insertions(+), 1 deletion(-)
 create mode 100644 hw/imx_avic.c

Index: qemu-working/hw/arm/Makefile.objs
===
--- qemu-working.orig/hw/arm/Makefile.objs  2012-06-20 09:14:02.140594261 
+1000
+++ qemu-working/hw/arm/Makefile.objs   2012-06-20 09:14:02.892598215 +1000
@@ -34,7 +34,7 @@ obj-y += framebuffer.o
 obj-y += vexpress.o
 obj-y += strongarm.o
 obj-y += collie.o
-obj-y += imx_serial.o imx_ccm.o imx_timer.o
+obj-y += imx_serial.o imx_ccm.o imx_timer.o imx_avic.o
 obj-y += pl041.o lm4549.o
 obj-$(CONFIG_FDT) += ../device_tree.o
 
Index: qemu-working/hw/imx_avic.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_avic.c  2012-06-20 09:14:02.896598236 +1000
@@ -0,0 +1,408 @@
+/*
+ * i.MX31 Vectored Interrupt Controller
+ *
+ * Note this is NOT the PL192 provided by ARM, but
+ * a custom implementation by Freescale.
+ *
+ * Copyright (c) 2008 OKL
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally Written by Hans Jiang
+ *
+ * This code is licenced under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * TODO: implement vectors.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "host-utils.h"
+
+#define DEBUG_INT 1
+#undef DEBUG_INT /* comment out for debugging */
+
+#ifdef DEBUG_INT
+#define DPRINTF(fmt, args...) \
+do { printf("imx_avic: " 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_avic: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+#define IMX_AVIC_NUM_IRQS 64
+
+/* Interrupt Control Bits */
+#define ABFLAG (1<<25)
+#define ABFEN (1<<24)
+#define NIDIS (1<<22) /* Normal Interrupt disable */
+#define FIDIS (1<<21) /* Fast interrupt disable */
+#define NIAD  (1<<20) /* Normal Interrupt Arbiter Rise ARM level */
+#define FIAD  (1<<19) /* Fast Interrupt Arbiter Rise ARM level */
+#define NM(1<<18) /* Normal interrupt mode */
+
+
+#define PRIO_PER_WORD (sizeof(uint32_t) * 8 / 4)
+#define PRIO_WORDS (IMX_AVIC_NUM_IRQS/PRIO_PER_WORD)
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+uint64_t pending;
+uint64_t enabled;
+uint64_t is_fiq;
+uint32_t intcntl;
+uint32_t intmask;
+qemu_irq irq;
+qemu_irq fiq;
+uint32_t prio[PRIO_WORDS]; /* Priorities are 4-bits each */
+} IMXAVICState;
+
+static const VMStateDescription vmstate_imx_avic = {
+.name = "imx-avic",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT64(pending, IMXAVICState),
+VMSTATE_UINT64(enabled, IMXAVICState),
+VMSTATE_UINT64(is_fiq, IMXAVICState),
+VMSTATE_UINT32(intcntl, IMXAVICState),
+VMSTATE_UINT32(intmask, IMXAVICState),
+VMSTATE_UINT32_ARRAY(prio, IMXAVICState, PRIO_WORDS),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+
+static inline int imx_avic_prio(IMXAVICState *s, int irq)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+return 0xf & (s->prio[word] >> part);
+}
+
+static inline void imx_avic_set_prio(IMXAVICState *s, int irq, int prio)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+uint32_t mask = ~(0xf << part);
+s->prio[word] &= mask;
+s->prio[word] |= prio << part;
+}
+
+/* Update interrupts.  */
+static void imx_avic_update(IMXAVICState *s)
+{
+int i;
+uint64_t new = s->pending & s->enabled;
+uint64_t flags;
+
+flags = new & s->is_fiq;
+qemu_set_irq(s->fiq, !!flags);
+
+flags = new & ~s->is_fiq;
+if (!flags || (s->intmask == 0x1f)) {
+qemu_set_irq(s->irq, !!flags);
+return;
+}
+
+/*
+ * Take interrupt if there's a pending interrupt with
+ * priority higher than the value of intmask
+ */
+for (i = 0; i < IMX_AVIC_NUM_IRQS; i++) {
+if (flags & (1UL << i)) {
+if (imx_avic_prio(s, i) > s->intmask) {
+qemu_set_irq(s->irq, 1);
+retu

[Qemu-devel] [Patch V10 1/5] i.MX: UART support

2012-06-19 Thread Peter Chubb
Implement the Freescale i.MX UART.  This uart is used in a variety of
SoCs, including some by Motorola, as well as in the Freescale i.MX
series.

This patch gives only a `bare-bones' implementation, enough to run Linux 
or OKL4, but that's about it.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
Reviewed-by: Peter Maydell 
---
 hw/arm/Makefile.objs |1 
 hw/imx.h |   16 +
 hw/imx_serial.c  |  467 +++
 3 files changed, 484 insertions(+)
 create mode 100644 hw/imx_serial.c

Index: qemu-working/hw/arm/Makefile.objs
===
--- qemu-working.orig/hw/arm/Makefile.objs  2012-06-20 09:13:58.432574739 
+1000
+++ qemu-working/hw/arm/Makefile.objs   2012-06-20 09:13:59.636581087 +1000
@@ -34,6 +34,7 @@ obj-y += framebuffer.o
 obj-y += vexpress.o
 obj-y += strongarm.o
 obj-y += collie.o
+obj-y += imx_serial.o
 obj-y += pl041.o lm4549.o
 obj-$(CONFIG_FDT) += ../device_tree.o
 
Index: qemu-working/hw/imx.h
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx.h   2012-06-20 09:13:59.636581087 +1000
@@ -0,0 +1,16 @@
+/*
+ * i.MX31 emulation
+ *
+ * Copyright (C) 2012 Peter Chubb
+ * NICTA
+ *
+ * This code is released under the GPL, version 2.0 or later
+ * See the file `../COPYING' for details.
+ */
+
+#ifndef IMX_H
+#define IMX_H
+
+void imx_serial_create(int uart, const target_phys_addr_t addr, qemu_irq irq);
+
+#endif /* IMX_H */
Index: qemu-working/hw/imx_serial.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_serial.c2012-06-20 09:13:59.636581087 +1000
@@ -0,0 +1,467 @@
+/*
+ * IMX31 UARTS
+ *
+ * Copyright (c) 2008 OKL
+ * Originally Written by Hans Jiang
+ * Copyright (c) 2011 NICTA Pty Ltd.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * This is a `bare-bones' implementation of the IMX series serial ports.
+ * TODO:
+ *  -- implement FIFOs.  The real hardware has 32 word transmit
+ *   and receive FIFOs; we currently use a 1-char buffer
+ *  -- implement DMA
+ *  -- implement BAUD-rate and modem lines, for when the backend
+ * is a real serial device.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "sysemu.h"
+#include "qemu-char.h"
+#include "imx.h"
+
+//#define DEBUG_SERIAL 1
+#ifdef DEBUG_SERIAL
+#define DPRINTF(fmt, args...) \
+do { printf("imx_serial: " 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
+#ifdef DEBUG_IMPLEMENTATION
+#  define IPRINTF(fmt, args...) \
+do  { fprintf(stderr, "imx_serial: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+int32_t readbuff;
+
+uint32_t usr1;
+uint32_t usr2;
+uint32_t ucr1;
+uint32_t ucr2;
+uint32_t uts1;
+
+/*
+ * The registers below are implemented just so that the
+ * guest OS sees what it has written
+ */
+uint32_t onems;
+uint32_t ufcr;
+uint32_t ubmr;
+uint32_t ubrc;
+uint32_t ucr3;
+
+qemu_irq irq;
+CharDriverState *chr;
+} IMXSerialState;
+
+static const VMStateDescription vmstate_imx_serial = {
+.name = "imx-serial",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_INT32(readbuff, IMXSerialState),
+VMSTATE_UINT32(usr1, IMXSerialState),
+VMSTATE_UINT32(usr2, IMXSerialState),
+VMSTATE_UINT32(ucr1, IMXSerialState),
+VMSTATE_UINT32(uts1, IMXSerialState),
+VMSTATE_UINT32(onems, IMXSerialState),
+VMSTATE_UINT32(ufcr, IMXSerialState),
+VMSTATE_UINT32(ubmr, IMXSerialState),
+VMSTATE_UINT32(ubrc, IMXSerialState),
+VMSTATE_UINT32(ucr3, IMXSerialState),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+#define URXD_CHARRDY(1<<15)   /* character read is valid */
+#define URXD_ERR(1<<14)   /* Character has error */
+#define URXD_BRK(1<<11)   /* Break received */
+
+#define USR1_PARTYER(1<<15)   /* Parity Error */
+#define USR1_RTSS   (1<<14)   /* RTS pin status */
+#define USR1_TRDY   (1<<13)   /* Tx ready */
+#define USR1_RTSD   (1<<12)   /* RTS delta: pin changed state */
+#define USR1_ESCF   (1<<11)   /* Escape sequence interrupt */
+#define USR1_FRAMERR(1<<10)   /* Framing error  */
+

[Qemu-devel] [Patch V10 2/5] i.MX31: Clock Control Module

2012-06-19 Thread Peter Chubb
For Linux to be able to work out how fast its clocks are going, so
that timer ticks come approximately at the right time, it needs to
be able to query the clock control module (CCM). 

This is the start of a CCM implementation.  It currently knows only about 
the MCU, HSP and IPG clocks --- i.e., the ones used to feed the periodic 
and general purpose timers.

Signed-off-by: Peter Chubb 

---
 hw/arm/Makefile.objs |2 
 hw/imx.h |   10 +
 hw/imx_ccm.c |  321 +++
 3 files changed, 332 insertions(+), 1 deletion(-)

Index: qemu-working/hw/arm/Makefile.objs
===
--- qemu-working.orig/hw/arm/Makefile.objs  2012-06-20 09:13:59.968582831 
+1000
+++ qemu-working/hw/arm/Makefile.objs   2012-06-20 09:14:00.692586643 +1000
@@ -34,7 +34,7 @@ obj-y += framebuffer.o
 obj-y += vexpress.o
 obj-y += strongarm.o
 obj-y += collie.o
-obj-y += imx_serial.o
+obj-y += imx_serial.o imx_ccm.o
 obj-y += pl041.o lm4549.o
 obj-$(CONFIG_FDT) += ../device_tree.o
 
Index: qemu-working/hw/imx.h
===
--- qemu-working.orig/hw/imx.h  2012-06-20 09:13:59.968582831 +1000
+++ qemu-working/hw/imx.h   2012-06-20 09:14:00.696586665 +1000
@@ -13,4 +13,14 @@
 
 void imx_serial_create(int uart, const target_phys_addr_t addr, qemu_irq irq);
 
+typedef enum  {
+NOCLK,
+MCU,
+HSP,
+IPG,
+CLK_32k
+} IMXClk;
+
+uint32_t imx_clock_frequency(DeviceState *s, IMXClk clock);
+
 #endif /* IMX_H */
Index: qemu-working/hw/imx_ccm.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_ccm.c   2012-06-20 09:14:00.696586665 +1000
@@ -0,0 +1,321 @@
+/*
+ * IMX31 Clock Control Module
+ *
+ * Copyright (C) 2012 NICTA
+ *
+ * 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.h"
+#include "sysbus.h"
+#include "sysemu.h"
+#include "imx.h"
+
+#define CKIH_FREQ 2600 /* 26MHz crystal input */
+#define CKIL_FREQ32768 /* nominal 32khz clock */
+
+
+//#define DEBUG_CCM 1
+#ifdef DEBUG_CCM
+#define DPRINTF(fmt, args...) \
+do { printf("imx_ccm: " fmt , ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...) do {} while (0)
+#endif
+
+static int imx_ccm_post_load(void *opaque, int version_id);
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+
+uint32_t ccmr;
+uint32_t pdr0;
+uint32_t pdr1;
+uint32_t mpctl;
+uint32_t spctl;
+uint32_t cgr[3];
+uint32_t pmcr0;
+uint32_t pmcr1;
+
+/* Frequencies precalculated on register changes */
+uint32_t pll_refclk_freq;
+uint32_t mcu_clk_freq;
+uint32_t hsp_clk_freq;
+uint32_t ipg_clk_freq;
+} IMXCCMState;
+
+static const VMStateDescription vmstate_imx_ccm = {
+.name = "imx-ccm",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(ccmr, IMXCCMState),
+VMSTATE_UINT32(pdr0, IMXCCMState),
+VMSTATE_UINT32(pdr1, IMXCCMState),
+VMSTATE_UINT32(mpctl, IMXCCMState),
+VMSTATE_UINT32(spctl, IMXCCMState),
+VMSTATE_UINT32_ARRAY(cgr, IMXCCMState, 3),
+VMSTATE_UINT32(pmcr0, IMXCCMState),
+VMSTATE_UINT32(pmcr1, IMXCCMState),
+VMSTATE_UINT32(pll_refclk_freq, IMXCCMState),
+},
+.post_load = imx_ccm_post_load,
+};
+
+/* CCMR */
+#define CCMR_FPME (1<<0)
+#define CCMR_MPE  (1<<3)
+#define CCMR_MDS  (1<<7)
+#define CCMR_FPMF (1<<26)
+#define CCMR_PRCS (3<<1)
+
+/* PDR0 */
+#define PDR0_MCU_PODF_SHIFT (0)
+#define PDR0_MCU_PODF_MASK (0x7)
+#define PDR0_MAX_PODF_SHIFT (3)
+#define PDR0_MAX_PODF_MASK (0x7)
+#define PDR0_IPG_PODF_SHIFT (6)
+#define PDR0_IPG_PODF_MASK (0x3)
+#define PDR0_NFC_PODF_SHIFT (8)
+#define PDR0_NFC_PODF_MASK (0x7)
+#define PDR0_HSP_PODF_SHIFT (11)
+#define PDR0_HSP_PODF_MASK (0x7)
+#define PDR0_PER_PODF_SHIFT (16)
+#define PDR0_PER_PODF_MASK (0x1f)
+#define PDR0_CSI_PODF_SHIFT (23)
+#define PDR0_CSI_PODF_MASK (0x1ff)
+
+#define EXTRACT(value, name) (((value) >> PDR0_##name##_PODF_SHIFT) \
+  & PDR0_##name##_PODF_MASK)
+#define INSERT(value, name) (((value) & PDR0_##name##_PODF_MASK) << \
+ PDR0_##name##_PODF_SHIFT)
+/* PLL control registers */
+#define PD(v) (((v) >> 26) & 0xf)
+#define MFD(v) (((v) >> 16) & 0x3ff)
+#define MFI(v) (((v) >> 10) & 0xf);
+#define MFN(v) ((v) & 0x3ff)
+
+#define PLL_PD(x)   (((x) & 0xf) << 26)
+#define PLL_MFD(x)  (((x) & 0x3ff) <

[Qemu-devel] [Patch V10 5/5] i.MX31: KZM-ARM11-01 evaluation board

2012-06-19 Thread Peter Chubb
Board support for Kyoto Micro's KZM-ARM11-01, an evaluation board built
around the Freescale i.MX31.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 

---
 MAINTAINERS  |6 +
 hw/arm/Makefile.objs |1 
 hw/kzm.c |  154 +++
 3 files changed, 161 insertions(+)
 create mode 100644 hw/kzm.c

Index: qemu-working/MAINTAINERS
===
--- qemu-working.orig/MAINTAINERS   2012-06-20 09:31:58.311046949 +1000
+++ qemu-working/MAINTAINERS2012-06-20 09:33:32.927501381 +1000
@@ -207,6 +207,12 @@ M: qemu-devel@nongnu.org
 S: Orphan
 F: hw/gumstix.c
 
+i.MX31
+M: Peter Chubb 
+S: Odd fixes
+F: hw/imx*
+F: hw/kzm.c
+
 Integrator CP
 M: Paul Brook 
 M: Peter Maydell 
Index: qemu-working/hw/arm/Makefile.objs
===
--- qemu-working.orig/hw/arm/Makefile.objs  2012-06-20 09:32:12.659116627 
+1000
+++ qemu-working/hw/arm/Makefile.objs   2012-06-20 09:32:15.847132070 +1000
@@ -35,6 +35,7 @@ obj-y += vexpress.o
 obj-y += strongarm.o
 obj-y += collie.o
 obj-y += imx_serial.o imx_ccm.o imx_timer.o imx_avic.o
+obj-y += kzm.o
 obj-y += pl041.o lm4549.o
 obj-$(CONFIG_FDT) += ../device_tree.o
 
Index: qemu-working/hw/kzm.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/kzm.c   2012-06-20 09:32:15.851132090 +1000
@@ -0,0 +1,154 @@
+/*
+ * KZM Board System emulation.
+ *
+ * Copyright (c) 2008 OKL and 2011 NICTA
+ * Written by Hans at OK-Labs
+ * Updated by Peter Chubb.
+ *
+ * This code is licenced under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a Kyoto Microcomputer
+ * KZM-ARM11-01 evaluation board, with a Freescale
+ * i.MX31 SoC
+ */
+
+#include "sysbus.h"
+#include "exec-memory.h"
+#include "hw.h"
+#include "arm-misc.h"
+#include "devices.h"
+#include "net.h"
+#include "sysemu.h"
+#include "boards.h"
+#include "pc.h" /* for the FPGA UART that emulates a 16550 */
+#include "imx.h"
+
+/* Memory map for Kzm Emulation Baseboard:
+ * 0x-0x3fff 16k secure ROM   IGNORED
+ * 0x4000-0x00407fff Reserved IGNORED
+ * 0x00404000-0x00407fff ROM  IGNORED
+ * 0x00408000-0x0fff Reserved IGNORED
+ * 0x1000-0x1fffbfff RAM aliasing IGNORED
+ * 0x1fffc000-0x1fff RAM  EMULATED
+ * 0x2000-0x2fff Reserved IGNORED
+ * 0x3000-0x7fff I.MX31 Internal Register Space
+ *   0x43f0 IO_AREA0
+ *   0x43f9 UART1 EMULATED
+ *   0x43f94000 UART2 EMULATED
+ *   0x6800 AVIC  EMULATED
+ *   0x53f8 CCM   EMULATED
+ *   0x53f94000 PIT 1 EMULATED
+ *   0x53f98000 PIT 2 EMULATED
+ *   0x53f9 GPT   EMULATED
+ * 0x8000-0x87ff RAM  EMULATED
+ * 0x8800-0x8fff RAM Aliasing EMULATED
+ * 0xa000-0xafff NAND Flash   IGNORED
+ * 0xb000-0xb3ff Unavailable  IGNORED
+ * 0xb400-0xb4000fff 8-bit free space IGNORED
+ * 0xb4001000-0xb400100f Board controlIGNORED
+ *  0xb4001003   DIP switch
+ * 0xb4001010-0xb400101f 7-segment LEDIGNORED
+ * 0xb4001020-0xb400102f LED  IGNORED
+ * 0xb4001030-0xb400103f LED  IGNORED
+ * 0xb4001040-0xb400104f FPGA, UART   EMULATED
+ * 0xb4001050-0xb400105f FPGA, UART   EMULATED
+ * 0xb4001060-0xb40f FPGA IGNORED
+ * 0xb600-0xb61f LAN controller   EMULATED
+ * 0xb620-0xb62f FPGA NAND Controller IGNORED
+ * 0xb630-0xb7ff Free IGNORED
+ * 0xb800-0xb8004fff Memory control registers IGNORED
+ * 0xc000-0xc3ff PCMCIA/CFIGNORED
+ * 0xc400-0x Reserved IGNORED
+ */
+
+#define KZM_RAMADDRESS (0x8000)
+#define KZM_FPGA   (0xb4001040)
+
+static struct arm_boot_info kzm_binfo = {
+.loader_start = KZM_RAMADDRESS,
+.board_id = 1722,
+};
+
+static void kzm_init(ram_addr_t ram_size,
+ const char *boot_device,
+ const char *kernel_filename, const char *kernel_cmdline,
+ const char *initrd_filename, const char *cpu_model)
+{
+ARMCPU *cpu;
+MemoryRegion *address_space_mem = get_system_memory();
+MemoryRegion *ram = g_new(MemoryRegion, 1);
+MemoryRegion *sram = g_new(Mem

[Qemu-devel] [Patch V10 0/5] i.MX31: Add initial support

2012-06-19 Thread Peter Chubb
Changes since V9: Added MAINTAINERS entry, rebased (and tested)
against git tip.


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] Broken Microblaze timer

2012-06-14 Thread Peter Chubb
>>>>> "Peter" == Peter Crosthwaite  writes:

Peter> So ptimer has safeguards against misuse in periodic mode but
Peter> not one-shot mode? This strikes me as inconsistent. I.E. for
Peter> one use case the safeguard is in ptimer, and the other in the
Peter> client device. I think if we are in the bussiness of putting
Peter> these safeguards in ptimer itself then it should be there for
Peter> all use cases yes? I.E. the fix for this is making sure
Peter> one-shot ptimer give the cpu a look in.

When a one-shot timer fires, it has to be reset by the CPU before
it'll fire again.  So the CPU always gets a look in --- or ought to.

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



Re: [Qemu-devel] Broken Microblaze timer

2012-06-14 Thread Peter Chubb
>>>>> "Paolo" == Paolo Bonzini  writes:

Paolo> Il 14/06/2012 04:29, Peter Crosthwaite ha scritto:
>> Obviously this sucks as a patch, but without this hack, the system
>> freezes on boot. I managed to ascertain that its coming from the
>> ptimer used by the system timer (hw/xilinx_timer.c). The CPU is
>> either halted and never resumes, or the timer is flooding with halt
>> requests and the CPU never gets another look in.
>> 
>> The question is, is this a failure in ptimer, xilinx_timer or the
>> async framework? Can ptimer be misused such that the CPU is locked
>> up?

Paolo> Yes, this looks like the ptimer is flooding the iothread so
Paolo> that the CPU does not get an occasion to run.

Paolo> Perhaps you want to limit the rate of the hw/xilinx_timer.c to
Paolo> something like 1000 Hz or something like that.

Changeset cf36b31db209a261ee3bc2737e788e1ced0a1bec Limit ptimer rate
to something achievable
is meant to fix this in the cases where the timer is auto-reloaded.

xilinx_timer.c always uses the timer in one-shot mode, so it needs to
be fixed in there.



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



[Qemu-devel] [patch V9 5/5] i.MX31: KZM-ARM11-01 evaluation board

2012-06-06 Thread peter . chubb
Board support for Kyoto Micro's KZM-ARM11-01, an evaluation board built
around the Freescale i.MX31.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 

---
 Makefile.target |2 
 hw/kzm.c|  156 
 2 files changed, 157 insertions(+), 1 deletion(-)
 create mode 100644 hw/kzm.c

Index: qemu-working/Makefile.target
===
--- qemu-working.orig/Makefile.target   2012-06-07 11:32:03.972100328 +1000
+++ qemu-working/Makefile.target2012-06-07 11:32:06.004117344 +1000
@@ -368,7 +368,7 @@ obj-arm-y += vexpress.o
 obj-arm-y += strongarm.o
 obj-arm-y += collie.o
 obj-arm-y += pl041.o lm4549.o
-obj-arm-y += imx_serial.o imx_ccm.o imx_timer.o imx_avic.o
+obj-arm-y += imx_serial.o imx_ccm.o imx_timer.o imx_avic.o kzm.o
 obj-arm-$(CONFIG_FDT) += device_tree.o
 
 obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
Index: qemu-working/hw/kzm.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/kzm.c   2012-06-07 11:32:06.004117344 +1000
@@ -0,0 +1,156 @@
+/*
+ * KZM Board System emulation.
+ *
+ * Copyright (c) 2008 OKL and 2011 NICTA
+ * Written by Hans at OK-Labs
+ * Updated by Peter Chubb.
+ *
+ * This code is licenced under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a Kyoto Microcomputer
+ * KZM-ARM11-01 evaluation board, with a Freescale
+ * i.MX31 SoC
+ */
+
+#include "sysbus.h"
+#include "exec-memory.h"
+#include "hw.h"
+#include "arm-misc.h"
+#include "devices.h"
+#include "net.h"
+#include "sysemu.h"
+#include "boards.h"
+#include "pc.h" /* for the FPGA UART that emulates a 16550 */
+#include "imx.h"
+
+/* Memory map for Kzm Emulation Baseboard:
+ * 0x-0x3fff 16k secure ROM   IGNORED
+ * 0x4000-0x00407fff Reserved IGNORED
+ * 0x00404000-0x00407fff ROM  IGNORED
+ * 0x00408000-0x0fff Reserved IGNORED
+ * 0x1000-0x1fffbfff RAM aliasing IGNORED
+ * 0x1fffc000-0x1fff RAM  EMULATED
+ * 0x2000-0x2fff Reserved IGNORED
+ * 0x3000-0x7fff I.MX31 Internal Register Space
+ *   0x43f0 IO_AREA0
+ *   0x43f9 UART1 EMULATED
+ *   0x43f94000 UART2 EMULATED
+ *   0x6800 AVIC  EMULATED
+ *   0x53f8 CCM   EMULATED
+ *   0x53f94000 PIT 1 EMULATED
+ *   0x53f98000 PIT 2 EMULATED
+ *   0x53f9 GPT   EMULATED
+ * 0x8000-0x87ff RAM  EMULATED
+ * 0x8800-0x8fff RAM Aliasing EMULATED
+ * 0xa000-0xafff NAND Flash   IGNORED
+ * 0xb000-0xb3ff Unavailable  IGNORED
+ * 0xb400-0xb4000fff 8-bit free space IGNORED
+ * 0xb4001000-0xb400100f Board controlIGNORED
+ *  0xb4001003   DIP switch
+ * 0xb4001010-0xb400101f 7-segment LEDIGNORED
+ * 0xb4001020-0xb400102f LED  IGNORED
+ * 0xb4001030-0xb400103f LED  IGNORED
+ * 0xb4001040-0xb400104f FPGA, UART   EMULATED
+ * 0xb4001050-0xb400105f FPGA, UART   EMULATED
+ * 0xb4001060-0xb40f FPGA IGNORED
+ * 0xb600-0xb61f LAN controller   EMULATED
+ * 0xb620-0xb62f FPGA NAND Controller IGNORED
+ * 0xb630-0xb7ff Free IGNORED
+ * 0xb800-0xb8004fff Memory control registers IGNORED
+ * 0xc000-0xc3ff PCMCIA/CFIGNORED
+ * 0xc400-0x Reserved IGNORED
+ */
+
+#define KZM_RAMADDRESS (0x8000)
+#define KZM_FPGA   (0xb4001040)
+
+static struct arm_boot_info kzm_binfo = {
+.loader_start = KZM_RAMADDRESS,
+.board_id = 1722,
+};
+
+static void kzm_init(ram_addr_t ram_size,
+ const char *boot_device,
+ const char *kernel_filename, const char *kernel_cmdline,
+ const char *initrd_filename, const char *cpu_model)
+{
+ARMCPU *cpu;
+CPUARMState *env;
+MemoryRegion *address_space_mem = get_system_memory();
+MemoryRegion *ram = g_new(MemoryRegion, 1);
+MemoryRegion *sram = g_new(MemoryRegion, 1);
+MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
+qemu_irq *cpu_pic;
+DeviceState *dev;
+DeviceState *ccm;
+
+if (!cpu_model) {
+cpu_model = "arm1136";
+}
+
+cpu = arm_cpu_init(cpu_model);
+if (!cpu) {
+fprintf(stderr, "Unable to find 

[Qemu-devel] [patch V9 1/5] i.MX: UART support

2012-06-06 Thread peter . chubb
Implement the Freescale i.MX UART.  This uart is used in a variety of
SoCs, including some by Motorola, as well as in the Freescale i.MX
series.

This patch gives only a `bare-bones' implementation, enough to run Linux 
or OKL4, but that's about it.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
Reviewed-by: Peter Maydell 
---
 Makefile.target |1 
 hw/imx.h|   16 +
 hw/imx_serial.c |  467 
 3 files changed, 484 insertions(+)
 create mode 100644 hw/imx_serial.c

Index: qemu-working/Makefile.target
===
--- qemu-working.orig/Makefile.target   2012-06-07 11:31:58.972058181 +1000
+++ qemu-working/Makefile.target2012-06-07 11:32:00.460070764 +1000
@@ -368,6 +368,7 @@ obj-arm-y += vexpress.o
 obj-arm-y += strongarm.o
 obj-arm-y += collie.o
 obj-arm-y += pl041.o lm4549.o
+obj-arm-y += imx_serial.o
 obj-arm-$(CONFIG_FDT) += device_tree.o
 
 obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
Index: qemu-working/hw/imx.h
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx.h   2012-06-07 11:32:00.460070764 +1000
@@ -0,0 +1,16 @@
+/*
+ * i.MX31 emulation
+ *
+ * Copyright (C) 2012 Peter Chubb
+ * NICTA
+ *
+ * This code is released under the GPL, version 2.0 or later
+ * See the file `../COPYING' for details.
+ */
+
+#ifndef IMX_H
+#define IMX_H
+
+void imx_serial_create(int uart, const target_phys_addr_t addr, qemu_irq irq);
+
+#endif /* IMX_H */
Index: qemu-working/hw/imx_serial.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_serial.c2012-06-07 11:32:00.460070764 +1000
@@ -0,0 +1,467 @@
+/*
+ * IMX31 UARTS
+ *
+ * Copyright (c) 2008 OKL
+ * Originally Written by Hans Jiang
+ * Copyright (c) 2011 NICTA Pty Ltd.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * This is a `bare-bones' implementation of the IMX series serial ports.
+ * TODO:
+ *  -- implement FIFOs.  The real hardware has 32 word transmit
+ *   and receive FIFOs; we currently use a 1-char buffer
+ *  -- implement DMA
+ *  -- implement BAUD-rate and modem lines, for when the backend
+ * is a real serial device.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "sysemu.h"
+#include "qemu-char.h"
+#include "imx.h"
+
+//#define DEBUG_SERIAL 1
+#ifdef DEBUG_SERIAL
+#define DPRINTF(fmt, args...) \
+do { printf("imx_serial: " 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
+#ifdef DEBUG_IMPLEMENTATION
+#  define IPRINTF(fmt, args...) \
+do  { fprintf(stderr, "imx_serial: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+int32_t readbuff;
+
+uint32_t usr1;
+uint32_t usr2;
+uint32_t ucr1;
+uint32_t ucr2;
+uint32_t uts1;
+
+/*
+ * The registers below are implemented just so that the
+ * guest OS sees what it has written
+ */
+uint32_t onems;
+uint32_t ufcr;
+uint32_t ubmr;
+uint32_t ubrc;
+uint32_t ucr3;
+
+qemu_irq irq;
+CharDriverState *chr;
+} IMXSerialState;
+
+static const VMStateDescription vmstate_imx_serial = {
+.name = "imx-serial",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_INT32(readbuff, IMXSerialState),
+VMSTATE_UINT32(usr1, IMXSerialState),
+VMSTATE_UINT32(usr2, IMXSerialState),
+VMSTATE_UINT32(ucr1, IMXSerialState),
+VMSTATE_UINT32(uts1, IMXSerialState),
+VMSTATE_UINT32(onems, IMXSerialState),
+VMSTATE_UINT32(ufcr, IMXSerialState),
+VMSTATE_UINT32(ubmr, IMXSerialState),
+VMSTATE_UINT32(ubrc, IMXSerialState),
+VMSTATE_UINT32(ucr3, IMXSerialState),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+#define URXD_CHARRDY(1<<15)   /* character read is valid */
+#define URXD_ERR(1<<14)   /* Character has error */
+#define URXD_BRK(1<<11)   /* Break received */
+
+#define USR1_PARTYER(1<<15)   /* Parity Error */
+#define USR1_RTSS   (1<<14)   /* RTS pin status */
+#define USR1_TRDY   (1<<13)   /* Tx ready */
+#define USR1_RTSD   (1<<12)   /* RTS delta: pin changed state */
+#define USR1_ESCF   (1<<11)   /* Escape sequence interrupt */
+#define USR1_FRAM

[Qemu-devel] [patch V9 2/5] i.MX31: Clock Control Module

2012-06-06 Thread peter . chubb
For Linux to be able to work out how fast its clocks are going, so
that timer ticks come approximately at the right time, it needs to
be able to query the clock control module (CCM). 

This is the start of a CCM implementation.  It currently knows only about 
the MCU, HSP and IPG clocks --- i.e., the ones used to feed the periodic 
and general purpose timers.

Signed-off-by: Peter Chubb 

---
 Makefile.target |2 
 hw/imx.h|   10 +
 hw/imx_ccm.c|  321 
 3 files changed, 332 insertions(+), 1 deletion(-)

Index: qemu-working/Makefile.target
===
--- qemu-working.orig/Makefile.target   2012-06-07 11:32:00.788073534 +1000
+++ qemu-working/Makefile.target2012-06-07 11:32:01.548079944 +1000
@@ -368,7 +368,7 @@ obj-arm-y += vexpress.o
 obj-arm-y += strongarm.o
 obj-arm-y += collie.o
 obj-arm-y += pl041.o lm4549.o
-obj-arm-y += imx_serial.o
+obj-arm-y += imx_serial.o imx_ccm.o
 obj-arm-$(CONFIG_FDT) += device_tree.o
 
 obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
Index: qemu-working/hw/imx.h
===
--- qemu-working.orig/hw/imx.h  2012-06-07 11:32:00.788073534 +1000
+++ qemu-working/hw/imx.h   2012-06-07 11:32:01.548079944 +1000
@@ -13,4 +13,14 @@
 
 void imx_serial_create(int uart, const target_phys_addr_t addr, qemu_irq irq);
 
+typedef enum  {
+NOCLK,
+MCU,
+HSP,
+IPG,
+CLK_32k
+} IMXClk;
+
+uint32_t imx_clock_frequency(DeviceState *s, IMXClk clock);
+
 #endif /* IMX_H */
Index: qemu-working/hw/imx_ccm.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_ccm.c   2012-06-07 11:32:01.552079977 +1000
@@ -0,0 +1,321 @@
+/*
+ * IMX31 Clock Control Module
+ *
+ * Copyright (C) 2012 NICTA
+ *
+ * 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.h"
+#include "sysbus.h"
+#include "sysemu.h"
+#include "imx.h"
+
+#define CKIH_FREQ 2600 /* 26MHz crystal input */
+#define CKIL_FREQ32768 /* nominal 32khz clock */
+
+
+//#define DEBUG_CCM 1
+#ifdef DEBUG_CCM
+#define DPRINTF(fmt, args...) \
+do { printf("imx_ccm: " fmt , ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...) do {} while (0)
+#endif
+
+static int imx_ccm_post_load(void *opaque, int version_id);
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+
+uint32_t ccmr;
+uint32_t pdr0;
+uint32_t pdr1;
+uint32_t mpctl;
+uint32_t spctl;
+uint32_t cgr[3];
+uint32_t pmcr0;
+uint32_t pmcr1;
+
+/* Frequencies precalculated on register changes */
+uint32_t pll_refclk_freq;
+uint32_t mcu_clk_freq;
+uint32_t hsp_clk_freq;
+uint32_t ipg_clk_freq;
+} IMXCCMState;
+
+static const VMStateDescription vmstate_imx_ccm = {
+.name = "imx-ccm",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(ccmr, IMXCCMState),
+VMSTATE_UINT32(pdr0, IMXCCMState),
+VMSTATE_UINT32(pdr1, IMXCCMState),
+VMSTATE_UINT32(mpctl, IMXCCMState),
+VMSTATE_UINT32(spctl, IMXCCMState),
+VMSTATE_UINT32_ARRAY(cgr, IMXCCMState, 3),
+VMSTATE_UINT32(pmcr0, IMXCCMState),
+VMSTATE_UINT32(pmcr1, IMXCCMState),
+VMSTATE_UINT32(pll_refclk_freq, IMXCCMState),
+},
+.post_load = imx_ccm_post_load,
+};
+
+/* CCMR */
+#define CCMR_FPME (1<<0)
+#define CCMR_MPE  (1<<3)
+#define CCMR_MDS  (1<<7)
+#define CCMR_FPMF (1<<26)
+#define CCMR_PRCS (3<<1)
+
+/* PDR0 */
+#define PDR0_MCU_PODF_SHIFT (0)
+#define PDR0_MCU_PODF_MASK (0x7)
+#define PDR0_MAX_PODF_SHIFT (3)
+#define PDR0_MAX_PODF_MASK (0x7)
+#define PDR0_IPG_PODF_SHIFT (6)
+#define PDR0_IPG_PODF_MASK (0x3)
+#define PDR0_NFC_PODF_SHIFT (8)
+#define PDR0_NFC_PODF_MASK (0x7)
+#define PDR0_HSP_PODF_SHIFT (11)
+#define PDR0_HSP_PODF_MASK (0x7)
+#define PDR0_PER_PODF_SHIFT (16)
+#define PDR0_PER_PODF_MASK (0x1f)
+#define PDR0_CSI_PODF_SHIFT (23)
+#define PDR0_CSI_PODF_MASK (0x1ff)
+
+#define EXTRACT(value, name) (((value) >> PDR0_##name##_PODF_SHIFT) \
+  & PDR0_##name##_PODF_MASK)
+#define INSERT(value, name) (((value) & PDR0_##name##_PODF_MASK) << \
+ PDR0_##name##_PODF_SHIFT)
+/* PLL control registers */
+#define PD(v) (((v) >> 26) & 0xf)
+#define MFD(v) (((v) >> 16) & 0x3ff)
+#define MFI(v) (((v) >> 10) & 0xf);
+#define MFN(v) ((v) & 0x3ff)
+
+#define PLL_PD(x)   (((x) & 0xf) << 26)
+#defi

[Qemu-devel] [patch V9 3/5] i.MX31: Timers

2012-06-06 Thread peter . chubb
Implement the timers on the Freescale i.MX31 SoC.
This is not a complete implementation, but gives enough for 
Linux to boot and run. In particular external triggers, which are 
not useful under QEMU, are not implemented.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
---
 Makefile.target |2 
 hw/imx.h|8 
 hw/imx_timer.c  |  689 
 3 files changed, 698 insertions(+), 1 deletion(-)
 create mode 100644 hw/imx_timer.c

Index: qemu-working/Makefile.target
===
--- qemu-working.orig/Makefile.target   2012-06-07 11:32:01.892082843 +1000
+++ qemu-working/Makefile.target2012-06-07 11:32:02.612088902 +1000
@@ -368,7 +368,7 @@ obj-arm-y += vexpress.o
 obj-arm-y += strongarm.o
 obj-arm-y += collie.o
 obj-arm-y += pl041.o lm4549.o
-obj-arm-y += imx_serial.o imx_ccm.o
+obj-arm-y += imx_serial.o imx_ccm.o imx_timer.o
 obj-arm-$(CONFIG_FDT) += device_tree.o
 
 obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
Index: qemu-working/hw/imx.h
===
--- qemu-working.orig/hw/imx.h  2012-06-07 11:32:01.892082843 +1000
+++ qemu-working/hw/imx.h   2012-06-07 11:32:02.616088936 +1000
@@ -23,4 +23,12 @@ typedef enum  {
 
 uint32_t imx_clock_frequency(DeviceState *s, IMXClk clock);
 
+void imx_timerp_create(const target_phys_addr_t addr,
+  qemu_irq irq,
+  DeviceState *ccm);
+void imx_timerg_create(const target_phys_addr_t addr,
+  qemu_irq irq,
+  DeviceState *ccm);
+
+
 #endif /* IMX_H */
Index: qemu-working/hw/imx_timer.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_timer.c 2012-06-07 11:32:02.616088936 +1000
@@ -0,0 +1,689 @@
+/*
+ * IMX31 Timer
+ *
+ * Copyright (c) 2008 OK Labs
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally Written by Hans Jiang
+ * Updated by Peter Chubb
+ *
+ * This code is licenced under GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw.h"
+#include "qemu-timer.h"
+#include "ptimer.h"
+#include "sysbus.h"
+#include "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
+
+/*
+ * GPT : General purpose timer
+ *
+ * This timer counts up continuously while it is enabled, resetting itself
+ * to 0 when it reaches TIMER_MAX (in freerun mode) or when it
+ * reaches the value of ocr1 (in periodic mode).  WE simulate this using a
+ * QEMU ptimer counting down from ocr1 and reloading from ocr1 in
+ * periodic mode, or counting from ocr1 to zero, then TIMER_MAX - ocr1.
+ * waiting_rov is set when counting from TIMER_MAX.
+ *
+ * In the real hardware, there are three comparison registers that can
+ * trigger interrupts, and compare channel 1 can be used to
+ * force-reset the timer. However, this is a `bare-bones'
+ * implementation: only what Linux 3.x uses has been implemented
+ * (free-running timer from 0 to OCR1 or TIMER_MAX) .
+ */
+
+
+#define TIMER_MAX  0XUL
+
+/* Control register.  Not all of these bits have any effect (yet) */
+#define GPT_CR_EN (1 << 0)  /* GPT Enable */
+#define GPT_CR_ENMOD  (1 << 1)  /* GPT Enable Mode */
+#define GPT_CR_DBGEN  (1 << 2)  /* GPT Debug mode enable */
+#define GPT_CR_WAITEN (1 << 3)  /* GPT Wait Mode Enable  */
+#define GPT_CR_DOZEN  (1 << 4)  /* GPT Doze mode enable */
+#define GPT_CR_STOPEN (1 << 5)  /* GPT Stop Mode Enable */
+#define GPT_CR_CLKSRC_SHIFT (6)
+#define GPT_CR_CLKSRC_MASK  (0x7)
+
+#define GPT_CR_FRR(1 << 9)  /* Freerun or Restart */
+#define GPT_CR_SWR(1 << 15) /* Software Reset */
+#define GPT_CR_IM1(3 << 16) /* Input capture channel 1 mode (2 bits) */
+#define GPT_CR_IM2(3 << 18) /* Input capture channel 2 mode (2 bits) */
+#define GPT_CR_OM1(7 << 20) /* Output Compare Channel 1 Mode (3 bits) */
+#define GPT_CR_OM2(7 << 23) /* Output Compare Channel 2 Mode (3 bits) */
+#define GPT_CR_OM3(7 << 26) /* Output Compare Channel 3 Mode (3 bits) */
+#define GPT_CR_FO1(1 << 29) /* Force Output Compare Channel 1 */
+#define GPT_CR_FO2(1 << 30) /* Force Output Compar

[Qemu-devel] [patch V9 4/5] i.MX31: Interrupt Controller

2012-06-06 Thread peter . chubb
Implement the Freescale i.MX31 advanced vectored interrupt controller, at least
to the extent it is used by Linux 3.x

Vectors are not implemented.

Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
Reviewed-by: Peter Maydell 

---
 Makefile.target |2 
 hw/imx_avic.c   |  408 
 2 files changed, 409 insertions(+), 1 deletion(-)
 create mode 100644 hw/imx_avic.c

Index: qemu-working/Makefile.target
===
--- qemu-working.orig/Makefile.target   2012-06-07 11:32:02.964091864 +1000
+++ qemu-working/Makefile.target2012-06-07 11:32:03.652097641 +1000
@@ -368,7 +368,7 @@ obj-arm-y += vexpress.o
 obj-arm-y += strongarm.o
 obj-arm-y += collie.o
 obj-arm-y += pl041.o lm4549.o
-obj-arm-y += imx_serial.o imx_ccm.o imx_timer.o
+obj-arm-y += imx_serial.o imx_ccm.o imx_timer.o imx_avic.o
 obj-arm-$(CONFIG_FDT) += device_tree.o
 
 obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
Index: qemu-working/hw/imx_avic.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_avic.c  2012-06-07 11:32:03.656097675 +1000
@@ -0,0 +1,408 @@
+/*
+ * i.MX31 Vectored Interrupt Controller
+ *
+ * Note this is NOT the PL192 provided by ARM, but
+ * a custom implementation by Freescale.
+ *
+ * Copyright (c) 2008 OKL
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally Written by Hans Jiang
+ *
+ * This code is licenced under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * TODO: implement vectors.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "host-utils.h"
+
+#define DEBUG_INT 1
+#undef DEBUG_INT /* comment out for debugging */
+
+#ifdef DEBUG_INT
+#define DPRINTF(fmt, args...) \
+do { printf("imx_avic: " 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_avic: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+#define IMX_AVIC_NUM_IRQS 64
+
+/* Interrupt Control Bits */
+#define ABFLAG (1<<25)
+#define ABFEN (1<<24)
+#define NIDIS (1<<22) /* Normal Interrupt disable */
+#define FIDIS (1<<21) /* Fast interrupt disable */
+#define NIAD  (1<<20) /* Normal Interrupt Arbiter Rise ARM level */
+#define FIAD  (1<<19) /* Fast Interrupt Arbiter Rise ARM level */
+#define NM(1<<18) /* Normal interrupt mode */
+
+
+#define PRIO_PER_WORD (sizeof(uint32_t) * 8 / 4)
+#define PRIO_WORDS (IMX_AVIC_NUM_IRQS/PRIO_PER_WORD)
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+uint64_t pending;
+uint64_t enabled;
+uint64_t is_fiq;
+uint32_t intcntl;
+uint32_t intmask;
+qemu_irq irq;
+qemu_irq fiq;
+uint32_t prio[PRIO_WORDS]; /* Priorities are 4-bits each */
+} IMXAVICState;
+
+static const VMStateDescription vmstate_imx_avic = {
+.name = "imx-avic",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT64(pending, IMXAVICState),
+VMSTATE_UINT64(enabled, IMXAVICState),
+VMSTATE_UINT64(is_fiq, IMXAVICState),
+VMSTATE_UINT32(intcntl, IMXAVICState),
+VMSTATE_UINT32(intmask, IMXAVICState),
+VMSTATE_UINT32_ARRAY(prio, IMXAVICState, PRIO_WORDS),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+
+static inline int imx_avic_prio(IMXAVICState *s, int irq)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+return 0xf & (s->prio[word] >> part);
+}
+
+static inline void imx_avic_set_prio(IMXAVICState *s, int irq, int prio)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+uint32_t mask = ~(0xf << part);
+s->prio[word] &= mask;
+s->prio[word] |= prio << part;
+}
+
+/* Update interrupts.  */
+static void imx_avic_update(IMXAVICState *s)
+{
+int i;
+uint64_t new = s->pending & s->enabled;
+uint64_t flags;
+
+flags = new & s->is_fiq;
+qemu_set_irq(s->fiq, !!flags);
+
+flags = new & ~s->is_fiq;
+if (!flags || (s->intmask == 0x1f)) {
+qemu_set_irq(s->irq, !!flags);
+return;
+}
+
+/*
+ * Take interrupt if there's a pending interrupt with
+ * priority higher than the value of intmask
+ */
+for (i = 0; i < IMX_AVIC_NUM_IRQS; i++) {
+if (flags & (1UL << i)) {
+if (imx_avic_prio(s, i) > s->intmask) {
+qemu_s

[Qemu-devel] [patch V9 0/5] i.MX31: Add initial support

2012-06-06 Thread peter . chubb
Changes since V8: Recovered my stuff-up from backup --- changes that
were in V7 are back in!
Andreas's comments addressed (except adding MAINTAINER field)
Peter Maydell's comments against V6/7 are addressed.

Peter C

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




[Qemu-devel] [patch] target-microblaze/translate.c fails to compile with gcc 4.7

2012-06-06 Thread Peter Chubb

n current qemu.git, I see:
 CCmicroblaze-softmmu/translate.o
/home/peterc/src/work/QEMU/qemu-working/target-microblaze/translate.c: In 
function ‘dec_store’:
/home/peterc/src/work/QEMU/qemu-working/target-microblaze/translate.c:1108:5: 
error: invalid initializer

This is the obvious fix:
---
 target-microblaze/translate.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: qemu-working/target-microblaze/translate.c
===
--- qemu-working.orig/target-microblaze/translate.c 2012-06-07 
10:52:56.210980100 +1000
+++ qemu-working/target-microblaze/translate.c  2012-06-07 11:47:19.682479289 
+1000
@@ -1105,7 +1105,7 @@ static void gen_store(DisasContext *dc,
 
 static void dec_store(DisasContext *dc)
 {
-TCGv t, *addr, swx_addr, r_check = 0;
+TCGv t, *addr, swx_addr, r_check;
 int swx_skip = 0;
 unsigned int size, rev = 0, ex = 0;
 

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



Re: [Qemu-devel] [patch v8 0/5] i.MX31 support

2012-06-06 Thread Peter Chubb
>>>>> "Andreas" == Andreas Färber  writes:

Andreas> Hello Peter, Am 06.06.2012 05:47, schrieb Peter Chubb:
>> There are no major changes since last time, just rebased to current
>> tip now that QEMU 1.2 is open.
>> 
>> For those who have come into the story late, this is a series of
>> patches to allow QEMU to emulate a Freescale i.MX31 on a Kyoto
>> Microsystems evaluation board.  It's pretty bare-bones, but runs
>> Linux and seL4 nicely.

Andreas> Something is wrong with the patch submission, they are shown
Andreas> as attachments and Thunderbird doesn't let me comment
Andreas> inline. Please use git-send-email to submit.

This is a known issue with some thunderbird versions --- Mozilla/Mime
support  is a bit weird when it comes to emails with a
Content-Disposition: inline with a filename.  

Andreas> Also the diffstat doesn't match the patch wrt file ordering,
Andreas> so it would be advisable to use git-format-patch.

Andreas> Our concept of topics in the subject seems to be troubling
Andreas> you, you have added " support" since v7 (still readable, so
Andreas> I'm okay) whereas what we usually use is a lower-case tag as
Andreas> described here plus an active description of what it's doing
Andreas> (e.g., "foo: Add/Introduce bar"):
Andreas> https://live.gnome.org/Git/CommitMessages

This series was broken in a couple of ways.  Please ignore it! (my
laptop got restored from a backup and in moving forward again I think
some changes that were in v7 got lost, including this one).

Andreas> On patch 5: Please use cpu_arm_init() in place of cpu_init()
Andreas> and prefer ARMCPU. This is already in qemu.git and many more
Andreas> conversions are in the QOM CPUState part 3 PULL and on
Andreas> qom-next.

I dunno what happened there.  I put that in, then the result wouldn;t
compile, so I reverted it.

Andreas> Also note that arm_pic_init_cpu() and arm_load_kernel() are
Andreas> being changed to take that ARMCPU, so this needs to be
Andreas> coordinated.

OK.

Andreas> Please remove the semicolon after machine_init() and check
Andreas> the indentation. After sysbus_create_varargs() for instance I
Andreas> spot one space too few and below for imx_serial_create()
Andreas> there's a double space.

OK.  Dunno why checkpatch didn't catch this.

Andreas> Please also make all your TypeInfos static const, probably
Andreas> same for QEMUMachine.

OK.

Andreas> The description sounds misleading: In qemu-system-arm all
Andreas> boards are ARM architecture, and your wording may sound as if
Andreas> the board were from ARM (Holdings plc) when it is from Kyoto
Andreas> Micro and uses a Freescale SoC.  Maybe also mention the exact
Andreas> board name from the commit message and mention i.MX31?

OK.

Andreas> s/I.MX31/i.MX31/ in the header?

Ok.
Andreas> On patch 4: There's an empty line after type_init(), please
Andreas> remove.
OK.

Andreas> On patch 3: In IMXTimerGState you're saving DeviceState
Andreas> *ccm. That should probably become a QOM link<> property,
Andreas> possibly after the initial submission.  CC'ing Paolo.

I'm not sure what this means.

Andreas> What should be considered as a second step is factoring out
Andreas> all the devices individually added to the board into an
Andreas> i.MX31 SoC, which has implications on how the devices are
Andreas> initialized (compare my recent prep_pci and Anthony's i440fx
Andreas> patches). For a less sophisticated way using functions check
Andreas> out exynos4210. The way it's done right now there's no
Andreas> distinction of what is on the SoC and what is on the board,
Andreas> so it needs to be done by you.

Let's get the first round in first.

Andreas> Missing is an entry to MAINTAINERS for this board and its
Andreas> exclusive devices, naming who is to be cc'ed on patches.

OK.

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



[Qemu-devel] [patch v8 5/5] i.MX31 support: KZM-ARM11-01 evaluation board

2012-06-05 Thread Peter Chubb
Board support for Kyoto Micro's KZM-ARM11-01, an evaluation board built
around the FreeScale i.MX31.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 

---
 Makefile.target |2 
 hw/kzm.c|  155 
 2 files changed, 156 insertions(+), 1 deletion(-)
 create mode 100644 hw/kzm.c

Index: qemu-working/hw/kzm.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/kzm.c   2012-06-06 13:42:24.031963326 +1000
@@ -0,0 +1,155 @@
+/*
+ * KZM Board System emulation.
+ *
+ * Copyright (c) 2008 OKL and 2011 NICTA
+ * Written by Hans
+ * Updated by Peter Chubb.
+ *
+ * This code is licenced under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a Kyoto Microcomputer
+ * KZM-ARM11-01 evaluation board, with a FreeScale
+ * I.MX31 SoC
+ */
+
+#include "sysbus.h"
+#include "exec-memory.h"
+#include "hw.h"
+#include "arm-misc.h"
+#include "devices.h"
+#include "net.h"
+#include "sysemu.h"
+#include "boards.h"
+#include "pc.h" /* for the FPGA UART that emulates a 16550 */
+#include "imx.h"
+
+/* Memory map for Kzm Emulation Baseboard:
+ * 0x-0x3fff 16k secure ROM   IGNORED
+ * 0x4000-0x00407fff Reserved IGNORED
+ * 0x00404000-0x00407fff ROM  IGNORED
+ * 0x00408000-0x0fff Reserved IGNORED
+ * 0x1000-0x1fffbfff RAM aliasing IGNORED
+ * 0x1fffc000-0x1fff RAM  EMULATED
+ * 0x2000-0x2fff Reserved IGNORED
+ * 0x3000-0x7fff I.MX31 Internal Register Space
+ *   0x43f0 IO_AREA0
+ *   0x43f9 UART1 EMULATED
+ *   0x43f94000 UART2 EMULATED
+ *   0x6800 AVIC  EMULATED
+ *   0x53f8 CCM   EMULATED
+ *   0x53f94000 PIT 1 EMULATED
+ *   0x53f98000 PIT 2 EMULATED
+ *   0x53f9 GPT   EMULATED
+ * 0x8000-0x87ff RAM  EMULATED
+ * 0x8800-0x8fff RAM Aliasing EMULATED
+ * 0xa000-0xafff NAND Flash   IGNORED
+ * 0xb000-0xb3ff Unavailable  IGNORED
+ * 0xb400-0xb4000fff 8-bit free space IGNORED
+ * 0xb4001000-0xb400100f Board controlIGNORED
+ *  0xb4001003   DIP switch
+ * 0xb4001010-0xb400101f 7-segment LEDIGNORED
+ * 0xb4001020-0xb400102f LED  IGNORED
+ * 0xb4001030-0xb400103f LED  IGNORED
+ * 0xb4001040-0xb400104f FPGA, UART   EMULATED
+ * 0xb4001050-0xb400105f FPGA, UART   EMULATED
+ * 0xb4001060-0xb40f FPGA IGNORED
+ * 0xb600-0xb61f LAN controller   EMULATED
+ * 0xb620-0xb62f FPGA NAND Controller IGNORED
+ * 0xb630-0xb7ff Free IGNORED
+ * 0xb800-0xb8004fff Memory control registers IGNORED
+ * 0xc000-0xc3ff PCMCIA/CFIGNORED
+ * 0xc400-0x Reserved IGNORED
+ */
+
+#define KZM_RAMADDRESS (0x8000)
+#define KZM_FPGA   (0xb4001040)
+
+static struct arm_boot_info kzm_binfo = {
+.loader_start = KZM_RAMADDRESS,
+.board_id = 1722,
+};
+
+static void kzm_init(ram_addr_t ram_size,
+ const char *boot_device,
+ const char *kernel_filename, const char *kernel_cmdline,
+ const char *initrd_filename, const char *cpu_model)
+{
+CPUARMState *env;
+MemoryRegion *address_space_mem = get_system_memory();
+MemoryRegion *ram = g_new(MemoryRegion, 1);
+MemoryRegion *sram = g_new(MemoryRegion, 1);
+MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
+qemu_irq *cpu_pic;
+DeviceState *dev;
+DeviceState *ccm;
+
+if (!cpu_model) {
+cpu_model = "arm1136";
+}
+
+env = cpu_init(cpu_model);
+if (!env) {
+fprintf(stderr, "Unable to find CPU definition\n");
+exit(1);
+}
+
+/* On a real system, the first 16k is a `secure boot rom' */
+
+memory_region_init_ram(ram, "kzm.ram", ram_size);
+vmstate_register_ram_global(ram);
+memory_region_add_subregion(address_space_mem, KZM_RAMADDRESS, ram);
+
+memory_region_init_alias(ram_alias, "ram.alias", ram, 0, ram_size);
+memory_region_add_subregion(address_space_mem, 0x8800, ram_alias);
+
+memory_region_init_ram(sram, "kzm.sram", 0x4000);
+memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
+
+
+cpu_pic = arm_pic_init_cpu(env);
+de

[Qemu-devel] [patch v8 2/5] i.MX31 support: Clock Control Module

2012-06-05 Thread Peter Chubb
For Linux to be able to work out how fast its clocks are going, so
that timer ticks come approximately at the right time, it needs to
be able to query the clock control module (CCM). 

This is the start of a CCM implementation.  It currently knows only about 
the MCU, HSP and IPG clocks --- i.e., the ones used to feed the periodic 
and general purpose timers.

Signed-off-by: Peter Chubb 

---
 Makefile.target |2 
 hw/imx.h|   10 +
 hw/imx_ccm.c|  321 
 3 files changed, 332 insertions(+), 1 deletion(-)

Index: qemu-working/Makefile.target
===
--- qemu-working.orig/Makefile.target   2012-06-06 13:42:16.455921401 +1000
+++ qemu-working/Makefile.target2012-06-06 13:42:19.335937338 +1000
@@ -365,7 +365,7 @@ obj-arm-y += vexpress.o
 obj-arm-y += strongarm.o
 obj-arm-y += collie.o
 obj-arm-y += pl041.o lm4549.o
-obj-arm-y += imx_serial.o
+obj-arm-y += imx_serial.o imx_ccm.o
 obj-arm-$(CONFIG_FDT) += device_tree.o
 
 obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
Index: qemu-working/hw/imx_ccm.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_ccm.c   2012-06-06 13:42:19.335937338 +1000
@@ -0,0 +1,321 @@
+/*
+ * IMX31 Clock Control Module
+ *
+ * Copyright (C) 2012 NICTA
+ *
+ * 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.h"
+#include "sysbus.h"
+#include "sysemu.h"
+#include "imx.h"
+
+#define CKIH_FREQ 2600 /* 26MHz crystal input */
+#define CKIL_FREQ32768 /* nominal 32khz clock */
+
+
+//#define DEBUG_CCM 1
+#ifdef DEBUG_CCM
+#define DPRINTF(fmt, args...) \
+do { printf("imx_ccm: " fmt , ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...) do {} while (0)
+#endif
+
+static int imx_ccm_post_load(void *opaque, int version_id);
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+
+uint32_t ccmr;
+uint32_t pdr0;
+uint32_t pdr1;
+uint32_t mpctl;
+uint32_t spctl;
+uint32_t cgr[3];
+uint32_t pmcr0;
+uint32_t pmcr1;
+
+/* Frequencies precalculated on register changes */
+uint32_t pll_refclk_freq;
+uint32_t mcu_clk_freq;
+uint32_t hsp_clk_freq;
+uint32_t ipg_clk_freq;
+} IMXCCMState;
+
+static const VMStateDescription vmstate_imx_ccm = {
+.name = "imx-ccm",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(ccmr, IMXCCMState),
+VMSTATE_UINT32(pdr0, IMXCCMState),
+VMSTATE_UINT32(pdr1, IMXCCMState),
+VMSTATE_UINT32(mpctl, IMXCCMState),
+VMSTATE_UINT32(spctl, IMXCCMState),
+VMSTATE_UINT32_ARRAY(cgr, IMXCCMState, 3),
+VMSTATE_UINT32(pmcr0, IMXCCMState),
+VMSTATE_UINT32(pmcr1, IMXCCMState),
+VMSTATE_UINT32(pll_refclk_freq, IMXCCMState),
+},
+.post_load = imx_ccm_post_load,
+};
+
+/* CCMR */
+#define CCMR_FPME (1<<0)
+#define CCMR_MPE  (1<<3)
+#define CCMR_MDS  (1<<7)
+#define CCMR_FPMF (1<<26)
+#define CCMR_PRCS (3<<1)
+
+/* PDR0 */
+#define PDR0_MCU_PODF_SHIFT (0)
+#define PDR0_MCU_PODF_MASK (0x7)
+#define PDR0_MAX_PODF_SHIFT (3)
+#define PDR0_MAX_PODF_MASK (0x7)
+#define PDR0_IPG_PODF_SHIFT (6)
+#define PDR0_IPG_PODF_MASK (0x3)
+#define PDR0_NFC_PODF_SHIFT (8)
+#define PDR0_NFC_PODF_MASK (0x7)
+#define PDR0_HSP_PODF_SHIFT (11)
+#define PDR0_HSP_PODF_MASK (0x7)
+#define PDR0_PER_PODF_SHIFT (16)
+#define PDR0_PER_PODF_MASK (0x1f)
+#define PDR0_CSI_PODF_SHIFT (23)
+#define PDR0_CSI_PODF_MASK (0x1ff)
+
+#define EXTRACT(value, name) (((value) >> PDR0_##name##_PODF_SHIFT) \
+  & PDR0_##name##_PODF_MASK)
+#define INSERT(value, name) (((value) & PDR0_##name##_PODF_MASK) << \
+ PDR0_##name##_PODF_SHIFT)
+/* PLL control registers */
+#define PD(v) (((v) >> 26) & 0xf)
+#define MFD(v) (((v) >> 16) & 0x3ff)
+#define MFI(v) (((v) >> 10) & 0xf);
+#define MFN(v) ((v) & 0x3ff)
+
+#define PLL_PD(x)   (((x) & 0xf) << 26)
+#define PLL_MFD(x)  (((x) & 0x3ff) << 16)
+#define PLL_MFI(x)  (((x) & 0xf) << 10)
+#define PLL_MFN(x)  (((x) & 0x3ff) << 0)
+
+uint32_t imx_clock_frequency(DeviceState *dev, IMXClk clock)
+{
+IMXCCMState *s = container_of(dev, IMXCCMState, busdev.qdev);
+
+switch (clock) {
+case NOCLK:
+return 0;
+case MCU:
+return s->mcu_clk_freq;
+case HSP:
+return s->hsp_clk_freq;
+case IPG:
+re

[Qemu-devel] [patch v8 1/5] i.MX UART support

2012-06-05 Thread Peter Chubb
Implement the FreeScale i.MX UART.  This uart is used in a variety of
SoCs, including some by Motorola, as well as in the FreeScale i.MX
series.

This patch gives only a `bare-bones' implementation, enough to run Linux 
or OKL4, but that's about it.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
Reviewed-by: Peter Maydell 
---
 Makefile.target |1 
 hw/imx.h|   16 +
 hw/imx_serial.c |  467 
 3 files changed, 484 insertions(+)
 create mode 100644 hw/imx_serial.c

Index: qemu-working/hw/imx_serial.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_serial.c2012-06-06 13:42:16.127919586 +1000
@@ -0,0 +1,467 @@
+/*
+ * IMX31 UARTS
+ *
+ * Copyright (c) 2008 OKL
+ * Originally Written by Hans Jiang
+ * Copyright (c) 2011 NICTA Pty Ltd.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * This is a `bare-bones' implementation of the IMX series serial ports.
+ * TODO:
+ *  -- implement FIFOs.  The real hardware has 32 word transmit
+ *   and receive FIFOs; we currently use a 1-char buffer
+ *  -- implement DMA
+ *  -- implement BAUD-rate and modem lines, for when the backend
+ * is a real serial device.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "sysemu.h"
+#include "qemu-char.h"
+#include "imx.h"
+
+//#define DEBUG_SERIAL 1
+#ifdef DEBUG_SERIAL
+#define DPRINTF(fmt, args...) \
+do { printf("imx_serial: " 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
+#ifdef DEBUG_IMPLEMENTATION
+#  define IPRINTF(fmt, args...) \
+do  { fprintf(stderr, "imx_serial: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+int32_t readbuff;
+
+uint32_t usr1;
+uint32_t usr2;
+uint32_t ucr1;
+uint32_t ucr2;
+uint32_t uts1;
+
+/*
+ * The registers below are implemented just so that the
+ * guest OS sees what it has written
+ */
+uint32_t onems;
+uint32_t ufcr;
+uint32_t ubmr;
+uint32_t ubrc;
+uint32_t ucr3;
+
+qemu_irq irq;
+CharDriverState *chr;
+} IMXSerialState;
+
+static const VMStateDescription vmstate_imx_serial = {
+.name = "imx-serial",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_INT32(readbuff, IMXSerialState),
+VMSTATE_UINT32(usr1, IMXSerialState),
+VMSTATE_UINT32(usr2, IMXSerialState),
+VMSTATE_UINT32(ucr1, IMXSerialState),
+VMSTATE_UINT32(uts1, IMXSerialState),
+VMSTATE_UINT32(onems, IMXSerialState),
+VMSTATE_UINT32(ufcr, IMXSerialState),
+VMSTATE_UINT32(ubmr, IMXSerialState),
+VMSTATE_UINT32(ubrc, IMXSerialState),
+VMSTATE_UINT32(ucr3, IMXSerialState),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+#define URXD_CHARRDY(1<<15)   /* character read is valid */
+#define URXD_ERR(1<<14)   /* Character has error */
+#define URXD_BRK(1<<11)   /* Break received */
+
+#define USR1_PARTYER(1<<15)   /* Parity Error */
+#define USR1_RTSS   (1<<14)   /* RTS pin status */
+#define USR1_TRDY   (1<<13)   /* Tx ready */
+#define USR1_RTSD   (1<<12)   /* RTS delta: pin changed state */
+#define USR1_ESCF   (1<<11)   /* Escape sequence interrupt */
+#define USR1_FRAMERR(1<<10)   /* Framing error  */
+#define USR1_RRDY   (1<<9)/* receiver ready */
+#define USR1_AGTIM  (1<<8)/* Aging timer interrupt */
+#define USR1_DTRD   (1<<7)/* DTR changed */
+#define USR1_RXDS   (1<<6)/* Receiver is idle */
+#define USR1_AIRINT (1<<5)/* Aysnch IR interrupt */
+#define USR1_AWAKE  (1<<4)/* Falling edge detected on RXd pin */
+
+#define USR2_ADET   (1<<15)   /* Autobaud complete */
+#define USR2_TXFE   (1<<14)   /* Transmit FIFO empty */
+#define USR2_DTRF   (1<<13)   /* DTR/DSR transition */
+#define USR2_IDLE   (1<<12)   /* UART has been idle for too long */
+#define USR2_ACST   (1<<11)   /* Autobaud counter stopped */
+#define USR2_RIDELT (1<<10)   /* Ring Indicator delta */
+#define USR2_RIIN   (1<<9)/* Ring Indicator Input */
+#define USR2_IRINT  (1<<8)/* Serial Infrared Interrupt */
+#define USR2_WAKE   (1<<7)/* Start bit detected */
+#def

[Qemu-devel] [patch v8 0/5] i.MX31 support

2012-06-05 Thread Peter Chubb
There are no major changes since last time, just rebased to current
tip now that  QEMU 1.2 is open.

For those who have come into the story late, this is a series of
patches to allow QEMU to emulate a Freescale i.MX31 on a Kyoto
Microsystems evaluation board.  It's pretty bare-bones, but runs Linux
and seL4 nicely.

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



[Qemu-devel] [patch v8 4/5] i.MX31 support: AVIC

2012-06-05 Thread Peter Chubb
Implement the FreeSCALE i.MX31 advanced vectored interrupt controller, at least
to the extent it is used by Linux 3.0.x

Vectors are not implemented.

Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
Reviewed-by: Peter Maydell 

---
 Makefile.target |2 
 hw/imx_avic.c   |  409 
 2 files changed, 410 insertions(+), 1 deletion(-)
 create mode 100644 hw/imx_avic.c

Index: qemu-working/hw/imx_avic.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_avic.c  2012-06-06 13:42:23.007957660 +1000
@@ -0,0 +1,409 @@
+/*
+ * IMX31 Vectored Interrupt Controller
+ *
+ * Note this is NOT the PL192 provided by ARM, but
+ * a custom implementation by FreeScale.
+ *
+ * Copyright (c) 2008 OKL
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally Written by Hans Jiang
+ *
+ * This code is licenced under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * TODO: implement vectors.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "host-utils.h"
+
+#define DEBUG_INT 1
+#undef DEBUG_INT /* comment out for debugging */
+
+#ifdef DEBUG_INT
+#define DPRINTF(fmt, args...) \
+do { printf("imx_avic: " 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_avic: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+#define IMX_AVIC_NUM_IRQS 64
+
+/* Interrupt Control Bits */
+#define ABFLAG (1<<25)
+#define ABFEN (1<<24)
+#define NIDIS (1<<22) /* Normal Interrupt disable */
+#define FIDIS (1<<21) /* Fast interrupt disable */
+#define NIAD  (1<<20) /* Normal Interrupt Arbiter Rise ARM level */
+#define FIAD  (1<<19) /* Fast Interrupt Arbiter Rise ARM level */
+#define NM(1<<18) /* Normal interrupt mode */
+
+
+#define PRIO_PER_WORD (sizeof(uint32_t) * 8 / 4)
+#define PRIO_WORDS (IMX_AVIC_NUM_IRQS/PRIO_PER_WORD)
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+uint64_t pending;
+uint64_t enabled;
+uint64_t is_fiq;
+uint32_t intcntl;
+uint32_t intmask;
+qemu_irq irq;
+qemu_irq fiq;
+uint32_t prio[PRIO_WORDS]; /* Priorities are 4-bits each */
+} IMXAVICState;
+
+static const VMStateDescription vmstate_imx_avic = {
+.name = "imx-avic",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT64(pending, IMXAVICState),
+VMSTATE_UINT64(enabled, IMXAVICState),
+VMSTATE_UINT64(is_fiq, IMXAVICState),
+VMSTATE_UINT32(intcntl, IMXAVICState),
+VMSTATE_UINT32(intmask, IMXAVICState),
+VMSTATE_UINT32_ARRAY(prio, IMXAVICState, PRIO_WORDS),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+
+static inline int imx_avic_prio(IMXAVICState *s, int irq)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+return 0xf & (s->prio[word] >> part);
+}
+
+static inline void imx_avic_set_prio(IMXAVICState *s, int irq, int prio)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+uint32_t mask = ~(0xf << part);
+s->prio[word] &= mask;
+s->prio[word] |= prio << part;
+}
+
+/* Update interrupts.  */
+static void imx_avic_update(IMXAVICState *s)
+{
+int i;
+uint64_t new = s->pending & s->enabled;
+uint64_t flags;
+
+flags = new & s->is_fiq;
+qemu_set_irq(s->fiq, !!flags);
+
+flags = new & ~s->is_fiq;
+if (!flags || (s->intmask == 0x1f)) {
+qemu_set_irq(s->irq, !!flags);
+return;
+}
+
+/*
+ * Take interrupt if there's a pending interrupt with
+ * priority higher than the value of intmask
+ */
+for (i = 0; i < IMX_AVIC_NUM_IRQS; i++) {
+if (flags & (1UL << i)) {
+if (imx_avic_prio(s, i) > s->intmask) {
+qemu_set_irq(s->irq, 1);
+return;
+}
+}
+}
+qemu_set_irq(s->irq, 0);
+}
+
+static void imx_avic_set_irq(void *opaque, int irq, int level)
+{
+IMXAVICState *s = (IMXAVICState *)opaque;
+
+if (level) {
+DPRINTF("Raising IRQ %d, prio %d\n",
+irq, imx_avic_prio(s, irq));
+s->pending |= (1ULL << irq);
+} else {
+DPRINTF("Clearing IRQ %d, prio %d\n",
+irq, imx_avic_prio(s, irq));
+s->pending &= ~(1ULL << irq);
+}
+
+

[Qemu-devel] [patch v8 3/5] i.MX31 support: Timers

2012-06-05 Thread Peter Chubb
Implement the timers on the FreeScale i.MX31 SoC.
This is not a complete implementation, but gives enough for 
Linux to boot and run. In particular external triggers, which are 
not useful under QEMU, are not implemented.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
---
 Makefile.target |2 
 hw/imx.h|8 
 hw/imx_timer.c  |  689 
 3 files changed, 698 insertions(+), 1 deletion(-)
 create mode 100644 hw/imx_timer.c

Index: qemu-working/hw/imx_timer.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_timer.c 2012-06-06 13:42:21.315948297 +1000
@@ -0,0 +1,689 @@
+/*
+ * IMX31 Timer
+ *
+ * Copyright (c) 2008 OK Labs
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally Written by Hans Jiang
+ * Updated by Peter Chubb
+ *
+ * This code is licenced under GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw.h"
+#include "qemu-timer.h"
+#include "ptimer.h"
+#include "sysbus.h"
+#include "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
+
+/*
+ * GPT : General purpose timer
+ *
+ * This timer counts up continuously while it is enabled, resetting itself
+ * to 0 when it reaches TIMER_MAX (in freerun mode) or when it
+ * reaches the value of ocr1 (in periodic mode).  WE simulate this using a
+ * QEMU ptimer counting down from ocr1 and reloading from ocr1 in
+ * periodic mode, or counting from ocr1 to zero, then TIMER_MAX - ocr1.
+ * waiting_rov is set when counting from TIMER_MAX.
+ *
+ * In the real hardware, there are three comparison registers that can
+ * trigger interrupts, and compare channel 1 can be used to
+ * force-reset the timer. However, this is a `bare-bones'
+ * implementation: only what Linux 3.x uses has been implemented
+ * (free-running timer from 0 to OCR1 or TIMER_MAX) .
+ */
+
+
+#define TIMER_MAX  0XUL
+
+/* Control register.  Not all of these bits have any effect (yet) */
+#define GPT_CR_EN (1 << 0)  /* GPT Enable */
+#define GPT_CR_ENMOD  (1 << 1)  /* GPT Enable Mode */
+#define GPT_CR_DBGEN  (1 << 2)  /* GPT Debug mode enable */
+#define GPT_CR_WAITEN (1 << 3)  /* GPT Wait Mode Enable  */
+#define GPT_CR_DOZEN  (1 << 4)  /* GPT Doze mode enable */
+#define GPT_CR_STOPEN (1 << 5)  /* GPT Stop Mode Enable */
+#define GPT_CR_CLKSRC_SHIFT (6)
+#define GPT_CR_CLKSRC_MASK  (0x7)
+
+#define GPT_CR_FRR(1 << 9)  /* Freerun or Restart */
+#define GPT_CR_SWR(1 << 15) /* Software Reset */
+#define GPT_CR_IM1(3 << 16) /* Input capture channel 1 mode (2 bits) */
+#define GPT_CR_IM2(3 << 18) /* Input capture channel 2 mode (2 bits) */
+#define GPT_CR_OM1(7 << 20) /* Output Compare Channel 1 Mode (3 bits) */
+#define GPT_CR_OM2(7 << 23) /* Output Compare Channel 2 Mode (3 bits) */
+#define GPT_CR_OM3(7 << 26) /* Output Compare Channel 3 Mode (3 bits) */
+#define GPT_CR_FO1(1 << 29) /* Force Output Compare Channel 1 */
+#define GPT_CR_FO2(1 << 30) /* Force Output Compare Channel 2 */
+#define GPT_CR_FO3(1 << 31) /* Force Output Compare Channel 3 */
+
+#define GPT_SR_OF1  (1 << 0)
+#define GPT_SR_ROV  (1 << 5)
+
+#define GPT_IR_OF1IE  (1 << 0)
+#define GPT_IR_ROVIE  (1 << 5)
+
+typedef struct {
+SysBusDevice busdev;
+ptimer_state *timer;
+MemoryRegion iomem;
+DeviceState *ccm;
+
+uint32_t cr;
+uint32_t pr;
+uint32_t sr;
+uint32_t ir;
+uint32_t ocr1;
+uint32_t cnt;
+
+uint32_t waiting_rov;
+qemu_irq irq;
+} IMXTimerGState;
+
+static const VMStateDescription vmstate_imx_timerg = {
+.name = "imx-timerg",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields  = (VMStateField[]) {
+VMSTATE_UINT32(cr, IMXTimerGState),
+VMSTATE_UINT32(pr, IMXTimerGState),
+VMSTATE_UINT32(sr, IMXTimerGState),
+VMSTATE_UINT32(ir, IMXTimerGState),
+VMSTATE_UINT32(ocr1, IMXTimerGState),
+VMSTATE_UINT32(cnt, IMXTimerGState),
+VMSTATE_UINT32(waiting_rov, IMXTimerGState),
+VMSTATE_PTIMER(timer, IMXTimerGState),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static

[Qemu-devel] [PATCH v7 1/5] i.MX: UART support

2012-05-01 Thread Peter Chubb
Implement the Freescale i.MX UART.  This uart is used in a variety of
SoCs, including some by Motorola, as well as in the Freescale i.MX
series.

This patch gives only a `bare-bones' implementation, enough to run Linux 
or OKL4, but that's about it.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
Reviewed-by: Peter Maydell 
---
 Makefile.target |1 
 hw/imx.h|   16 +
 hw/imx_serial.c |  467 
 3 files changed, 484 insertions(+)
 create mode 100644 hw/imx_serial.c

Index: qemu-working/hw/imx_serial.c
===
--- /dev/null
+++ qemu-working/hw/imx_serial.c
@@ -0,0 +1,467 @@
+/*
+ * IMX31 UARTS
+ *
+ * Copyright (c) 2008 OKL
+ * Originally Written by Hans Jiang
+ * Copyright (c) 2011 NICTA Pty Ltd.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * This is a `bare-bones' implementation of the IMX series serial ports.
+ * TODO:
+ *  -- implement FIFOs.  The real hardware has 32 word transmit
+ *   and receive FIFOs; we currently use a 1-char buffer
+ *  -- implement DMA
+ *  -- implement BAUD-rate and modem lines, for when the backend
+ * is a real serial device.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "sysemu.h"
+#include "qemu-char.h"
+#include "imx.h"
+
+//#define DEBUG_SERIAL 1
+#ifdef DEBUG_SERIAL
+#define DPRINTF(fmt, args...) \
+do { printf("imx_serial: " 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
+#ifdef DEBUG_IMPLEMENTATION
+#  define IPRINTF(fmt, args...) \
+do  { fprintf(stderr, "imx_serial: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+int32_t readbuff;
+
+uint32_t usr1;
+uint32_t usr2;
+uint32_t ucr1;
+uint32_t ucr2;
+uint32_t uts1;
+
+/*
+ * The registers below are implemented just so that the
+ * guest OS sees what it has written
+ */
+uint32_t onems;
+uint32_t ufcr;
+uint32_t ubmr;
+uint32_t ubrc;
+uint32_t ucr3;
+
+qemu_irq irq;
+CharDriverState *chr;
+} IMXSerialState;
+
+static const VMStateDescription vmstate_imx_serial = {
+.name = "imx-serial",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_INT32(readbuff, IMXSerialState),
+VMSTATE_UINT32(usr1, IMXSerialState),
+VMSTATE_UINT32(usr2, IMXSerialState),
+VMSTATE_UINT32(ucr1, IMXSerialState),
+VMSTATE_UINT32(uts1, IMXSerialState),
+VMSTATE_UINT32(onems, IMXSerialState),
+VMSTATE_UINT32(ufcr, IMXSerialState),
+VMSTATE_UINT32(ubmr, IMXSerialState),
+VMSTATE_UINT32(ubrc, IMXSerialState),
+VMSTATE_UINT32(ucr3, IMXSerialState),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+#define URXD_CHARRDY(1<<15)   /* character read is valid */
+#define URXD_ERR(1<<14)   /* Character has error */
+#define URXD_BRK(1<<11)   /* Break received */
+
+#define USR1_PARTYER(1<<15)   /* Parity Error */
+#define USR1_RTSS   (1<<14)   /* RTS pin status */
+#define USR1_TRDY   (1<<13)   /* Tx ready */
+#define USR1_RTSD   (1<<12)   /* RTS delta: pin changed state */
+#define USR1_ESCF   (1<<11)   /* Escape sequence interrupt */
+#define USR1_FRAMERR(1<<10)   /* Framing error  */
+#define USR1_RRDY   (1<<9)/* receiver ready */
+#define USR1_AGTIM  (1<<8)/* Aging timer interrupt */
+#define USR1_DTRD   (1<<7)/* DTR changed */
+#define USR1_RXDS   (1<<6)/* Receiver is idle */
+#define USR1_AIRINT (1<<5)/* Aysnch IR interrupt */
+#define USR1_AWAKE  (1<<4)/* Falling edge detected on RXd pin */
+
+#define USR2_ADET   (1<<15)   /* Autobaud complete */
+#define USR2_TXFE   (1<<14)   /* Transmit FIFO empty */
+#define USR2_DTRF   (1<<13)   /* DTR/DSR transition */
+#define USR2_IDLE   (1<<12)   /* UART has been idle for too long */
+#define USR2_ACST   (1<<11)   /* Autobaud counter stopped */
+#define USR2_RIDELT (1<<10)   /* Ring Indicator delta */
+#define USR2_RIIN   (1<<9)/* Ring Indicator Input */
+#define USR2_IRINT  (1<<8)/* Serial Infrared Interrupt */
+#define USR2_WAKE   (1<<7)/* Start bit detected */
+#define USR2_DCDDELT(1<<6)/* Data Carrier Detect delta */
+#define USR2_DCDIN

[Qemu-devel] [PATCH v7 3/5] i.MX31: Timers

2012-05-01 Thread Peter Chubb
Implement the timers on the Freescale i.MX31 SoC.
This is not a complete implementation, but gives enough for 
Linux to boot and run. In particular external triggers, which are 
not useful under QEMU, are not implemented.

Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
Reviewed-by: Peter Maydell 

---
 Makefile.target |2 
 hw/imx.h|8 
 hw/imx_timer.c  |  689 
 3 files changed, 698 insertions(+), 1 deletion(-)
 create mode 100644 hw/imx_timer.c

Index: qemu-working/hw/imx_timer.c
===
--- /dev/null
+++ qemu-working/hw/imx_timer.c
@@ -0,0 +1,689 @@
+/*
+ * IMX31 Timer
+ *
+ * Copyright (c) 2008 OK Labs
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally Written by Hans Jiang
+ * Updated by Peter Chubb
+ *
+ * This code is licenced under GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw.h"
+#include "qemu-timer.h"
+#include "ptimer.h"
+#include "sysbus.h"
+#include "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
+
+/*
+ * GPT : General purpose timer
+ *
+ * This timer counts up continuously while it is enabled, resetting itself
+ * to 0 when it reaches TIMER_MAX (in freerun mode) or when it
+ * reaches the value of ocr1 (in periodic mode).  WE simulate this using a
+ * QEMU ptimer counting down from ocr1 and reloading from ocr1 in
+ * periodic mode, or counting from ocr1 to zero, then TIMER_MAX - ocr1.
+ * waiting_rov is set when counting from TIMER_MAX.
+ *
+ * In the real hardware, there are three comparison registers that can
+ * trigger interrupts, and compare channel 1 can be used to
+ * force-reset the timer. However, this is a `bare-bones'
+ * implementation: only what Linux 3.x uses has been implemented
+ * (free-running timer from 0 to OCR1 or TIMER_MAX) .
+ */
+
+
+#define TIMER_MAX  0XUL
+
+/* Control register.  Not all of these bits have any effect (yet) */
+#define GPT_CR_EN (1 << 0)  /* GPT Enable */
+#define GPT_CR_ENMOD  (1 << 1)  /* GPT Enable Mode */
+#define GPT_CR_DBGEN  (1 << 2)  /* GPT Debug mode enable */
+#define GPT_CR_WAITEN (1 << 3)  /* GPT Wait Mode Enable  */
+#define GPT_CR_DOZEN  (1 << 4)  /* GPT Doze mode enable */
+#define GPT_CR_STOPEN (1 << 5)  /* GPT Stop Mode Enable */
+#define GPT_CR_CLKSRC_SHIFT (6)
+#define GPT_CR_CLKSRC_MASK  (0x7)
+
+#define GPT_CR_FRR(1 << 9)  /* Freerun or Restart */
+#define GPT_CR_SWR(1 << 15) /* Software Reset */
+#define GPT_CR_IM1(3 << 16) /* Input capture channel 1 mode (2 bits) */
+#define GPT_CR_IM2(3 << 18) /* Input capture channel 2 mode (2 bits) */
+#define GPT_CR_OM1(7 << 20) /* Output Compare Channel 1 Mode (3 bits) */
+#define GPT_CR_OM2(7 << 23) /* Output Compare Channel 2 Mode (3 bits) */
+#define GPT_CR_OM3(7 << 26) /* Output Compare Channel 3 Mode (3 bits) */
+#define GPT_CR_FO1(1 << 29) /* Force Output Compare Channel 1 */
+#define GPT_CR_FO2(1 << 30) /* Force Output Compare Channel 2 */
+#define GPT_CR_FO3(1 << 31) /* Force Output Compare Channel 3 */
+
+#define GPT_SR_OF1  (1 << 0)
+#define GPT_SR_ROV  (1 << 5)
+
+#define GPT_IR_OF1IE  (1 << 0)
+#define GPT_IR_ROVIE  (1 << 5)
+
+typedef struct {
+SysBusDevice busdev;
+ptimer_state *timer;
+MemoryRegion iomem;
+DeviceState *ccm;
+
+uint32_t cr;
+uint32_t pr;
+uint32_t sr;
+uint32_t ir;
+uint32_t ocr1;
+uint32_t cnt;
+
+uint32_t waiting_rov;
+qemu_irq irq;
+} IMXTimerGState;
+
+static const VMStateDescription vmstate_imx_timerg = {
+.name = "imx-timerg",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields  = (VMStateField[]) {
+VMSTATE_UINT32(cr, IMXTimerGState),
+VMSTATE_UINT32(pr, IMXTimerGState),
+VMSTATE_UINT32(sr, IMXTimerGState),
+VMSTATE_UINT32(ir, IMXTimerGState),
+VMSTATE_UINT32(ocr1, IMXTimerGState),
+VMSTATE_UINT32(cnt, IMXTimerGState),
+VMSTATE_UINT32(waiting_rov, IMXTimerGState),
+VMSTATE_PTIMER(timer, IMXTimerGState),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static const IMXClk imx_timerg_clocks[] = {
+NOCLK, 

[Qemu-devel] [PATCH v7 2/5] i.MX31: Clock Control Module

2012-05-01 Thread Peter Chubb
For Linux to be able to work out how fast its clocks are going, so
that timer ticks come approximately at the right time, it needs to
be able to query the clock control module (CCM). 

This is the start of a CCM implementation.  It currently knows only about 
the MCU, HSP and IPG clocks --- i.e., the ones used to feed the periodic 
and general purpose timers.

Signed-off-by: Peter Chubb 

---
 Makefile.target |2 
 hw/imx.h|   10 +
 hw/imx_ccm.c|  321 
 3 files changed, 332 insertions(+), 1 deletion(-)

Index: qemu-working/Makefile.target
===
--- qemu-working.orig/Makefile.target
+++ qemu-working/Makefile.target
@@ -402,7 +402,7 @@ obj-arm-y += vexpress.o
 obj-arm-y += strongarm.o
 obj-arm-y += collie.o
 obj-arm-y += pl041.o lm4549.o
-obj-arm-y += imx_serial.o
+obj-arm-y += imx_serial.o imx_ccm.o
 obj-arm-$(CONFIG_FDT) += device_tree.o
 
 obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
Index: qemu-working/hw/imx_ccm.c
===
--- /dev/null
+++ qemu-working/hw/imx_ccm.c
@@ -0,0 +1,321 @@
+/*
+ * IMX31 Clock Control Module
+ *
+ * Copyright (C) 2012 NICTA
+ *
+ * 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.h"
+#include "sysbus.h"
+#include "sysemu.h"
+#include "imx.h"
+
+#define CKIH_FREQ 2600 /* 26MHz crystal input */
+#define CKIL_FREQ32768 /* nominal 32khz clock */
+
+
+//#define DEBUG_CCM 1
+#ifdef DEBUG_CCM
+#define DPRINTF(fmt, args...) \
+do { printf("imx_ccm: " fmt , ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...) do {} while (0)
+#endif
+
+static int imx_ccm_post_load(void *opaque, int version_id);
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+
+uint32_t ccmr;
+uint32_t pdr0;
+uint32_t pdr1;
+uint32_t mpctl;
+uint32_t spctl;
+uint32_t cgr[3];
+uint32_t pmcr0;
+uint32_t pmcr1;
+
+/* Frequencies precalculated on register changes */
+uint32_t pll_refclk_freq;
+uint32_t mcu_clk_freq;
+uint32_t hsp_clk_freq;
+uint32_t ipg_clk_freq;
+} IMXCCMState;
+
+static const VMStateDescription vmstate_imx_ccm = {
+.name = "imx-ccm",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(ccmr, IMXCCMState),
+VMSTATE_UINT32(pdr0, IMXCCMState),
+VMSTATE_UINT32(pdr1, IMXCCMState),
+VMSTATE_UINT32(mpctl, IMXCCMState),
+VMSTATE_UINT32(spctl, IMXCCMState),
+VMSTATE_UINT32_ARRAY(cgr, IMXCCMState, 3),
+VMSTATE_UINT32(pmcr0, IMXCCMState),
+VMSTATE_UINT32(pmcr1, IMXCCMState),
+VMSTATE_UINT32(pll_refclk_freq, IMXCCMState),
+},
+.post_load = imx_ccm_post_load,
+};
+
+/* CCMR */
+#define CCMR_FPME (1<<0)
+#define CCMR_MPE  (1<<3)
+#define CCMR_MDS  (1<<7)
+#define CCMR_FPMF (1<<26)
+#define CCMR_PRCS (3<<1)
+
+/* PDR0 */
+#define PDR0_MCU_PODF_SHIFT (0)
+#define PDR0_MCU_PODF_MASK (0x7)
+#define PDR0_MAX_PODF_SHIFT (3)
+#define PDR0_MAX_PODF_MASK (0x7)
+#define PDR0_IPG_PODF_SHIFT (6)
+#define PDR0_IPG_PODF_MASK (0x3)
+#define PDR0_NFC_PODF_SHIFT (8)
+#define PDR0_NFC_PODF_MASK (0x7)
+#define PDR0_HSP_PODF_SHIFT (11)
+#define PDR0_HSP_PODF_MASK (0x7)
+#define PDR0_PER_PODF_SHIFT (16)
+#define PDR0_PER_PODF_MASK (0x1f)
+#define PDR0_CSI_PODF_SHIFT (23)
+#define PDR0_CSI_PODF_MASK (0x1ff)
+
+#define EXTRACT(value, name) (((value) >> PDR0_##name##_PODF_SHIFT) \
+  & PDR0_##name##_PODF_MASK)
+#define INSERT(value, name) (((value) & PDR0_##name##_PODF_MASK) << \
+ PDR0_##name##_PODF_SHIFT)
+/* PLL control registers */
+#define PD(v) (((v) >> 26) & 0xf)
+#define MFD(v) (((v) >> 16) & 0x3ff)
+#define MFI(v) (((v) >> 10) & 0xf);
+#define MFN(v) ((v) & 0x3ff)
+
+#define PLL_PD(x)   (((x) & 0xf) << 26)
+#define PLL_MFD(x)  (((x) & 0x3ff) << 16)
+#define PLL_MFI(x)  (((x) & 0xf) << 10)
+#define PLL_MFN(x)  (((x) & 0x3ff) << 0)
+
+uint32_t imx_clock_frequency(DeviceState *dev, IMXClk clock)
+{
+IMXCCMState *s = container_of(dev, IMXCCMState, busdev.qdev);
+
+switch (clock) {
+case NOCLK:
+return 0;
+case MCU:
+return s->mcu_clk_freq;
+case HSP:
+return s->hsp_clk_freq;
+case IPG:
+return s->ipg_clk_freq;
+case CLK_32k:
+return CKIL_FREQ;
+}
+return 0;
+}
+
+/*
+ * Calculate PLL output frequency
+ */
+static 

[Qemu-devel] [PATCH v7 4/5] i.MX31: Interrupt Controller

2012-05-01 Thread Peter Chubb
Implement the Freescale i.MX31 advanced vectored interrupt controller, at least
to the extent it is used by Linux 3.x

Vectors are not implemented.

Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
Reviewed-by: Peter Maydell 

---
 Makefile.target |2 
 hw/imx_avic.c   |  409 
 2 files changed, 410 insertions(+), 1 deletion(-)
 create mode 100644 hw/imx_avic.c

Index: qemu-working/hw/imx_avic.c
===
--- /dev/null
+++ qemu-working/hw/imx_avic.c
@@ -0,0 +1,409 @@
+/*
+ * IMX31 Vectored Interrupt Controller
+ *
+ * Note this is NOT the PL192 provided by ARM, but
+ * a custom implementation by Freescale.
+ *
+ * Copyright (c) 2008 OKL
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally Written by Hans Jiang
+ *
+ * This code is licenced under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * TODO: implement vectors.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "host-utils.h"
+
+#define DEBUG_INT 1
+#undef DEBUG_INT /* comment out for debugging */
+
+#ifdef DEBUG_INT
+#define DPRINTF(fmt, args...) \
+do { printf("imx_avic: " 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_avic: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+#define IMX_AVIC_NUM_IRQS 64
+
+/* Interrupt Control Bits */
+#define ABFLAG (1<<25)
+#define ABFEN (1<<24)
+#define NIDIS (1<<22) /* Normal Interrupt disable */
+#define FIDIS (1<<21) /* Fast interrupt disable */
+#define NIAD  (1<<20) /* Normal Interrupt Arbiter Rise ARM level */
+#define FIAD  (1<<19) /* Fast Interrupt Arbiter Rise ARM level */
+#define NM(1<<18) /* Normal interrupt mode */
+
+
+#define PRIO_PER_WORD (sizeof(uint32_t) * 8 / 4)
+#define PRIO_WORDS (IMX_AVIC_NUM_IRQS/PRIO_PER_WORD)
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+uint64_t pending;
+uint64_t enabled;
+uint64_t is_fiq;
+uint32_t intcntl;
+uint32_t intmask;
+qemu_irq irq;
+qemu_irq fiq;
+uint32_t prio[PRIO_WORDS]; /* Priorities are 4-bits each */
+} IMXAVICState;
+
+static const VMStateDescription vmstate_imx_avic = {
+.name = "imx-avic",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT64(pending, IMXAVICState),
+VMSTATE_UINT64(enabled, IMXAVICState),
+VMSTATE_UINT64(is_fiq, IMXAVICState),
+VMSTATE_UINT32(intcntl, IMXAVICState),
+VMSTATE_UINT32(intmask, IMXAVICState),
+VMSTATE_UINT32_ARRAY(prio, IMXAVICState, PRIO_WORDS),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+
+static inline int imx_avic_prio(IMXAVICState *s, int irq)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+return 0xf & (s->prio[word] >> part);
+}
+
+static inline void imx_avic_set_prio(IMXAVICState *s, int irq, int prio)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+uint32_t mask = ~(0xf << part);
+s->prio[word] &= mask;
+s->prio[word] |= prio << part;
+}
+
+/* Update interrupts.  */
+static void imx_avic_update(IMXAVICState *s)
+{
+int i;
+uint64_t new = s->pending & s->enabled;
+uint64_t flags;
+
+flags = new & s->is_fiq;
+qemu_set_irq(s->fiq, !!flags);
+
+flags = new & ~s->is_fiq;
+if (!flags || (s->intmask == 0x1f)) {
+qemu_set_irq(s->irq, !!flags);
+return;
+}
+
+/*
+ * Take interrupt if there's a pending interrupt with
+ * priority higher than the value of intmask
+ */
+for (i = 0; i < IMX_AVIC_NUM_IRQS; i++) {
+if (flags & (1UL << i)) {
+if (imx_avic_prio(s, i) > s->intmask) {
+qemu_set_irq(s->irq, 1);
+return;
+}
+}
+}
+qemu_set_irq(s->irq, 0);
+}
+
+static void imx_avic_set_irq(void *opaque, int irq, int level)
+{
+IMXAVICState *s = (IMXAVICState *)opaque;
+
+if (level) {
+DPRINTF("Raising IRQ %d, prio %d\n",
+irq, imx_avic_prio(s, irq));
+s->pending |= (1ULL << irq);
+} else {
+DPRINTF("Clearing IRQ %d, prio %d\n",
+irq, imx_avic_prio(s, irq));
+s->pending &= ~(1ULL << irq);
+}
+
+imx_avic_update(s);
+}
+
+
+static uint64_t imx_avic_read(void *opaque,
+   

[Qemu-devel] [PATCH v7 5/5] i.MX31: KZM-ARM11-01 evaluation board

2012-05-01 Thread Peter Chubb
Board support for Kyoto Micro's KZM-ARM11-01, an evaluation board built
around the Freescale i.MX31.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 

---
 Makefile.target |2 
 hw/kzm.c|  155 
 2 files changed, 156 insertions(+), 1 deletion(-)
 create mode 100644 hw/kzm.c

Index: qemu-working/hw/kzm.c
===
--- /dev/null
+++ qemu-working/hw/kzm.c
@@ -0,0 +1,155 @@
+/*
+ * KZM Board System emulation.
+ *
+ * Copyright (c) 2008 OKL and 2011 NICTA
+ * Written by Hans
+ * Updated by Peter Chubb.
+ *
+ * This code is licenced under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a Kyoto Microcomputer
+ * KZM-ARM11-01 evaluation board, with a Freescale
+ * I.MX31 SoC
+ */
+
+#include "sysbus.h"
+#include "exec-memory.h"
+#include "hw.h"
+#include "arm-misc.h"
+#include "devices.h"
+#include "net.h"
+#include "sysemu.h"
+#include "boards.h"
+#include "pc.h" /* for the FPGA UART that emulates a 16550 */
+#include "imx.h"
+
+/* Memory map for Kzm Emulation Baseboard:
+ * 0x-0x3fff 16k secure ROM   IGNORED
+ * 0x4000-0x00407fff Reserved IGNORED
+ * 0x00404000-0x00407fff ROM  IGNORED
+ * 0x00408000-0x0fff Reserved IGNORED
+ * 0x1000-0x1fffbfff RAM aliasing IGNORED
+ * 0x1fffc000-0x1fff RAM  EMULATED
+ * 0x2000-0x2fff Reserved IGNORED
+ * 0x3000-0x7fff I.MX31 Internal Register Space
+ *   0x43f0 IO_AREA0
+ *   0x43f9 UART1 EMULATED
+ *   0x43f94000 UART2 EMULATED
+ *   0x6800 AVIC  EMULATED
+ *   0x53f8 CCM   EMULATED
+ *   0x53f94000 PIT 1 EMULATED
+ *   0x53f98000 PIT 2 EMULATED
+ *   0x53f9 GPT   EMULATED
+ * 0x8000-0x87ff RAM  EMULATED
+ * 0x8800-0x8fff RAM Aliasing EMULATED
+ * 0xa000-0xafff NAND Flash   IGNORED
+ * 0xb000-0xb3ff Unavailable  IGNORED
+ * 0xb400-0xb4000fff 8-bit free space IGNORED
+ * 0xb4001000-0xb400100f Board controlIGNORED
+ *  0xb4001003   DIP switch
+ * 0xb4001010-0xb400101f 7-segment LEDIGNORED
+ * 0xb4001020-0xb400102f LED  IGNORED
+ * 0xb4001030-0xb400103f LED  IGNORED
+ * 0xb4001040-0xb400104f FPGA, UART   EMULATED
+ * 0xb4001050-0xb400105f FPGA, UART   EMULATED
+ * 0xb4001060-0xb40f FPGA IGNORED
+ * 0xb600-0xb61f LAN controller   EMULATED
+ * 0xb620-0xb62f FPGA NAND Controller IGNORED
+ * 0xb630-0xb7ff Free IGNORED
+ * 0xb800-0xb8004fff Memory control registers IGNORED
+ * 0xc000-0xc3ff PCMCIA/CFIGNORED
+ * 0xc400-0x Reserved IGNORED
+ */
+
+#define KZM_RAMADDRESS (0x8000)
+#define KZM_FPGA   (0xb4001040)
+
+static struct arm_boot_info kzm_binfo = {
+.loader_start = KZM_RAMADDRESS,
+.board_id = 1722,
+};
+
+static void kzm_init(ram_addr_t ram_size,
+ const char *boot_device,
+ const char *kernel_filename, const char *kernel_cmdline,
+ const char *initrd_filename, const char *cpu_model)
+{
+CPUARMState *env;
+MemoryRegion *address_space_mem = get_system_memory();
+MemoryRegion *ram = g_new(MemoryRegion, 1);
+MemoryRegion *sram = g_new(MemoryRegion, 1);
+MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
+qemu_irq *cpu_pic;
+DeviceState *dev;
+DeviceState *ccm;
+
+if (!cpu_model) {
+cpu_model = "arm1136";
+}
+
+env = cpu_init(cpu_model);
+if (!env) {
+fprintf(stderr, "Unable to find CPU definition\n");
+exit(1);
+}
+
+/* On a real system, the first 16k is a `secure boot rom' */
+
+memory_region_init_ram(ram, "kzm.ram", ram_size);
+vmstate_register_ram_global(ram);
+memory_region_add_subregion(address_space_mem, KZM_RAMADDRESS, ram);
+
+memory_region_init_alias(ram_alias, "ram.alias", ram, 0, ram_size);
+memory_region_add_subregion(address_space_mem, 0x8800, ram_alias);
+
+memory_region_init_ram(sram, "kzm.sram", 0x4000);
+memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
+
+
+cpu_pic = arm_pic_init_cpu(env);
+dev = sysbus_create_varargs("imx_avic", 0x6800,
+ 

[Qemu-devel] [PATCH v7 0/5] add i.MX31 support

2012-05-01 Thread Peter Chubb
This patch series adds rudimentary support for the Freescale i.MX31 SoC,
and the Kyoto Micro KZM-ARM11-01, an evaluation board built
around the Freescale i.MX31.

Changes since last patch round: (v6)
   * shortened patch titles
   * canonised spelling of `Freescale'
   * Fixed 10 to 32-bit sign extension in the clock-control-module 
   * Use a post-load hook in the clock-control-module instead of 
 storing frequencies in the VMState.
   * Deleted undocumented second UART on KZM board's FPGA.

Apart from that the patches are unchanged.  Thanks to Peter M and Andreas F for
comments.
-- 
Dr Peter Chubbwww.nicta.com.au  peter DOT chubb AT nicta.com.au
http://www.ertos.nicta.com.au   ERTOS within National ICT Australia
>From Imagination to Impact   Imagining the (ICT) Future




Re: [Qemu-devel] [PATCH v6 0/5] FreeSCALE i.MX31 support

2012-04-24 Thread Peter Chubb
>>>>> "Andreas" == Andreas Färber  writes:

Andreas> Am 23.04.2012 01:31, schrieb Peter Chubb:
>> Hi all, Most of the files are unchanged since last time.

Andreas> Indeed... On v5 I had asked you to shorten the subjects to
Andreas> conform to our commit message scheme and to make patches
Andreas> better readable. There were even suggestions. Also I
Andreas> implicitly suggested to use one spelling of "Freescale"
Andreas> consistently throughout your patches.

Sorry, yes I missed that comment.   V7 will come soon.


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



Re: [Qemu-devel] [PATCH v6 2/5] Implement i.MX31 Clock Control Module

2012-04-24 Thread Peter Chubb
>>>>> "Paolo" == Paolo Bonzini  writes:

Paolo> Il 23/04/2012 22:54, Peter Chubb ha scritto:
Peter> What is this calculation supposed to do? It doesn't convert a
Peter> 10-bit signed twos-complement number into an int32_t, unless
Peter> I'm confused... Also, it's a rather opaque way to write "mfn &=
Peter> 0x200;".
>> 
>> I'll use a different way to calculate.  Maybe: 
>> mfn <<= (32-10); 
>> mfn >= (32-10);

Paolo> The magic that you wanted is

Paolo>mfn |= -(mfn & 0x200);


Yes.  I'd actually been thinking of mfn -= 2 * (mfn & 0x200);
but forgot the 2*.  But the shifts should be faster, and that's wjhat
I'm testing at the moment.


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 v6 5/5] FreeSCALE i.MX31 support: KZM-ARM11-01 evaluation board

2012-04-23 Thread Peter Chubb
>>>>> "Peter" == Peter Maydell  writes:

Peter> On 23 April 2012 00:31, Peter Chubb 
Peter> wrote:
>> Board support for Kyoto Micro's KZM-ARM11-01, an evaluation board
>> built around the FreeScale i.MX31.

>> +    if (serial_hds[3]) { 
>> +         serial_mm_init(address_space_mem, KZM_FPGA, 0, 
>> +                        qdev_get_gpio_in(dev, 52), 
>> +                       14745600, serial_hds[3], 
>> +                       DEVICE_NATIVE_ENDIAN); 
>> +     } 
>> +    if (serial_hds[2]) { /* touchscreen */ 
>> +        serial_mm_init(address_space_mem, KZM_FPGA+0x10, 0, 
>> +                       qdev_get_gpio_in(dev, 52), 
>> +                       14745600, serial_hds[2], 
>> +                       DEVICE_NATIVE_ENDIAN); 
>> +    }

Peter> Are these two devices really on the same IRQ?

Yes.  A single interrupt line comes from the FPGA into the AVIC.
Inside the FPGA the interrupts for the UARTs, SD card and NAND flash
are connected to that single interrupt line.
The non-touchscreen FPGA UART isn't mentioned in the KZM manual, but
is available on the board as a debug port.

To avoid confusion I think I'll just get rid of it.


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



Re: [Qemu-devel] [PATCH v6 2/5] Implement i.MX31 Clock Control Module

2012-04-23 Thread Peter Chubb
>>>>> "Peter" == Peter Maydell  writes:

Peter> On 23 April 2012 00:31, Peter Chubb 
Peter> wrote:

Peter> Rather than having the *_clk_freq saved and loaded in the
Peter> vmstate, I think it would be nicer to have a post-load-hook
Peter> that called update_clocks().

OK.


>>    /* mfn is 10-bit signed twos-complement */ 
>> +    mfn -= (mfn & 0x200);

Peter> What is this calculation supposed to do? It doesn't convert a
Peter> 10-bit signed twos-complement number into an int32_t, unless
Peter> I'm confused... Also, it's a rather opaque way to write "mfn &=
Peter> 0x200;".

I'll use a different way to calculate.  Maybe:
 mfn <<= (32-10);
 mfn >>= (32-10);

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



[Qemu-devel] [PATCH v6 4/5] FreeSCALE i.MX31 support: AVIC

2012-04-22 Thread Peter Chubb
Implement the FreeSCALE i.MX31 advanced vectored interrupt controller, at least
to the extent it is used by Linux 3.0.x

Vectors are not implemented.

Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
Reviewed-by: Peter Maydell 

---
 Makefile.target |2 
 hw/imx_avic.c   |  409 
 2 files changed, 410 insertions(+), 1 deletion(-)
 create mode 100644 hw/imx_avic.c

Index: qemu-working/hw/imx_avic.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_avic.c  2012-04-23 08:24:55.189274038 +1000
@@ -0,0 +1,409 @@
+/*
+ * IMX31 Vectored Interrupt Controller
+ *
+ * Note this is NOT the PL192 provided by ARM, but
+ * a custom implementation by FreeScale.
+ *
+ * Copyright (c) 2008 OKL
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally Written by Hans Jiang
+ *
+ * This code is licenced under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * TODO: implement vectors.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "host-utils.h"
+
+#define DEBUG_INT 1
+#undef DEBUG_INT /* comment out for debugging */
+
+#ifdef DEBUG_INT
+#define DPRINTF(fmt, args...) \
+do { printf("imx_avic: " 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_avic: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+#define IMX_AVIC_NUM_IRQS 64
+
+/* Interrupt Control Bits */
+#define ABFLAG (1<<25)
+#define ABFEN (1<<24)
+#define NIDIS (1<<22) /* Normal Interrupt disable */
+#define FIDIS (1<<21) /* Fast interrupt disable */
+#define NIAD  (1<<20) /* Normal Interrupt Arbiter Rise ARM level */
+#define FIAD  (1<<19) /* Fast Interrupt Arbiter Rise ARM level */
+#define NM(1<<18) /* Normal interrupt mode */
+
+
+#define PRIO_PER_WORD (sizeof(uint32_t) * 8 / 4)
+#define PRIO_WORDS (IMX_AVIC_NUM_IRQS/PRIO_PER_WORD)
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+uint64_t pending;
+uint64_t enabled;
+uint64_t is_fiq;
+uint32_t intcntl;
+uint32_t intmask;
+qemu_irq irq;
+qemu_irq fiq;
+uint32_t prio[PRIO_WORDS]; /* Priorities are 4-bits each */
+} IMXAVICState;
+
+static const VMStateDescription vmstate_imx_avic = {
+.name = "imx-avic",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT64(pending, IMXAVICState),
+VMSTATE_UINT64(enabled, IMXAVICState),
+VMSTATE_UINT64(is_fiq, IMXAVICState),
+VMSTATE_UINT32(intcntl, IMXAVICState),
+VMSTATE_UINT32(intmask, IMXAVICState),
+VMSTATE_UINT32_ARRAY(prio, IMXAVICState, PRIO_WORDS),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+
+static inline int imx_avic_prio(IMXAVICState *s, int irq)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+return 0xf & (s->prio[word] >> part);
+}
+
+static inline void imx_avic_set_prio(IMXAVICState *s, int irq, int prio)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+uint32_t mask = ~(0xf << part);
+s->prio[word] &= mask;
+s->prio[word] |= prio << part;
+}
+
+/* Update interrupts.  */
+static void imx_avic_update(IMXAVICState *s)
+{
+int i;
+uint64_t new = s->pending & s->enabled;
+uint64_t flags;
+
+flags = new & s->is_fiq;
+qemu_set_irq(s->fiq, !!flags);
+
+flags = new & ~s->is_fiq;
+if (!flags || (s->intmask == 0x1f)) {
+qemu_set_irq(s->irq, !!flags);
+return;
+}
+
+/*
+ * Take interrupt if there's a pending interrupt with
+ * priority higher than the value of intmask
+ */
+for (i = 0; i < IMX_AVIC_NUM_IRQS; i++) {
+if (flags & (1UL << i)) {
+if (imx_avic_prio(s, i) > s->intmask) {
+qemu_set_irq(s->irq, 1);
+return;
+}
+}
+}
+qemu_set_irq(s->irq, 0);
+}
+
+static void imx_avic_set_irq(void *opaque, int irq, int level)
+{
+IMXAVICState *s = (IMXAVICState *)opaque;
+
+if (level) {
+DPRINTF("Raising IRQ %d, prio %d\n",
+irq, imx_avic_prio(s, irq));
+s->pending |= (1ULL << irq);
+} else {
+DPRINTF("Clearing IRQ %d, prio %d\n",
+irq, imx_avic_prio(s, irq));
+s->pending &= ~(1ULL << irq);
+}
+
+

[Qemu-devel] [PATCH v6 3/5] FreeSCALE i.MX31 support: Timers

2012-04-22 Thread Peter Chubb
Implement the timers on the FreeScale i.MX31 SoC.
This is not a complete implementation, but gives enough for 
Linux to boot and run. In particular external triggers, which are 
not useful under QEMU, are not implemented.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
---
 Makefile.target |2 
 hw/imx.h|8 
 hw/imx_timer.c  |  689 
 3 files changed, 698 insertions(+), 1 deletion(-)
 create mode 100644 hw/imx_timer.c

Index: qemu-working/hw/imx_timer.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_timer.c 2012-04-23 08:24:54.045563023 +1000
@@ -0,0 +1,689 @@
+/*
+ * IMX31 Timer
+ *
+ * Copyright (c) 2008 OK Labs
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally Written by Hans Jiang
+ * Updated by Peter Chubb
+ *
+ * This code is licenced under GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw.h"
+#include "qemu-timer.h"
+#include "ptimer.h"
+#include "sysbus.h"
+#include "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
+
+/*
+ * GPT : General purpose timer
+ *
+ * This timer counts up continuously while it is enabled, resetting itself
+ * to 0 when it reaches TIMER_MAX (in freerun mode) or when it
+ * reaches the value of ocr1 (in periodic mode).  WE simulate this using a
+ * QEMU ptimer counting down from ocr1 and reloading from ocr1 in
+ * periodic mode, or counting from ocr1 to zero, then TIMER_MAX - ocr1.
+ * waiting_rov is set when counting from TIMER_MAX.
+ *
+ * In the real hardware, there are three comparison registers that can
+ * trigger interrupts, and compare channel 1 can be used to
+ * force-reset the timer. However, this is a `bare-bones'
+ * implementation: only what Linux 3.x uses has been implemented
+ * (free-running timer from 0 to OCR1 or TIMER_MAX) .
+ */
+
+
+#define TIMER_MAX  0XUL
+
+/* Control register.  Not all of these bits have any effect (yet) */
+#define GPT_CR_EN (1 << 0)  /* GPT Enable */
+#define GPT_CR_ENMOD  (1 << 1)  /* GPT Enable Mode */
+#define GPT_CR_DBGEN  (1 << 2)  /* GPT Debug mode enable */
+#define GPT_CR_WAITEN (1 << 3)  /* GPT Wait Mode Enable  */
+#define GPT_CR_DOZEN  (1 << 4)  /* GPT Doze mode enable */
+#define GPT_CR_STOPEN (1 << 5)  /* GPT Stop Mode Enable */
+#define GPT_CR_CLKSRC_SHIFT (6)
+#define GPT_CR_CLKSRC_MASK  (0x7)
+
+#define GPT_CR_FRR(1 << 9)  /* Freerun or Restart */
+#define GPT_CR_SWR(1 << 15) /* Software Reset */
+#define GPT_CR_IM1(3 << 16) /* Input capture channel 1 mode (2 bits) */
+#define GPT_CR_IM2(3 << 18) /* Input capture channel 2 mode (2 bits) */
+#define GPT_CR_OM1(7 << 20) /* Output Compare Channel 1 Mode (3 bits) */
+#define GPT_CR_OM2(7 << 23) /* Output Compare Channel 2 Mode (3 bits) */
+#define GPT_CR_OM3(7 << 26) /* Output Compare Channel 3 Mode (3 bits) */
+#define GPT_CR_FO1(1 << 29) /* Force Output Compare Channel 1 */
+#define GPT_CR_FO2(1 << 30) /* Force Output Compare Channel 2 */
+#define GPT_CR_FO3(1 << 31) /* Force Output Compare Channel 3 */
+
+#define GPT_SR_OF1  (1 << 0)
+#define GPT_SR_ROV  (1 << 5)
+
+#define GPT_IR_OF1IE  (1 << 0)
+#define GPT_IR_ROVIE  (1 << 5)
+
+typedef struct {
+SysBusDevice busdev;
+ptimer_state *timer;
+MemoryRegion iomem;
+DeviceState *ccm;
+
+uint32_t cr;
+uint32_t pr;
+uint32_t sr;
+uint32_t ir;
+uint32_t ocr1;
+uint32_t cnt;
+
+uint32_t waiting_rov;
+qemu_irq irq;
+} IMXTimerGState;
+
+static const VMStateDescription vmstate_imx_timerg = {
+.name = "imx-timerg",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields  = (VMStateField[]) {
+VMSTATE_UINT32(cr, IMXTimerGState),
+VMSTATE_UINT32(pr, IMXTimerGState),
+VMSTATE_UINT32(sr, IMXTimerGState),
+VMSTATE_UINT32(ir, IMXTimerGState),
+VMSTATE_UINT32(ocr1, IMXTimerGState),
+VMSTATE_UINT32(cnt, IMXTimerGState),
+VMSTATE_UINT32(waiting_rov, IMXTimerGState),
+VMSTATE_PTIMER(timer, IMXTimerGState),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static

[Qemu-devel] [PATCH v6 1/5] i.MX UART support

2012-04-22 Thread Peter Chubb
Implement the FreeScale i.MX UART.  This uart is used in a variety of
SoCs, including some by Motorola, as well as in the FreeScale i.MX
series.

This patch gives only a `bare-bones' implementation, enough to run Linux 
or OKL4, but that's about it.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
Reviewed-by: Peter Maydell 
---
 Makefile.target |1 
 hw/imx.h|   16 +
 hw/imx_serial.c |  467 
 3 files changed, 484 insertions(+)
 create mode 100644 hw/imx_serial.c

Index: qemu-working/hw/imx_serial.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_serial.c2012-04-23 08:24:51.730152297 +1000
@@ -0,0 +1,467 @@
+/*
+ * IMX31 UARTS
+ *
+ * Copyright (c) 2008 OKL
+ * Originally Written by Hans Jiang
+ * Copyright (c) 2011 NICTA Pty Ltd.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * This is a `bare-bones' implementation of the IMX series serial ports.
+ * TODO:
+ *  -- implement FIFOs.  The real hardware has 32 word transmit
+ *   and receive FIFOs; we currently use a 1-char buffer
+ *  -- implement DMA
+ *  -- implement BAUD-rate and modem lines, for when the backend
+ * is a real serial device.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "sysemu.h"
+#include "qemu-char.h"
+#include "imx.h"
+
+//#define DEBUG_SERIAL 1
+#ifdef DEBUG_SERIAL
+#define DPRINTF(fmt, args...) \
+do { printf("imx_serial: " 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
+#ifdef DEBUG_IMPLEMENTATION
+#  define IPRINTF(fmt, args...) \
+do  { fprintf(stderr, "imx_serial: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+int32_t readbuff;
+
+uint32_t usr1;
+uint32_t usr2;
+uint32_t ucr1;
+uint32_t ucr2;
+uint32_t uts1;
+
+/*
+ * The registers below are implemented just so that the
+ * guest OS sees what it has written
+ */
+uint32_t onems;
+uint32_t ufcr;
+uint32_t ubmr;
+uint32_t ubrc;
+uint32_t ucr3;
+
+qemu_irq irq;
+CharDriverState *chr;
+} IMXSerialState;
+
+static const VMStateDescription vmstate_imx_serial = {
+.name = "imx-serial",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_INT32(readbuff, IMXSerialState),
+VMSTATE_UINT32(usr1, IMXSerialState),
+VMSTATE_UINT32(usr2, IMXSerialState),
+VMSTATE_UINT32(ucr1, IMXSerialState),
+VMSTATE_UINT32(uts1, IMXSerialState),
+VMSTATE_UINT32(onems, IMXSerialState),
+VMSTATE_UINT32(ufcr, IMXSerialState),
+VMSTATE_UINT32(ubmr, IMXSerialState),
+VMSTATE_UINT32(ubrc, IMXSerialState),
+VMSTATE_UINT32(ucr3, IMXSerialState),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+#define URXD_CHARRDY(1<<15)   /* character read is valid */
+#define URXD_ERR(1<<14)   /* Character has error */
+#define URXD_BRK(1<<11)   /* Break received */
+
+#define USR1_PARTYER(1<<15)   /* Parity Error */
+#define USR1_RTSS   (1<<14)   /* RTS pin status */
+#define USR1_TRDY   (1<<13)   /* Tx ready */
+#define USR1_RTSD   (1<<12)   /* RTS delta: pin changed state */
+#define USR1_ESCF   (1<<11)   /* Escape sequence interrupt */
+#define USR1_FRAMERR(1<<10)   /* Framing error  */
+#define USR1_RRDY   (1<<9)/* receiver ready */
+#define USR1_AGTIM  (1<<8)/* Aging timer interrupt */
+#define USR1_DTRD   (1<<7)/* DTR changed */
+#define USR1_RXDS   (1<<6)/* Receiver is idle */
+#define USR1_AIRINT (1<<5)/* Aysnch IR interrupt */
+#define USR1_AWAKE  (1<<4)/* Falling edge detected on RXd pin */
+
+#define USR2_ADET   (1<<15)   /* Autobaud complete */
+#define USR2_TXFE   (1<<14)   /* Transmit FIFO empty */
+#define USR2_DTRF   (1<<13)   /* DTR/DSR transition */
+#define USR2_IDLE   (1<<12)   /* UART has been idle for too long */
+#define USR2_ACST   (1<<11)   /* Autobaud counter stopped */
+#define USR2_RIDELT (1<<10)   /* Ring Indicator delta */
+#define USR2_RIIN   (1<<9)/* Ring Indicator Input */
+#define USR2_IRINT  (1<<8)/* Serial Infrared Interrupt */
+#define USR2_WAKE   (1<<7)/* Start bit detected */
+#def

[Qemu-devel] [PATCH v6 5/5] FreeSCALE i.MX31 support: KZM-ARM11-01 evaluation board

2012-04-22 Thread Peter Chubb
Board support for Kyoto Micro's KZM-ARM11-01, an evaluation board built
around the FreeScale i.MX31.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 

---
 Makefile.target |2 
 hw/kzm.c|  161 
 2 files changed, 162 insertions(+), 1 deletion(-)
 create mode 100644 hw/kzm.c

Index: qemu-working/hw/kzm.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/kzm.c   2012-04-23 08:24:56.380974317 +1000
@@ -0,0 +1,161 @@
+/*
+ * KZM Board System emulation.
+ *
+ * Copyright (c) 2008 OKL and 2011 NICTA
+ * Written by Hans
+ * Updated by Peter Chubb.
+ *
+ * This code is licenced under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a Kyoto Microcomputer
+ * KZM-ARM11-01 evaluation board, with a FreeScale
+ * I.MX31 SoC
+ */
+
+#include "sysbus.h"
+#include "exec-memory.h"
+#include "hw.h"
+#include "arm-misc.h"
+#include "devices.h"
+#include "net.h"
+#include "sysemu.h"
+#include "boards.h"
+#include "pc.h" /* for the FPGA UART that emulates a 16550 */
+#include "imx.h"
+
+/* Memory map for Kzm Emulation Baseboard:
+ * 0x-0x3fff 16k secure ROM   IGNORED
+ * 0x4000-0x00407fff Reserved IGNORED
+ * 0x00404000-0x00407fff ROM  IGNORED
+ * 0x00408000-0x0fff Reserved IGNORED
+ * 0x1000-0x1fffbfff RAM aliasing IGNORED
+ * 0x1fffc000-0x1fff RAM  EMULATED
+ * 0x2000-0x2fff Reserved IGNORED
+ * 0x3000-0x7fff I.MX31 Internal Register Space
+ *   0x43f0 IO_AREA0
+ *   0x43f9 UART1 EMULATED
+ *   0x43f94000 UART2 EMULATED
+ *   0x6800 AVIC  EMULATED
+ *   0x53f8 CCM   EMULATED
+ *   0x53f94000 PIT 1 EMULATED
+ *   0x53f98000 PIT 2 EMULATED
+ *   0x53f9 GPT   EMULATED
+ * 0x8000-0x87ff RAM  EMULATED
+ * 0x8800-0x8fff RAM Aliasing EMULATED
+ * 0xa000-0xafff NAND Flash   IGNORED
+ * 0xb000-0xb3ff Unavailable  IGNORED
+ * 0xb400-0xb4000fff 8-bit free space IGNORED
+ * 0xb4001000-0xb400100f Board controlIGNORED
+ *  0xb4001003   DIP switch
+ * 0xb4001010-0xb400101f 7-segment LEDIGNORED
+ * 0xb4001020-0xb400102f LED  IGNORED
+ * 0xb4001030-0xb400103f LED  IGNORED
+ * 0xb4001040-0xb400104f FPGA, UART   EMULATED
+ * 0xb4001050-0xb400105f FPGA, UART   EMULATED
+ * 0xb4001060-0xb40f FPGA IGNORED
+ * 0xb600-0xb61f LAN controller   EMULATED
+ * 0xb620-0xb62f FPGA NAND Controller IGNORED
+ * 0xb630-0xb7ff Free IGNORED
+ * 0xb800-0xb8004fff Memory control registers IGNORED
+ * 0xc000-0xc3ff PCMCIA/CFIGNORED
+ * 0xc400-0x Reserved IGNORED
+ */
+
+#define KZM_RAMADDRESS (0x8000)
+#define KZM_FPGA   (0xb4001040)
+
+static struct arm_boot_info kzm_binfo = {
+.loader_start = KZM_RAMADDRESS,
+.board_id = 1722,
+};
+
+static void kzm_init(ram_addr_t ram_size,
+ const char *boot_device,
+ const char *kernel_filename, const char *kernel_cmdline,
+ const char *initrd_filename, const char *cpu_model)
+{
+CPUARMState *env;
+MemoryRegion *address_space_mem = get_system_memory();
+MemoryRegion *ram = g_new(MemoryRegion, 1);
+MemoryRegion *sram = g_new(MemoryRegion, 1);
+MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
+qemu_irq *cpu_pic;
+DeviceState *dev;
+DeviceState *ccm;
+
+if (!cpu_model) {
+cpu_model = "arm1136";
+}
+
+env = cpu_init(cpu_model);
+if (!env) {
+fprintf(stderr, "Unable to find CPU definition\n");
+exit(1);
+}
+
+/* On a real system, the first 16k is a `secure boot rom' */
+
+memory_region_init_ram(ram, "kzm.ram", ram_size);
+vmstate_register_ram_global(ram);
+memory_region_add_subregion(address_space_mem, KZM_RAMADDRESS, ram);
+
+memory_region_init_alias(ram_alias, "ram.alias", ram, 0, ram_size);
+memory_region_add_subregion(address_space_mem, 0x8800, ram_alias);
+
+memory_region_init_ram(sram, "kzm.sram", 0x4000);
+memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
+
+
+cpu_pic = arm_pic_init_cpu(env);
+de

[Qemu-devel] [PATCH v6 2/5] Implement i.MX31 Clock Control Module

2012-04-22 Thread Peter Chubb
For Linux to be able to work out how fast its clocks are going, so
that timer ticks come approximately at the right time, it needs to
be able to query the clock control module (CCM). 

This is the start of a CCM implementation.  It currently knows only about 
the MCU, HSP and IPG clocks --- i.e., the ones used to feed the periodic 
and general purpose timers.

Signed-off-by: Peter Chubb 

---
 Makefile.target |2 
 hw/imx.h|   10 +
 hw/imx_ccm.c|  312 
 3 files changed, 323 insertions(+), 1 deletion(-)

Index: qemu-working/Makefile.target
===
--- qemu-working.orig/Makefile.target   2012-04-23 08:24:52.106056219 +1000
+++ qemu-working/Makefile.target2012-04-23 08:24:52.945842194 +1000
@@ -399,7 +399,7 @@ obj-arm-y += vexpress.o
 obj-arm-y += strongarm.o
 obj-arm-y += collie.o
 obj-arm-y += pl041.o lm4549.o
-obj-arm-y += imx_serial.o
+obj-arm-y += imx_serial.o imx_ccm.o
 obj-arm-$(CONFIG_FDT) += device_tree.o
 
 obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
Index: qemu-working/hw/imx_ccm.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_ccm.c   2012-04-23 08:24:52.945842194 +1000
@@ -0,0 +1,312 @@
+/*
+ * IMX31 Clock Control Module
+ *
+ * Copyright (C) 2012 NICTA
+ *
+ * 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.h"
+#include "sysbus.h"
+#include "sysemu.h"
+#include "imx.h"
+
+#define CKIH_FREQ 2600 /* 26MHz crystal input */
+#define CKIL_FREQ32768 /* nominal 32khz clock */
+
+
+//#define DEBUG_CCM 1
+#ifdef DEBUG_CCM
+#define DPRINTF(fmt, args...) \
+do { printf("imx_ccm: " fmt , ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...) do {} while (0)
+#endif
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+
+uint32_t ccmr;
+uint32_t pdr0;
+uint32_t pdr1;
+uint32_t mpctl;
+uint32_t spctl;
+uint32_t cgr[3];
+uint32_t pmcr0;
+uint32_t pmcr1;
+
+/* Frequencies precalculated on register changes */
+uint32_t pll_refclk_freq;
+uint32_t mcu_clk_freq;
+uint32_t hsp_clk_freq;
+uint32_t ipg_clk_freq;
+} IMXCCMState;
+
+static const VMStateDescription vmstate_imx_ccm = {
+.name = "imx-ccm",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(ccmr, IMXCCMState),
+VMSTATE_UINT32(pdr0, IMXCCMState),
+VMSTATE_UINT32(pdr1, IMXCCMState),
+VMSTATE_UINT32(mpctl, IMXCCMState),
+VMSTATE_UINT32(spctl, IMXCCMState),
+VMSTATE_UINT32_ARRAY(cgr, IMXCCMState, 3),
+VMSTATE_UINT32(pmcr0, IMXCCMState),
+VMSTATE_UINT32(pmcr1, IMXCCMState),
+VMSTATE_UINT32(pll_refclk_freq, IMXCCMState),
+VMSTATE_UINT32(mcu_clk_freq, IMXCCMState),
+VMSTATE_UINT32(hsp_clk_freq, IMXCCMState),
+VMSTATE_UINT32(ipg_clk_freq, IMXCCMState),
+},
+};
+
+/* CCMR */
+#define CCMR_FPME (1<<0)
+#define CCMR_MPE  (1<<3)
+#define CCMR_MDS  (1<<7)
+#define CCMR_FPMF (1<<26)
+#define CCMR_PRCS (3<<1)
+
+/* PDR0 */
+#define PDR0_MCU_PODF_SHIFT (0)
+#define PDR0_MCU_PODF_MASK (0x7)
+#define PDR0_MAX_PODF_SHIFT (3)
+#define PDR0_MAX_PODF_MASK (0x7)
+#define PDR0_IPG_PODF_SHIFT (6)
+#define PDR0_IPG_PODF_MASK (0x3)
+#define PDR0_NFC_PODF_SHIFT (8)
+#define PDR0_NFC_PODF_MASK (0x7)
+#define PDR0_HSP_PODF_SHIFT (11)
+#define PDR0_HSP_PODF_MASK (0x7)
+#define PDR0_PER_PODF_SHIFT (16)
+#define PDR0_PER_PODF_MASK (0x1f)
+#define PDR0_CSI_PODF_SHIFT (23)
+#define PDR0_CSI_PODF_MASK (0x1ff)
+
+#define EXTRACT(value, name) (((value) >> PDR0_##name##_PODF_SHIFT) \
+  & PDR0_##name##_PODF_MASK)
+#define INSERT(value, name) (((value) & PDR0_##name##_PODF_MASK) << \
+ PDR0_##name##_PODF_SHIFT)
+/* PLL control registers */
+#define PD(v) (((v) >> 26) & 0xf)
+#define MFD(v) (((v) >> 16) & 0x3ff)
+#define MFI(v) (((v) >> 10) & 0xf);
+#define MFN(v) ((v) & 0x3ff)
+
+#define PLL_PD(x)   (((x) & 0xf) << 26)
+#define PLL_MFD(x)  (((x) & 0x3ff) << 16)
+#define PLL_MFI(x)  (((x) & 0xf) << 10)
+#define PLL_MFN(x)  (((x) & 0x3ff) << 0)
+
+uint32_t imx_clock_frequency(DeviceState *dev, IMXClk clock)
+{
+IMXCCMState *s = container_of(dev, IMXCCMState, busdev.qdev);
+
+switch (clock) {
+case NOCLK:
+return 0;
+case MCU:
+return s->mcu_clk_freq;
+case HSP:
+

[Qemu-devel] [PATCH v6 0/5] FreeSCALE i.MX31 support

2012-04-22 Thread Peter Chubb
Hi all,
   Most of the files are unchanged since last time.  Main differences
   are:
   -- Change the way the timers are hooked up to the board to address
  Peter M's review comments.
   -- Move timer tick rate limiting out of the imx-timers implementation into a
  separate patch (not in this series) against ptimer.c
   -- Move function prototypes in imx.h into the correct patch.

Peter C

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



[Qemu-devel] [PATCH] Limit ptimer rate to something achievable

2012-04-19 Thread Peter Chubb

If a guest sets very short timeouts, and asks for a timer to be reloaded on 
timeout, QEMU can go to 100%CPU utilisation and become unresponsive,
as it is spending all its time generating timeout interrupts.  On real
hardware this doesn't matter, as the interrupts are just coalesced,
and the effect is to have the interrupt asserted all the time.

This patch is a band-aid, that prevents timeouts less than 10
microseconds from being set.  10 microseconds is a limit that was
determined empirically on a variety of machines as the shortest that
allowed QEMU to pick up a control-a c sequence to get at the monitor.

Reported-by: Anna Lyons 
Signed-off-by: Peter Chubb 

---
 hw/ptimer.c |   13 +
 1 file changed, 13 insertions(+)

Index: qemu-working/hw/ptimer.c
===
--- qemu-working.orig/hw/ptimer.c   2012-04-20 15:09:09.317922659 +1000
+++ qemu-working/hw/ptimer.c2012-04-20 15:30:42.108486207 +1000
@@ -180,6 +180,19 @@ void ptimer_set_freq(ptimer_state *s, ui
count = limit.  */
 void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload)
 {
+/*
+ * Artificially limit timeout rate to something
+ * achievable under QEMU.  Otherwise, QEMU spends all
+ * its time generating timer interrupts, and there
+ * is no forward progress.
+ * About ten microseconds is the fastest that really works
+ * on the current generation of host machines.
+ */
+
+if (limit * s->period < 1 && s->period) {
+limit = 1 / s->period;
+}
+
 s->limit = limit;
 if (reload)
 s->delta = limit;
--
Dr Peter Chubb  peter.chubb AT nicta.com.au
http://www.ssrg.nicta.com.au  Software Systems Research Group/NICTA



Re: [Qemu-devel] [patch V5 3/5] FreeSCALE i.MX31 support: Timers

2012-04-09 Thread Peter Chubb
>>>>> "Peter" == Peter Chubb  writes:

Peter> I'm not sure how to make qdev properties work.  The timers need
Peter> to be able to get at the CCM-generated frequencies, which of
Peter> course are private to the CCM.

I've just split the problematic function into two:
iomx_timerg_create() and imx_timerp_create(). That gets rid of the
strcmp, and makes it more obvious what's going on.  Because there will
only ever be one CCM, there's no point in making it a property.

I'm still not sure what to do about rate-limiting timer timeouts.  I
agree with you, Peter M, that it should be handled in the QEMU timer
layer somewhere.  Having had another look at the code, I really don't
want to touch it.

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 V5 3/5] FreeSCALE i.MX31 support: Timers

2012-04-09 Thread Peter Chubb
>>>>> "Peter" == Peter Maydell  writes:

Peter> On 3 April 2012 02:55, Peter Chubb 
Peter> wrote:

>+/*
>+ * Artificially limit tick rate to something
>+ * achievable under QEMU.  Otherwise, QEMU spends all
>+ * its time generating timer interrupts, and there
>+ * is no forward progress.
>+ * About ten microseconds is the fastest that really works.
>+ */
>+if ((value * 100)/s->freq < 10) {
>+value = 10*100/s->freq;
>+}
>+ptimer_set_limit(s->timer, value, !!(s->cr & CR_IOVW));
>+break;
+
Peter> This seems like the wrong level to do this. If over-eager timer
Peter> ticks are a problem we ought to be applying the limit globally
Peter> in the timer infrastructure layer somewhere, not via ad-hoc
Peter> bandaids in individual device models.

There appears to be some attempt in some code paths to limit the
interval between timer ticks to 250us in the timer code, but tracing
the relationship between ptimers, qemu-timers and the underlying posix
timers is difficult.  In particular it's easy to create a ptimer that
runs so fast that QEMU spends all its time there.  On real hardware
this isn't a problem --- interrupts end up being coalesced, 

I have a test image that reliably hangs without this hack and the
corresponding one in the timerp code.  It works on the real hardware.



>> +void imx_timer_create(const char * const name, +                  
>>            const target_phys_addr_t addr, +                        
>>      qemu_irq irq, +                              DeviceState *ccm)
>> +{ +    IMXTimerGState *gp; +    IMXTimerPState *pp; +  
>>  DeviceState *dev; + +    dev = sysbus_create_simple(name, addr,
>> irq); +    if (strcmp(name, "imx_timerp") == 0) { +        pp =
>> container_of(dev, IMXTimerPState, busdev.qdev); +        pp->ccm =
>> ccm; +    } else { +        gp = container_of(dev, IMXTimerGState,
>> busdev.qdev); +        gp->ccm = ccm; +    } + +}

Peter> This is wrong in two ways: (a) strcmp() on the device name is
Peter> pretty ugly (b) this kind of helper creation method mustn't go
Peter> reaching into the implementation of the device like this. If
Peter> you need to hand something to the device it needs to be a qdev
Peter> property.

I'm not sure how to make qdev properties work.  The timers need to be
able to get at the CCM-generated frequencies, which of course are
private to the CCM.

The same thing happens in the imx_serial emulation, to hook the right
serial device to the right host device.

Is there any documentation or appropriate examples anywhere?

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



Re: [Qemu-devel] [patch V5 2/5] Implement i.MX31 Clock Control Module

2012-04-09 Thread Peter Chubb
>>>>> "Peter" == Peter Maydell  writes:

Peter> On 3 April 2012 02:55, Peter Chubb 
Peter> wrote:
> +
> +uint32_t imx_timer_frequency(DeviceState *s, IMXClk clock);
> +void imx_timer_create(const char * const name,
> +  const target_phys_addr_t addr,
> +  qemu_irq irq,
> +  DeviceState *ccm);
> +

Peter> These function prototypes should be in the other patch, surely?

Yes. At least, the second one does.  Thanks, moved to the imx_timer.c patch.

>> +/* PDR0 */ +#define PDR0_MCU_PODF_SHIFT (0) +#define
>> PDR0_MCU_PODF_MASK (0x7) +#define PDR0_MAX_PODF_SHIFT (3) +#define
>> PDR0_MAX_PODF_MASK (0x7) +#define PDR0_IPG_PODF_SHIFT (6) +#define
>> PDR0_IPG_PODF_MASK (0x3) +#define PDR0_NFC_PODF_SHIFT (8) +#define
>> PDR0_NFC_PODF_MASK (7)

Peter> Some consistency about whether you're using 7 or 0x7 for masks
Peter> would be nice.

Done.

> +static void imx_ccm_reset(DeviceState *dev)
> +{
> +IMXCCMState *s = container_of(dev, IMXCCMState, busdev.qdev);
> +
> +s->cgr[0] = s->cgr[1] = s->cgr[2] = 0x;
> +s->pmcr0 = 0x80209828;
> +s->pdr1 = 0x49fcfe7f;
> +s->spctl = PLL_PD(1) | PLL_MFD(4) | PLL_MFI(0xc) | PLL_MFN(1);
> +
> +/*
> + * Really should predicate this on arm_boot_info->is_linux
> + * but I don't know how to do that.
> + */
> +if (1) {
> +imx_ccm_uboot_reset(s);
> +} else {
> +imx_ccm_hw_reset(s);
> +}
> +update_clocks(s);
> +}
> +

Peter> Urgh. Device models need to act like the device. Setting up
Peter> devices the way u-boot happens to initialise them should be
Peter> done somewhere else, ie driven by our built in bootloader, if
Peter> we do it at all.

I'd like to be able to do
  arm-system-qemu -M kzm -nographic -kernel zImage
and have it work the same as if it'd been booted on the real
hardware.

For now I've removed the u-boot stuff.

Is there a sane way to add to the built-in bootloader?  

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



[Qemu-devel] [patch V5 3/5] FreeSCALE i.MX31 support: Timers

2012-04-02 Thread Peter Chubb
Implement the timers on the FreeScale i.MX31 SoC.
This is not a complete implementation, but gives enough for 
Linux to boot and run. In particular external triggers, which are 
not useful under QEMU, are not implemented.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
---
 Makefile.target |2 
 hw/imx_timer.c  |  693 
 2 files changed, 694 insertions(+), 1 deletion(-)
 create mode 100644 hw/imx_timer.c

Index: qemu-working/hw/imx_timer.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_timer.c 2012-04-03 11:48:49.788710797 +1000
@@ -0,0 +1,693 @@
+/*
+ * IMX31 Timer
+ *
+ * Copyright (c) 2008 OK Labs
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally Written by Hans Jiang
+ * Updated by Peter Chubb
+ *
+ * This code is licenced under GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw.h"
+#include "qemu-timer.h"
+#include "ptimer.h"
+#include "sysbus.h"
+#include "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
+
+/*
+ * GPT : General purpose timer
+ *
+ * This timer counts up continuously while it is enabled, resetting itself
+ * to 0 when it reaches TIMER_MAX (in freerun mode) or when it
+ * reaches the value of ocr1 (in periodic mode).  WE simulate this using a
+ * QEMU ptimer counting down from ocr1 and reloading from ocr1 in
+ * periodic mode, or counting from ocr1 to zero, then TIMER_MAX - ocr1.
+ * waiting_rov is set when counting from TIMER_MAX.
+ *
+ * In the real hardware, there are three comparison registers that can
+ * trigger interrupts, and compare channel 1 can be used to
+ * force-reset the timer. However, this is a `bare-bones'
+ * implementation: only what Linux 3.x uses has been implemented
+ * (free-running timer from 0 to OCR1 or TIMER_MAX) .
+ */
+
+
+#define TIMER_MAX  0XUL
+
+/* Control register.  Not all of these bits have any effect (yet) */
+#define GPT_CR_EN (1 << 0)  /* GPT Enable */
+#define GPT_CR_ENMOD  (1 << 1)  /* GPT Enable Mode */
+#define GPT_CR_DBGEN  (1 << 2)  /* GPT Debug mode enable */
+#define GPT_CR_WAITEN (1 << 3)  /* GPT Wait Mode Enable  */
+#define GPT_CR_DOZEN  (1 << 4)  /* GPT Doze mode enable */
+#define GPT_CR_STOPEN (1 << 5)  /* GPT Stop Mode Enable */
+#define GPT_CR_CLKSRC_SHIFT (6)
+#define GPT_CR_CLKSRC_MASK  (0x7)
+
+#define GPT_CR_FRR(1 << 9)  /* Freerun or Restart */
+#define GPT_CR_SWR(1 << 15) /* Software Reset */
+#define GPT_CR_IM1(3 << 16) /* Input capture channel 1 mode (2 bits) */
+#define GPT_CR_IM2(3 << 18) /* Input capture channel 2 mode (2 bits) */
+#define GPT_CR_OM1(7 << 20) /* Output Compare Channel 1 Mode (3 bits) */
+#define GPT_CR_OM2(7 << 23) /* Output Compare Channel 2 Mode (3 bits) */
+#define GPT_CR_OM3(7 << 26) /* Output Compare Channel 3 Mode (3 bits) */
+#define GPT_CR_FO1(1 << 29) /* Force Output Compare Channel 1 */
+#define GPT_CR_FO2(1 << 30) /* Force Output Compare Channel 2 */
+#define GPT_CR_FO3(1 << 31) /* Force Output Compare Channel 3 */
+
+#define GPT_SR_OF1  (1 << 0)
+#define GPT_SR_ROV  (1 << 5)
+
+#define GPT_IR_OF1IE  (1 << 0)
+#define GPT_IR_ROVIE  (1 << 5)
+
+typedef struct {
+SysBusDevice busdev;
+ptimer_state *timer;
+MemoryRegion iomem;
+DeviceState *ccm;
+
+uint32_t cr;
+uint32_t pr;
+uint32_t sr;
+uint32_t ir;
+uint32_t ocr1;
+uint32_t cnt;
+
+uint32_t waiting_rov;
+qemu_irq irq;
+} IMXTimerGState;
+
+static const VMStateDescription vmstate_imx_timerg = {
+.name = "imx-timerg",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields  = (VMStateField[]) {
+VMSTATE_UINT32(cr, IMXTimerGState),
+VMSTATE_UINT32(pr, IMXTimerGState),
+VMSTATE_UINT32(sr, IMXTimerGState),
+VMSTATE_UINT32(ir, IMXTimerGState),
+VMSTATE_UINT32(ocr1, IMXTimerGState),
+VMSTATE_UINT32(cnt, IMXTimerGState),
+VMSTATE_UINT32(waiting_rov, IMXTimerGState),
+VMSTATE_PTIMER(timer, IMXTimerGState),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static const IMXClk imx_tim

[Qemu-devel] [patch V5 1/5] i.MX UART support

2012-04-02 Thread Peter Chubb
Implement the FreeScale i.MX UART.  This uart is used in a variety of
SoCs, including some by Motorola, as well as in the FreeScale i.MX
series.

This patch gives only a `bare-bones' implementation, enough to run Linux 
or OKL4, but that's about it.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
Reviewed-by: Peter Maydell 
---
 Makefile.target |1 
 hw/imx.h|   16 +
 hw/imx_serial.c |  467 
 3 files changed, 484 insertions(+)
 create mode 100644 hw/imx_serial.c

Index: qemu-working/hw/imx_serial.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_serial.c2012-04-03 11:48:47.732705764 +1000
@@ -0,0 +1,467 @@
+/*
+ * IMX31 UARTS
+ *
+ * Copyright (c) 2008 OKL
+ * Originally Written by Hans Jiang
+ * Copyright (c) 2011 NICTA Pty Ltd.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * This is a `bare-bones' implementation of the IMX series serial ports.
+ * TODO:
+ *  -- implement FIFOs.  The real hardware has 32 word transmit
+ *   and receive FIFOs; we currently use a 1-char buffer
+ *  -- implement DMA
+ *  -- implement BAUD-rate and modem lines, for when the backend
+ * is a real serial device.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "sysemu.h"
+#include "qemu-char.h"
+#include "imx.h"
+
+//#define DEBUG_SERIAL 1
+#ifdef DEBUG_SERIAL
+#define DPRINTF(fmt, args...) \
+do { printf("imx_serial: " 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
+#ifdef DEBUG_IMPLEMENTATION
+#  define IPRINTF(fmt, args...) \
+do  { fprintf(stderr, "imx_serial: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+int32_t readbuff;
+
+uint32_t usr1;
+uint32_t usr2;
+uint32_t ucr1;
+uint32_t ucr2;
+uint32_t uts1;
+
+/*
+ * The registers below are implemented just so that the
+ * guest OS sees what it has written
+ */
+uint32_t onems;
+uint32_t ufcr;
+uint32_t ubmr;
+uint32_t ubrc;
+uint32_t ucr3;
+
+qemu_irq irq;
+CharDriverState *chr;
+} IMXSerialState;
+
+static const VMStateDescription vmstate_imx_serial = {
+.name = "imx-serial",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_INT32(readbuff, IMXSerialState),
+VMSTATE_UINT32(usr1, IMXSerialState),
+VMSTATE_UINT32(usr2, IMXSerialState),
+VMSTATE_UINT32(ucr1, IMXSerialState),
+VMSTATE_UINT32(uts1, IMXSerialState),
+VMSTATE_UINT32(onems, IMXSerialState),
+VMSTATE_UINT32(ufcr, IMXSerialState),
+VMSTATE_UINT32(ubmr, IMXSerialState),
+VMSTATE_UINT32(ubrc, IMXSerialState),
+VMSTATE_UINT32(ucr3, IMXSerialState),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+#define URXD_CHARRDY(1<<15)   /* character read is valid */
+#define URXD_ERR(1<<14)   /* Character has error */
+#define URXD_BRK(1<<11)   /* Break received */
+
+#define USR1_PARTYER(1<<15)   /* Parity Error */
+#define USR1_RTSS   (1<<14)   /* RTS pin status */
+#define USR1_TRDY   (1<<13)   /* Tx ready */
+#define USR1_RTSD   (1<<12)   /* RTS delta: pin changed state */
+#define USR1_ESCF   (1<<11)   /* Escape sequence interrupt */
+#define USR1_FRAMERR(1<<10)   /* Framing error  */
+#define USR1_RRDY   (1<<9)/* receiver ready */
+#define USR1_AGTIM  (1<<8)/* Aging timer interrupt */
+#define USR1_DTRD   (1<<7)/* DTR changed */
+#define USR1_RXDS   (1<<6)/* Receiver is idle */
+#define USR1_AIRINT (1<<5)/* Aysnch IR interrupt */
+#define USR1_AWAKE  (1<<4)/* Falling edge detected on RXd pin */
+
+#define USR2_ADET   (1<<15)   /* Autobaud complete */
+#define USR2_TXFE   (1<<14)   /* Transmit FIFO empty */
+#define USR2_DTRF   (1<<13)   /* DTR/DSR transition */
+#define USR2_IDLE   (1<<12)   /* UART has been idle for too long */
+#define USR2_ACST   (1<<11)   /* Autobaud counter stopped */
+#define USR2_RIDELT (1<<10)   /* Ring Indicator delta */
+#define USR2_RIIN   (1<<9)/* Ring Indicator Input */
+#define USR2_IRINT  (1<<8)/* Serial Infrared Interrupt */
+#define USR2_WAKE   (1<<7)/* Start bit detected */
+#def

[Qemu-devel] [patch V5 4/5] FreeSCALE i.MX31 support: AVIC

2012-04-02 Thread Peter Chubb
Implement the FreeSCALE i.MX31 advanced vectored interrupt controller, at least
to the extent it is used by Linux 3.0.x

Vectors are not implemented.

Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
Reviewed-by: Peter Maydell 

---
 Makefile.target |2 
 hw/imx_avic.c   |  409 
 2 files changed, 410 insertions(+), 1 deletion(-)
 create mode 100644 hw/imx_avic.c

Index: qemu-working/hw/imx_avic.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_avic.c  2012-04-03 11:48:50.900713524 +1000
@@ -0,0 +1,409 @@
+/*
+ * IMX31 Vectored Interrupt Controller
+ *
+ * Note this is NOT the PL192 provided by ARM, but
+ * a custom implementation by FreeScale.
+ *
+ * Copyright (c) 2008 OKL
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally Written by Hans Jiang
+ *
+ * This code is licenced under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * TODO: implement vectors.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "host-utils.h"
+
+#define DEBUG_INT 1
+#undef DEBUG_INT /* comment out for debugging */
+
+#ifdef DEBUG_INT
+#define DPRINTF(fmt, args...) \
+do { printf("imx_avic: " 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_avic: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+#define IMX_AVIC_NUM_IRQS 64
+
+/* Interrupt Control Bits */
+#define ABFLAG (1<<25)
+#define ABFEN (1<<24)
+#define NIDIS (1<<22) /* Normal Interrupt disable */
+#define FIDIS (1<<21) /* Fast interrupt disable */
+#define NIAD  (1<<20) /* Normal Interrupt Arbiter Rise ARM level */
+#define FIAD  (1<<19) /* Fast Interrupt Arbiter Rise ARM level */
+#define NM(1<<18) /* Normal interrupt mode */
+
+
+#define PRIO_PER_WORD (sizeof(uint32_t) * 8 / 4)
+#define PRIO_WORDS (IMX_AVIC_NUM_IRQS/PRIO_PER_WORD)
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+uint64_t pending;
+uint64_t enabled;
+uint64_t is_fiq;
+uint32_t intcntl;
+uint32_t intmask;
+qemu_irq irq;
+qemu_irq fiq;
+uint32_t prio[PRIO_WORDS]; /* Priorities are 4-bits each */
+} IMXAVICState;
+
+static const VMStateDescription vmstate_imx_avic = {
+.name = "imx-avic",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT64(pending, IMXAVICState),
+VMSTATE_UINT64(enabled, IMXAVICState),
+VMSTATE_UINT64(is_fiq, IMXAVICState),
+VMSTATE_UINT32(intcntl, IMXAVICState),
+VMSTATE_UINT32(intmask, IMXAVICState),
+VMSTATE_UINT32_ARRAY(prio, IMXAVICState, PRIO_WORDS),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+
+static inline int imx_avic_prio(IMXAVICState *s, int irq)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+return 0xf & (s->prio[word] >> part);
+}
+
+static inline void imx_avic_set_prio(IMXAVICState *s, int irq, int prio)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+uint32_t mask = ~(0xf << part);
+s->prio[word] &= mask;
+s->prio[word] |= prio << part;
+}
+
+/* Update interrupts.  */
+static void imx_avic_update(IMXAVICState *s)
+{
+int i;
+uint64_t new = s->pending & s->enabled;
+uint64_t flags;
+
+flags = new & s->is_fiq;
+qemu_set_irq(s->fiq, !!flags);
+
+flags = new & ~s->is_fiq;
+if (!flags || (s->intmask == 0x1f)) {
+qemu_set_irq(s->irq, !!flags);
+return;
+}
+
+/*
+ * Take interrupt if there's a pending interrupt with
+ * priority higher than the value of intmask
+ */
+for (i = 0; i < IMX_AVIC_NUM_IRQS; i++) {
+if (flags & (1UL << i)) {
+if (imx_avic_prio(s, i) > s->intmask) {
+qemu_set_irq(s->irq, 1);
+return;
+}
+}
+}
+qemu_set_irq(s->irq, 0);
+}
+
+static void imx_avic_set_irq(void *opaque, int irq, int level)
+{
+IMXAVICState *s = (IMXAVICState *)opaque;
+
+if (level) {
+DPRINTF("Raising IRQ %d, prio %d\n",
+irq, imx_avic_prio(s, irq));
+s->pending |= (1ULL << irq);
+} else {
+DPRINTF("Clearing IRQ %d, prio %d\n",
+irq, imx_avic_prio(s, irq));
+s->pending &= ~(1ULL << irq);
+}
+
+

[Qemu-devel] [patch V5 2/5] Implement i.MX31 Clock Control Module

2012-04-02 Thread Peter Chubb
For Linux to be able to work out how fast its clocks are going, so
that timer ticks come approximately at the right time, it needs to
be able to query the clock control module (CCM). 

This is the start of a CCM implementation.  It currently knows only about 
the MCU, HSP and IPG clocks --- i.e., the ones used to feed the periodic 
and general purpose timers.

Signed-off-by: Peter Chubb 

---
 Makefile.target |2 
 hw/imx.h|   14 ++
 hw/imx_ccm.c|  334 
 3 files changed, 349 insertions(+), 1 deletion(-)

Index: qemu-working/Makefile.target
===
--- qemu-working.orig/Makefile.target   2012-04-03 11:48:48.088706634 +1000
+++ qemu-working/Makefile.target2012-04-03 11:48:48.776708322 +1000
@@ -393,7 +393,7 @@ obj-arm-y += vexpress.o
 obj-arm-y += strongarm.o
 obj-arm-y += collie.o
 obj-arm-y += pl041.o lm4549.o
-obj-arm-y += imx_serial.o
+obj-arm-y += imx_serial.o imx_ccm.o
 obj-arm-$(CONFIG_FDT) += device_tree.o
 
 obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
Index: qemu-working/hw/imx.h
===
--- qemu-working.orig/hw/imx.h  2012-04-03 11:48:48.088706634 +1000
+++ qemu-working/hw/imx.h   2012-04-03 11:48:48.776708322 +1000
@@ -13,4 +13,18 @@
 
 void imx_serial_create(int uart, const target_phys_addr_t addr, qemu_irq irq);
 
+typedef enum  {
+NOCLK,
+MCU,
+HSP,
+IPG,
+CLK_32k
+} IMXClk;
+
+uint32_t imx_timer_frequency(DeviceState *s, IMXClk clock);
+void imx_timer_create(const char * const name,
+  const target_phys_addr_t addr,
+  qemu_irq irq,
+  DeviceState *ccm);
+
 #endif /* IMX_H */
Index: qemu-working/hw/imx_ccm.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_ccm.c   2012-04-03 11:48:48.776708322 +1000
@@ -0,0 +1,334 @@
+/*
+ * IMX31 Clock Control Module
+ *
+ * Copyright (C) 2012 NICTA
+ *
+ * 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.h"
+#include "sysbus.h"
+#include "sysemu.h"
+#include "imx.h"
+
+#define CKIH_FREQ 2600 /* 26MHz crystal input */
+#define CKIL_FREQ32768 /* nominal 32khz clock */
+
+
+//#define DEBUG_CCM 1
+#ifdef DEBUG_CCM
+#define DPRINTF(fmt, args...) \
+do { printf("imx_ccm: " fmt , ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...) do {} while (0)
+#endif
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+
+uint32_t ccmr;
+uint32_t pdr0;
+uint32_t pdr1;
+uint32_t mpctl;
+uint32_t spctl;
+uint32_t cgr[3];
+uint32_t pmcr0;
+uint32_t pmcr1;
+
+/* Frequencies precalculated on register changes */
+uint32_t pll_refclk_freq;
+uint32_t mcu_clk_freq;
+uint32_t hsp_clk_freq;
+uint32_t ipg_clk_freq;
+} IMXCCMState;
+
+static const VMStateDescription vmstate_imx_ccm = {
+.name = "imx-ccm",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(ccmr, IMXCCMState),
+VMSTATE_UINT32(pdr0, IMXCCMState),
+VMSTATE_UINT32(pdr1, IMXCCMState),
+VMSTATE_UINT32(mpctl, IMXCCMState),
+VMSTATE_UINT32(spctl, IMXCCMState),
+VMSTATE_UINT32_ARRAY(cgr, IMXCCMState, 3),
+VMSTATE_UINT32(pmcr0, IMXCCMState),
+VMSTATE_UINT32(pmcr1, IMXCCMState),
+VMSTATE_UINT32(pll_refclk_freq, IMXCCMState),
+VMSTATE_UINT32(mcu_clk_freq, IMXCCMState),
+VMSTATE_UINT32(hsp_clk_freq, IMXCCMState),
+VMSTATE_UINT32(ipg_clk_freq, IMXCCMState),
+},
+};
+
+/* CCMR */
+#define CCMR_FPME (1<<0)
+#define CCMR_MPE  (1<<3)
+#define CCMR_MDS  (1<<7)
+#define CCMR_FPMF (1<<26)
+#define CCMR_PRCS (3<<1)
+
+/* PDR0 */
+#define PDR0_MCU_PODF_SHIFT (0)
+#define PDR0_MCU_PODF_MASK (0x7)
+#define PDR0_MAX_PODF_SHIFT (3)
+#define PDR0_MAX_PODF_MASK (0x7)
+#define PDR0_IPG_PODF_SHIFT (6)
+#define PDR0_IPG_PODF_MASK (0x3)
+#define PDR0_NFC_PODF_SHIFT (8)
+#define PDR0_NFC_PODF_MASK (7)
+#define PDR0_HSP_PODF_SHIFT (11)
+#define PDR0_HSP_PODF_MASK (7)
+#define PDR0_PER_PODF_SHIFT (16)
+#define PDR0_PER_PODF_MASK (0x1f)
+#define PDR0_CSI_PODF_SHIFT (23)
+#define PDR0_CSI_PODF_MASK (0x1ff)
+
+#define EXTRACT(value, name) (((value) >> PDR0_##name##_PODF_SHIFT) \
+  & PDR0_##name##_PODF_MASK)
+#define INSERT(value, name) (((value) & PDR0_##name##_PODF_MASK) << \
+ PDR0_##name##_PODF_SHIFT)
+/* PLL control registers */
+#define PD(v) (((v

[Qemu-devel] [patch V5 0/5] i.MX31 support

2012-04-02 Thread Peter Chubb
This is the fifth round of patches for preliminary Freescale i.MX31
support.

The only changes in the patches for imx UART and AVIC are the
CamelCasing of the typedef names, and removal of unwanted #include
files.

The major change has been in the timer implementation.  I've added a
partial implementation of the clock control module, so that Linux gets
the frequency of the clocks right, and totally reimplemented the
general-purpose timer in terms of QEMU ptimers.

This meant a small change to the board-level file, hw/kzm.c so that
the timers could know about the CCM.

I've tested the result with Linux 3.3.0 and a variety of unit tests.
DVFS is still not implemented; but apart from that, timer ticks seem to
come at around the right rate, and the timer values when read are sane.

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



[Qemu-devel] [patch V5 5/5] FreeSCALE i.MX31 support: KZM-ARM11-01 evaluation board

2012-04-02 Thread Peter Chubb
Board support for Kyoto Micro's KZM-ARM11-01, an evaluation board built
around the FreeScale i.MX31.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 

---
 Makefile.target |2 
 hw/kzm.c|  161 
 2 files changed, 162 insertions(+), 1 deletion(-)
 create mode 100644 hw/kzm.c

Index: qemu-working/hw/kzm.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/kzm.c   2012-04-03 11:48:51.876715919 +1000
@@ -0,0 +1,161 @@
+/*
+ * KZM Board System emulation.
+ *
+ * Copyright (c) 2008 OKL and 2011 NICTA
+ * Written by Hans
+ * Updated by Peter Chubb.
+ *
+ * This code is licenced under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a Kyoto Microcomputer
+ * KZM-ARM11-01 evaluation board, with a FreeScale
+ * I.MX31 SoC
+ */
+
+#include "sysbus.h"
+#include "exec-memory.h"
+#include "hw.h"
+#include "arm-misc.h"
+#include "devices.h"
+#include "net.h"
+#include "sysemu.h"
+#include "boards.h"
+#include "pc.h" /* for the FPGA UART that emulates a 16550 */
+#include "imx.h"
+
+/* Memory map for Kzm Emulation Baseboard:
+ * 0x-0x3fff 16k secure ROM   IGNORED
+ * 0x4000-0x00407fff Reserved IGNORED
+ * 0x00404000-0x00407fff ROM  IGNORED
+ * 0x00408000-0x0fff Reserved IGNORED
+ * 0x1000-0x1fffbfff RAM aliasing IGNORED
+ * 0x1fffc000-0x1fff RAM  EMULATED
+ * 0x2000-0x2fff Reserved IGNORED
+ * 0x3000-0x7fff I.MX31 Internal Register Space
+ *   0x43f0 IO_AREA0
+ *   0x43f9 UART1 EMULATED
+ *   0x43f94000 UART2 EMULATED
+ *   0x6800 AVIC  EMULATED
+ *   0x53f8 CCM   EMULATED
+ *   0x53f94000 PIT 1 EMULATED
+ *   0x53f98000 PIT 2 EMULATED
+ *   0x53f9 GPT   EMULATED
+ * 0x8000-0x87ff RAM  EMULATED
+ * 0x8800-0x8fff RAM Aliasing EMULATED
+ * 0xa000-0xafff NAND Flash   IGNORED
+ * 0xb000-0xb3ff Unavailable  IGNORED
+ * 0xb400-0xb4000fff 8-bit free space IGNORED
+ * 0xb4001000-0xb400100f Board controlIGNORED
+ *  0xb4001003   DIP switch
+ * 0xb4001010-0xb400101f 7-segment LEDIGNORED
+ * 0xb4001020-0xb400102f LED  IGNORED
+ * 0xb4001030-0xb400103f LED  IGNORED
+ * 0xb4001040-0xb400104f FPGA, UART   EMULATED
+ * 0xb4001050-0xb400105f FPGA, UART   EMULATED
+ * 0xb4001060-0xb40f FPGA IGNORED
+ * 0xb600-0xb61f LAN controller   EMULATED
+ * 0xb620-0xb62f FPGA NAND Controller IGNORED
+ * 0xb630-0xb7ff Free IGNORED
+ * 0xb800-0xb8004fff Memory control registers IGNORED
+ * 0xc000-0xc3ff PCMCIA/CFIGNORED
+ * 0xc400-0x Reserved IGNORED
+ */
+
+#define KZM_RAMADDRESS (0x8000)
+#define KZM_FPGA   (0xb4001040)
+
+static struct arm_boot_info kzm_binfo = {
+.loader_start = KZM_RAMADDRESS,
+.board_id = 1722,
+};
+
+static void kzm_init(ram_addr_t ram_size,
+ const char *boot_device,
+ const char *kernel_filename, const char *kernel_cmdline,
+ const char *initrd_filename, const char *cpu_model)
+{
+CPUARMState *env;
+MemoryRegion *address_space_mem = get_system_memory();
+MemoryRegion *ram = g_new(MemoryRegion, 1);
+MemoryRegion *sram = g_new(MemoryRegion, 1);
+MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
+qemu_irq *cpu_pic;
+DeviceState *dev;
+DeviceState *ccm;
+
+if (!cpu_model) {
+cpu_model = "arm1136";
+}
+
+env = cpu_init(cpu_model);
+if (!env) {
+fprintf(stderr, "Unable to find CPU definition\n");
+exit(1);
+}
+
+/* On a real system, the first 16k is a `secure boot rom' */
+
+memory_region_init_ram(ram, "kzm.ram", ram_size);
+vmstate_register_ram_global(ram);
+memory_region_add_subregion(address_space_mem, KZM_RAMADDRESS, ram);
+
+memory_region_init_alias(ram_alias, "ram.alias", ram, 0, ram_size);
+memory_region_add_subregion(address_space_mem, 0x8800, ram_alias);
+
+memory_region_init_ram(sram, "kzm.sram", 0x4000);
+memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
+
+
+cpu_pic = arm_pic_init_cpu(env);
+de

Re: [Qemu-devel] [patch V4 1/4] i.MX UART support

2012-03-15 Thread Peter Chubb
Thanks for your reviewing time and expertise Peter. It's much
appreciated.

May I add your Reviewed-By: line to the imx-serial patch too?  The
only change is CamelCasing the typedef.

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 V4 2/4] FreeSCALE i.MX31 support: Timers

2012-03-15 Thread Peter Chubb
>>>>> "Peter" == Peter Maydell  writes:

Peter> ...that would work better if I cc'd the people I meant to...

Peter> On 15 March 2012 17:08, Peter Maydell
Peter>  wrote:
>> On 9 March 2012 03:27,   wrote:
>>> Implement the timers on the FreeScale i.MX31 SoC.  This is not a
>>> complete implementation, but gives enough for Linux to boot and
>>> run. In particular external triggers, which are not useful under
>>> QEMU, are not implemented.
>> 
>> 

>> The rest looks OK to me but I'm not very good with qemu's timer
>> API. Paolo or Paul -- could you check this looks ok on that front?
>> 

Yes please!  I think there's a bug in there somewhere when using the G
timer, as interrupts appear to arrive too far apart in some modes.

The scaling is probably wrong somewhere.

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



[Qemu-devel] [patch V4 1/4] i.MX UART support

2012-03-08 Thread peter . chubb
Implement the FreeScale i.MX UART.  This uart is used in a variety of
SoCs, including some by Motorola, as well as in the FreeScale i.MX
series.

This patch gives only a `bare-bones' implementation, enough to run Linux 
or OKL4, but that's about it.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
---
 Makefile.target |1 
 hw/imx_serial.c |  466 
 2 files changed, 467 insertions(+)
 create mode 100644 hw/imx_serial.c

Index: qemu-working/hw/imx_serial.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_serial.c2012-03-09 14:13:49.714061283 +1100
@@ -0,0 +1,466 @@
+/*
+ * IMX31 UARTS
+ *
+ * Copyright (c) 2008 OKL
+ * Originally Written by Hans Jiang
+ * Copyright (c) 2011 NICTA Pty Ltd.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * This is a `bare-bones' implementation of the IMX series serial ports.
+ * TODO:
+ *  -- implement FIFOs.  The real hardware has 32 word transmit
+ *   and receive FIFOs; we currently use a 1-char buffer
+ *  -- implement DMA
+ *  -- implement BAUD-rate and modem lines, for when the backend
+ * is a real serial device.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "sysemu.h"
+#include "qemu-char.h"
+#include "imx.h"
+
+//#define DEBUG_SERIAL 1
+#ifdef DEBUG_SERIAL
+#define DPRINTF(fmt, args...) \
+do { printf("imx_serial: " 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
+#ifdef DEBUG_IMPLEMENTATION
+#  define IPRINTF(fmt, args...) \
+do  { fprintf(stderr, "imx_serial: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+int32_t readbuff;
+
+uint32_t usr1;
+uint32_t usr2;
+uint32_t ucr1;
+uint32_t ucr2;
+uint32_t uts1;
+
+/*
+ * The registers below are implemented just so that the
+ * guest OS sees what it has written
+ */
+uint32_t onems;
+uint32_t ufcr;
+uint32_t ubmr;
+uint32_t ubrc;
+uint32_t ucr3;
+
+qemu_irq irq;
+CharDriverState *chr;
+} imx_state;
+
+static const VMStateDescription vmstate_imx_serial  = {
+.name = "imx-serial",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_INT32(readbuff, imx_state),
+VMSTATE_UINT32(usr1, imx_state),
+VMSTATE_UINT32(usr2, imx_state),
+VMSTATE_UINT32(ucr1, imx_state),
+VMSTATE_UINT32(uts1, imx_state),
+VMSTATE_UINT32(onems, imx_state),
+VMSTATE_UINT32(ufcr, imx_state),
+VMSTATE_UINT32(ubmr, imx_state),
+VMSTATE_UINT32(ubrc, imx_state),
+VMSTATE_UINT32(ucr3, imx_state),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+#define URXD_CHARRDY(1<<15)   /* character read is valid */
+#define URXD_ERR(1<<14)   /* Character has error */
+#define URXD_BRK(1<<11)   /* Break received */
+
+#define USR1_PARTYER(1<<15)   /* Parity Error */
+#define USR1_RTSS   (1<<14)   /* RTS pin status */
+#define USR1_TRDY   (1<<13)   /* Tx ready */
+#define USR1_RTSD   (1<<12)   /* RTS delta: pin changed state */
+#define USR1_ESCF   (1<<11)   /* Escape sequence interrupt */
+#define USR1_FRAMERR(1<<10)   /* Framing error  */
+#define USR1_RRDY   (1<<9)/* receiver ready */
+#define USR1_AGTIM  (1<<8)/* Aging timer interrupt */
+#define USR1_DTRD   (1<<7)/* DTR changed */
+#define USR1_RXDS   (1<<6)/* Receiver is idle */
+#define USR1_AIRINT (1<<5)/* Aysnch IR interrupt */
+#define USR1_AWAKE  (1<<4)/* Falling edge detected on RXd pin */
+
+#define USR2_ADET   (1<<15)   /* Autobaud complete */
+#define USR2_TXFE   (1<<14)   /* Transmit FIFO empty */
+#define USR2_DTRF   (1<<13)   /* DTR/DSR transition */
+#define USR2_IDLE   (1<<12)   /* UART has been idle for too long */
+#define USR2_ACST   (1<<11)   /* Autobaud counter stopped */
+#define USR2_RIDELT (1<<10)   /* Ring Indicator delta */
+#define USR2_RIIN   (1<<9)/* Ring Indicator Input */
+#define USR2_IRINT  (1<<8)/* Serial Infrared Interrupt */
+#define USR2_WAKE   (1<<7)/* Start bit detected */
+#define USR2_DCDDELT(1<<6)/* Data Carrier Detect delta */
+#define USR2_DCDIN  (1<<5)/* Dat

[Qemu-devel] [patch V4 3/4] FreeSCALE i.MX31 support: AVIC

2012-03-08 Thread peter . chubb
Implement the FreeSCALE i.MX31 advanced vectored interrupt controller, at least
to the extent it is used by Linux 3.0.x

Vectors are not implemented.

Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
---
 Makefile.target |2 
 hw/imx_avic.c   |  409 
 2 files changed, 410 insertions(+), 1 deletion(-)
 create mode 100644 hw/imx_avic.c

Index: qemu-working/hw/imx_avic.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_avic.c  2012-03-09 14:13:52.878104591 +1100
@@ -0,0 +1,409 @@
+/*
+ * IMX31 Vectored Interrupt Controller
+ *
+ * Note this is NOT the PL192 provided by ARM, but
+ * a custom implementation by FreeScale.
+ *
+ * Copyright (c) 2008 OKL
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally Written by Hans Jiang
+ *
+ * This code is licenced under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * TODO: implement vectors.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "host-utils.h"
+
+#define DEBUG_INT 1
+#undef DEBUG_INT /* comment out for debugging */
+
+#ifdef DEBUG_INT
+#define DPRINTF(fmt, args...) \
+do { printf("imx_avic: " 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_avic: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+#define IMX_AVIC_NUM_IRQS 64
+
+/* Interrupt Control Bits */
+#define ABFLAG (1<<25)
+#define ABFEN (1<<24)
+#define NIDIS (1<<22) /* Normal Interrupt disable */
+#define FIDIS (1<<21) /* Fast interrupt disable */
+#define NIAD  (1<<20) /* Normal Interrupt Arbiter Rise ARM level */
+#define FIAD  (1<<19) /* Fast Interrupt Arbiter Rise ARM level */
+#define NM(1<<18) /* Normal interrupt mode */
+
+
+#define PRIO_PER_WORD (sizeof(uint32_t) * 8 / 4)
+#define PRIO_WORDS (IMX_AVIC_NUM_IRQS/PRIO_PER_WORD)
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+uint64_t pending;
+uint64_t enabled;
+uint64_t is_fiq;
+uint32_t intcntl;
+uint32_t intmask;
+qemu_irq irq;
+qemu_irq fiq;
+uint32_t prio[PRIO_WORDS]; /* Priorities are 4-bits each */
+} imx_avic_state;
+
+static const VMStateDescription vmstate_imx_avic = {
+.name = "imx-avic",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT64(pending, imx_avic_state),
+VMSTATE_UINT64(enabled, imx_avic_state),
+VMSTATE_UINT64(is_fiq, imx_avic_state),
+VMSTATE_UINT32(intcntl, imx_avic_state),
+VMSTATE_UINT32(intmask, imx_avic_state),
+VMSTATE_UINT32_ARRAY(prio, imx_avic_state, PRIO_WORDS),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+
+static inline int imx_avic_prio(imx_avic_state *s, int irq)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+return 0xf & (s->prio[word] >> part);
+}
+
+static inline void imx_avic_set_prio(imx_avic_state *s, int irq, int prio)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+uint32_t mask = ~(0xf << part);
+s->prio[word] &= mask;
+s->prio[word] |= prio << part;
+}
+
+/* Update interrupts.  */
+static void imx_avic_update(imx_avic_state *s)
+{
+int i;
+uint64_t new = s->pending & s->enabled;
+uint64_t flags;
+
+flags = new & s->is_fiq;
+qemu_set_irq(s->fiq, !!flags);
+
+flags = new & ~s->is_fiq;
+if (!flags || (s->intmask == 0x1f)) {
+qemu_set_irq(s->irq, !!flags);
+return;
+}
+
+/*
+ * Take interrupt if there's a pending interrupt with
+ * priority higher than the value of intmask
+ */
+for (i = 0; i < IMX_AVIC_NUM_IRQS; i++) {
+if (flags & (1UL << i)) {
+if (imx_avic_prio(s, i) > s->intmask) {
+qemu_set_irq(s->irq, 1);
+return;
+}
+}
+}
+qemu_set_irq(s->irq, 0);
+}
+
+static void imx_avic_set_irq(void *opaque, int irq, int level)
+{
+imx_avic_state *s = (imx_avic_state *)opaque;
+
+if (level) {
+DPRINTF("Raising IRQ %d, prio %d\n",
+irq, imx_avic_prio(s, irq));
+s->pending |= (1ULL << irq);
+} else {
+DPRINTF("Clearing IRQ %d, prio %d\n",
+irq, imx_avic_prio(s, irq));
+s->pending &= ~(1ULL << irq);
+}
+
+imx_

[Qemu-devel] [patch V4 4/4] FreeSCALE i.MX31 support: KZM-ARM11-01 evaluation board

2012-03-08 Thread peter . chubb
Board support for Kyoto Micro's KZM-ARM11-01, an evaluation board built
around the FreeScale i.MX31.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
---
 Makefile.target |1 
 hw/kzm.c|  159 
 2 files changed, 160 insertions(+)
 create mode 100644 hw/kzm.c

Index: qemu-working/hw/kzm.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/kzm.c   2012-03-09 14:13:54.578127780 +1100
@@ -0,0 +1,159 @@
+/*
+ * KZM Board System emulation.
+ *
+ * Copyright (c) 2008 OKL and 2011 NICTA
+ * Written by Hans
+ * Updated by Peter Chubb.
+ *
+ * This code is licenced under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a Kyoto Microcomputer
+ * KZM-ARM11-01 evaluation board, with a FreeScale
+ * I.MX31 SoC
+ */
+
+#include "sysbus.h"
+#include "exec-memory.h"
+#include "hw.h"
+#include "arm-misc.h"
+#include "primecell.h"
+#include "devices.h"
+#include "pci.h"
+#include "net.h"
+#include "sysemu.h"
+#include "boards.h"
+#include "pc.h" /* for the FPGA UART that emulates a 16550 */
+#include "imx.h"
+
+/* Memory map for Kzm Emulation Baseboard:
+ * 0x-0x3fff 16k secure ROM   IGNORED
+ * 0x4000-0x00407fff Reserved IGNORED
+ * 0x00404000-0x00407fff ROM  IGNORED
+ * 0x00408000-0x0fff Reserved IGNORED
+ * 0x1000-0x1fffBfff RAM aliasing IGNORED
+ * 0x1fffc000-0x1fff RAM  EMULATED
+ * 0x2000-0x2fff Reserved IGNORED
+ * 0x3000-0x7fff I.MX31 Internal Register Space
+ *   0x43f0 IO_AREA0
+ *   0x43f9 UART1 EMULATED
+ *   0x43f94000 UART2 EMULATED
+ *   0x6800 PIC   EMULATED
+ *   0x53f94000 PIT 1 EMULATED
+ *   0x53f98000 PIT 2 EMULATED
+ *   0x53f9 GPT   EMULATED
+ * 0x8000-0x87ff RAM  EMULATED
+ * 0x8800-0x8fff RAM Aliasing EMULATED
+ * 0xa000-0xafff NAND Flash   IGNORED
+ * 0xb000-0xb3ff Unavailable  IGNORED
+ * 0xb400-0xb4000fff 8-bit free space IGNORED
+ * 0xb4001000-0xb400100f Board controlIGNORED
+ *  0xb4001003   DIP switch
+ * 0xb4001010-0xb400101f 7-segment LEDIGNORED
+ * 0xb4001020-0xb400102f LED  IGNORED
+ * 0xb4001030-0xb400103f LED  IGNORED
+ * 0xb4001040-0xb400104f FPGA, UART   EMULATED
+ * 0xb4001050-0xb400105f FPGA, UART   EMULATED
+ * 0xb4001060-0xb40f FPGA IGNORED
+ * 0xb600-0xb61f LAN controller   EMULATED
+ * 0xb620-0xb62f FPGA NAND Controller IGNORED
+ * 0xb630-0xb7ff Free IGNORED
+ * 0xb800-0xb8004fff Memory control registers IGNORED
+ * 0xc000-0xc3ff PCMCIA/CFIGNORED
+ * 0xc400-0x Reserved IGNORED
+ */
+
+#define KZM_RAMADDRESS (0x8000)
+#define KZM_FPGA   (0xb4001040)
+
+static struct arm_boot_info kzm_binfo = {
+.loader_start = KZM_RAMADDRESS,
+.board_id = 1722,
+};
+
+static void kzm_init(ram_addr_t ram_size,
+ const char *boot_device,
+ const char *kernel_filename, const char *kernel_cmdline,
+ const char *initrd_filename, const char *cpu_model)
+{
+CPUState *env;
+MemoryRegion *address_space_mem = get_system_memory();
+MemoryRegion *ram = g_new(MemoryRegion, 1);
+MemoryRegion *sram = g_new(MemoryRegion, 1);
+MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
+qemu_irq *cpu_pic;
+DeviceState *dev;
+
+if (!cpu_model) {
+cpu_model = "arm1136";
+}
+
+env = cpu_init(cpu_model);
+if (!env) {
+fprintf(stderr, "Unable to find CPU definition\n");
+exit(1);
+}
+
+/* On a real system, the first 16k is a `secure boot rom' */
+
+memory_region_init_ram(ram, "kzm.ram", ram_size);
+vmstate_register_ram_global(ram);
+memory_region_add_subregion(address_space_mem, KZM_RAMADDRESS, ram);
+
+memory_region_init_alias(ram_alias, "ram.alias", ram, 0, ram_size);
+memory_region_add_subregion(address_space_mem, 0x8800, ram_alias);
+
+memory_region_init_ram(sram, "kzm.sram", 0x4000);
+memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
+
+
+cpu_pic = arm_pic_init_cpu(env);
+dev = sysbus_create_varargs("imx_avic&q

[Qemu-devel] [patch V4 0/4] Support for i.MX31 and the Kyoto KZM11 board

2012-03-08 Thread peter . chubb
This is version 4 of the patchset. The major changes since the last
round are:
 * Moved to new QEMU object model for devices
   -- this requred rearranging the intialisation of the serial device,
  to ensure that the lowest address uart got serial 0, so qemu
  -nographic would work as expected.
 * Hans Jiang and Alex Clench (original patch authors) have left
   OK-Labs, so the Signed-Off-By: line is changed to their boss who
   has given permission for release.

 * EPIT now honours prescaler and clocksource fields.

 * I *think* all previous comments have been addressed:
   -- now all files under GPL 2.0 or later
   -- better emulation of which fields in which registers are
  read-only
   -- AVIC implements priorities.

Still to do:
  Clock module support --- assumes 50MHz ipg_clk
  clock source and prescaler etc., for the general purpose timer
  UART is very bare-bones -- ignores baud rate, and implements only a
 one character FIFO
-- 
Dr Peter Chubb  peter.chubb AT nicta.com.au
http://www.ssrg.nicta.com.au  Software Systems Research Group/NICTA



[Qemu-devel] [patch V4 2/4] FreeSCALE i.MX31 support: Timers

2012-03-08 Thread peter . chubb
Implement the timers on the FreeScale i.MX31 SoC.
This is not a complete implementation, but gives enough for 
Linux to boot and run. In particular external triggers, which are 
not useful under QEMU, are not implemented.


Signed-off-by: Philip O'Sullivan 
Signed-off-by: Peter Chubb 
---
 Makefile.target |2 
 hw/imx_timer.c  |  575 
 2 files changed, 576 insertions(+), 1 deletion(-)
 create mode 100644 hw/imx_timer.c

Index: qemu-working/hw/imx_timer.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_timer.c 2012-03-09 14:13:51.406084465 +1100
@@ -0,0 +1,575 @@
+/*
+ * IMX31 Timer
+ *
+ * Copyright (c) 2008 OK Labs
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally Written by Hans Jiang
+ * Updated by Peter Chubb
+ *
+ * This code is licenced under GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "hw.h"
+#include "qemu-timer.h"
+#include "ptimer.h"
+#include "sysbus.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
+
+/*
+ * GPT : General purpose timer
+ *
+ * This timer counts up continuously while it is enabled, resetting itself
+ * to 0 after it reaches TIMER_MAX (in freerun mode) or when it
+ * reaches the value of ocr1 (in periodic mode).  Unfortunately, the
+ * Qemu ptimer abstraction doesn't have a mode like this, so the code
+ * uses Qemu timers directly.
+ *
+ * The code emulates a free-running timer by using Qemu's nanosecond
+ * clock, suitably scaled, using the remainder after dividing by the
+ * timer's period.  In the real hardware, there are three comparison
+ * registers that can trigger interrupts, and compare channel 1 can be
+ * used to force-reset the timer. However, this is a `bare-bones'
+ * implementation: only what Linux 3.0.x uses has been implemented
+ * (free-running timer from 0 to OCR1 or TIMER_MAX) Likewise, only a
+ * single frequency is implemented, rather than all the complicated
+ * clock-source and prescaling logic that the real hardware implements
+ * (most of which doesn't make sense on Qemu)
+ */
+
+#define TIMER_MAX  0XULL
+#define GPT_FREQ   5000/* Hz == 50 MHz */
+
+/* Control register.  Not all of these bits have any effect (yet) */
+#define GPT_CR_EN (1 << 0)  /* GPT Enable */
+#define GPT_CR_ENMOD  (1 << 1)  /* GPT Enable Mode */
+#define GPT_CR_DBGEN  (1 << 2)  /* GPT Debug mode enable */
+#define GPT_CR_WAITEN (1 << 3)  /* GPT Wait Mode Enable  */
+#define GPT_CR_DOZEN  (1 << 4)  /* GPT Doze mode enable */
+#define GPT_CR_STOPEN (1 << 5)  /* GPT Stop Mode Enable */
+#define GPT_CR_CLKSRC (7 << 6)  /* Clock source select (3 bits) */
+#define GPT_CR_FRR(1 << 9)  /* Freerun or Restart */
+#define GPT_CR_SWR(1 << 15) /* Software Reset */
+#define GPT_CR_IM1(3 << 16) /* Input capture channel 1 mode (2 bits) */
+#define GPT_CR_IM2(3 << 18) /* Input capture channel 2 mode (2 bits) */
+#define GPT_CR_OM1(7 << 20) /* Output Compare Channel 1 Mode (3 bits) */
+#define GPT_CR_OM2(7 << 23) /* Output Compare Channel 2 Mode (3 bits) */
+#define GPT_CR_OM3(7 << 26) /* Output Compare Channel 3 Mode (3 bits) */
+#define GPT_CR_FO1(1 << 29) /* Force Output Compare Channel 1 */
+#define GPT_CR_FO2(1 << 30) /* Force Output Compare Channel 2 */
+#define GPT_CR_FO3(1 << 31) /* Force Output Compare Channel 3 */
+
+#define GPT_SR_OF1  (1 << 0)
+#define GPT_SR_ROV  (1 << 5)
+
+#define GPT_IR_OF1IE  (1 << 0)
+#define GPT_IR_ROVIE  (1 << 5)
+
+typedef struct {
+SysBusDevice busdev;
+QEMUTimer *timer;
+MemoryRegion iomem;
+uint32_t cr;
+uint32_t pr;
+uint32_t sr;
+uint32_t ir;
+uint32_t ocr1;
+uint32_t cnt;
+
+uint32_t waiting_rov;
+qemu_irq irq;
+} imx_timerg_state;
+
+static const VMStateDescription vmstate_imx_timerg = {
+.name = "imx-timerg",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields  = (VMStateField[]) {
+VMSTATE_UINT32(cr, imx_timerg_state),
+VMSTATE_UINT32(pr, imx_timerg_state),
+VMSTATE_UINT32(sr, imx_timerg_state),
+VMSTATE_UIN

Re: [Qemu-devel] [PATCH V3 3/4] Implement the FreeSCALE i.MX31 advanced vectored interrupt controller, at least to the extent it is used by Linux 3.0.x

2011-12-05 Thread Peter Chubb
>>>>> "Peter" == Peter Maydell  writes:

Peter> On 30 November 2011 03:36, Peter Chubb
Peter>  wrote:
>> Signed-off-by: Hans Jang  Signed-off-by: Adam
>> Clench  Signed-off-by: Peter Chubb
>> 
>> ---
>>  Makefile.target |    2  hw/imx_avic.c   |  378
>>   2 files
>> changed, 379 insertions(+), 1 deletion(-)  create mode 100644
>> hw/imx_avic.c
>> 
>> Index: qemu-working/hw/imx_avic.c
>> ===
>> --- /dev/null   1970-01-01 00:00:00.0 + +++
>> qemu-working/hw/imx_avic.c  2011-11-30 13:38:27.070791665 +1100 @@
>> -0,0 +1,378 @@ +/* + * IMX31 Vectored Interrupt Controller + * + *
>> Note this is NOT the PL192 provided by ARM, but + * a custom
>> implementation by FreeScale.  + * + * Copyright (c) 2008 OKL + *
>> Copyright (c) 2011 NICTA Pty Ltd + * Originally Written by Hans
>> Jiang + * + * This code is licenced under the GPL version 2 or
>> later.  See + * the COPYING file in the top-level directory.  + * +
>> * TODO: implement vectors and priorities.

Peter> Vectors are harder (they require support from the target-arm
Peter> core implementation which isn't there) but I think you should
Peter> implement priorities. That should be purely internal to this
Peter> device, and it would be good not to have yet another interrupt
Peter> controller in the tree which doesn't get interrupt priorities
Peter> right (the NVIC being our other).


OK, I've implemented them, but have no way to test them (because Linux
doesn't use them!)

Peter C



Re: [Qemu-devel] [PATCH V3 1/4] Implement the FreeScale i.MX UART. This uart is used in a variety of SoCs, including some by Motorola, as well as in the FreeScale i.MX series.

2011-12-05 Thread Peter Chubb
>>>>> "Peter" == Peter Maydell  writes:

Peter> On 30 November 2011 03:36, Peter Chubb
Peter>  wrote: Commit messages should be
Peter> formatted with a short summary line, then a blank line, then a
Peter> more detailed description. You've put everything into one
Peter> extremely long summary line here, which looks odd in git
Peter> log. Try:

Thanks I've fixed that now.

>> top-level directory.

Peter> Still GPL v2 only.

Fixed.


>> +    uint32_t ubrm;

Peter> The MCIMX31RM calls this UBMR, not UBRM...

Fixed.


Peter> My copy of the MCIMX31RM says we also set RXDS on reset.

Fixed.

>> +    s->usr2 = USR2_TXFE | USR2_TXDC;

Peter> Presumably we don't set DCDIN here because we haven't
Peter> implemented the modem control signals yet?

Exactly.  But there's no harm in setting it, so I've added it in.

>> +    s->uts1 = UTS1_RXEMPTY | UTS1_TXEMPTY; +    s->ubrm = 0; +  
>>  s->ubrc = 0;

Peter> RM says the reset value for UBRC is 0x4.

OK.

Peter> You also need to reset s->ucr1. (If you want to retain that
Peter> hack in the init function then you still need to reset the
Peter> other bits even if you don't allow reset to clear UARTEN.)

OK.  Fixed.

>> +    s->readbuff = 0; 
>> +    imx_update(s);

Peter> This will call qemu_set_irq() which is a bad idea in a reset
Peter> function.  Don't call imx_update() here, instead call it after
Peter> calling imx_serial_reset() from your register write function.

Does the infrastructure guarantee that any interrupt will be cleared
when the reset function is called?

>> +   case  0x21: /* UCR2 */ 
>> +        return 1; /* reset complete */

Peter> UCR2_SRST.

Fixed.


>>    case 0x20: /* UCR1 */ 
>> +        s->ucr1 = value;

Peter> RM says the top 16 bits of UCR1 are read-only.

Fixed.

Peter> This doesn't implement writing to any of the other bits of
Peter> UCR2.

No, apart from the TXEN and RXEN bits they're all to do with 

>> +    case 0x26: /* USR2 */ 
>> +       /* 
>> +        * Writing 1 to some bits clears them; all other 
>> +        * values are ignored 
>> +        */ 
>> +        value &= (1<<15) | (1<<13) | (1<<12) |  (1<<11) | (1<<10)| 
>> +            (1<<8) | (1<<7) | (1<<6) | (1<<4) | (1<<2) | (1<<1);

Peter> define and use USR2_FOO named constants.

Done.


>> UCR3 */ +    case 0x23: /* UCR4 */ +    case 0x24: /* UFCR */ +  
>>  case 0x25: /* USR1 */ +    case 0x2c: /* BIPR1 */ +        /* TODO
>> */

Peter> No IPRINTF() ?

This one gets hit too often.

>> +    .qdev.size  = sizeof (imx_state),

Peter> Unnecessary space (and checkpatch will complain).

I disagree -- there should be a space between the sizeof operator and
the cast that is its operand.  sizeof is not a function; and the
parentheses in this case are part of its operand.

I couldn't find any mention of sizeof in the Coding Style
document. However, I'll go with whatever makes you happier (but
note that the current qemu source mixes sizeof (type) and sizeof(type)
all over the place).

Look out for a new patch series real soon now...

Peter C
--
Dr Peter Chubb  http://www.gelato.unsw.edu.au  peterc AT gelato.unsw.edu.au
http://www.ertos.nicta.com.au   ERTOS within National ICT Australia



Re: [Qemu-devel] [PATCH V3 1/4] Implement the FreeScale i.MX UART. This uart is used in a variety of SoCs, including some by Motorola, as well as in the FreeScale i.MX series.

2011-12-01 Thread Peter Chubb
>>>>> "Peter" == Peter Maydell  writes:

Peter> On 1 December 2011 16:55, Peter Maydell
Peter>  wrote:
>> On 30 November 2011 03:36, Peter Chubb 
>> wrote:
>>> Signed-off-by: Hans Jang 

Peter> Is this email address correct? Trying to send this email got
Peter> me: 550 550 ... User not known (state 17).

He's left the company and noone knows where he is :-(

Peter> -- PMM


--
Dr Peter Chubb  peter DOT chubb AT nicta.com.au
http://www.ertos.nicta.com.au   ERTOS within National ICT Australia
All things shall perish from under the sky/Music alone shall live, never to die



Re: [Qemu-devel] [PATCH V3 0/4] i.MX31 and KZM board support

2011-11-29 Thread Peter Chubb
>>>>> "Stefan" == Stefan Weil  writes:

Stefan> Am 30.11.2011 04:36, schrieb Peter Chubb:
>> Changes since last patchset: * All files now under GPL version 2 or
>> later (I've talked with OK-Labs and they've agreed).

Stefan> hw/imx_serial.c is still GPL 2 only. I did not review the
Stefan> rest.

Missed one, sorry.

>> * `DPRINTF' like macro for printing out guest kernel and qemu
>> implementation errors * Fixed bugs in avic implementation, as found
>> by PMM * Use a static initialiser and sysbus_register_withprop()
>> instead of calls to sysbus_register() adn vmstate_register() *
>> Fixed bugs in imx_timer.c as noted by PMM and Andreas

Stefan> Could you please use 'git send-email' to send the patches?
Stefan> Patches which are appended to a mail make review and answering
Stefan> difficult.

I used quilt mail --send

Peter C

--
Dr Peter Chubb  http://www.gelato.unsw.edu.au  peterc AT gelato.unsw.edu.au
http://www.ertos.nicta.com.au   ERTOS within National ICT Australia



[Qemu-devel] [PATCH V3 1/4] Implement the FreeScale i.MX UART. This uart is used in a variety of SoCs, including some by Motorola, as well as in the FreeScale i.MX series.

2011-11-29 Thread Peter Chubb
Signed-off-by: Hans Jang 
Signed-off-by: Adam Clench 
Signed-off-by: Peter Chubb 
---
 Makefile.target |1 
 hw/imx_serial.c |  320 
 2 files changed, 321 insertions(+)
 create mode 100644 hw/imx_serial.c

Index: qemu-working/hw/imx_serial.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_serial.c2011-11-30 13:38:24.434778115 +1100
@@ -0,0 +1,320 @@
+/*
+ * IMX31 UARTS
+ *
+ * Copyright (c) 2008 OKL
+ * Originally Written by Hans Jiang
+ * Copyright (c) 2011 NICTA Pty Ltd.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ * This is a `bare-bones' implementation of the IMX series serial ports.
+ * TODO:
+ *  -- implement FIFOs.  The real hardware has 32 word transmit
+ *   and receive FIFOs; we currently use a 1-char buffer
+ *  -- implement DMA
+ *  -- implement BAUD-rate and modem lines, for when the backend
+ * is a real serial device.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "qemu-char.h"
+
+//#define DEBUG_SERIAL 1
+
+#ifdef DEBUG_SERIAL
+#define DPRINTF(fmt, args...) \
+do { printf("imx_serial: " 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_serial: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+int32_t readbuff;
+
+uint32_t usr1;
+uint32_t usr2;
+uint32_t ucr1;
+uint32_t uts1;
+
+uint32_t ubrm;
+uint32_t ubrc;
+
+qemu_irq irq;
+CharDriverState *chr;
+} imx_state;
+
+static const VMStateDescription vmstate_imx_serial  = {
+.name = "imx-serial",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_INT32(readbuff, imx_state),
+VMSTATE_UINT32(usr1, imx_state),
+VMSTATE_UINT32(usr2, imx_state),
+VMSTATE_UINT32(ucr1, imx_state),
+VMSTATE_UINT32(uts1, imx_state),
+VMSTATE_UINT32(ubrm, imx_state),
+VMSTATE_UINT32(ubrc, imx_state),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+#define URXD_CHARRDY(1<<15)   /* character read is valid */
+
+#define USR1_TRDY   (1<<13)   /* Xmitter ready */
+#define USR1_RRDY   (1<<9)/* receiver ready */
+
+#define USR2_TXFE   (1<<14)   /* Transmit FIFO empty */
+#define USR2_TXDC   (1<<3)/* Transmission complete */
+#define USR2_RDR(1<<0)/* Receive data ready */
+
+#define UCR1_TRDYEN (1<<13)
+#define UCR1_RRDYEN (1<<9)
+#define UCR1_TXMPTYEN   (1<<6)
+#define UCR1_UARTEN (1<<0)
+
+#define UTS1_TXEMPTY(1<<6)
+#define UTS1_RXEMPTY(1<<5)
+#define UTS1_TXFULL (1<<4)
+#define UTS1_RXFULL (1<<3)
+
+static void imx_update(imx_state *s)
+{
+uint32_t flags;
+
+flags = ((s->usr1 & s->ucr1)) & (USR1_TRDY|USR1_RRDY);
+if (!(s->ucr1 & UCR1_TXMPTYEN)) {
+flags &= ~USR1_TRDY;
+}
+
+if (flags) {
+DPRINTF("imx_serial: raising interrupt\n");
+}
+
+qemu_set_irq(s->irq, !!flags);
+}
+
+static void imx_serial_reset(DeviceState *dev)
+{
+imx_state *s = container_of(dev, imx_state, busdev.qdev);
+
+s->usr1 = USR1_TRDY;
+s->usr2 = USR2_TXFE | USR2_TXDC;
+s->uts1 = UTS1_RXEMPTY | UTS1_TXEMPTY;
+s->ubrm = 0;
+s->ubrc = 0;
+s->readbuff = 0;
+
+imx_update(s);
+}
+
+static uint64_t imx_serial_read(void *opaque, target_phys_addr_t offset,
+unsigned size)
+{
+imx_state *s = (imx_state *)opaque;
+uint32_t c;
+
+DPRINTF("read(offset=%x)\n", offset >> 2);
+switch (offset >> 2) {
+case 0x0: /* URXD */
+c = s->readbuff;
+if (!(s->uts1 & UTS1_RXEMPTY)) {
+/* Character is valid */
+c |= URXD_CHARRDY;
+s->usr1 &= ~USR1_RRDY;
+s->usr2 &= ~USR2_RDR;
+s->uts1 |= UTS1_RXEMPTY;
+imx_update(s);
+qemu_chr_accept_input(s->chr);
+}
+return c;
+
+case 0x20: /* UCR1 */
+return s->ucr1;
+
+case 0x21: /* UCR2 */
+return 1; /* reset complete */
+
+case 0x25: /* USR1 */
+return s->usr1;
+
+case 0x26: /* USR2 */
+return s->usr2;
+
+case 0x2A: /* BRM Modulator */
+return s-

[Qemu-devel] [PATCH V3 2/4] Implement the timers on the FreeScale i.MX31 SoC. This is not a complete implementation, but gives enough for Linux to boot and run.

2011-11-29 Thread Peter Chubb

Signed-off-by: Hans Jang 
Signed-off-by: Adam Clench 
Signed-off-by: Peter Chubb 
---
 Makefile.target |2 
 hw/imx_timer.c  |  460 
 2 files changed, 461 insertions(+), 1 deletion(-)
 create mode 100644 hw/imx_timer.c

Index: qemu-working/hw/imx_timer.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_timer.c 2011-11-30 13:38:25.818785258 +1100
@@ -0,0 +1,460 @@
+/*
+ * IMX31 Timer
+ *
+ * Copyright (c) 2008 OKL
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally Written by Hans Jiang
+ * Updated by Peter Chubb
+ *
+ * This code is licenced under GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "hw.h"
+#include "qemu-timer.h"
+#include "sysbus.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
+
+/*
+ * GPT : General purpose timer
+ */
+
+#define TIMER_MAX  0xUL
+#define GPT_FREQ   5000/* Hz == 50 MHz */
+
+/* Control register.  Not all of these bits have any effect (yet) */
+#define GPT_CR_EN   (1 << 0)/* GPT Enable */
+#define GPT_CR_ENMODE (1 << 1)  /* GPT Enable Mode */
+#define GPT_CR_DBGEN (1 << 2)   /* GPT Debug mode enable */
+#define GPT_CR_WAITEN (1 << 3)  /* GPT Wait Mode Enable  */
+#define GPT_CR_DOZEN (1 << 4)   /* GPT Doze mode enable */
+#define GPT_CR_STOPEN (1 << 5)  /* GPT Stop Mode Enable */
+#define GPT_CR_CLKSRC (7 << 6) /* Clock source select (3 bits) */
+#define GPT_CR_FRR  (1 << 9)/* Freerun or Restart */
+#define GPT_CR_SWR  (1 << 15)
+#define GPT_CR_IM1  (3 << 16)   /* Input capture channel 1 mode (2 bits) */
+#define GPT_CR_IM2  (3 << 18)   /* Input capture channel 2 mode (2 bits) */
+#define GPT_CR_OM1  (7 << 20)   /* Output Compare Channel 1 Mode (3 bits) */
+#define GPT_CR_OM2  (7 << 23)   /* Output Compare Channel 2 Mode (3 bits) */
+#define GPT_CR_OM3  (7 << 26)   /* Output Compare Channel 3 Mode (3 bits) */
+#define GPT_CR_FO1  (1 << 29)   /* Force Output Compare Channel 1 */
+#define GPT_CR_FO2  (1 << 30)   /* Force Output Compare Channel 2 */
+#define GPT_CR_FO3  (1 << 31)   /* Force Output Compare Channel 3 */
+
+#define GPT_SR_OF1  (1 << 0)
+#define GPT_SR_ROV  (1 << 5)
+
+#define GPT_IR_OF1IE  (1 << 0)
+#define GPT_IR_ROVIE  (1 << 5)
+
+typedef struct {
+SysBusDevice busdev;
+QEMUTimer *timer;
+MemoryRegion iomem;
+uint32_t cr;
+uint32_t sr;
+uint32_t pr;
+uint32_t ir;
+uint32_t ocr1;
+uint32_t cnt;
+
+int waiting_rov;
+qemu_irq irq;
+} imxg_timer_state;
+
+static const VMStateDescription vmstate_imxg_timer = {
+.name = "imxg-timer",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields  = (VMStateField[]) {
+VMSTATE_UINT32(cr, imxg_timer_state),
+VMSTATE_UINT32(sr, imxg_timer_state),
+VMSTATE_UINT32(ir, imxg_timer_state),
+VMSTATE_UINT32(cnt, imxg_timer_state),
+VMSTATE_UINT32(ocr1, imxg_timer_state),
+VMSTATE_TIMER(timer, imxg_timer_state),
+VMSTATE_END_OF_LIST()
+}
+};
+
+
+/* Check all active timers, and schedule the next timer interrupt.  */
+static void imxg_timer_update(imxg_timer_state *s)
+{
+uint32_t flags = s->sr & s->ir & (GPT_SR_OF1 | GPT_SR_ROV);
+
+if ((s->cr & GPT_CR_EN) && flags) {
+qemu_irq_raise(s->irq);
+} else {
+qemu_irq_lower(s->irq);
+}
+}
+
+static uint64_t imxg_timer_update_count(imxg_timer_state *s)
+{
+uint64_t clk = qemu_get_clock_ns(vm_clock);
+
+s->cnt = ((uint32_t)muldiv64(clk, GPT_FREQ/100,
+ 1000)) % TIMER_MAX;
+return clk;
+}
+
+static void imxg_timer_run(imxg_timer_state *s, uint32_t timeout)
+{
+uint64_t clk = imxg_timer_update_count(s);
+uint32_t diff_cnt;
+if (s->cnt < timeout) {
+diff_cnt = (timeout - s->cnt);
+s->waiting_rov = 0;
+} else {
+diff_cnt = (TIMER_MAX - s->cnt);
+s->waiting_rov = 1;
+}
+qemu_mod_timer(s->timer, clk + diff_cnt * 1000 / (GPT_FREQ/100));
+}
+
+static uint64_t imxg_timer_read(void *opaque, target_phys_addr_t offset,
+unsigned size)
+{

[Qemu-devel] [PATCH V3 3/4] Implement the FreeSCALE i.MX31 advanced vectored interrupt controller, at least to the extent it is used by Linux 3.0.x

2011-11-29 Thread Peter Chubb
Signed-off-by: Hans Jang 
Signed-off-by: Adam Clench 
Signed-off-by: Peter Chubb 
---
 Makefile.target |2 
 hw/imx_avic.c   |  378 
 2 files changed, 379 insertions(+), 1 deletion(-)
 create mode 100644 hw/imx_avic.c

Index: qemu-working/hw/imx_avic.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_avic.c  2011-11-30 13:38:27.070791665 +1100
@@ -0,0 +1,378 @@
+/*
+ * IMX31 Vectored Interrupt Controller
+ *
+ * Note this is NOT the PL192 provided by ARM, but
+ * a custom implementation by FreeScale.
+ *
+ * Copyright (c) 2008 OKL
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally Written by Hans Jiang
+ *
+ * This code is licenced under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * TODO: implement vectors and priorities.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "host-utils.h"
+
+#define DEBUG_INT 1
+#undef DEBUG_INT /* comment out for debugging */
+
+#ifdef DEBUG_INT
+#define DPRINTF(fmt, args...) \
+do { printf("imx_avic: " 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_avic: " fmt, ##args); } while (0)
+#else
+#  define IPRINTF(fmt, args...) do {} while (0)
+#endif
+
+#define IMX_INT_NUM_IRQS 64
+
+/* Interrupt Control Bits */
+#define ABFLAG (1<<25)
+#define ABFEN (1<<24)
+#define NIDIS (1<<22) /* Normal Interrupt disable */
+#define FIDIS (1<<21) /* Fast interrupt disable */
+#define NIAD  (1<<20) /* Normal Interrupt Arbiter Rise ARM level */
+#define FIAD  (1<<19) /* Fast Interrupt Arbiter Rise ARM level */
+#define NM(1<<18) /* Normal interrupt mode */
+
+
+#define PRIO_PER_WORD (sizeof(uint32_t) * 8 / 4)
+#define PRIO_WORDS (IMX_INT_NUM_IRQS/PRIO_PER_WORD)
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+uint64_t pending;
+uint64_t enabled;
+uint64_t is_fiq;
+uint32_t intcntl;
+uint32_t intmask;
+qemu_irq irq;
+qemu_irq fiq;
+uint32_t prio[PRIO_WORDS]; /* Priorities are 4-bits each */
+} imx_int_state;
+
+static const VMStateDescription vmstate_imx_avic = {
+.name = "imx-avic",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT64(pending, imx_int_state),
+VMSTATE_UINT64(enabled, imx_int_state),
+VMSTATE_UINT64(is_fiq, imx_int_state),
+VMSTATE_UINT32(intcntl, imx_int_state),
+VMSTATE_UINT32(intmask, imx_int_state),
+VMSTATE_UINT32_ARRAY(prio, imx_int_state, PRIO_WORDS),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+
+static inline int imx_int_prio(imx_int_state *s, int irq)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+return 0xf & (s->prio[word] >> part);
+}
+
+static inline void imx_int_set_prio(imx_int_state *s, int irq, int prio)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+uint32_t mask = ~(0xf << part);
+s->prio[word] &= mask;
+s->prio[word] |= prio << part;
+}
+
+/* Update interrupts.  */
+static void imx_int_update(imx_int_state *s)
+{
+int i;
+uint64_t new = s->pending;
+uint64_t flags;
+
+flags = new & s->enabled & s->is_fiq;
+qemu_set_irq(s->fiq, !!flags);
+
+flags = new & s->enabled & ~s->is_fiq;
+if (!flags || (s->intmask == 0x1f)) {
+qemu_set_irq(s->irq, !!flags);
+return;
+}
+
+/*
+ * Take interrupt if prio lower than the value of intmask
+ * (should really take highest priority interrupt here,
+ * but that would involve processing interrupt sources
+ * in priority order)
+ */
+for (i = 0; i < IMX_INT_NUM_IRQS; i++) {
+if (flags & (1UL << i)) {
+if (imx_int_prio(s, i) > s->intmask) {
+qemu_set_irq(s->irq, 1);
+return;
+}
+}
+}
+qemu_set_irq(s->irq, 0);
+}
+
+static void imx_int_set_irq(void *opaque, int irq, int level)
+{
+imx_int_state *s = (imx_int_state *)opaque;
+
+if (level) {
+s->pending |= (1ULL << irq);
+} else {
+s->pending &= ~(1ULL << irq);
+}
+
+imx_int_update(s);
+}
+
+
+static uint64_t imx_int_read(void *opaque,
+ target_phys_addr_t offset, unsigned size)
+{
+imx_int_state *s = (imx_int_state *)opaque;
+
+
+DPRINTF("read(offset = 0x%x)\n

[Qemu-devel] [PATCH V3 4/4] Board support for Kyoto Micros KZM-ARM11-01, an evaluation board built around the FreeScale i.MX31.

2011-11-29 Thread Peter Chubb
Signed-off-by: Hans Jang 
Signed-off-by: Adam Clench 
Signed-off-by: Peter Chubb 
---
 Makefile.target |1 
 hw/kzm.c|  155 
 2 files changed, 156 insertions(+)
 create mode 100644 hw/kzm.c

Index: qemu-working/hw/kzm.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/kzm.c   2011-11-30 13:38:28.210797633 +1100
@@ -0,0 +1,155 @@
+/*
+ * KZM Board System emulation.
+ *
+ * Copyright (c) 2008 OKL and 2011 NICTA
+ * Written by Hans
+ * Updated by Peter Chubb.
+ *
+ * This code is licenced under the GPL, version 2 or later.
+ *
+ * It (partially) emulates a Kyoto Microcomputer
+ * KZM-ARM11-01 evaluation board, with a FreeScale
+ * I.MX31 SoC
+ */
+
+#include "sysbus.h"
+#include "exec-memory.h"
+#include "hw.h"
+#include "arm-misc.h"
+#include "primecell.h"
+#include "devices.h"
+#include "pci.h"
+#include "net.h"
+#include "sysemu.h"
+#include "boards.h"
+#include "pc.h" /* for the FPGA UART that emulates a 16550 */
+
+/* Memory map for Kzm Emulation Baseboard:
+ * 0x-0x3fff 16k secure ROM   IGNORED
+ * 0x4000-0x00407fff Reserved IGNORED
+ * 0x00404000-0x00407fff ROM  IGNORED
+ * 0x00408000-0x0fff Reserved IGNORED
+ * 0x1000-0x1fffBfff RAM aliasing IGNORED
+ * 0x1fffc000-0x1fff RAM  EMULATED
+ * 0x2000-0x2fff Reserved IGNORED
+ * 0x3000-0x7fff I.MX31 Internal Register Space
+ *   0x43f0 IO_AREA0
+ *   0x43f9 UART1 EMULATED
+ *   0x43f94000 UART2 EMULATED
+ *   0x6800 PIC   EMULATED
+ *   0x53f94000 PIT 1 EMULATED
+ *   0x53f98000 PIT 2 EMULATED
+ *   0x53f9 GPT   EMULATED
+ * 0x8000-0x87ff RAM  EMULATED
+ * 0x8800-0x8fff RAM Aliasing EMULATED
+ * 0xa000-0xafff NAND Flash   IGNORED
+ * 0xb000-0xb3ff Unavailable  IGNORED
+ * 0xb400-0xb4000fff 8-bit free space IGNORED
+ * 0xb4001000-0xb400100f Board controlIGNORED
+ *  0xb4001003   DIP switch
+ * 0xb4001010-0xb400101f 7-segment LEDIGNORED
+ * 0xb4001020-0xb400102f LED  IGNORED
+ * 0xb4001030-0xb400103f LED  IGNORED
+ * 0xb4001040-0xb400104f FPGA, UART   EMULATED
+ * 0xb4001050-0xb400105f FPGA, UART   EMULATED
+ * 0xb4001060-0xb40f FPGA IGNORED
+ * 0xb600-0xb61f LAN controller   EMULATED
+ * 0xb620-0xb62f FPGA NAND Controller IGNORED
+ * 0xb630-0xb7ff Free IGNORED
+ * 0xb800-0xb8004fff Memory control registers IGNORED
+ * 0xc000-0xc3ff PCMCIA/CFIGNORED
+ * 0xc400-0x Reserved IGNORED
+ */
+
+#define KZM_RAMADDRESS (0x8000)
+#define KZM_FPGA   (0xb4001040)
+
+static struct arm_boot_info kzm_binfo = {
+.loader_start = KZM_RAMADDRESS,
+.board_id = 1722,
+};
+
+static void kzm_init(ram_addr_t ram_size,
+ const char *boot_device,
+ const char *kernel_filename, const char *kernel_cmdline,
+ const char *initrd_filename, const char *cpu_model)
+{
+CPUState *env;
+MemoryRegion *address_space_mem = get_system_memory();
+MemoryRegion *ram = g_new(MemoryRegion, 1);
+MemoryRegion *sram = g_new(MemoryRegion, 1);
+MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
+qemu_irq *cpu_pic;
+DeviceState *dev;
+
+if (!cpu_model) {
+cpu_model = "arm1136";
+}
+
+env = cpu_init(cpu_model);
+if (!env) {
+fprintf(stderr, "Unable to find CPU definition\n");
+exit(1);
+}
+
+/* On a real system, the first 16k is a `secure boot rom' */
+
+memory_region_init_ram(ram, NULL, "kzm.ram", ram_size);
+memory_region_add_subregion(address_space_mem, KZM_RAMADDRESS, ram);
+
+memory_region_init_alias(ram_alias, "ram.alias", ram, 0, ram_size);
+memory_region_add_subregion(address_space_mem, 0x8800, ram_alias);
+
+memory_region_init_ram(sram, NULL, "kzm.sram", 0x4000);
+memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
+
+
+cpu_pic = arm_pic_init_cpu(env);
+dev = sysbus_create_varargs("imx_int", 0x6800,
+   cpu_pic[ARM_PIC_CPU_IRQ],
+   cpu_pic[ARM_PIC_CPU_FIQ], NULL);
+
+
+sysbus_create_simple("imx_serial", 0x43f9,

[Qemu-devel] [PATCH V3 0/4] i.MX31 and KZM board support

2011-11-29 Thread Peter Chubb
Changes since last patchset:
  * All files now under GPL version 2 or later (I've talked with
OK-Labs and they've agreed).
  * `DPRINTF' like macro for printing out guest kernel and qemu
implementation errors 
  * Fixed bugs in avic implementation, as found by PMM
  * Use a static initialiser and sysbus_register_withprop() instead of
calls to sysbus_register() adn vmstate_register()
  * Fixed bugs in imx_timer.c as noted by PMM and Andreas

-- 
Dr Peter Chubb  http://www.gelato.unsw.edu.au  peterc AT gelato.unsw.edu.au
http://www.ertos.nicta.com.au   ERTOS within National ICT Australia



Re: [Qemu-devel] [PATCH V2 0/4] imx.31 and KZM board support

2011-11-25 Thread Peter Chubb
>>>>> "Andreas" == Andreas Färber  writes:

Andreas> Am 23.11.2011 01:51, schrieb Peter Chubb:
>>>>>>> "Peter" == Peter Chubb  writes:
>> 
>> 
Peter> All comments received so far have been addressed --- I've added
Peter> a macro, `scream' that gives at most 10 lines of output for OS
Peter> error reporting.
>> 
>> Except I noticed a thinko in the macro.  The decrement should be
>> inside the guard, thus:
>> 
>> #define scream(fmt, args...) \ do { \ static int printable = 10;\
>> if (printable) { \ printable--;\ fprintf(stderr, fmt, ##args); \ }
>> \ } while (0)

Andreas> Another issue:

Andreas> scream("black"); scream("black"); scream("black");
Andreas> scream("black"); scream("black"); scream("black");
Andreas> scream("black"); scream("black"); scream("black");
Andreas> scream("black"); scream("red");

Andreas> To show us "red", in addition to the integer count a
Andreas> duplicate of the string contents would need to be stored and
Andreas> compared to the newly formatted string.

No, because it's a macro.  Each time it appears the static count is
instantiated--- so there's a count for each call site.

Andreas> If we want to do this, it should go into a central file so
Andreas> that it can be reused and centrally maintained.

Agree -- but do we want to do this?

For this patch series, Peter M says to just use hw_error() (even
though he really doesn't like it).

Peter C



[Qemu-devel] Who maintains checkpatch.pl now?

2011-11-24 Thread Peter Chubb

Who maintainss checkpatch.pl now?
checkpatch.pl says to look for CHECKPATCH in the MAINTAINERS file, but
that entry isn't there.  


The issue I'm encountering is that sizeof is not a function, but an
operator, that takes as its operand either a variable or a cast.  As
such there needn't be any parentheses (if the operand is a variable),
and there should a space before the cast.

In the QEMU code at present, the use of whitespace around sizeof varies
from file to file; 
checkpatch.pl complains about

   sizeof (struct foo)
WARNING: space prohibited between function name and open parenthesis '('

If I fix the problem as in the appended patch, I start seeing other
complaints:

ERROR: space prohibited after that '*' (ctx:WxW)
+#define PRIO_PER_WORD (sizeof (uint32_t) * 8 / 4)
  ^

Index: qemu-working/scripts/checkpatch.pl
===
--- qemu-working.orig/scripts/checkpatch.pl 2011-11-10 10:16:43.215022488 
+1100
+++ qemu-working/scripts/checkpatch.pl  2011-11-25 14:02:30.908358997 +1100
@@ -1953,21 +1953,21 @@ sub process {
}
 
 # check for spaces between functions and their parentheses.
while ($line =~ /($Ident)\s+\(/g) {
my $name = $1;
my $ctx_before = substr($line, 0, $-[1]);
my $ctx = "$ctx_before$name";
 
# Ignore those directives where spaces _are_ permitted.
if ($name =~ /^(?:
-   if|for|while|switch|return|case|
+   if|for|while|switch|return|case|sizeof|
volatile|__volatile__|
__attribute__|format|__extension__|
asm|__asm__)$/x)
{
 
# cpp #define statements have non-optional spaces, ie
# if there is a space between the name and the open
# parenthesis it is simply not a parameter group.
} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
 



--
Dr Peter Chubb  http://www.gelato.unsw.edu.au  peterc AT gelato.unsw.edu.au
http://www.ertos.nicta.com.au   ERTOS within National ICT Australia



Re: [Qemu-devel] [PATCH V2 1/4] imx.31 and KZM board support: UART support

2011-11-24 Thread Peter Chubb
Thanks Peter,
   I've fixed the problems you noted, and have asked the OK-Labs
   folks about Licencing.  When I hear back from them I'll roll a
   new patchset --- I don't expect `GPL v2 or later' to be a
   problem.

   -- Peter C
--
Dr Peter Chubb  http://www.gelato.unsw.edu.au  peterc AT gelato.unsw.edu.au
http://www.ertos.nicta.com.au   ERTOS within National ICT Australia



Re: [Qemu-devel] [PATCH V2 0/4] imx.31 and KZM board support

2011-11-22 Thread Peter Chubb
>>>>> "Peter" == Peter Chubb  writes:


Peter> All comments received so far have been addressed --- I've added
Peter> a macro, `scream' that gives at most 10 lines of output for OS
Peter> error reporting.

Except I noticed a thinko in the macro.  The decrement should be
inside the guard, thus:

#define scream(fmt, args...) \
do { \
static int printable = 10;\
if (printable) { \
printable--;\
fprintf(stderr, fmt, ##args); \
    } \
} while (0)


--
Dr Peter Chubb  http://www.gelato.unsw.edu.au  peterc AT gelato.unsw.edu.au
http://www.ertos.nicta.com.au   ERTOS within National ICT Australia



Re: [Qemu-devel] [PATCH] imx.31 and KZM board support

2011-11-22 Thread Peter Chubb
>>>>> "Juan" == Juan Quintela  writes:

Juan> Peter Chubb  wrote:
Juan> This is not used.  Shouldn't a call like this be needed?


Juan>vmstate_register(&dev->qdev, -1, &vmstate_imxg_timer, s);
Juan> ???

Yes!! Thanks for checking.

I've altered the source ready for the next rollout of patches, which
will be version 3.
--
Dr Peter Chubb  http://www.gelato.unsw.edu.au  peterc AT gelato.unsw.edu.au
http://www.ertos.nicta.com.au   ERTOS within National ICT Australia



Re: [Qemu-devel] [PATCH V2 4/4] imx.31 and KZM board support: Makefile and board

2011-11-21 Thread Peter Chubb
Board support for Kyoto Micro's KZM-ARM11-01, an evaluation board built
around the FreeScale i.MX31.

Signed-off-by: Hans Jang 
Signed-off-by: Adam Clench 
Signed-off-by: Peter Chubb 
---
 Makefile.target |2 
 hw/kzm.c|  155 
 2 files changed, 157 insertions(+)
 create mode 100644 hw/kzm.c

Index: qemu-working/hw/kzm.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/kzm.c   2011-11-22 14:47:11.358042471 +1100
@@ -0,0 +1,155 @@
+/*
+ * KZM Board System emulation.
+ *
+ * Copyright (c) 2008 OKL and 2011 NICTA
+ * Written by Hans
+ * Updated by Peter Chubb.
+ *
+ * This code is licenced under the GPL, version 2 or later.
+ *
+ * It (partially) emulates a Kyoto Microcomputer
+ * KZM-ARM11-01 evaluation board, with a FreeScale
+ * I.MX31 SoC
+ */
+
+#include "sysbus.h"
+#include "exec-memory.h"
+#include "hw.h"
+#include "arm-misc.h"
+#include "primecell.h"
+#include "devices.h"
+#include "pci.h"
+#include "net.h"
+#include "sysemu.h"
+#include "boards.h"
+#include "pc.h" /* for the FPGA UART that emulates a 16550 */
+
+/* Memory map for Kzm Emulation Baseboard:
+ * 0x-0x3fff 16k secure ROM   IGNORED
+ * 0x4000-0x00407fff Reserved IGNORED
+ * 0x00404000-0x00407fff ROM  IGNORED
+ * 0x00408000-0x0fff Reserved IGNORED
+ * 0x1000-0x1fffBfff RAM aliasing IGNORED
+ * 0x1fffc000-0x1fff RAM  EMULATED
+ * 0x2000-0x2fff Reserved IGNORED
+ * 0x3000-0x7fff I.MX31 Internal Register Space
+ *   0x43f0 IO_AREA0
+ *   0x43f9 UART1 EMULATED
+ *   0x43f94000 UART2 EMULATED
+ *   0x6800 PIC   EMULATED
+ *   0x53f94000 PIT 1 EMULATED
+ *   0x53f98000 PIT 2 EMULATED
+ *   0x53f9 GPT   EMULATED
+ * 0x8000-0x87ff RAM  EMULATED
+ * 0x8800-0x8fff RAM Aliasing EMULATED
+ * 0xa000-0xafff NAND Flash   IGNORED
+ * 0xb000-0xb3ff Unavailable  IGNORED
+ * 0xb400-0xb4000fff 8-bit free space IGNORED
+ * 0xb4001000-0xb400100f Board controlIGNORED
+ *  0xb4001003   DIP switch
+ * 0xb4001010-0xb400101f 7-segment LEDIGNORED
+ * 0xb4001020-0xb400102f LED  IGNORED
+ * 0xb4001030-0xb400103f LED  IGNORED
+ * 0xb4001040-0xb400104f FPGA, UART   EMULATED
+ * 0xb4001050-0xb400105f FPGA, UART   EMULATED
+ * 0xb4001060-0xb40f FPGA IGNORED
+ * 0xb600-0xb61f LAN controller   EMULATED
+ * 0xb620-0xb62f FPGA NAND Controller IGNORED
+ * 0xb630-0xb7ff Free IGNORED
+ * 0xb800-0xb8004fff Memory control registers IGNORED
+ * 0xc000-0xc3ff PCMCIA/CFIGNORED
+ * 0xc400-0x Reserved IGNORED
+ */
+
+#define KZM_RAMADDRESS (0x8000)
+#define KZM_FPGA   (0xb4001040)
+
+static struct arm_boot_info kzm_binfo = {
+.loader_start = KZM_RAMADDRESS,
+.board_id = 1722,
+};
+
+static void kzm_init(ram_addr_t ram_size,
+ const char *boot_device,
+ const char *kernel_filename, const char *kernel_cmdline,
+ const char *initrd_filename, const char *cpu_model)
+{
+CPUState *env;
+MemoryRegion *address_space_mem = get_system_memory();
+MemoryRegion *ram = g_new(MemoryRegion, 1);
+MemoryRegion *sram = g_new(MemoryRegion, 1);
+MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
+qemu_irq *cpu_pic;
+DeviceState *dev;
+
+if (!cpu_model) {
+cpu_model = "arm1136";
+}
+
+env = cpu_init(cpu_model);
+if (!env) {
+fprintf(stderr, "Unable to find CPU definition\n");
+exit(1);
+}
+
+/* On a real system, the first 16k is a `secure boot rom' */
+
+memory_region_init_ram(ram, NULL, "kzm.ram", ram_size);
+memory_region_add_subregion(address_space_mem, KZM_RAMADDRESS, ram);
+
+memory_region_init_alias(ram_alias, "ram.alias", ram, 0, ram_size);
+memory_region_add_subregion(address_space_mem, 0x8800, ram_alias);
+
+memory_region_init_ram(sram, NULL, "kzm.sram", 0x4000);
+memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
+
+
+cpu_pic = arm_pic_init_cpu(env);
+dev = sysbus_create_varargs("imx_int", 0x6800,
+   cpu_pic[ARM_PIC_CPU_IRQ],
+  

Re: [Qemu-devel] [PATCH V2 3/4] imx.31 and KZM board support: interrupt controller

2011-11-21 Thread Peter Chubb
Implement the FreeSCALE i.MX31 advanced vectored interrupt controller, at least
to the extent it is used by Linux 3.0.x

Signed-off-by: Hans Jang 
Signed-off-by: Adam Clench 
Signed-off-by: Peter Chubb 
---
 hw/imx_avic.c |  363 ++
 1 file changed, 363 insertions(+)
 create mode 100644 hw/imx_avic.c

Index: qemu-working/hw/imx_avic.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_avic.c  2011-11-22 14:47:10.706040936 +1100
@@ -0,0 +1,363 @@
+/*
+ * IMX31 Vectored Interrupt Controller
+ *
+ * Note this is NOT the PL192 provided by ARM, but
+ * a custom implementation by FreeScale.
+ *
+ * Copyright (c) 2008 OKL
+ * Written by Hans
+ *
+ * This code is licenced under the GPL version 2 or later.
+ *
+ * TODO: implement vectors and priorities.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include  /* ffsll */
+
+#define DEBUG_INT 1
+#undef DEBUG_INT /* comment out for debugging */
+
+#ifdef DEBUG_INT
+#define DPRINTF(fmt, args...) \
+do { printf("imx_int: " fmt , ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...) do {} while (0)
+#endif
+
+/*
+ * Print a message at most ten times.
+ */
+#define scream(fmt, args...) \
+do { \
+static int printable = 10;\
+if (printable--) { \
+fprintf(stderr, fmt, ##args); \
+} \
+} while (0)
+
+
+#define IMX_INT_NUM_IRQS 64
+
+/* Interrupt Control Bits */
+#define ABFLAG (1<<25)
+#define ABFEN (1<<24)
+#define NIDIS (1<<22) /* Normal Interrupt disable */
+#define FIDIS (1<<21) /* Fast interrupt disable */
+#define NIAD  (1<<20) /* Normal Interrupt Arbiter Rise ARM level */
+#define FIAD  (1<<19) /* Fast Interrupt Arbiter Rise ARM level */
+#define NM(1<<18) /* Normal interrupt mode */
+
+
+#define PRIO_PER_WORD (sizeof (uint32_t) * 8 / 4)
+#define PRIO_WORDS (IMX_INT_NUM_IRQS/PRIO_PER_WORD)
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+uint64_t pending;
+uint64_t enabled;
+uint64_t is_fiq;
+uint32_t intcntl;
+uint32_t intmask;
+qemu_irq irq;
+qemu_irq fiq;
+uint32_t prio[PRIO_WORDS]; /* Priorities are 4-bits each */
+} imx_int_state;
+
+static const VMStateDescription vmstate_imx_avic = {
+.name = "imx-avic",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField []) {
+VMSTATE_UINT64(pending, imx_int_state),
+VMSTATE_UINT64(enabled, imx_int_state),
+VMSTATE_UINT64(is_fiq, imx_int_state),
+VMSTATE_UINT32(intcntl, imx_int_state),
+VMSTATE_UINT32(intmask, imx_int_state),
+VMSTATE_UINT32_ARRAY(prio, imx_int_state, PRIO_WORDS),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+
+static inline int imx_int_prio(imx_int_state *s, int irq)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+return 0xf & (s->prio[word] >> part);
+}
+
+static inline void imx_int_set_prio(imx_int_state *s, int irq, int prio)
+{
+uint32_t word = irq / PRIO_PER_WORD;
+uint32_t part = 4 * (irq % PRIO_PER_WORD);
+uint32_t mask = ~(0xf << part);
+s->prio[word] &= mask;
+s->prio[word] |= prio << part;
+}
+
+/* Update interrupts.  */
+static void imx_int_update(imx_int_state *s)
+{
+int i;
+uint64_t new = s->pending;
+uint64_t flags;
+
+flags = new & s->enabled & s->is_fiq;
+qemu_set_irq(s->fiq, !!flags);
+
+flags = new & s->enabled & ~s->is_fiq;
+if (!flags || ((s->intmask & 0x1f) == 0x1f)) {
+qemu_set_irq(s->irq, !!flags);
+return;
+}
+
+/* Take interrupt if  prio lower than the value of intmask */
+for (i = 0; i < IMX_INT_NUM_IRQS; i++) {
+if (flags & (1UL << i)) {
+if (imx_int_prio(s, i) > s->intmask) {
+qemu_set_irq(s->irq, 1);
+return;
+}
+}
+}
+
+}
+
+static void imx_int_set_irq(void *opaque, int irq, int level)
+{
+imx_int_state *s = (imx_int_state *)opaque;
+
+if (level) {
+s->pending |= (1ULL << irq);
+} else {
+s->pending &= ~(1ULL << irq);
+}
+
+imx_int_update(s);
+}
+
+
+static uint64_t imx_int_read(void *opaque,
+ target_phys_addr_t offset, unsigned size)
+{
+imx_int_state *s = (imx_int_state *)opaque;
+
+
+DPRINTF("read(offset = 0x%x)\n", offset >> 2);
+switch (offset >> 2) {
+case 0: /* INTCNTL */
+return s->intcntl;
+
+case 1: /* Normal Interrupt Mask Register, NIMASK */
+return s->intmask;
+
+case 2: /* Interrupt Enable Number Register, INTENNUM */
+case 3: /* Interrupt Disable Number Regi

Re: [Qemu-devel] [PATCH V2 2/4] imx.31 and KZM board support: Timer support

2011-11-21 Thread Peter Chubb
Implement the timers on the FreeScale i.MX31 SoC.
This is not a complete implementation, but gives enough for 
Linux to boot and run.


Signed-off-by: Hans Jang 
Signed-off-by: Adam Clench 
Signed-off-by: Peter Chubb 
---
 hw/imx_timer.c |  441 +
 1 file changed, 441 insertions(+)
 create mode 100644 hw/imx_timer.c

Index: qemu-working/hw/imx_timer.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_timer.c 2011-11-22 14:47:10.058038639 +1100
@@ -0,0 +1,441 @@
+/*
+ * IMX31 Timer
+ *
+ * Copyright (c) 2008 OKL
+ * Written by Hans
+ * Updated by Peter Chubb
+ *
+ * This code is licenced under GPL version 2 or later.
+ */
+
+#include "hw.h"
+#include "qemu-timer.h"
+#include "sysbus.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
+
+/*
+ * Print a message at most ten times.
+ */
+#define scream(fmt, args...) \
+do { \
+static int printable = 10;\
+if (printable--) { \
+fprintf(stderr, fmt, ##args);\
+} \
+} while (0)
+
+
+/*
+ * GPT : General purpose timer
+ */
+
+#define TIMER_MAX  0xUL
+#define GPT_FREQ   5000/* Hz == 50 MHz */
+
+/* Control register.  Not all of these bits have any effect (yet) */
+#define GPT_CR_EN   (1 << 0)/* GPT Enable */
+#define GPT_CR_ENMODE (1 << 1)  /* GPT Enable Mode */
+#define GPT_CR_DBGEN (1 << 2)   /* GPT Debug mode enable */
+#define GPT_CR_WAITEN (1 << 3)  /* GPT Wait Mode Enable  */
+#define GPT_CR_DOZEN (1 << 4)   /* GPT Doze mode enable */
+#define GPT_CR_STOPEN (1 << 5)  /* GPT Stop Mode Enable */
+#define GPT_CR_CLKSRC (7 << 6) /* Clock source select (3 bits) */
+#define GPT_CR_FRR  (1 << 9)/* Freerun or Restart */
+#define GPT_CR_SWR  (1 << 15)
+#define GPT_CR_IM1  (3 << 16)   /* Input capture channel 1 mode (2 bits) */
+#define GPT_CR_IM2  (3 << 18)   /* Input capture channel 2 mode (2 bits) */
+#define GPT_CR_OM1  (7 << 20)   /* Output Compare Channel 1 Mode (3 bits) */
+#define GPT_CR_OM2  (7 << 23)   /* Output Compare Channel 2 Mode (3 bits) */
+#define GPT_CR_OM3  (7 << 26)   /* Output Compare Channel 3 Mode (3 bits) */
+#define GPT_CR_FO1  (1 << 29)   /* Force Output Compare Channel 1 */
+#define GPT_CR_FO2  (1 << 30)   /* Force Output Compare Channel 2 */
+#define GPT_CR_FO3  (1 << 31)   /* Force Output Compare Channel 3 */
+
+
+
+
+#define GPT_SR_OF1  (1 << 0)
+#define GPT_SR_ROV  (1 << 5)
+#define GPT_IR_OF1IE  (1 << 0)
+#define GPT_IR_ROVIE  (1 << 5)
+
+typedef struct {
+SysBusDevice busdev;
+QEMUTimer *timer;
+MemoryRegion iomem;
+uint32_t cr;
+uint32_t sr;
+uint32_t pr;
+uint32_t ir;
+uint32_t ocr1;
+uint32_t cnt;
+
+int waiting_rov;
+qemu_irq irq;
+} imxg_timer_state;
+
+static const VMStateDescription vmstate_imxg_timer = {
+.name = "imxg-timer",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields  = (VMStateField[]) {
+VMSTATE_UINT32(cr, imxg_timer_state),
+VMSTATE_UINT32(sr, imxg_timer_state),
+VMSTATE_UINT32(ir, imxg_timer_state),
+VMSTATE_UINT32(cnt, imxg_timer_state),
+VMSTATE_UINT32(ocr1, imxg_timer_state),
+VMSTATE_TIMER(timer, imxg_timer_state),
+VMSTATE_END_OF_LIST()
+}
+};
+
+
+/* Check all active timers, and schedule the next timer interrupt.  */
+static void imxg_timer_update(imxg_timer_state *s)
+{
+/* Update interrupts.  */
+if ((s->cr & GPT_CR_EN)
+&& (((s->sr & GPT_SR_OF1) && (s->ir & GPT_IR_OF1IE)) ||
+((s->sr & GPT_SR_ROV) && (s->ir & GPT_IR_ROVIE {
+qemu_irq_raise(s->irq);
+} else {
+qemu_irq_lower(s->irq);
+}
+}
+
+static uint64_t imxg_timer_update_count(imxg_timer_state *s)
+{
+uint64_t clk = qemu_get_clock_ns(vm_clock);
+
+s->cnt = ((uint32_t)muldiv64(clk, GPT_FREQ/100,
+ 1000)) % TIMER_MAX;
+return clk;
+}
+
+static void imxg_timer_run(imxg_timer_state *s, uint32_t timeout)
+{
+uint64_t clk = imxg_timer_update_count(s);
+uint32_t diff_cnt;
+if (s->cnt < timeout) {
+diff_cnt = (timeout - s->cnt);
+s->waiting_rov = 0;
+} else {
+diff_cnt = (TIMER_MAX - s->cnt);
+s->waiting_rov = 1;
+}
+qemu_mod_timer(s->timer, clk + diff_cnt * 1000 / (GPT_FREQ/100));
+/*
+   clk + muldiv64(get_ticks_per_sec(),
+diff_cnt, GPT_FREQ)

Re: [Qemu-devel] [PATCH V2 1/4] imx.31 and KZM board support: UART support

2011-11-21 Thread Peter Chubb

Implement the FreeScale i.MX UART.  This uart is used in a variety of
SoCs, including some by Motorola, as well as in the FreeScale i.MX
series.

Signed-off-by: Hans Jang 
Signed-off-by: Adam Clench 
Signed-off-by: Peter Chubb 
---
 hw/imx_serial.c |  307 
 1 file changed, 307 insertions(+)
 create mode 100644 hw/imx_serial.c

Index: qemu-working/hw/imx_serial.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ qemu-working/hw/imx_serial.c2011-11-22 14:47:09.242035743 +1100
@@ -0,0 +1,307 @@
+/*
+ * IMX31 UARTS
+ *
+ * Copyright (c) 2008 OKL
+ * Written by Hans
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ * This is a `bare-bones' implementation of the IMX series serial ports.
+ * TODO:
+ *  -- implement FIFOs.  The real hardware has 32 word transmit
+ *   and receive FIFOs
+ *  -- implement DMA
+ *  -- implement BAUD-rate and modem lines, for when the backend
+ * is a real serial device.
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "qemu-char.h"
+
+//#define DEBUG_SERIAL 1
+
+#ifdef DEBUG_SERIAL
+#define DPRINTF(fmt, args...) \
+do { printf("imx_serial: " fmt , ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...) do {} while (0)
+#endif
+
+/*
+ * Print a message at most ten times.
+ */
+#define scream(fmt, args...) \
+do { \
+static int printable = 10;\
+if (printable--) { \
+fprintf(stderr, fmt, ##args); \
+} \
+} while (0)
+
+
+typedef struct {
+SysBusDevice busdev;
+MemoryRegion iomem;
+int32_t readbuff;
+
+uint32_t usr1;
+uint32_t usr2;
+uint32_t ucr1;
+uint32_t uts1;
+
+uint32_t ubrm;
+uint32_t ubrc;
+
+qemu_irq irq;
+CharDriverState *chr;
+} imx_state;
+
+static const VMStateDescription vmstate_imx_serial  = {
+.name = "imx-serial",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField []) {
+VMSTATE_UINT32(usr1, imx_state),
+VMSTATE_UINT32(usr2, imx_state),
+VMSTATE_UINT32(ucr1, imx_state),
+VMSTATE_UINT32(uts1, imx_state),
+VMSTATE_UINT32(ubrm, imx_state),
+VMSTATE_UINT32(ubrc, imx_state),
+VMSTATE_END_OF_LIST()
+},
+};
+
+
+#define URXD_CHARRDY(1<<15)   /* character read is valid */
+
+#define USR1_TRDY   (1<<13)   /* Xmitter ready */
+#define USR1_RRDY   (1<<9)/* receiver ready */
+
+#define USR2_TXFE   (1<<14)   /* Transmit FIFO empty */
+#define USR2_RDR(1<<0)/* Receive data ready */
+#define USR2_TXDC   (1<<3)/* Transmission complete */
+
+#define UCR1_UARTEN (1<<0)
+#define UCR1_RRDYEN (1<<9)
+#define UCR1_TRDYEN (1<<13)
+#define UCR1_TXMPTYEN   (1<<6)
+
+#define UTS1_TXEMPTY(1<<6)
+#define UTS1_RXEMPTY(1<<5)
+#define UTS1_TXFULL (1<<4)
+#define UTS1_RXFULL (1<<3)
+
+static void imx_update(imx_state *s)
+{
+uint32_t flags;
+
+flags = ((s->usr1 & s->ucr1)) & (USR1_TRDY|USR1_RRDY);
+if (!(s->ucr1 & UCR1_TXMPTYEN)) {
+flags &= ~USR1_TRDY;
+}
+
+qemu_set_irq(s->irq, !!flags);
+}
+
+static void imx_serial_reset(imx_state *s)
+{
+s->usr1 = USR1_TRDY;
+s->usr2 = USR2_TXFE | USR2_TXDC;
+s->uts1 = UTS1_RXEMPTY;
+s->ubrm = 0;
+s->ubrc = 0;
+s->readbuff = 0;
+}
+
+static uint64_t imx_serial_read(void *opaque, target_phys_addr_t offset,
+unsigned size)
+{
+imx_state *s = (imx_state *)opaque;
+uint32_t c;
+
+DPRINTF("read(offset=%x)\n", offset >> 2);
+switch (offset >> 2) {
+case 0x0: /* URXD */
+c = s->readbuff;
+s->usr1 &= ~USR1_RRDY;
+s->usr2 &= ~USR2_RDR;
+s->uts1 |= UTS1_RXEMPTY;
+imx_update(s);
+qemu_chr_accept_input(s->chr);
+return c | URXD_CHARRDY;
+
+case 0x20: /* UCR1 */
+return s->ucr1;
+
+case 0x21: /* UCR2 */
+return 1; /* reset complete */
+
+case 0x25: /* USR1 */
+imx_update(s);
+return s->usr1;
+
+case 0x26: /* USR2 */
+imx_update(s);
+return s->usr2;
+
+
+case 0x2A: /* BRM Modulator */
+return s->ubrm;
+
+case 0x2B: /* Baud Rate Count */
+return s->ubrc;
+
+case 0x2d: /* UTS1 */
+return s->uts1;
+
+
+case 0x22: /* UCR3 */
+case 0x23: /* UCR4 */
+case 0x24: /* UFCR */
+case 0x29: /* BRM Incremental */
+return 0x0; /* TODO */
+
+default:
+scream("imx_serial_read: bad offset: 0x%x\n", (int)offset);
+r

[Qemu-devel] [PATCH V2 0/4] imx.31 and KZM board support

2011-11-21 Thread Peter Chubb
Here follow four patches in separate emails, to implement basic
i.mx31 SoC support, and the KZM evaluation board built around this
chip.

The patch to the Makefile to build all the files is in the last of
the series, rather than changing Makefile.hw in each patch.

All comments received so far have been addressed --- I've added a
macro, `scream' that gives at most 10 lines of output for OS error
reporting.

Signed-off-by lines are in each individual patch.  The work was
originally done by people at OK-Labs sufficient to get OK-L4 running;
I've cleaned it up and added sufficient new functionality to get Linux
running with an initial RAM disk.
--
Dr Peter Chubb  http://www.gelato.unsw.edu.au  peterc AT gelato.unsw.edu.au
http://www.ertos.nicta.com.au   ERTOS within National ICT Australia



Re: [Qemu-devel] [PATCH] [ARM] Fix sp804 dual-timer

2011-11-21 Thread Peter Chubb
Properly implement dual-timer read/write for the sp804 dual timer module.
Based on ARM specs at
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0271d/index.html

Signed-off-by: Hans Jang 
Signed-off-by: David Mirabito 
Signed-off-by: Peter Chubb 

---
 hw/arm_timer.c |   41 +++--
 1 file changed, 35 insertions(+), 6 deletions(-)

Index: qemu-working/hw/arm_timer.c
===
--- qemu-working.orig/hw/arm_timer.c2011-11-22 14:21:50.873221242 +1100
+++ qemu-working/hw/arm_timer.c 2011-11-22 14:22:21.986129734 +1100
@@ -163,64 +163,93 @@ static arm_timer_state *arm_timer_init(u
 s->freq = freq;
 s->control = TIMER_CTRL_IE;
 
 bh = qemu_bh_new(arm_timer_tick, s);
 s->timer = ptimer_init(bh);
 vmstate_register(NULL, -1, &vmstate_arm_timer, s);
 return s;
 }
 
 /* ARM PrimeCell SP804 dual timer module.
-   Docs for this device don't seem to be publicly available.  This
-   implementation is based on guesswork, the linux kernel sources and the
-   Integrator/CP timer modules.  */
+ * Docs at
+ * 
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0271d/index.html
+*/
 
 typedef struct {
 SysBusDevice busdev;
 MemoryRegion iomem;
 arm_timer_state *timer[2];
 int level[2];
 qemu_irq irq;
 } sp804_state;
 
+static const uint8_t sp804_ids[] = {
+/* Timer ID */
+0x04, 0x18, 0x14, 0,
+/* PrimeCell ID */
+0xd, 0xf0, 0x05, 0xb1
+};
+
 /* Merge the IRQs from the two component devices.  */
 static void sp804_set_irq(void *opaque, int irq, int level)
 {
 sp804_state *s = (sp804_state *)opaque;
 
 s->level[irq] = level;
 qemu_set_irq(s->irq, s->level[0] || s->level[1]);
 }
 
 static uint64_t sp804_read(void *opaque, target_phys_addr_t offset,
unsigned size)
 {
 sp804_state *s = (sp804_state *)opaque;
 
-/* ??? Don't know the PrimeCell ID for this device.  */
 if (offset < 0x20) {
 return arm_timer_read(s->timer[0], offset);
-} else {
+}
+if (offset < 0x40) {
 return arm_timer_read(s->timer[1], offset - 0x20);
 }
+
+/* TimerPeriphID */
+if (offset >= 0xfe0 && offset <= 0xffc) {
+return sp804_ids[(offset - 0xfe0) >> 2];
+}
+
+switch (offset) {
+/* Integration Test control registers, which we won't support */
+case 0xf00: /* TimerITCR */
+case 0xf04: /* TimerITOP (strictly write only but..) */
+return 0;
+}
+
+hw_error("%s: Bad offset %x\n", __func__, (int)offset);
+return 0;
 }
 
 static void sp804_write(void *opaque, target_phys_addr_t offset,
 uint64_t value, unsigned size)
 {
 sp804_state *s = (sp804_state *)opaque;
 
 if (offset < 0x20) {
 arm_timer_write(s->timer[0], offset, value);
-} else {
+return;
+}
+
+if (offset < 0x40) {
 arm_timer_write(s->timer[1], offset - 0x20, value);
+return;
 }
+
+/* Technically we could be writing to the Test Registers, but not likely */
+hw_error("%s: Bad offset %x\n", __func__, (int)offset);
 }
 
 static const MemoryRegionOps sp804_ops = {
 .read = sp804_read,
 .write = sp804_write,
 .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static const VMStateDescription vmstate_sp804 = {
 .name = "sp804",

--
Dr Peter Chubb  http://www.gelato.unsw.edu.au  peterc AT gelato.unsw.edu.au
http://www.ertos.nicta.com.au   ERTOS within National ICT Australia



  1   2   >