diff mbox

Changes to Broadcom(BCM) files and Raspberry Pi files. Addition of PanelEmu

Message ID 757990479.60759.1494722527715@mail.yahoo.com (mailing list archive)
State New, archived
Headers show

Commit Message

Denis V. Lunev" via May 14, 2017, 12:42 a.m. UTC
From 7f74f048f135d9c9c230a9e90f72451c841c6d35 Mon Sep 17 00:00:00 2001
From: John Bradley <flypie@rocketmail.com>
Date: Sat, 13 May 2017 23:07:47 +0100
Subject: [PATCH] Changes to Broadcom(BCM) files and Raspberry Pi files.
Addition of PanelEmu

The files add the ability to attach, via TCP, a panel emulator
The include a unification of several PD Raspberry PI additions
A modification to dev-network to all circle SDK WWW client to work
The DummyPanel is not included but available at
https://github.com/flypie/GDummyPanel.git

Signed-off-by: John Bradley <flypie@rocketmail.com>
---
.gitignore                           |   54 ++
hw/arm/Makefile.objs                 |    2 +-
hw/arm/bcm2835.c                     |  114 ++++
hw/arm/bcm2835_peripherals.c         |  104 ++++
hw/arm/bcm2836.c                     |    3 +-
hw/arm/raspi.c                       |   77 ++-
hw/gpio/bcm2835_gpio.c               |  333 ++++++-----
hw/misc/Makefile.objs                |    2 +
hw/misc/bcm2835_mphi.c               |  163 ++++++
hw/misc/bcm2835_power.c              |  106 ++++
hw/timer/Makefile.objs               |    2 +
hw/timer/bcm2835_st.c                |  202 +++++++
hw/timer/bcm2835_timer.c             |  224 +++++++
hw/usb/Makefile.objs                 |    4 +-
hw/usb/bcm2835_usb.c                 |  604 +++++++++++++++++++
hw/usb/bcm2835_usb_regs.h            | 1061 ++++++++++++++++++++++++++++++++++
hw/usb/dev-network.c                 |    2 +-
include/hw/arm/bcm2835.h             |   37 ++
include/hw/arm/bcm2835_peripherals.h |   10 +
include/hw/gpio/bcm2835_gpio.h       |    5 +
include/hw/intc/bcm2835_control.h    |   53 ++
include/hw/intc/bcm2836_control.h    |    2 +
include/hw/misc/bcm2835_mphi.h       |   28 +
include/hw/misc/bcm2835_power.h      |   22 +
include/hw/timer/bcm2835_st.h        |   25 +
include/hw/timer/bcm2835_timer.h     |   32 +
include/hw/usb/bcm2835_usb.h         |   78 +++
include/qemu/PanelEmu.h              |   53 ++
util/Makefile.objs                   |    1 +
util/PanelEmu.c                      |  293 ++++++++++
30 files changed, 3547 insertions(+), 149 deletions(-)
create mode 100644 hw/arm/bcm2835.c
create mode 100644 hw/misc/bcm2835_mphi.c
create mode 100644 hw/misc/bcm2835_power.c
create mode 100644 hw/timer/bcm2835_st.c
create mode 100644 hw/timer/bcm2835_timer.c
create mode 100644 hw/usb/bcm2835_usb.c
create mode 100644 hw/usb/bcm2835_usb_regs.h
create mode 100644 include/hw/arm/bcm2835.h
create mode 100644 include/hw/intc/bcm2835_control.h
create mode 100644 include/hw/misc/bcm2835_mphi.h
create mode 100644 include/hw/misc/bcm2835_power.h
create mode 100644 include/hw/timer/bcm2835_st.h
create mode 100644 include/hw/timer/bcm2835_timer.h
create mode 100644 include/hw/usb/bcm2835_usb.h
create mode 100644 include/qemu/PanelEmu.h
create mode 100644 util/PanelEmu.c

Comments

Alistair Francis May 15, 2017, 4:46 p.m. UTC | #1
On Sat, May 13, 2017 at 5:42 PM, John Bradley via Qemu-devel
<qemu-devel@nongnu.org> wrote:
> From 7f74f048f135d9c9c230a9e90f72451c841c6d35 Mon Sep 17 00:00:00 2001
> From: John Bradley <flypie@rocketmail.com>
> Date: Sat, 13 May 2017 23:07:47 +0100
> Subject: [PATCH] Changes to Broadcom(BCM) files and Raspberry Pi files.
> Addition of PanelEmu
>
> The files add the ability to attach, via TCP, a panel emulator
> The include a unification of several PD Raspberry PI additions
> A modification to dev-network to all circle SDK WWW client to work
> The DummyPanel is not included but available at
> https://github.com/flypie/GDummyPanel.git
>
> Signed-off-by: John Bradley <flypie@rocketmail.com>

Hey John,

Thanks for the patch!

Unfortunately this patch is too long to review, you need to split the
patch up into shorter more readable patches. Otherwise it's too hard
to people to understand what you are changing and why.

There are some details here:
http://wiki.qemu.org/Contribute/SubmitAPatch about how to split up
patches. Each patch applied in order shouldn't break any compilation
or runtime. Generally the flow is to add the logic in earlier patches
and then connect it and switch it on in the later patches.

Try splitting up adding/editing each individual device and send that
our first. That is generally the easiest to review/accept.

Thanks,

Alistair

> ---
> .gitignore                           |   54 ++
> hw/arm/Makefile.objs                 |    2 +-
> hw/arm/bcm2835.c                     |  114 ++++
> hw/arm/bcm2835_peripherals.c         |  104 ++++
> hw/arm/bcm2836.c                     |    3 +-
> hw/arm/raspi.c                       |   77 ++-
> hw/gpio/bcm2835_gpio.c               |  333 ++++++-----
> hw/misc/Makefile.objs                |    2 +
> hw/misc/bcm2835_mphi.c               |  163 ++++++
> hw/misc/bcm2835_power.c              |  106 ++++
> hw/timer/Makefile.objs               |    2 +
> hw/timer/bcm2835_st.c                |  202 +++++++
> hw/timer/bcm2835_timer.c             |  224 +++++++
> hw/usb/Makefile.objs                 |    4 +-
> hw/usb/bcm2835_usb.c                 |  604 +++++++++++++++++++
> hw/usb/bcm2835_usb_regs.h            | 1061 ++++++++++++++++++++++++++++++++++
> hw/usb/dev-network.c                 |    2 +-
> include/hw/arm/bcm2835.h             |   37 ++
> include/hw/arm/bcm2835_peripherals.h |   10 +
> include/hw/gpio/bcm2835_gpio.h       |    5 +
> include/hw/intc/bcm2835_control.h    |   53 ++
> include/hw/intc/bcm2836_control.h    |    2 +
> include/hw/misc/bcm2835_mphi.h       |   28 +
> include/hw/misc/bcm2835_power.h      |   22 +
> include/hw/timer/bcm2835_st.h        |   25 +
> include/hw/timer/bcm2835_timer.h     |   32 +
> include/hw/usb/bcm2835_usb.h         |   78 +++
> include/qemu/PanelEmu.h              |   53 ++
> util/Makefile.objs                   |    1 +
> util/PanelEmu.c                      |  293 ++++++++++
> 30 files changed, 3547 insertions(+), 149 deletions(-)
> create mode 100644 hw/arm/bcm2835.c
> create mode 100644 hw/misc/bcm2835_mphi.c
> create mode 100644 hw/misc/bcm2835_power.c
> create mode 100644 hw/timer/bcm2835_st.c
> create mode 100644 hw/timer/bcm2835_timer.c
> create mode 100644 hw/usb/bcm2835_usb.c
> create mode 100644 hw/usb/bcm2835_usb_regs.h
> create mode 100644 include/hw/arm/bcm2835.h
> create mode 100644 include/hw/intc/bcm2835_control.h
> create mode 100644 include/hw/misc/bcm2835_mphi.h
> create mode 100644 include/hw/misc/bcm2835_power.h
> create mode 100644 include/hw/timer/bcm2835_st.h
> create mode 100644 include/hw/timer/bcm2835_timer.h
> create mode 100644 include/hw/usb/bcm2835_usb.h
> create mode 100644 include/qemu/PanelEmu.h
> create mode 100644 util/PanelEmu.c
>
Denis V. Lunev" via May 15, 2017, 5:50 p.m. UTC | #2
Hi,
That is going to be very difficult as a lot of the changes are interlinked the vast majority of the patch is new files. John BradleyTel: 07896 839635Skype: flypie125 125B Grove StreetEdge Hill Liverpool L7 7AF 

    On Monday, 15 May 2017, 17:54, Alistair Francis <alistair.francis@xilinx.com> wrote:
 

 On Sat, May 13, 2017 at 5:42 PM, John Bradley via Qemu-devel
<qemu-devel@nongnu.org> wrote:
> From 7f74f048f135d9c9c230a9e90f72451c841c6d35 Mon Sep 17 00:00:00 2001
> From: John Bradley <flypie@rocketmail.com>
> Date: Sat, 13 May 2017 23:07:47 +0100
> Subject: [PATCH] Changes to Broadcom(BCM) files and Raspberry Pi files.
> Addition of PanelEmu
>
> The files add the ability to attach, via TCP, a panel emulator
> The include a unification of several PD Raspberry PI additions
> A modification to dev-network to all circle SDK WWW client to work
> The DummyPanel is not included but available at
> https://github.com/flypie/GDummyPanel.git
>
> Signed-off-by: John Bradley <flypie@rocketmail.com>

Hey John,

Thanks for the patch!

Unfortunately this patch is too long to review, you need to split the
patch up into shorter more readable patches. Otherwise it's too hard
to people to understand what you are changing and why.

There are some details here:
http://wiki.qemu.org/Contribute/SubmitAPatch about how to split up
patches. Each patch applied in order shouldn't break any compilation
or runtime. Generally the flow is to add the logic in earlier patches
and then connect it and switch it on in the later patches.

Try splitting up adding/editing each individual device and send that
our first. That is generally the easiest to review/accept.

Thanks,

Alistair

> ---
> .gitignore                          |  54 ++
> hw/arm/Makefile.objs                |    2 +-
> hw/arm/bcm2835.c                    |  114 ++++
> hw/arm/bcm2835_peripherals.c        |  104 ++++
> hw/arm/bcm2836.c                    |    3 +-
> hw/arm/raspi.c                      |  77 ++-
> hw/gpio/bcm2835_gpio.c              |  333 ++++++-----
> hw/misc/Makefile.objs                |    2 +
> hw/misc/bcm2835_mphi.c              |  163 ++++++
> hw/misc/bcm2835_power.c              |  106 ++++
> hw/timer/Makefile.objs              |    2 +
> hw/timer/bcm2835_st.c                |  202 +++++++
> hw/timer/bcm2835_timer.c            |  224 +++++++
> hw/usb/Makefile.objs                |    4 +-
> hw/usb/bcm2835_usb.c                |  604 +++++++++++++++++++
> hw/usb/bcm2835_usb_regs.h            | 1061 ++++++++++++++++++++++++++++++++++
> hw/usb/dev-network.c                |    2 +-
> include/hw/arm/bcm2835.h            |  37 ++
> include/hw/arm/bcm2835_peripherals.h |  10 +
> include/hw/gpio/bcm2835_gpio.h      |    5 +
> include/hw/intc/bcm2835_control.h    |  53 ++
> include/hw/intc/bcm2836_control.h    |    2 +
> include/hw/misc/bcm2835_mphi.h      |  28 +
> include/hw/misc/bcm2835_power.h      |  22 +
> include/hw/timer/bcm2835_st.h        |  25 +
> include/hw/timer/bcm2835_timer.h    |  32 +
> include/hw/usb/bcm2835_usb.h        |  78 +++
> include/qemu/PanelEmu.h              |  53 ++
> util/Makefile.objs                  |    1 +
> util/PanelEmu.c                      |  293 ++++++++++
> 30 files changed, 3547 insertions(+), 149 deletions(-)
> create mode 100644 hw/arm/bcm2835.c
> create mode 100644 hw/misc/bcm2835_mphi.c
> create mode 100644 hw/misc/bcm2835_power.c
> create mode 100644 hw/timer/bcm2835_st.c
> create mode 100644 hw/timer/bcm2835_timer.c
> create mode 100644 hw/usb/bcm2835_usb.c
> create mode 100644 hw/usb/bcm2835_usb_regs.h
> create mode 100644 include/hw/arm/bcm2835.h
> create mode 100644 include/hw/intc/bcm2835_control.h
> create mode 100644 include/hw/misc/bcm2835_mphi.h
> create mode 100644 include/hw/misc/bcm2835_power.h
> create mode 100644 include/hw/timer/bcm2835_st.h
> create mode 100644 include/hw/timer/bcm2835_timer.h
> create mode 100644 include/hw/usb/bcm2835_usb.h
> create mode 100644 include/qemu/PanelEmu.h
> create mode 100644 util/PanelEmu.c
>
Philippe Mathieu-Daudé May 15, 2017, 11:20 p.m. UTC | #3
Hi John,

> That is going to be very difficult as a lot of the changes are
> interlinked the vast majority of the patch is new files.

I rebased your branch on latest qemu/master here:

https://github.com/philmd/qemu/tree/flypie-GDummyPanel-rebased

It is much easier to follow now, the big XML files you added/removed 
also disappeared (gitk was crashing 'Out Of Memory' trying to look at 
your tree).

I hope it can help you to continue reordering in smaller patches.

Regards,

Phil.

On 05/15/2017 01:46 PM, Alistair Francis wrote:
>
> Hey John,
>
> Thanks for the patch!
>
> Unfortunately this patch is too long to review, you need to split the
> patch up into shorter more readable patches. Otherwise it's too hard
> to people to understand what you are changing and why.
>
> There are some details here:
> http://wiki.qemu.org/Contribute/SubmitAPatch
> <http://wiki.qemu.org/Contribute/SubmitAPatch>about how to split up
> patches. Each patch applied in order shouldn't break any compilation
> or runtime. Generally the flow is to add the logic in earlier patches
> and then connect it and switch it on in the later patches.
>
> Try splitting up adding/editing each individual device and send that
> our first. That is generally the easiest to review/accept.
>
> Thanks,
>
> Alistair
>
>> ---
>> .gitignore                          |  54 ++
>> hw/arm/Makefile.objs                |    2 +-
>> hw/arm/bcm2835.c                    |  114 ++++
>> hw/arm/bcm2835_peripherals.c        |  104 ++++
>> hw/arm/bcm2836.c                    |    3 +-
>> hw/arm/raspi.c                      |  77 ++-
>> hw/gpio/bcm2835_gpio.c              |  333 ++++++-----
>> hw/misc/Makefile.objs                |    2 +
>> hw/misc/bcm2835_mphi.c              |  163 ++++++
>> hw/misc/bcm2835_power.c              |  106 ++++
>> hw/timer/Makefile.objs              |    2 +
>> hw/timer/bcm2835_st.c                |  202 +++++++
>> hw/timer/bcm2835_timer.c            |  224 +++++++
>> hw/usb/Makefile.objs                |    4 +-
>> hw/usb/bcm2835_usb.c                |  604 +++++++++++++++++++
>> hw/usb/bcm2835_usb_regs.h            | 1061
> ++++++++++++++++++++++++++++++++++
>> hw/usb/dev-network.c                |    2 +-
>> include/hw/arm/bcm2835.h            |  37 ++
>> include/hw/arm/bcm2835_peripherals.h |  10 +
>> include/hw/gpio/bcm2835_gpio.h      |    5 +
>> include/hw/intc/bcm2835_control.h    |  53 ++
>> include/hw/intc/bcm2836_control.h    |    2 +
>> include/hw/misc/bcm2835_mphi.h      |  28 +
>> include/hw/misc/bcm2835_power.h      |  22 +
>> include/hw/timer/bcm2835_st.h        |  25 +
>> include/hw/timer/bcm2835_timer.h    |  32 +
>> include/hw/usb/bcm2835_usb.h        |  78 +++
>> include/qemu/PanelEmu.h              |  53 ++
>> util/Makefile.objs                  |    1 +
>> util/PanelEmu.c                      |  293 ++++++++++
>> 30 files changed, 3547 insertions(+), 149 deletions(-)
>> create mode 100644 hw/arm/bcm2835.c
>> create mode 100644 hw/misc/bcm2835_mphi.c
>> create mode 100644 hw/misc/bcm2835_power.c
>> create mode 100644 hw/timer/bcm2835_st.c
>> create mode 100644 hw/timer/bcm2835_timer.c
>> create mode 100644 hw/usb/bcm2835_usb.c
>> create mode 100644 hw/usb/bcm2835_usb_regs.h
>> create mode 100644 include/hw/arm/bcm2835.h
>> create mode 100644 include/hw/intc/bcm2835_control.h
>> create mode 100644 include/hw/misc/bcm2835_mphi.h
>> create mode 100644 include/hw/misc/bcm2835_power.h
>> create mode 100644 include/hw/timer/bcm2835_st.h
>> create mode 100644 include/hw/timer/bcm2835_timer.h
>> create mode 100644 include/hw/usb/bcm2835_usb.h
>> create mode 100644 include/qemu/PanelEmu.h
>> create mode 100644 util/PanelEmu.c
>>
>
>
Denis V. Lunev" via May 16, 2017, 12:01 a.m. UTC | #4
Hi,
The XML files in the base are not in the patch. They where net beans files. I can easily get it into 3 files, one large at 91KB but contains only new files and so is easy to read. Could be smaller but seems pointless. 

another which is about 19KB of quite simple changes to mostly make files.
Then one 15KB which quite straight forward when you look at it. Applying them in that order should allow step wise addition. I've uploaded them to a share if anyone wants to comment.

The 3 files are new.patch
  
|  
|   
|   
|   |    |

   |

  |
|  
|    |  
new.patch
 Shared with Dropbox  |   |

  |

  |

 
 mod1.patch

  
|  
|   
|   
|   |    |

   |

  |
|  
|    |  
mod1.patch
 Shared with Dropbox  |   |

  |

  |

 

and 
 a_hw_gpio_bcm2835_gpio.c.patch
  
|  
|   
|   
|   |    |

   |

  |
|  
|    |  
a_hw_gpio_bcm2835_gpio.c.patch
 Shared with Dropbox  |   |

  |

  |

 



John BradleyTel: 07896 839635Skype: flypie125 125B Grove StreetEdge Hill Liverpool L7 7AF 

    On Tuesday, 16 May 2017, 0:20, Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
 

 Hi John,

> That is going to be very difficult as a lot of the changes are
> interlinked the vast majority of the patch is new files.

I rebased your branch on latest qemu/master here:

https://github.com/philmd/qemu/tree/flypie-GDummyPanel-rebased

It is much easier to follow now, the big XML files you added/removed 
also disappeared (gitk was crashing 'Out Of Memory' trying to look at 
your tree).

I hope it can help you to continue reordering in smaller patches.

Regards,

Phil.

On 05/15/2017 01:46 PM, Alistair Francis wrote:
>
> Hey John,
>
> Thanks for the patch!
>
> Unfortunately this patch is too long to review, you need to split the
> patch up into shorter more readable patches. Otherwise it's too hard
> to people to understand what you are changing and why.
>
> There are some details here:
> http://wiki.qemu.org/Contribute/SubmitAPatch
> <http://wiki.qemu.org/Contribute/SubmitAPatch>about how to split up
> patches. Each patch applied in order shouldn't break any compilation
> or runtime. Generally the flow is to add the logic in earlier patches
> and then connect it and switch it on in the later patches.
>
> Try splitting up adding/editing each individual device and send that
> our first. That is generally the easiest to review/accept.
>
> Thanks,
>
> Alistair
>
>> ---
>> .gitignore                          |  54 ++
>> hw/arm/Makefile.objs                |    2 +-
>> hw/arm/bcm2835.c                    |  114 ++++
>> hw/arm/bcm2835_peripherals.c        |  104 ++++
>> hw/arm/bcm2836.c                    |    3 +-
>> hw/arm/raspi.c                      |  77 ++-
>> hw/gpio/bcm2835_gpio.c              |  333 ++++++-----
>> hw/misc/Makefile.objs                |    2 +
>> hw/misc/bcm2835_mphi.c              |  163 ++++++
>> hw/misc/bcm2835_power.c              |  106 ++++
>> hw/timer/Makefile.objs              |    2 +
>> hw/timer/bcm2835_st.c                |  202 +++++++
>> hw/timer/bcm2835_timer.c            |  224 +++++++
>> hw/usb/Makefile.objs                |    4 +-
>> hw/usb/bcm2835_usb.c                |  604 +++++++++++++++++++
>> hw/usb/bcm2835_usb_regs.h            | 1061
> ++++++++++++++++++++++++++++++++++
>> hw/usb/dev-network.c                |    2 +-
>> include/hw/arm/bcm2835.h            |  37 ++
>> include/hw/arm/bcm2835_peripherals.h |  10 +
>> include/hw/gpio/bcm2835_gpio.h      |    5 +
>> include/hw/intc/bcm2835_control.h    |  53 ++
>> include/hw/intc/bcm2836_control.h    |    2 +
>> include/hw/misc/bcm2835_mphi.h      |  28 +
>> include/hw/misc/bcm2835_power.h      |  22 +
>> include/hw/timer/bcm2835_st.h        |  25 +
>> include/hw/timer/bcm2835_timer.h    |  32 +
>> include/hw/usb/bcm2835_usb.h        |  78 +++
>> include/qemu/PanelEmu.h              |  53 ++
>> util/Makefile.objs                  |    1 +
>> util/PanelEmu.c                      |  293 ++++++++++
>> 30 files changed, 3547 insertions(+), 149 deletions(-)
>> create mode 100644 hw/arm/bcm2835.c
>> create mode 100644 hw/misc/bcm2835_mphi.c
>> create mode 100644 hw/misc/bcm2835_power.c
>> create mode 100644 hw/timer/bcm2835_st.c
>> create mode 100644 hw/timer/bcm2835_timer.c
>> create mode 100644 hw/usb/bcm2835_usb.c
>> create mode 100644 hw/usb/bcm2835_usb_regs.h
>> create mode 100644 include/hw/arm/bcm2835.h
>> create mode 100644 include/hw/intc/bcm2835_control.h
>> create mode 100644 include/hw/misc/bcm2835_mphi.h
>> create mode 100644 include/hw/misc/bcm2835_power.h
>> create mode 100644 include/hw/timer/bcm2835_st.h
>> create mode 100644 include/hw/timer/bcm2835_timer.h
>> create mode 100644 include/hw/usb/bcm2835_usb.h
>> create mode 100644 include/qemu/PanelEmu.h
>> create mode 100644 util/PanelEmu.c
>>
>
>
Geert Martin Ijewski May 16, 2017, 8:55 a.m. UTC | #5
Am 14.05.2017 um 02:42 schrieb John Bradley via Qemu-devel:
>>From 7f74f048f135d9c9c230a9e90f72451c841c6d35 Mon Sep 17 00:00:00 2001
> From: John Bradley <flypie@rocketmail.com>
> Date: Sat, 13 May 2017 23:07:47 +0100
> Subject: [PATCH] Changes to Broadcom(BCM) files and Raspberry Pi files.
> Addition of PanelEmu
>
> The files add the ability to attach, via TCP, a panel emulator
> The include a unification of several PD Raspberry PI additions
> A modification to dev-network to all circle SDK WWW client to work
> The DummyPanel is not included but available at
> https://github.com/flypie/GDummyPanel.git
>
> Signed-off-by: John Bradley <flypie@rocketmail.com>
> ---
> [ ... snip ... ]
> diff --git a/util/PanelEmu.c b/util/PanelEmu.c
> new file mode 100644
> index 0000000000..59c87d2747
> --- /dev/null
> +++ b/util/PanelEmu.c
> @@ -0,0 +1,293 @@
> +/*
> + * Emulation for Rasp PI GPIO via Server connected to via Socket
> + *
> + */
> +#include "qemu/osdep.h"
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <memory.h>
> +#include <errno.h>
> +#include <string.h>
> +#include <sys/types.h>
> +#ifdef __MINGW32__
I think that should be #ifdef _WIN32.
Maybe in the far future QEMU could also be compiled with Visual Studio 
or any other windows compiler
> +#include <winsock2.h>
> +#else
> +#include <sys/socket.h>
> +#include <arpa/inet.h>
> +#include <netinet/in.h>
> +#endif
> +
> +
> +#include "qemu/PanelEmu.h"
> +
> +typedef enum
> +{
> +    MACHINEDESC = 0,
> +    PINSTOPANEL = 1,
> +    READREQ = 2,
> +    PINCOUNT = 3,
> +    ENABLEMAP = 4,
> +    INPUTMAP = 5,
> +    OUTPUTMAP = 6,
> +    PINSTOQEMU = 7
> +} PacketType;
> +
> +#define MAXPACKET   255
> +
> +#define PACKETLEN   0  //Includes Packet Length
> +#define PACKETTYPE  1
> +
> +typedef struct
> +{
> +    unsigned short int Data[MAXPACKET];
> +} CommandPacket;

Why not something like
typedef struct
{
     uint8_t len;
     uint8_t type;
     union {
         struct {
             uint8_t cnt;
         } pinCount;
         struct {
             uint16_t pin0to15;
             uint16_t pin16to31;
             uint16_t pin32to47;
             uint16_t pin48to63;
         } dataUpdate;
         /* todo: other packet types */
     };
} CommandPacket;
> [ ... snip ... ]
> +/* Set a pin to a specified value */
> +void senddatatopanel(panel_connection_t* h, uint64_t pin, bool val)
> +{
> +    CommandPacket Pkt;
> +
> +    Pkt.Data[PACKETLEN] = (char *) &Pkt.Data[6 + 1]-(char *) &Pkt.Data[0];
what's the use of this pointer aritmethic instead of just 6?

Geert
Geert Martin Ijewski May 16, 2017, 8:55 a.m. UTC | #6
Am 16.05.2017 um 02:01 schrieb John Bradley via Qemu-devel:
> Hi,
> The XML files in the base are not in the patch. They where net beans files. I can easily get it into 3 files, one large at 91KB but contains only new files and so is easy to read. Could be smaller but seems pointless.
>
I think what Alistar meant was something along the lines of:
patch/commit 1) add the remaining bcm2835 devices from Markus 
Armbruster's code to QEMU (btw: any reason why that hasn't been done? 
The USB stuff does seem nice to have)
-- with a more meaningful commit title
2) add utils/panelemu.c and the include
3) bcm2835 now uses the emupanel
and then your other commits e.g.
4) USB CDC Ethernet driver dropped packets
5) emupanel: fixed compilation errors on linux
6) emupanel: removed last blocking I/O

Along the way you also seem to fix indentation in other code a lot, that 
makes following the patches more confusing than they need to be.
It's harder to gauge at a quick glance whether you changed something 
meaingul or not.

Maybe even send a RFC just detailing the protocol, because it's probably 
important to get that right from the start.

Geert
> another which is about 19KB of quite simple changes to mostly make files.
> Then one 15KB which quite straight forward when you look at it. Applying them in that order should allow step wise addition. I've uploaded them to a share if anyone wants to comment.
>
> The 3 files are new.patch
>
> |
> |
> |
> |   |    |
>
>    |
>
>   |
> |
> |    |
> new.patch
>  Shared with Dropbox  |   |
>
>   |
>
>   |
>
>
>  mod1.patch
>
>
> |
> |
> |
> |   |    |
>
>    |
>
>   |
> |
> |    |
> mod1.patch
>  Shared with Dropbox  |   |
>
>   |
>
>   |
>
>
>
> and
>  a_hw_gpio_bcm2835_gpio.c.patch
>
> |
> |
> |
> |   |    |
>
>    |
>
>   |
> |
> |    |
> a_hw_gpio_bcm2835_gpio.c.patch
>  Shared with Dropbox  |   |
>
>   |
>
>   |
>
>
>
>
>
> John BradleyTel: 07896 839635Skype: flypie125 125B Grove StreetEdge Hill Liverpool L7 7AF
>
>     On Tuesday, 16 May 2017, 0:20, Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>
>
>  Hi John,
>
>> That is going to be very difficult as a lot of the changes are
>> interlinked the vast majority of the patch is new files.
>
> I rebased your branch on latest qemu/master here:
>
> https://github.com/philmd/qemu/tree/flypie-GDummyPanel-rebased
>
> It is much easier to follow now, the big XML files you added/removed
> also disappeared (gitk was crashing 'Out Of Memory' trying to look at
> your tree).
>
> I hope it can help you to continue reordering in smaller patches.
>
> Regards,
>
> Phil.
>
> On 05/15/2017 01:46 PM, Alistair Francis wrote:
>>
>> Hey John,
>>
>> Thanks for the patch!
>>
>> Unfortunately this patch is too long to review, you need to split the
>> patch up into shorter more readable patches. Otherwise it's too hard
>> to people to understand what you are changing and why.
>>
>> There are some details here:
>> http://wiki.qemu.org/Contribute/SubmitAPatch
>> <http://wiki.qemu.org/Contribute/SubmitAPatch>about how to split up
>> patches. Each patch applied in order shouldn't break any compilation
>> or runtime. Generally the flow is to add the logic in earlier patches
>> and then connect it and switch it on in the later patches.
>>
>> Try splitting up adding/editing each individual device and send that
>> our first. That is generally the easiest to review/accept.
>>
>> Thanks,
>>
>> Alistair
>>
>>> ---
>>> .gitignore                          |  54 ++
>>> hw/arm/Makefile.objs                |    2 +-
>>> hw/arm/bcm2835.c                    |  114 ++++
>>> hw/arm/bcm2835_peripherals.c        |  104 ++++
>>> hw/arm/bcm2836.c                    |    3 +-
>>> hw/arm/raspi.c                      |  77 ++-
>>> hw/gpio/bcm2835_gpio.c              |  333 ++++++-----
>>> hw/misc/Makefile.objs                |    2 +
>>> hw/misc/bcm2835_mphi.c              |  163 ++++++
>>> hw/misc/bcm2835_power.c              |  106 ++++
>>> hw/timer/Makefile.objs              |    2 +
>>> hw/timer/bcm2835_st.c                |  202 +++++++
>>> hw/timer/bcm2835_timer.c            |  224 +++++++
>>> hw/usb/Makefile.objs                |    4 +-
>>> hw/usb/bcm2835_usb.c                |  604 +++++++++++++++++++
>>> hw/usb/bcm2835_usb_regs.h            | 1061
>> ++++++++++++++++++++++++++++++++++
>>> hw/usb/dev-network.c                |    2 +-
>>> include/hw/arm/bcm2835.h            |  37 ++
>>> include/hw/arm/bcm2835_peripherals.h |  10 +
>>> include/hw/gpio/bcm2835_gpio.h      |    5 +
>>> include/hw/intc/bcm2835_control.h    |  53 ++
>>> include/hw/intc/bcm2836_control.h    |    2 +
>>> include/hw/misc/bcm2835_mphi.h      |  28 +
>>> include/hw/misc/bcm2835_power.h      |  22 +
>>> include/hw/timer/bcm2835_st.h        |  25 +
>>> include/hw/timer/bcm2835_timer.h    |  32 +
>>> include/hw/usb/bcm2835_usb.h        |  78 +++
>>> include/qemu/PanelEmu.h              |  53 ++
>>> util/Makefile.objs                  |    1 +
>>> util/PanelEmu.c                      |  293 ++++++++++
>>> 30 files changed, 3547 insertions(+), 149 deletions(-)
>>> create mode 100644 hw/arm/bcm2835.c
>>> create mode 100644 hw/misc/bcm2835_mphi.c
>>> create mode 100644 hw/misc/bcm2835_power.c
>>> create mode 100644 hw/timer/bcm2835_st.c
>>> create mode 100644 hw/timer/bcm2835_timer.c
>>> create mode 100644 hw/usb/bcm2835_usb.c
>>> create mode 100644 hw/usb/bcm2835_usb_regs.h
>>> create mode 100644 include/hw/arm/bcm2835.h
>>> create mode 100644 include/hw/intc/bcm2835_control.h
>>> create mode 100644 include/hw/misc/bcm2835_mphi.h
>>> create mode 100644 include/hw/misc/bcm2835_power.h
>>> create mode 100644 include/hw/timer/bcm2835_st.h
>>> create mode 100644 include/hw/timer/bcm2835_timer.h
>>> create mode 100644 include/hw/usb/bcm2835_usb.h
>>> create mode 100644 include/qemu/PanelEmu.h
>>> create mode 100644 util/PanelEmu.c
>>>
>>
>>
>
>
>
>
Denis V. Lunev" via May 16, 2017, 1:51 p.m. UTC | #7
"I think that should be #ifdef _WIN32.
Maybe in the far future QEMU could also be compiled with Visual Studio 
or any other windows compiler"
The reason for doing it this way is that MINGW64, which is the dev platform I uses on Windows10, does not include a port of the GNU Socket library so I have to use the native Win Sock Library.
 
"Why not something like
typedef struct
{
    uint8_t len;
    uint8_t type;
    union {
        struct {
            uint8_t cnt;
        } pinCount;
        struct {
            uint16_t pin0to15;
            uint16_t pin16to31;
            uint16_t pin32to47;
            uint16_t pin48to63;
        } dataUpdate;
        /* todo: other packet types */
    };
} CommandPacket;"

The problem with that is packing. I tried to do it that way but the different compilers I am using for QEMU and GDummyPanel pack and align in different way and no collection of pragmas and directives could make them pack the same. While writing this I have also noticed I have made an implicit assumption about the endedness of the data, which is not good. Also keep in mind someone may write a client in any language from Fortran, Forth to Python.

"what's the use of this pointer aritmethic instead of just 6?"

This is a similar attempt at robustness across compilers.

John BradleyTel: 07896 839635Skype: flypie125 125B Grove StreetEdge Hill Liverpool L7 7AF 

    On Tuesday, 16 May 2017, 9:56, Geert Martin Ijewski <gm.ijewski@web.de> wrote:
 

 Am 14.05.2017 um 02:42 schrieb John Bradley via Qemu-devel:
>>From 7f74f048f135d9c9c230a9e90f72451c841c6d35 Mon Sep 17 00:00:00 2001
> From: John Bradley <flypie@rocketmail.com>
> Date: Sat, 13 May 2017 23:07:47 +0100
> Subject: [PATCH] Changes to Broadcom(BCM) files and Raspberry Pi files.
> Addition of PanelEmu
>
> The files add the ability to attach, via TCP, a panel emulator
> The include a unification of several PD Raspberry PI additions
> A modification to dev-network to all circle SDK WWW client to work
> The DummyPanel is not included but available at
> https://github.com/flypie/GDummyPanel.git
>
> Signed-off-by: John Bradley <flypie@rocketmail.com>
> ---
> [ ... snip ... ]
> diff --git a/util/PanelEmu.c b/util/PanelEmu.c
> new file mode 100644
> index 0000000000..59c87d2747
> --- /dev/null
> +++ b/util/PanelEmu.c
> @@ -0,0 +1,293 @@
> +/*
> + * Emulation for Rasp PI GPIO via Server connected to via Socket
> + *
> + */
> +#include "qemu/osdep.h"
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <memory.h>
> +#include <errno.h>
> +#include <string.h>
> +#include <sys/types.h>
> +#ifdef __MINGW32__
I think that should be #ifdef _WIN32.
Maybe in the far future QEMU could also be compiled with Visual Studio 
or any other windows compiler
> +#include <winsock2.h>
> +#else
> +#include <sys/socket.h>
> +#include <arpa/inet.h>
> +#include <netinet/in.h>
> +#endif
> +
> +
> +#include "qemu/PanelEmu.h"
> +
> +typedef enum
> +{
> +    MACHINEDESC = 0,
> +    PINSTOPANEL = 1,
> +    READREQ = 2,
> +    PINCOUNT = 3,
> +    ENABLEMAP = 4,
> +    INPUTMAP = 5,
> +    OUTPUTMAP = 6,
> +    PINSTOQEMU = 7
> +} PacketType;
> +
> +#define MAXPACKET  255
> +
> +#define PACKETLEN  0  //Includes Packet Length
> +#define PACKETTYPE  1
> +
> +typedef struct
> +{
> +    unsigned short int Data[MAXPACKET];
> +} CommandPacket;

Why not something like
typedef struct
{
    uint8_t len;
    uint8_t type;
    union {
        struct {
            uint8_t cnt;
        } pinCount;
        struct {
            uint16_t pin0to15;
            uint16_t pin16to31;
            uint16_t pin32to47;
            uint16_t pin48to63;
        } dataUpdate;
        /* todo: other packet types */
    };
} CommandPacket;
> [ ... snip ... ]
> +/* Set a pin to a specified value */
> +void senddatatopanel(panel_connection_t* h, uint64_t pin, bool val)
> +{
> +    CommandPacket Pkt;
> +
> +    Pkt.Data[PACKETLEN] = (char *) &Pkt.Data[6 + 1]-(char *) &Pkt.Data[0];
what's the use of this pointer aritmethic instead of just 6?

Geert
Denis V. Lunev" via May 16, 2017, 1:53 p.m. UTC | #8
The idea of an RFC is good, but with it I would like to have a demo. Something with no mass implementation to worry about and this would be it. 
I should also add a version number to the initialisation of the protocol to increase robustness, between versions. I'll call this one V 0.
 John BradleyTel: 07896 839635Skype: flypie125 125B Grove StreetEdge Hill Liverpool L7 7AF 

    On Tuesday, 16 May 2017, 9:56, Geert Martin Ijewski <gm.ijewski@web.de> wrote:
 

 Am 16.05.2017 um 02:01 schrieb John Bradley via Qemu-devel:
> Hi,
> The XML files in the base are not in the patch. They where net beans files. I can easily get it into 3 files, one large at 91KB but contains only new files and so is easy to read. Could be smaller but seems pointless.
>
I think what Alistar meant was something along the lines of:
patch/commit 1) add the remaining bcm2835 devices from Markus 
Armbruster's code to QEMU (btw: any reason why that hasn't been done? 
The USB stuff does seem nice to have)
-- with a more meaningful commit title
2) add utils/panelemu.c and the include
3) bcm2835 now uses the emupanel
and then your other commits e.g.
4) USB CDC Ethernet driver dropped packets
5) emupanel: fixed compilation errors on linux
6) emupanel: removed last blocking I/O

Along the way you also seem to fix indentation in other code a lot, that 
makes following the patches more confusing than they need to be.
It's harder to gauge at a quick glance whether you changed something 
meaingul or not.

Maybe even send a RFC just detailing the protocol, because it's probably 
important to get that right from the start.

Geert
> another which is about 19KB of quite simple changes to mostly make files.
> Then one 15KB which quite straight forward when you look at it. Applying them in that order should allow step wise addition. I've uploaded them to a share if anyone wants to comment.
>
> The 3 files are new.patch
>
> |
> |
> |
> |  |    |
>
>    |
>
>  |
> |
> |    |
> new.patch
>  Shared with Dropbox  |  |
>
>  |
>
>  |
>
>
>  mod1.patch
>
>
> |
> |
> |
> |  |    |
>
>    |
>
>  |
> |
> |    |
> mod1.patch
>  Shared with Dropbox  |  |
>
>  |
>
>  |
>
>
>
> and
>  a_hw_gpio_bcm2835_gpio.c.patch
>
> |
> |
> |
> |  |    |
>
>    |
>
>  |
> |
> |    |
> a_hw_gpio_bcm2835_gpio.c.patch
>  Shared with Dropbox  |  |
>
>  |
>
>  |
>
>
>
>
>
> John BradleyTel: 07896 839635Skype: flypie125 125B Grove StreetEdge Hill Liverpool L7 7AF
>
>    On Tuesday, 16 May 2017, 0:20, Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>
>
>  Hi John,
>
>> That is going to be very difficult as a lot of the changes are
>> interlinked the vast majority of the patch is new files.
>
> I rebased your branch on latest qemu/master here:
>
> https://github.com/philmd/qemu/tree/flypie-GDummyPanel-rebased
>
> It is much easier to follow now, the big XML files you added/removed
> also disappeared (gitk was crashing 'Out Of Memory' trying to look at
> your tree).
>
> I hope it can help you to continue reordering in smaller patches.
>
> Regards,
>
> Phil.
>
> On 05/15/2017 01:46 PM, Alistair Francis wrote:
>>
>> Hey John,
>>
>> Thanks for the patch!
>>
>> Unfortunately this patch is too long to review, you need to split the
>> patch up into shorter more readable patches. Otherwise it's too hard
>> to people to understand what you are changing and why.
>>
>> There are some details here:
>> http://wiki.qemu.org/Contribute/SubmitAPatch
>> <http://wiki.qemu.org/Contribute/SubmitAPatch>about how to split up
>> patches. Each patch applied in order shouldn't break any compilation
>> or runtime. Generally the flow is to add the logic in earlier patches
>> and then connect it and switch it on in the later patches.
>>
>> Try splitting up adding/editing each individual device and send that
>> our first. That is generally the easiest to review/accept.
>>
>> Thanks,
>>
>> Alistair
>>
>>> ---
>>> .gitignore                          |  54 ++
>>> hw/arm/Makefile.objs                |    2 +-
>>> hw/arm/bcm2835.c                    |  114 ++++
>>> hw/arm/bcm2835_peripherals.c        |  104 ++++
>>> hw/arm/bcm2836.c                    |    3 +-
>>> hw/arm/raspi.c                      |  77 ++-
>>> hw/gpio/bcm2835_gpio.c              |  333 ++++++-----
>>> hw/misc/Makefile.objs                |    2 +
>>> hw/misc/bcm2835_mphi.c              |  163 ++++++
>>> hw/misc/bcm2835_power.c              |  106 ++++
>>> hw/timer/Makefile.objs              |    2 +
>>> hw/timer/bcm2835_st.c                |  202 +++++++
>>> hw/timer/bcm2835_timer.c            |  224 +++++++
>>> hw/usb/Makefile.objs                |    4 +-
>>> hw/usb/bcm2835_usb.c                |  604 +++++++++++++++++++
>>> hw/usb/bcm2835_usb_regs.h            | 1061
>> ++++++++++++++++++++++++++++++++++
>>> hw/usb/dev-network.c                |    2 +-
>>> include/hw/arm/bcm2835.h            |  37 ++
>>> include/hw/arm/bcm2835_peripherals.h |  10 +
>>> include/hw/gpio/bcm2835_gpio.h      |    5 +
>>> include/hw/intc/bcm2835_control.h    |  53 ++
>>> include/hw/intc/bcm2836_control.h    |    2 +
>>> include/hw/misc/bcm2835_mphi.h      |  28 +
>>> include/hw/misc/bcm2835_power.h      |  22 +
>>> include/hw/timer/bcm2835_st.h        |  25 +
>>> include/hw/timer/bcm2835_timer.h    |  32 +
>>> include/hw/usb/bcm2835_usb.h        |  78 +++
>>> include/qemu/PanelEmu.h              |  53 ++
>>> util/Makefile.objs                  |    1 +
>>> util/PanelEmu.c                      |  293 ++++++++++
>>> 30 files changed, 3547 insertions(+), 149 deletions(-)
>>> create mode 100644 hw/arm/bcm2835.c
>>> create mode 100644 hw/misc/bcm2835_mphi.c
>>> create mode 100644 hw/misc/bcm2835_power.c
>>> create mode 100644 hw/timer/bcm2835_st.c
>>> create mode 100644 hw/timer/bcm2835_timer.c
>>> create mode 100644 hw/usb/bcm2835_usb.c
>>> create mode 100644 hw/usb/bcm2835_usb_regs.h
>>> create mode 100644 include/hw/arm/bcm2835.h
>>> create mode 100644 include/hw/intc/bcm2835_control.h
>>> create mode 100644 include/hw/misc/bcm2835_mphi.h
>>> create mode 100644 include/hw/misc/bcm2835_power.h
>>> create mode 100644 include/hw/timer/bcm2835_st.h
>>> create mode 100644 include/hw/timer/bcm2835_timer.h
>>> create mode 100644 include/hw/usb/bcm2835_usb.h
>>> create mode 100644 include/qemu/PanelEmu.h
>>> create mode 100644 util/PanelEmu.c
>>>
>>
>>
>
>
>
>
diff mbox

Patch

diff --git a/.gitignore b/.gitignore
index 55a001e3b8..08e0ac978f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@ 
+/bin
/config-devices.*
/config-all-devices.*
/config-all-disas.*
@@ -131,3 +132,56 @@  trace-dtrace-root.h
trace-dtrace-root.dtrace
trace-ust-all.h
trace-ust-all.c
+
+bin/debug/x86_64-w64-mingw64/Makefile
+
+bin/debug/x86_64-w64-mingw64/arm-softmmu/Makefile
+
+bin/debug/x86_64-w64-mingw64/arm-softmmu/config-devices.mak
+
+# Compiled source #
+###################
+*.com
+*.class
+*.dll
+*.exe
+*.o
+*.so
+
+# Packages #
+############
+# it's better to unpack these files and commit the raw source
+# git has its own built in compression methods
+*.7z
+*.dmg
+*.gz
+*.iso
+*.jar
+*.rar
+*.tar
+*.zip
+
+# Logs and databases #
+######################
+*.log
+*.sql
+*.sqlite
+
+# OS generated files #
+######################
+.DS_Store
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+ehthumbs.db
+Thumbs.db
+.cproject
+.project
+### NetBeans ###
+nbproject/private/
+build/
+nbbuild/
+dist/
+nbdist/
+.nb-gradle/
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 4c5c4ee76c..35b2da24f5 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -11,7 +11,7 @@  obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
obj-$(CONFIG_DIGIC) += digic.o
obj-y += omap1.o omap2.o strongarm.o
obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o
-obj-$(CONFIG_RASPI) += bcm2835_peripherals.o bcm2836.o raspi.o
+obj-$(CONFIG_RASPI) += bcm2835.o bcm2835_peripherals.o bcm2836.o raspi.o
obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
diff --git a/hw/arm/bcm2835.c b/hw/arm/bcm2835.c
new file mode 100644
index 0000000000..e5744c1620
--- /dev/null
+++ b/hw/arm/bcm2835.c
@@ -0,0 +1,114 @@ 
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * Upstreaming code cleanup [including bcm2835_*] (c) 2013 Jan Petrous
+ *
+ * Rasperry Pi 2 emulation and refactoring Copyright (c) 2015, Microsoft
+ * Written by Andrew Baumann
+ *
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "hw/arm/bcm2835.h"
+#include "hw/arm/raspi_platform.h"
+#include "hw/sysbus.h"
+#include "exec/address-spaces.h"
+
+
+/* Peripheral base address seen by the CPU */
+#define BCM2835_PERI_BASE       0x20000000
+
+static void bcm2835_init(Object *obj)
+{
+    BCM2835State *s = BCM2835(obj);
+
+    object_initialize(&s->cpus[0], sizeof(s->cpus[0]), "arm1176-" TYPE_ARM_CPU);
+    object_property_add_child(obj, "cpu", OBJECT(&s->cpus[0]), &error_abort);
+
+    object_initialize(&s->peripherals, sizeof(s->peripherals),
+                      TYPE_BCM2835_PERIPHERALS);
+    object_property_add_child(obj, "peripherals", OBJECT(&s->peripherals),
+                              &error_abort);
+    object_property_add_alias(obj, "board-rev", OBJECT(&s->peripherals),
+                              "board-rev", &error_abort);
+    object_property_add_alias(obj, "vcram-size", OBJECT(&s->peripherals),
+                              "vcram-size", &error_abort);
+    qdev_set_parent_bus(DEVICE(&s->peripherals), sysbus_get_default());
+}
+
+static void bcm2835_realize(DeviceState *dev, Error **errp)
+{
+    BCM2835State *s = BCM2835(dev);
+    Object *obj;
+    Error *err = NULL;
+
+    /* common peripherals from bcm2835 */
+    obj = object_property_get_link(OBJECT(dev), "ram", &err);
+    if (obj == NULL) {
+        error_setg(errp, "%s: required ram link not found: %s",
+                   __func__, error_get_pretty(err));
+        return;
+    }
+
+    object_property_add_const_link(OBJECT(&s->peripherals), "ram", obj, &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    object_property_set_bool(OBJECT(&s->peripherals), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->peripherals),
+                              "sd-bus", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->peripherals), 0,
+                            BCM2835_PERI_BASE, 1);
+
+    object_property_set_bool(OBJECT(&s->cpus[0]), true, "realized", &err);
+    if (err) {
+        error_report_err(err);
+        exit(1);
+    }
+
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 0,
+                       qdev_get_gpio_in(DEVICE(&s->cpus[0]), ARM_CPU_IRQ));
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 1,
+                       qdev_get_gpio_in(DEVICE(&s->cpus[0]), ARM_CPU_FIQ));
+}
+
+static Property bcm2835_props[] = {
+    DEFINE_PROP_UINT32("enabled-cpus", BCM2835State, enabled_cpus, BCM2835_NCPUS),
+    DEFINE_PROP_END_OF_LIST()
+};
+
+static void bcm2835_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->props = bcm2835_props;
+    dc->realize = bcm2835_realize;
+}
+
+static const TypeInfo bcm2835_type_info = {
+    .name = TYPE_BCM2835,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(BCM2835State),
+    .instance_init = bcm2835_init,
+    .class_init = bcm2835_class_init,
+};
+
+static void bcm2835_register_types(void)
+{
+    type_register_static(&bcm2835_type_info);
+}
+
+type_init(bcm2835_register_types)
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index 369ef1e3bd..e0e8525eab 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -56,6 +56,29 @@  static void bcm2835_peripherals_init(Object *obj)
object_property_add_child(obj, "aux", OBJECT(&s->aux), NULL);
qdev_set_parent_bus(DEVICE(&s->aux), sysbus_get_default());

+    /* System timer */
+    object_initialize(&s->st, sizeof(s->st), TYPE_BCM2835_ST);
+    object_property_add_child(obj, "systimer", OBJECT(&s->st), NULL);
+    qdev_set_parent_bus(DEVICE(&s->st), sysbus_get_default());
+
+    /* ARM timer */
+    object_initialize(&s->timer, sizeof(s->timer), TYPE_BCM2835_TIMER);
+    object_property_add_child(obj, "armtimer", OBJECT(&s->timer), NULL);
+    qdev_set_parent_bus(DEVICE(&s->timer), sysbus_get_default());
+
+    /* USB controller */
+    object_initialize(&s->usb, sizeof(s->usb), TYPE_BCM2835_USB);
+    object_property_add_child(obj, "usb", OBJECT(&s->usb), NULL);
+    qdev_set_parent_bus(DEVICE(&s->usb), sysbus_get_default());
+
+    object_property_add_const_link(OBJECT(&s->usb), "dma_mr",
+                                   OBJECT(&s->gpu_bus_mr), &error_abort);
+
+    /* MPHI - Message-based Parallel Host Interface */
+    object_initialize(&s->mphi, sizeof(s->mphi), TYPE_BCM2835_MPHI);
+    object_property_add_child(obj, "mphi", OBJECT(&s->mphi), NULL);
+    qdev_set_parent_bus(DEVICE(&s->mphi), sysbus_get_default());
+
/* Mailboxes */
object_initialize(&s->mboxes, sizeof(s->mboxes), TYPE_BCM2835_MBOX);
object_property_add_child(obj, "mbox", OBJECT(&s->mboxes), NULL);
@@ -64,6 +87,11 @@  static void bcm2835_peripherals_init(Object *obj)
object_property_add_const_link(OBJECT(&s->mboxes), "mbox-mr",
OBJECT(&s->mbox_mr), &error_abort);

+    /* Power management */
+    object_initialize(&s->power, sizeof(s->power), TYPE_BCM2835_POWER);
+    object_property_add_child(obj, "power", OBJECT(&s->power), NULL);
+    qdev_set_parent_bus(DEVICE(&s->power), sysbus_get_default());
+
/* Framebuffer */
object_initialize(&s->fb, sizeof(s->fb), TYPE_BCM2835_FB);
object_property_add_child(obj, "fb", OBJECT(&s->fb), NULL);
@@ -179,6 +207,7 @@  static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(s->uart0, 0,
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
INTERRUPT_UART));
+
/* AUX / UART1 */
qdev_prop_set_chr(DEVICE(&s->aux), "chardev", serial_hds[1]);

@@ -194,6 +223,67 @@  static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
INTERRUPT_AUX));

+    /* System timer */
+    object_property_set_bool(OBJECT(&s->st), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    memory_region_add_subregion(&s->peri_mr, ST_OFFSET,
+                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->st), 0));
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->st), 0,
+        qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
+                               INTERRUPT_TIMER0));
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->st), 1,
+        qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
+                               INTERRUPT_TIMER1));
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->st), 2,
+        qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
+                               INTERRUPT_TIMER2));
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->st), 3,
+        qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
+                               INTERRUPT_TIMER3));
+
+    /* ARM timer */
+    object_property_set_bool(OBJECT(&s->timer), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    memory_region_add_subregion(&s->peri_mr, ARMCTRL_TIMER0_1_OFFSET,
+                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer), 0));
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer), 0,
+        qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_ARM_IRQ,
+                               INTERRUPT_ARM_TIMER));
+
+    /* USB controller */
+    object_property_set_bool(OBJECT(&s->usb), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    memory_region_add_subregion(&s->peri_mr, USB_OFFSET,
+                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->usb), 0));
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb), 0,
+        qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
+                               INTERRUPT_USB));
+
+    /* MPHI - Message-based Parallel Host Interface */
+    object_property_set_bool(OBJECT(&s->mphi), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    memory_region_add_subregion(&s->peri_mr, MPHI_OFFSET,
+                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mphi), 0));
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->mphi), 0,
+        qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
+                               INTERRUPT_HOSTPORT));
+
/* Mailboxes */
object_property_set_bool(OBJECT(&s->mboxes), true, "realized", &err);
if (err) {
@@ -207,6 +297,18 @@  static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_ARM_IRQ,
INTERRUPT_ARM_MAILBOX));

+    /* Power management */
+    object_property_set_bool(OBJECT(&s->power), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    memory_region_add_subregion(&s->mbox_mr, MBOX_CHAN_POWER << MBOX_AS_CHAN_SHIFT,
+                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->power), 0));
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->power), 0,
+                       qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_POWER));
+
/* Framebuffer */
vcram_size = (uint32_t)object_property_get_int(OBJECT(s), "vcram-size",
&err);
@@ -338,6 +440,8 @@  static void bcm2835_peripherals_class_init(ObjectClass *oc, void *data)
DeviceClass *dc = DEVICE_CLASS(oc);

dc->realize = bcm2835_peripherals_realize;
+    /* Reason: realize() method uses qemu_char_get_next_serial() */
+    dc->cannot_instantiate_with_device_add_yet = true;
}

static const TypeInfo bcm2835_peripherals_type_info = {
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
index 8c43291112..5f1bd15b24 100644
--- a/hw/arm/bcm2836.c
+++ b/hw/arm/bcm2836.c
@@ -27,7 +27,7 @@  static void bcm2836_init(Object *obj)
{
BCM2836State *s = BCM2836(obj);
int n;
-
+ 
for (n = 0; n < BCM2836_NCPUS; n++) {
object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
"cortex-a15-" TYPE_ARM_CPU);
@@ -106,6 +106,7 @@  static void bcm2836_realize(DeviceState *dev, Error **errp)
/* Mirror bcm2836, which has clusterid set to 0xf
* TODO: this should be converted to a property of ARM_CPU
*/
+
s->cpus[n].mp_affinity = 0xF00 | n;

/* set periphbase/CBAR value for CPU-local registers */
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index 2b295f14c4..8ed2d9785d 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -4,6 +4,8 @@ 
*
* Rasperry Pi 2 emulation Copyright (c) 2015, Microsoft
* Written by Andrew Baumann
+ * 
+ * Merge into QEMU root fork John Bradley April 2017
*
* This code is licensed under the GNU GPLv2 and later.
*/
@@ -12,6 +14,7 @@ 
#include "qapi/error.h"
#include "qemu-common.h"
#include "cpu.h"
+#include "hw/arm/bcm2835.h"
#include "hw/arm/bcm2836.h"
#include "qemu/error-report.h"
#include "hw/boards.h"
@@ -27,10 +30,20 @@ 
/* Table of Linux board IDs for different Pi versions */
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43};

-typedef struct RasPiState {
+/* Table of board revisions
+ * https://github.com/AndrewFromMelbourne/raspberry_pi_revision/blob/master/README.md
+ */
+static const uint32_t raspi_boardrev[] = {[1] = 0x10, [2] = 0xa21041};
+
+typedef struct RasPi1State {
+    BCM2835State soc;
+    MemoryRegion ram;
+} RasPi1State;
+
+typedef struct RasPi2State {
BCM2836State soc;
MemoryRegion ram;
-} RasPiState;
+} RasPi2State;

static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
{
@@ -113,9 +126,53 @@  static void setup_boot(MachineState *machine, int version, size_t ram_size)
arm_load_kernel(ARM_CPU(first_cpu), &binfo);
}

+static void raspi1_init(MachineState *machine)
+{
+    RasPi1State *s = g_new0(RasPi1State, 1);
+    uint32_t vcram_size;
+    DriveInfo *di;
+    BlockBackend *blk;
+    BusState *bus;
+    DeviceState *carddev;
+
+    object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM2835);
+    object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
+                              &error_abort);
+
+    /* Allocate and map RAM */
+    memory_region_allocate_system_memory(&s->ram, OBJECT(machine), "ram",
+                                         machine->ram_size);
+    /* FIXME: Remove when we have custom CPU address space support */
+    memory_region_add_subregion_overlap(get_system_memory(), 0, &s->ram, 0);
+
+    /* Setup the SOC */
+    object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
+                                   &error_abort);
+//   object_property_set_int(OBJECT(&s->soc), smp_cpus, "enabled-cpus",
+//                            &error_abort);
+    object_property_set_int(OBJECT(&s->soc), 0xa21041, "board-rev",
+                            &error_abort);
+    object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_abort);
+
+    /* Create and plug in the SD cards */
+    di = drive_get_next(IF_SD);
+    blk = di ? blk_by_legacy_dinfo(di) : NULL;
+    bus = qdev_get_child_bus(DEVICE(&s->soc), "sd-bus");
+    if (bus == NULL) {
+        error_report("No SD bus found in SOC object");
+        exit(1);
+    }
+    carddev = qdev_create(bus, TYPE_SD_CARD);
+    qdev_prop_set_drive(carddev, "drive", blk, &error_fatal);
+    object_property_set_bool(OBJECT(carddev), true, "realized", &error_fatal);
+
+    vcram_size = object_property_get_int(OBJECT(&s->soc), "vcram-size",
+                                         &error_abort);
+    setup_boot(machine, 1, machine->ram_size - vcram_size);
+}
static void raspi2_init(MachineState *machine)
{
-    RasPiState *s = g_new0(RasPiState, 1);
+    RasPi2State *s = g_new0(RasPi2State, 1);
uint32_t vcram_size;
DriveInfo *di;
BlockBackend *blk;
@@ -158,6 +215,20 @@  static void raspi2_init(MachineState *machine)
setup_boot(machine, 2, machine->ram_size - vcram_size);
}

+
+static void raspi1_machine_init(MachineClass *mc)
+{
+    mc->desc = "Raspberry Pi 1";
+    mc->init = raspi1_init;
+    mc->block_default_type = IF_SD;
+    mc->no_parallel = 1;
+    mc->no_floppy = 1;
+    mc->no_cdrom = 1;
+    mc->max_cpus = BCM2835_NCPUS;
+    mc->default_ram_size = 512 * 1024 * 1024;
+};
+DEFINE_MACHINE("raspi1", raspi1_machine_init)
+
static void raspi2_machine_init(MachineClass *mc)
{
mc->desc = "Raspberry Pi 2";
diff --git a/hw/gpio/bcm2835_gpio.c b/hw/gpio/bcm2835_gpio.c
index acc2e3cf9e..37be668d2a 100644
--- a/hw/gpio/bcm2835_gpio.c
+++ b/hw/gpio/bcm2835_gpio.c
@@ -19,6 +19,8 @@ 
#include "hw/sd/sd.h"
#include "hw/gpio/bcm2835_gpio.h"

+
+
#define GPFSEL0   0x00
#define GPFSEL1   0x04
#define GPFSEL2   0x08
@@ -53,9 +55,9 @@  static uint32_t gpfsel_get(BCM2835GpioState *s, uint8_t reg)
{
int i;
uint32_t value = 0;
-    for (i = 0; i < 10; i++) {
+    for (i = 0; i < 10; i ++) {
uint32_t index = 10 * reg + i;
-        if (index < sizeof(s->fsel)) {
+        if (index < sizeof (s->fsel)) {
value |= (s->fsel[index] & 0x7) << (3 * i);
}
}
@@ -65,9 +67,9 @@  static uint32_t gpfsel_get(BCM2835GpioState *s, uint8_t reg)
static void gpfsel_set(BCM2835GpioState *s, uint8_t reg, uint32_t value)
{
int i;
-    for (i = 0; i < 10; i++) {
+    for (i = 0; i < 10; i ++) {
uint32_t index = 10 * reg + i;
-        if (index < sizeof(s->fsel)) {
+        if (index < sizeof (s->fsel)) {
int fsel = (value >> (3 * i)) & 0x7;
s->fsel[index] = fsel;
}
@@ -75,24 +77,24 @@  static void gpfsel_set(BCM2835GpioState *s, uint8_t reg, uint32_t value)

/* SD controller selection (48-53) */
if (s->sd_fsel != 0
-            && (s->fsel[48] == 0) /* SD_CLK_R */
-            && (s->fsel[49] == 0) /* SD_CMD_R */
-            && (s->fsel[50] == 0) /* SD_DATA0_R */
-            && (s->fsel[51] == 0) /* SD_DATA1_R */
-            && (s->fsel[52] == 0) /* SD_DATA2_R */
-            && (s->fsel[53] == 0) /* SD_DATA3_R */
-            ) {
+        && (s->fsel[48] == 0) /* SD_CLK_R */
+        && (s->fsel[49] == 0) /* SD_CMD_R */
+        && (s->fsel[50] == 0) /* SD_DATA0_R */
+        && (s->fsel[51] == 0) /* SD_DATA1_R */
+        && (s->fsel[52] == 0) /* SD_DATA2_R */
+        && (s->fsel[53] == 0) /* SD_DATA3_R */
+        ) {
/* SDHCI controller selected */
sdbus_reparent_card(s->sdbus_sdhost, s->sdbus_sdhci);
s->sd_fsel = 0;
} else if (s->sd_fsel != 4
-            && (s->fsel[48] == 4) /* SD_CLK_R */
-            && (s->fsel[49] == 4) /* SD_CMD_R */
-            && (s->fsel[50] == 4) /* SD_DATA0_R */
-            && (s->fsel[51] == 4) /* SD_DATA1_R */
-            && (s->fsel[52] == 4) /* SD_DATA2_R */
-            && (s->fsel[53] == 4) /* SD_DATA3_R */
-            ) {
+               && (s->fsel[48] == 4) /* SD_CLK_R */
+               && (s->fsel[49] == 4) /* SD_CMD_R */
+               && (s->fsel[50] == 4) /* SD_DATA0_R */
+               && (s->fsel[51] == 4) /* SD_DATA1_R */
+               && (s->fsel[52] == 4) /* SD_DATA2_R */
+               && (s->fsel[53] == 4) /* SD_DATA3_R */
+               ) {
/* SDHost controller selected */
sdbus_reparent_card(s->sdbus_sdhci, s->sdbus_sdhost);
s->sd_fsel = 4;
@@ -108,13 +110,13 @@  static int gpfsel_is_out(BCM2835GpioState *s, int index)
}

static void gpset(BCM2835GpioState *s,
-        uint32_t val, uint8_t start, uint8_t count, uint32_t *lev)
+                  uint32_t val, uint8_t start, uint8_t count, uint32_t *lev)
{
-    uint32_t changes = val & ~*lev;
+    uint32_t changes = val & ~ *lev;
uint32_t cur = 1;

int i;
-    for (i = 0; i < count; i++) {
+    for (i = 0; i < count; i ++) {
if ((changes & cur) && (gpfsel_is_out(s, start + i))) {
qemu_set_irq(s->out[start + i], 1);
}
@@ -125,132 +127,165 @@  static void gpset(BCM2835GpioState *s,
}

static void gpclr(BCM2835GpioState *s,
-        uint32_t val, uint8_t start, uint8_t count, uint32_t *lev)
+                  uint32_t val, uint8_t start, uint8_t count, uint32_t *lev)
{
uint32_t changes = val & *lev;
uint32_t cur = 1;

int i;
-    for (i = 0; i < count; i++) {
+    for (i = 0; i < count; i ++) {
if ((changes & cur) && (gpfsel_is_out(s, start + i))) {
qemu_set_irq(s->out[start + i], 0);
}
cur <<= 1;
}

-    *lev &= ~val;
+    *lev &= ~ val;
}

-static uint64_t bcm2835_gpio_read(void *opaque, hwaddr offset,
-        unsigned size)
+static uint64_t bcm2835_gpio_read(void *opaque, hwaddr offset, unsigned size)
{
-    BCM2835GpioState *s = (BCM2835GpioState *)opaque;
+    BCM2835GpioState *s = (BCM2835GpioState *) opaque;
+
+    uint64_t Data;

switch (offset) {
-    case GPFSEL0:
-    case GPFSEL1:
-    case GPFSEL2:
-    case GPFSEL3:
-    case GPFSEL4:
-    case GPFSEL5:
-        return gpfsel_get(s, offset / 4);
-    case GPSET0:
-    case GPSET1:
-        /* Write Only */
-        return 0;
-    case GPCLR0:
-    case GPCLR1:
-        /* Write Only */
-        return 0;
-    case GPLEV0:
-        return s->lev0;
-    case GPLEV1:
-        return s->lev1;
-    case GPEDS0:
-    case GPEDS1:
-    case GPREN0:
-    case GPREN1:
-    case GPFEN0:
-    case GPFEN1:
-    case GPHEN0:
-    case GPHEN1:
-    case GPLEN0:
-    case GPLEN1:
-    case GPAREN0:
-    case GPAREN1:
-    case GPAFEN0:
-    case GPAFEN1:
-    case GPPUD:
-    case GPPUDCLK0:
-    case GPPUDCLK1:
-        /* Not implemented */
-        return 0;
-    default:
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
-                __func__, offset);
-        break;
+        case GPFSEL0:
+        case GPFSEL1:
+        case GPFSEL2:
+        case GPFSEL3:
+        case GPFSEL4:
+        case GPFSEL5:
+            return gpfsel_get(s, offset / 4);
+        case GPSET0:
+        case GPSET1:
+            /* Write Only */
+            return 0;
+        case GPCLR0:
+        case GPCLR1:
+            /* Write Only */
+            return 0;
+        case GPLEV0:
+            if (s->panel.socket != - 1) {
+                if (panel_read(&s->panel, &Data)) {
+                    s->lev0 = (uint32_t) Data;
+                    s->lev1 = (uint32_t) (Data >> 32);
+                }
+            }
+            return s->lev0;
+        case GPLEV1:
+            if (s->panel.socket != - 1) {
+                if (panel_read(&s->panel, &Data)) {
+                    s->lev0 = (uint32_t) Data;
+                    s->lev1 = (uint32_t) (Data >> 32);
+                }
+            }
+            return s->lev1;
+        case GPEDS0:
+        case GPEDS1:
+        case GPREN0:
+        case GPREN1:
+        case GPFEN0:
+        case GPFEN1:
+        case GPHEN0:
+        case GPHEN1:
+        case GPLEN0:
+        case GPLEN1:
+        case GPAREN0:
+        case GPAREN1:
+        case GPAFEN0:
+        case GPAFEN1:
+        case GPPUD:
+        case GPPUDCLK0:
+        case GPPUDCLK1:
+            /* Not implemented */
+            return 0;
+        default:
+            qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
+                          __func__, offset);
+            break;
}

return 0;
}

static void bcm2835_gpio_write(void *opaque, hwaddr offset,
-        uint64_t value, unsigned size)
+                               uint64_t value, unsigned size)
{
-    BCM2835GpioState *s = (BCM2835GpioState *)opaque;
+    BCM2835GpioState *s = (BCM2835GpioState *) opaque;
+    uint64_t Data;
+

switch (offset) {
-    case GPFSEL0:
-    case GPFSEL1:
-    case GPFSEL2:
-    case GPFSEL3:
-    case GPFSEL4:
-    case GPFSEL5:
-        gpfsel_set(s, offset / 4, value);
-        break;
-    case GPSET0:
-        gpset(s, value, 0, 32, &s->lev0);
-        break;
-    case GPSET1:
-        gpset(s, value, 32, 22, &s->lev1);
-        break;
-    case GPCLR0:
-        gpclr(s, value, 0, 32, &s->lev0);
-        break;
-    case GPCLR1:
-        gpclr(s, value, 32, 22, &s->lev1);
-        break;
-    case GPLEV0:
-    case GPLEV1:
-        /* Read Only */
-        break;
-    case GPEDS0:
-    case GPEDS1:
-    case GPREN0:
-    case GPREN1:
-    case GPFEN0:
-    case GPFEN1:
-    case GPHEN0:
-    case GPHEN1:
-    case GPLEN0:
-    case GPLEN1:
-    case GPAREN0:
-    case GPAREN1:
-    case GPAFEN0:
-    case GPAFEN1:
-    case GPPUD:
-    case GPPUDCLK0:
-    case GPPUDCLK1:
-        /* Not implemented */
-        break;
-    default:
-        goto err_out;
+        case GPFSEL0:
+        case GPFSEL1:
+        case GPFSEL2:
+        case GPFSEL3:
+        case GPFSEL4:
+        case GPFSEL5:
+            gpfsel_set(s, offset / 4, value);
+            break;
+        case GPSET0:
+            gpset(s, value, 0, 32, &s->lev0);
+            if (s->panel.socket != - 1) {
+                Data = value;
+                senddatatopanel(&s->panel, Data, true); //John Bradley dummy GPIO Panel
+            }
+            break;
+        case GPSET1:
+            gpset(s, value, 32, 22, &s->lev1);
+            if (s->panel.socket != - 1) {
+                Data = value;
+                Data <<= 32;
+                senddatatopanel(&s->panel, Data, true); //John Bradley dummy GPIO Panel
+            }
+            break;
+        case GPCLR0:
+            gpclr(s, value, 0, 32, &s->lev0);
+            if (s->panel.socket != - 1) {
+                Data = value;
+                senddatatopanel(&s->panel, Data, false); //John Bradley dummy GPIO Panel
+            }
+            break;
+        case GPCLR1:
+            gpclr(s, value, 32, 22, &s->lev1);
+            if (s->panel.socket != - 1) {
+                Data = value;
+                Data <<= 32;
+                senddatatopanel(&s->panel, Data, false); //John Bradley dummy GPIO Panel
+            }
+            break;
+        case GPLEV0:
+        case GPLEV1:
+            /* Read Only */
+            break;
+        case GPEDS0:
+        case GPEDS1:
+        case GPREN0:
+        case GPREN1:
+        case GPFEN0:
+        case GPFEN1:
+        case GPHEN0:
+        case GPHEN1:
+        case GPLEN0:
+        case GPLEN1:
+        case GPAREN0:
+        case GPAREN1:
+        case GPAFEN0:
+        case GPAFEN1:
+        case GPPUD:
+        case GPPUDCLK0:
+        case GPPUDCLK1:
+            /* Not implemented */
+            break;
+        default:
+            goto err_out;
}
return;

err_out:
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
-            __func__, offset);
+                  __func__, offset);
}

static void bcm2835_gpio_reset(DeviceState *dev)
@@ -258,7 +293,7 @@  static void bcm2835_gpio_reset(DeviceState *dev)
BCM2835GpioState *s = BCM2835_GPIO(dev);

int i;
-    for (i = 0; i < 6; i++) {
+    for (i = 0; i < 6; i ++) {
gpfsel_set(s, i, 0);
}

@@ -272,21 +307,22 @@  static void bcm2835_gpio_reset(DeviceState *dev)
}

static const MemoryRegionOps bcm2835_gpio_ops = {
-    .read = bcm2835_gpio_read,
-    .write = bcm2835_gpio_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
+                                                 .read = bcm2835_gpio_read,
+                                                 .write = bcm2835_gpio_write,
+                                                 .endianness = DEVICE_NATIVE_ENDIAN,
};

static const VMStateDescription vmstate_bcm2835_gpio = {
-    .name = "bcm2835_gpio",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_UINT8_ARRAY(fsel, BCM2835GpioState, 54),
-        VMSTATE_UINT32(lev0, BCM2835GpioState),
-        VMSTATE_UINT32(lev1, BCM2835GpioState),
-        VMSTATE_UINT8(sd_fsel, BCM2835GpioState),
-        VMSTATE_END_OF_LIST()
+                                                        .name = "bcm2835_gpio",
+                                                        .version_id = 1,
+                                                        .minimum_version_id = 1,
+                                                        .fields = (VMStateField[])
+    {
+     VMSTATE_UINT8_ARRAY(fsel, BCM2835GpioState, 54),
+     VMSTATE_UINT32(lev0, BCM2835GpioState),
+     VMSTATE_UINT32(lev1, BCM2835GpioState),
+     VMSTATE_UINT8(sd_fsel, BCM2835GpioState),
+     VMSTATE_END_OF_LIST()
}
};

@@ -296,13 +332,26 @@  static void bcm2835_gpio_init(Object *obj)
DeviceState *dev = DEVICE(obj);
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

-    qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
+    qbus_create_inplace(&s->sdbus, sizeof (s->sdbus),
TYPE_SD_BUS, DEVICE(s), "sd-bus");

memory_region_init_io(&s->iomem, obj,
-            &bcm2835_gpio_ops, s, "bcm2835_gpio", 0x1000);
+                          &bcm2835_gpio_ops, s, "bcm2835_gpio", 0x1000);
sysbus_init_mmio(sbd, &s->iomem);
qdev_init_gpio_out(dev, s->out, 54);
+
+    int err;
+
+    /* Get access to the GPIO panel, program will quit on fail */
+    err = panel_open(&s->panel);
+    if (err) {
+        printf("Couldn't connect to a GPIO panel\n"); //John Bradley dummy GPIO Panel
+    } else {
+        sendpincount(&s->panel, 54); //PI Has 54 Pins
+        sendenabledmap(&s->panel, 0x003FFFFFFFFFFFFC); //Pins 0 & 1 are I2C so disable
+        sendinputmap(&s->panel, 0x0000000000000000); //There are no dedicated input pins I know off
+        sendoutputmap(&s->panel, 0x0000800000000000); //Pin 53 is dedicated output LED
+    }
}

static void bcm2835_gpio_realize(DeviceState *dev, Error **errp)
@@ -314,7 +363,7 @@  static void bcm2835_gpio_realize(DeviceState *dev, Error **errp)
obj = object_property_get_link(OBJECT(dev), "sdbus-sdhci", &err);
if (obj == NULL) {
error_setg(errp, "%s: required sdhci link not found: %s",
-                __func__, error_get_pretty(err));
+                   __func__, error_get_pretty(err));
return;
}
s->sdbus_sdhci = SD_BUS(obj);
@@ -322,7 +371,7 @@  static void bcm2835_gpio_realize(DeviceState *dev, Error **errp)
obj = object_property_get_link(OBJECT(dev), "sdbus-sdhost", &err);
if (obj == NULL) {
error_setg(errp, "%s: required sdhost link not found: %s",
-                __func__, error_get_pretty(err));
+                   __func__, error_get_pretty(err));
return;
}
s->sdbus_sdhost = SD_BUS(obj);
@@ -332,17 +381,17 @@  static void bcm2835_gpio_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);

-    dc->vmsd = &vmstate_bcm2835_gpio;
-    dc->realize = &bcm2835_gpio_realize;
-    dc->reset = &bcm2835_gpio_reset;
+    dc->vmsd = & vmstate_bcm2835_gpio;
+    dc->realize = & bcm2835_gpio_realize;
+    dc->reset = & bcm2835_gpio_reset;
}

static const TypeInfo bcm2835_gpio_info = {
-    .name          = TYPE_BCM2835_GPIO,
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(BCM2835GpioState),
-    .instance_init = bcm2835_gpio_init,
-    .class_init    = bcm2835_gpio_class_init,
+                                           .name = TYPE_BCM2835_GPIO,
+                                           .parent = TYPE_SYS_BUS_DEVICE,
+                                           .instance_size = sizeof (BCM2835GpioState),
+                                           .instance_init = bcm2835_gpio_init,
+                                           .class_init = bcm2835_gpio_class_init,
};

static void bcm2835_gpio_register_types(void)
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index c8b489390f..fd0cc922ee 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -41,6 +41,8 @@  obj-$(CONFIG_OMAP) += omap_l4.o
obj-$(CONFIG_OMAP) += omap_sdrc.o
obj-$(CONFIG_OMAP) += omap_tap.o
obj-$(CONFIG_RASPI) += bcm2835_mbox.o
+obj-$(CONFIG_RASPI) += bcm2835_mphi.o
+obj-$(CONFIG_RASPI) += bcm2835_power.o
obj-$(CONFIG_RASPI) += bcm2835_property.o
obj-$(CONFIG_RASPI) += bcm2835_rng.o
obj-$(CONFIG_SLAVIO) += slavio_misc.o
diff --git a/hw/misc/bcm2835_mphi.c b/hw/misc/bcm2835_mphi.c
new file mode 100644
index 0000000000..7681e00684
--- /dev/null
+++ b/hw/misc/bcm2835_mphi.c
@@ -0,0 +1,163 @@ 
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/misc/bcm2835_mphi.h"
+
+#include "qemu/log.h"
+#include "qapi/error.h"
+
+static void bcm2835_mphi_update_irq(BCM2835MphiState *s)
+{
+    if (s->mphi_intstat) {
+        qemu_set_irq(s->irq, 1);
+    } else {
+        qemu_set_irq(s->irq, 0);
+    }
+}
+
+static uint64_t bcm2835_mphi_read(void *opaque, hwaddr offset,
+    unsigned size)
+{
+    BCM2835MphiState *s = (BCM2835MphiState *)opaque;
+    uint32_t res = 0;
+
+    assert(size == 4);
+
+    switch (offset) {
+    case 0x00:    /* mphi_base */
+        res = s->mphi_base;
+        break;
+    case 0x28:    /* mphi_outdda */
+        res = s->mphi_outdda;
+        break;
+    case 0x2c:    /* mphi_outddb */
+        res = s->mphi_outddb;
+        break;
+    case 0x4c:    /* mphi_ctrl */
+        res = s->mphi_ctrl;
+        break;
+    case 0x50:    /* mphi_intstat */
+        res = s->mphi_intstat;
+        break;
+
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+            "bcm2835_mphi_read: Bad offset %x\n", (int)offset);
+        res = 0;
+        break;
+    }
+
+    return res;
+}
+
+static void bcm2835_mphi_write(void *opaque, hwaddr offset,
+    uint64_t value, unsigned size)
+{
+    BCM2835MphiState *s = (BCM2835MphiState *)opaque;
+    int set_irq = 0;
+
+    assert(size == 4);
+
+    switch (offset) {
+    case 0x00:    /* mphi_base */
+        s->mphi_base = value;
+        break;
+    case 0x28:    /* mphi_outdda */
+        s->mphi_outdda = value;
+        break;
+    case 0x2c:    /* mphi_outddb */
+        s->mphi_outddb = value;
+        if (value & (1 << 29)) {
+            /* Enable MPHI interrupt */
+            s->mphi_intstat |= (1 << 16);
+            set_irq = 1;
+        }
+        break;
+    case 0x4c:    /* mphi_ctrl */
+        s->mphi_ctrl &= ~(1 << 31);
+        s->mphi_ctrl |= value & (1 << 31);
+
+        s->mphi_ctrl &= ~(3 << 16);
+        if (value & (1 << 16)) {
+            s->mphi_ctrl |= (3 << 16);
+        }
+
+        break;
+    case 0x50:    /* mphi_intstat */
+        s->mphi_intstat &= ~value;
+        set_irq = 1;
+        break;
+
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+            "bcm2835_mphi_write: Bad offset %x\n", (int)offset);
+        break;
+    }
+
+    if (set_irq) {
+        bcm2835_mphi_update_irq(s);
+    }
+}
+
+static const MemoryRegionOps bcm2835_mphi_ops = {
+    .read = bcm2835_mphi_read,
+    .write = bcm2835_mphi_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const VMStateDescription vmstate_bcm2835_mphi = {
+    .name = TYPE_BCM2835_MPHI,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void bcm2835_mphi_init(Object *obj)
+{
+    BCM2835MphiState *s = BCM2835_MPHI(obj);
+
+    memory_region_init_io(&s->iomem, obj, &bcm2835_mphi_ops, s,
+                          TYPE_BCM2835_MPHI, 0x1000);
+    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
+    sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq);
+}
+
+static void bcm2835_mphi_realize(DeviceState *dev, Error **errp)
+{
+    BCM2835MphiState *s = BCM2835_MPHI(dev);
+
+    s->mphi_base = 0;
+    s->mphi_ctrl = 0;
+    s->mphi_outdda = 0;
+    s->mphi_outddb = 0;
+    s->mphi_intstat = 0;
+}
+
+static void bcm2835_mphi_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = bcm2835_mphi_realize;
+    dc->vmsd = &vmstate_bcm2835_mphi;
+}
+
+static TypeInfo bcm2835_mphi_info = {
+    .name          = TYPE_BCM2835_MPHI,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(BCM2835MphiState),
+    .class_init    = bcm2835_mphi_class_init,
+    .instance_init = bcm2835_mphi_init,
+};
+
+static void bcm2835_mphi_register_types(void)
+{
+    type_register_static(&bcm2835_mphi_info);
+}
+
+type_init(bcm2835_mphi_register_types)
diff --git a/hw/misc/bcm2835_power.c b/hw/misc/bcm2835_power.c
new file mode 100644
index 0000000000..3bdb2b03da
--- /dev/null
+++ b/hw/misc/bcm2835_power.c
@@ -0,0 +1,106 @@ 
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/misc/bcm2835_power.h"
+#include "hw/misc/bcm2835_mbox_defs.h"
+
+#include "qemu/log.h"
+#include "qapi/error.h"
+
+static uint64_t bcm2835_power_read(void *opaque, hwaddr offset, unsigned size)
+{
+    BCM2835PowerState *s = (BCM2835PowerState *)opaque;
+    uint32_t res = 0;
+
+    switch (offset) {
+    case 0:
+        res = MBOX_CHAN_POWER;
+        s->pending = 0;
+        qemu_set_irq(s->mbox_irq, 0);
+        break;
+    case 4:
+        res = s->pending;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+            "bcm2835_power_read: Bad offset %x\n", (int)offset);
+        return 0;
+    }
+    return res;
+}
+
+static void bcm2835_power_write(void *opaque, hwaddr offset, uint64_t value,
+                                unsigned size)
+{
+    BCM2835PowerState *s = (BCM2835PowerState *)opaque;
+    switch (offset) {
+    case 0:
+        s->pending = 1;
+        qemu_set_irq(s->mbox_irq, 1);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+            "bcm2835_power_write: Bad offset %x\n", (int)offset);
+        return;
+    }
+
+}
+
+static const MemoryRegionOps bcm2835_power_ops = {
+    .read = bcm2835_power_read,
+    .write = bcm2835_power_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const VMStateDescription vmstate_bcm2835_power = {
+    .name = TYPE_BCM2835_POWER,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void bcm2835_power_init(Object *obj)
+{
+    BCM2835PowerState *s = BCM2835_POWER(obj);
+
+    sysbus_init_irq(SYS_BUS_DEVICE(s), &s->mbox_irq);
+    memory_region_init_io(&s->iomem, obj, &bcm2835_power_ops, s,
+                          TYPE_BCM2835_POWER, 0x10);
+    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
+}
+
+static void bcm2835_power_realize(DeviceState *dev, Error **errp)
+{
+    BCM2835PowerState *s = BCM2835_POWER(dev);
+
+    s->pending = 0;
+}
+
+static void bcm2835_power_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = bcm2835_power_realize;
+    dc->vmsd = &vmstate_bcm2835_power;
+}
+
+static TypeInfo bcm2835_power_info = {
+    .name          = TYPE_BCM2835_POWER,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(BCM2835PowerState),
+    .class_init    = bcm2835_power_class_init,
+    .instance_init = bcm2835_power_init,
+};
+
+static void bcm2835_power_register_types(void)
+{
+    type_register_static(&bcm2835_power_info);
+}
+
+type_init(bcm2835_power_register_types)
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index dd6f27e2a3..7beccc8747 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -29,6 +29,8 @@  obj-$(CONFIG_EXYNOS4) += exynos4210_rtc.o
obj-$(CONFIG_OMAP) += omap_gptimer.o
obj-$(CONFIG_OMAP) += omap_synctimer.o
obj-$(CONFIG_PXA2XX) += pxa2xx_timer.o
+obj-$(CONFIG_RASPI) += bcm2835_st.o
+obj-$(CONFIG_RASPI) += bcm2835_timer.o
obj-$(CONFIG_SH4) += sh_timer.o
obj-$(CONFIG_DIGIC) += digic-timer.o
obj-$(CONFIG_MIPS_CPS) += mips_gictimer.o
diff --git a/hw/timer/bcm2835_st.c b/hw/timer/bcm2835_st.c
new file mode 100644
index 0000000000..fb5cf5e573
--- /dev/null
+++ b/hw/timer/bcm2835_st.c
@@ -0,0 +1,202 @@ 
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+/* Based on several timers code found in various QEMU source files. */
+
+#include "qemu/osdep.h"
+#include "hw/timer/bcm2835_st.h"
+#include "qemu/log.h"
+
+static void bcm2835_st_update(BCM2835StState *s)
+{
+    int64_t now = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL);
+    uint32_t clo = (uint32_t)now;
+    uint32_t delta;
+    bool set = false;
+    int i;
+
+    /* Calculate new "next" value and reschedule */
+    for (i = 0; i < 4; i++) {
+        if (!(s->match & (1 << i))) {
+            if (!set || s->compare[i] - clo < delta) {
+                set = true;
+                s->next = s->compare[i];
+                delta = s->next - clo;
+            }
+        }
+    }
+
+    if (set) {
+        timer_mod(s->timer, now + delta);
+    } else {
+        timer_del(s->timer);
+    }
+}
+
+static void bcm2835_st_tick(void *opaque)
+{
+    BCM2835StState *s = (BCM2835StState *)opaque;
+    int i;
+
+    /* Trigger irqs for current "next" value */
+    for (i = 0; i < 4; i++) {
+        if (!(s->match & (1 << i)) && (s->next == s->compare[i])) {
+            s->match |= (1 << i);
+            qemu_set_irq(s->irq[i], 1);
+        }
+    }
+
+    bcm2835_st_update(s);
+}
+
+static uint64_t bcm2835_st_read(void *opaque, hwaddr offset,
+                           unsigned size)
+{
+    BCM2835StState *s = (BCM2835StState *)opaque;
+    uint32_t res = 0;
+    uint64_t now = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL);
+
+    assert(size == 4);
+
+    switch (offset) {
+    case 0x00:
+        res = s->match;
+        break;
+    case 0x04:
+        res = (uint32_t)now;
+        /* Ugly temporary hack to get Plan9 to boot... */
+        /* see http://plan9.bell-labs.com/sources/contrib/ \
+         * miller/rpi/sys/src/9/bcm/clock.c */
+        /* res = (now / 10000) * 10000; */
+        break;
+    case 0x08:
+        res = (now >> 32);
+        break;
+    case 0x0c:
+        res = s->compare[0];
+        break;
+    case 0x10:
+        res = s->compare[1];
+        break;
+    case 0x14:
+        res = s->compare[2];
+        break;
+    case 0x18:
+        res = s->compare[3];
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+            "bcm2835_st_read: Bad offset %x\n", (int)offset);
+        return 0;
+    }
+
+    return res;
+}
+
+static void bcm2835_st_write(void *opaque, hwaddr offset,
+                        uint64_t value, unsigned size)
+{
+    BCM2835StState *s = (BCM2835StState *)opaque;
+    int i;
+
+    assert(size == 4);
+
+    switch (offset) {
+    case 0x00:
+        s->match &= ~value & 0x0f;
+        for (i = 0; i < 4; i++) {
+            if (value & (1 << i)) {
+                qemu_set_irq(s->irq[i], 0);
+            }
+        }
+        break;
+    case 0x0c:
+        s->compare[0] = value;
+        break;
+    case 0x10:
+        s->compare[1] = value;
+        break;
+    case 0x14:
+        s->compare[2] = value;
+        break;
+    case 0x18:
+        s->compare[3] = value;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+            "bcm2835_st_write: Bad offset %x\n", (int)offset);
+        return;
+    }
+    bcm2835_st_update(s);
+}
+
+static const MemoryRegionOps bcm2835_st_ops = {
+    .read = bcm2835_st_read,
+    .write = bcm2835_st_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const VMStateDescription vmstate_bcm2835_st = {
+    .name = TYPE_BCM2835_ST,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(compare, BCM2835StState, 4),
+        VMSTATE_UINT32(match, BCM2835StState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void bcm2835_st_init(Object *obj)
+{
+    BCM2835StState *s = BCM2835_ST(obj);
+    int i;
+
+    for (i = 0; i < 4; i++) {
+        sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq[i]);
+    }
+
+    memory_region_init_io(&s->iomem, obj, &bcm2835_st_ops, s,
+                          TYPE_BCM2835_ST, 0x20);
+    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
+}
+
+static void bcm2835_st_realize(DeviceState *dev, Error **errp)
+{
+    BCM2835StState *s = BCM2835_ST(dev);
+    int i;
+
+    for (i = 0; i < 4; i++) {
+        s->compare[i] = 0;
+    }
+    s->match = 0;
+    s->timer = timer_new_us(QEMU_CLOCK_VIRTUAL, bcm2835_st_tick, s);
+
+    bcm2835_st_update(s);
+}
+
+static void bcm2835_st_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = bcm2835_st_realize;
+    dc->vmsd = &vmstate_bcm2835_st;
+}
+
+static TypeInfo bcm2835_st_info = {
+    .name          = TYPE_BCM2835_ST,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(BCM2835StState),
+    .class_init    = bcm2835_st_class_init,
+    .instance_init = bcm2835_st_init,
+};
+
+static void bcm2835_st_register_types(void)
+{
+    type_register_static(&bcm2835_st_info);
+}
+
+type_init(bcm2835_st_register_types)
diff --git a/hw/timer/bcm2835_timer.c b/hw/timer/bcm2835_timer.c
new file mode 100644
index 0000000000..87f14f8561
--- /dev/null
+++ b/hw/timer/bcm2835_timer.c
@@ -0,0 +1,224 @@ 
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/timer/bcm2835_timer.h"
+#include "qemu/main-loop.h"
+#include "qemu/log.h"
+
+#define SYSCLOCK_FREQ (252000000)
+#define APBCLOCK_FREQ (126000000)
+
+#define CTRL_FRC_EN (1 << 9)
+#define CTRL_TIMER_EN (1 << 7)
+#define CTRL_IRQ_EN (1 << 5)
+#define CTRL_PS_MASK (3 << 2)
+#define CTRL_PS_SHIFT 2
+#define CTRL_CNT_32 (1 << 1)
+#define CTRL_FRC_PS_MASK (0xff << 16)
+#define CTRL_FRC_PS_SHIFT 16
+
+static void timer_tick(void *opaque)
+{
+    BCM2835TimerState *s = (BCM2835TimerState *)opaque;
+    s->raw_irq = 1;
+    if (s->control & CTRL_IRQ_EN) {
+        qemu_set_irq(s->irq, 1);
+    }
+}
+static void frc_timer_tick(void *opaque)
+{
+    BCM2835TimerState *s = (BCM2835TimerState *)opaque;
+    s->frc_value++;
+}
+
+static uint64_t bcm2835_timer_read(void *opaque, hwaddr offset,
+    unsigned size)
+{
+    BCM2835TimerState *s = (BCM2835TimerState *)opaque;
+    uint32_t res = 0;
+
+    assert(size == 4);
+
+    switch (offset) {
+    case 0x0:
+        res = s->load;
+        break;
+    case 0x4:
+        res = ptimer_get_count(s->timer);
+        break;
+    case 0x8:
+        res = s->control;
+        break;
+    case 0xc:
+        res = 0x544d5241;
+        break;
+    case 0x10:
+        res = s->raw_irq;
+        break;
+    case 0x14:
+        if (s->control & CTRL_IRQ_EN) {
+            res = s->raw_irq;
+        }
+        break;
+    case 0x18:
+        res = s->load;
+        break;
+    case 0x1c:
+        res = s->prediv;
+        break;
+    case 0x20:
+        res = s->frc_value;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+            "bcm2835_timer_read: Bad offset %x\n", (int)offset);
+        return 0;
+    }
+
+    return res;
+}
+
+static void bcm2835_timer_write(void *opaque, hwaddr offset,
+    uint64_t value, unsigned size)
+{
+    BCM2835TimerState *s = (BCM2835TimerState *)opaque;
+    uint32_t freq;
+
+    assert(size == 4);
+
+    switch (offset) {
+    case 0x0:
+        s->load = value;
+        ptimer_set_limit(s->timer, s->load, 1);
+        break;
+    case 0x4:
+        break;
+    case 0x8:
+        if (s->control & CTRL_FRC_EN) {
+            ptimer_stop(s->frc_timer);
+        }
+        if (s->control & CTRL_TIMER_EN) {
+            ptimer_stop(s->timer);
+        }
+        s->control = value & 0x00ff03ae;
+
+        freq = SYSCLOCK_FREQ;
+        ptimer_set_freq(s->frc_timer, freq);
+        ptimer_set_limit(s->frc_timer,
+            ((s->control & CTRL_FRC_PS_MASK) >> CTRL_FRC_PS_SHIFT) + 1,
+            s->control & CTRL_FRC_EN);
+
+        freq = APBCLOCK_FREQ;
+        freq /= s->prediv + 1;
+        switch ((s->control & CTRL_PS_MASK) >> CTRL_PS_SHIFT) {
+        case 1:
+            freq >>= 4;
+            break;
+        case 2:
+            freq >>= 8;
+            break;
+        default:
+            break;
+        }
+        ptimer_set_freq(s->timer, freq);
+        ptimer_set_limit(s->timer, s->load, s->control & CTRL_TIMER_EN);
+
+        if (s->control & CTRL_TIMER_EN) {
+            ptimer_run(s->timer, 0);
+        }
+        if (s->control & CTRL_FRC_EN) {
+            s->frc_value++;
+            ptimer_run(s->frc_timer, 0);
+        }
+        break;
+    case 0xc:
+        s->raw_irq = 0;
+        qemu_set_irq(s->irq, 0);
+        break;
+    case 0x10:
+    case 0x14:
+        break;
+    case 0x18:
+        s->load = value;
+        ptimer_set_limit(s->timer, s->load, 0);
+        break;
+    case 0x1c:
+        s->prediv = value & 0x3ff;
+        break;
+    case 0x20:
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+            "bcm2835_timer_write: Bad offset %x\n", (int)offset);
+        return;
+    }
+}
+
+static const MemoryRegionOps bcm2835_timer_ops = {
+    .read = bcm2835_timer_read,
+    .write = bcm2835_timer_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const VMStateDescription vmstate_bcm2835_timer = {
+    .name = TYPE_BCM2835_TIMER,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void bcm2835_timer_init(Object *obj)
+{
+    BCM2835TimerState *s = BCM2835_TIMER(obj);
+
+    memory_region_init_io(&s->iomem, obj, &bcm2835_timer_ops, s,
+                          TYPE_BCM2835_TIMER, 0x100);
+    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
+    sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq);
+}
+
+static void bcm2835_timer_realize(DeviceState *dev, Error **errp)
+{
+    BCM2835TimerState *s = BCM2835_TIMER(dev);
+    QEMUBH *bh;
+
+    s->load = 0;
+    s->control = 0x3e << 16;
+    s->raw_irq = 0;
+    s->prediv = 0x7d;
+
+    bh = qemu_bh_new(timer_tick, s);
+    s->timer = ptimer_init(bh,PTIMER_POLICY_DEFAULT);
+
+    bh = qemu_bh_new(frc_timer_tick, s);
+    s->frc_timer = ptimer_init(bh,PTIMER_POLICY_DEFAULT);
+}
+
+static void bcm2835_timer_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = bcm2835_timer_realize;
+    dc->vmsd = &vmstate_bcm2835_timer;
+}
+
+static TypeInfo bcm2835_timer_info = {
+    .name          = TYPE_BCM2835_TIMER,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(BCM2835TimerState),
+    .class_init    = bcm2835_timer_class_init,
+    .instance_init = bcm2835_timer_init,
+};
+
+static void bcm2835_timer_register_types(void)
+{
+    type_register_static(&bcm2835_timer_info);
+}
+
+type_init(bcm2835_timer_register_types)
diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
index 5958be8ce3..9ac7cb4c41 100644
--- a/hw/usb/Makefile.objs
+++ b/hw/usb/Makefile.objs
@@ -40,5 +40,7 @@  common-obj-$(CONFIG_USB_REDIR) += redirect.o quirks.o
common-obj-y += $(patsubst %,host-%.o,$(HOST_USB))

ifeq ($(CONFIG_USB_LIBUSB),y)
-common-obj-$(CONFIG_XEN) += xen-usb.o
+common-obj-$(CONFIG_XEN_BACKEND) += xen-usb.o
endif
+
+obj-$(CONFIG_RASPI) += bcm2835_usb.o
diff --git a/hw/usb/bcm2835_usb.c b/hw/usb/bcm2835_usb.c
new file mode 100644
index 0000000000..ed745e5591
--- /dev/null
+++ b/hw/usb/bcm2835_usb.c
@@ -0,0 +1,604 @@ 
+/*
+ * Raspberry Pi emulation (c) 2012-2013 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+/* This is wrong at so many levels, but well, I'm releasing it anyway */
+
+#include "qemu/osdep.h"
+#include "hw/usb/bcm2835_usb.h"
+
+#include "qemu/log.h"
+#include "qapi/error.h"
+
+#include "sysemu/dma.h"
+
+#include "bcm2835_usb_regs.h"
+
+/* You may have to change these parameters to get an almost-usable mouse
+ * support.
+ * The problem is that frame scheduling is all done by software, so a LOT of
+ * interrupts are generated, which doesn't help... */
+#define SOF_INCR 1
+#define SOF_DELAY 5000
+
+static void bcm2835_usb_update_irq(BCM2835UsbState *s)
+{
+    int n;
+
+    s->haint = 0;
+    for (n = 0; n < BCM2835_USB_HCHANS; n++) {
+        if (s->hchan[n].hcint & s->hchan[n].hcintmsk) {
+            s->haint |= (1 << n);
+        }
+    }
+    s->gintsts &= ~gintsts_hcintr;
+    if (s->haint & s->haintmsk) {
+        s->gintsts |= gintsts_hcintr;
+    }
+
+    if ((s->hprt0 & hprt0_prtconndet)
+        || (s->hprt0 & hprt0_prtenchng)) {
+        s->gintsts |= gintsts_portintr;
+    } else {
+        s->gintsts &= ~gintsts_portintr;
+    }
+
+    s->gintsts |= gintsts_nptxfempty | gintsts_ptxfempty;
+
+    if (!(s->gahbcfg & gahbcfg_glblintrmsk)) {
+        qemu_set_irq(s->irq, 0);
+    } else {
+        if (s->gintsts & s->gintmsk) {
+            qemu_set_irq(s->irq, 1);
+        } else {
+            qemu_set_irq(s->irq, 0);
+        }
+    }
+}
+
+
+static void bcm2835_usb_sof_tick(void *opaque)
+{
+    BCM2835UsbState *s = (BCM2835UsbState *)opaque;
+    int64_t now;
+
+    uint32_t num = (s->hfnum & 0x3fff) + SOF_INCR;
+    s->hfnum = (num & 0x3fff) | (0x3210 << 16);
+    s->gintsts |= gintsts_sofintr;
+
+    bcm2835_usb_update_irq(s);
+
+    now = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL);
+    timer_mod(s->sof_timer, now + SOF_DELAY);
+}
+
+static void channel_enable(BCM2835UsbHcState *c)
+{
+    USBEndpoint *ep;
+    USBDevice *dev;
+
+    uint32_t epnum = (c->hcchar >> hcchar_epnum_shift) & hcchar_epnum_mask;
+    uint32_t devaddr = (c->hcchar >> hcchar_devaddr_shift)
+                       & hcchar_devaddr_mask;
+    uint32_t xfersize = (c->hctsiz >> hctsiz_xfersize_shift)
+                        & hctsiz_xfersize_mask;
+    uint32_t pid = (c->hctsiz >> hctsiz_pid_shift) & hctsiz_pid_mask;
+    uint32_t dma_addr = c->hcdma; /* ??? */
+    int actual_length;
+    int qpid;
+
+    if (!c->parent->reset_done) {
+        return;
+    }
+
+    if (c->hcchar & hcchar_epdir) {
+        /* IN */
+        qpid = USB_TOKEN_IN;
+    } else {
+        /* OUT/SETUP */
+        if (pid == DWC_HCTSIZ_SETUP) {
+            qpid = USB_TOKEN_SETUP;
+        } else {
+            qpid = USB_TOKEN_OUT;
+        }
+    }
+
+    dev = usb_find_device(&c->parent->port, devaddr);
+    assert(dev != NULL);
+
+    ep = usb_ep_get(dev, qpid, epnum);
+    usb_packet_setup(&c->packet, qpid, ep, 0, devaddr, 0, 0);
+
+    if (xfersize > 0) {
+        dma_memory_read(&c->parent->dma_as, dma_addr, c->buffer, xfersize);
+
+        usb_packet_addbuf(&c->packet, c->buffer, xfersize);
+    }
+    usb_handle_packet(dev, &c->packet);
+
+    if (c->packet.status == USB_RET_SUCCESS) {
+        if (qpid == USB_TOKEN_IN) {
+            actual_length = c->packet.actual_length;
+
+            xfersize -= actual_length;
+            c->hctsiz &= ~(hctsiz_xfersize_mask << hctsiz_xfersize_shift);
+            c->hctsiz |= xfersize << hctsiz_xfersize_shift;
+
+            dma_memory_write(&c->parent->dma_as, dma_addr, c->buffer,
+                             actual_length);
+        }
+
+        c->hcint |= hcint_xfercomp | hcint_chhltd;
+        bcm2835_usb_update_irq(c->parent);
+    } else if (c->packet.status == USB_RET_NAK) {
+        c->hcint |= hcint_chhltd | hcint_nak;
+        bcm2835_usb_update_irq(c->parent);
+    } else {
+        /* assert(0); */
+        c->hcint |= hcint_chhltd | hcint_stall;
+        bcm2835_usb_update_irq(c->parent);
+    }
+
+}
+
+static uint32_t bcm2835_usb_hchan_read(BCM2835UsbState *s, int ch,
+    int offset)
+{
+    BCM2835UsbHcState *c = &s->hchan[ch];
+    uint32_t res;
+
+    switch (offset) {
+    case 0x0:
+        res = c->hcchar;
+        break;
+    case 0x4:
+        res = c->hcsplt;
+        break;
+    case 0x8:
+        res = c->hcint;
+        break;
+    case 0xc:
+        res = c->hcintmsk;
+        break;
+    case 0x10:
+        res = c->hctsiz;
+        break;
+    case 0x14:
+        res = c->hcdma;
+        break;
+    case 0x1c:
+        res = c->hcdmab;
+        break;
+    default:
+        res = 0;
+        break;
+    }
+    return res;
+}
+static void bcm2835_usb_hchan_write(BCM2835UsbState *s, int ch,
+    int offset, uint32_t value, int *pset_irq)
+{
+    BCM2835UsbHcState *c = &s->hchan[ch];
+
+    switch (offset) {
+    case 0x0:
+        c->hcchar = value;
+        if (value & hcchar_chdis) {
+            c->hcchar &= ~(hcchar_chdis | hcchar_chen);
+            /* TODO irq */
+        }
+        if (value & hcchar_chen) {
+            channel_enable(c);
+        }
+        break;
+    case 0x4:
+        c->hcsplt = value;
+        break;
+    case 0x8:
+        /* Looks like a standard interrupt register */
+        c->hcint &= ~value;
+        *pset_irq = 1;
+        break;
+    case 0xc:
+        c->hcintmsk = value;
+        break;
+    case 0x10:
+        c->hctsiz = value;
+        break;
+    case 0x14:
+        c->hcdma = value;
+        break;
+    case 0x1c:
+        c->hcdmab = value;
+        break;
+    default:
+        break;
+    }
+}
+
+static uint64_t bcm2835_usb_read(void *opaque, hwaddr offset,
+    unsigned size)
+{
+    BCM2835UsbState *s = (BCM2835UsbState *)opaque;
+    uint32_t res = 0;
+    int i;
+
+    assert(size == 4);
+
+    switch (offset) {
+    case 0x0:
+        res = s->gotgctl;
+        break;
+    case 0x4:
+        res = s->gotgint;
+        break;
+    case 0x8:
+        res = s->gahbcfg;
+        break;
+    case 0xc:
+        res = s->gusbcfg;
+        break;
+    case 0x10:
+        res = s->grstctl;
+        break;
+    case 0x14:
+        res = s->gintsts;
+        /* Enforce Host mode */
+        res |= gintsts_curmode;
+        break;
+    case 0x18:
+        res = s->gintmsk;
+        break;
+    case 0x24:
+        res = s->grxfsiz;
+        break;
+    case 0x28:
+        res = s->gnptxfsiz;
+        break;
+    case 0x2c:
+        res = s->gnptxsts;
+        break;
+    case 0x3c:
+        res = s->guid;
+        break;
+    case 0x40:
+        res = 0x4f54280a;
+        break;
+    case 0x44:
+        res = 0;
+        break;
+    case 0x48:
+        res = 0x228ddd50;
+        break;
+    case 0x4c:
+        res = 0x0ff000e8;
+        break;
+    case 0x50:
+        res = 0x1ff00020;
+        break;
+    case 0x5c:
+        res = s->gdfifocfg;
+        break;
+    case 0x100:
+        res = s->hptxfsiz;
+        break;
+    case 0x400:
+        res = s->hcfg;
+        break;
+    case 0x408:
+        res = s->hfnum;
+        break;
+    case 0x410:
+        res = s->hptxsts;
+        break;
+    case 0x414:
+        res = s->haint;
+        break;
+    case 0x418:
+        res = s->haintmsk;
+        break;
+    case 0x440:
+        res = s->hprt0;
+        res &= ~hprt0_prtconnsts;
+        if (s->attached) {
+            res |= hprt0_prtconnsts;
+        }
+        break;
+    case 0x800:
+        res = s->dcfg;
+        break;
+
+    case 0xe00:
+    case 0x54:
+    case 0x58:
+        res = 0;
+        break;
+
+    default:
+        if ((offset >= 0x104) && (offset < 0x104 + (15 << 2))) {
+            res = s->dtxfsiz[(offset - 0x104) >> 2];
+        } else if ((offset >= 0x500) && (offset < 0x500 + 0x20*BCM2835_USB_HCHANS)) {
+            i = (offset - 0x500) >> 5;
+            res = bcm2835_usb_hchan_read(s, i, offset & 0x1f);
+        } else {
+            qemu_log_mask(LOG_GUEST_ERROR,
+                "bcm2835_usb_read: Bad offset %x\n", (int)offset);
+            res = 0;
+        }
+        break;
+    }
+    return res;
+}
+
+static void bcm2835_usb_write(void *opaque, hwaddr offset,
+    uint64_t value, unsigned size)
+{
+    BCM2835UsbState *s = (BCM2835UsbState *)opaque;
+
+    int i;
+    int set_irq = 0;
+
+    assert(size == 4);
+
+    switch (offset) {
+    case 0x0:
+        s->gotgctl = value;
+        break;
+    case 0x4:
+        /* Looks like a standard interrupt register */
+        s->gotgint &= ~value;
+        break;
+    case 0x8:
+        s->gahbcfg = value;
+        set_irq = 1;
+        break;
+    case 0xc:
+        s->gusbcfg = value;
+        break;
+    case 0x10:
+        s->grstctl &= ~0x7c0;
+        s->grstctl |= value & 0x7c0;
+        break;
+    case 0x14:
+        s->gintsts &= ~value;
+        /* Enforce Host mode */
+        s->gintsts |= gintsts_curmode;
+        set_irq = 1;
+        break;
+    case 0x18:
+        s->gintmsk = value;
+        break;
+    case 0x24:
+        s->grxfsiz = value;
+        break;
+    case 0x28:
+        s->gnptxfsiz = value;
+        break;
+    case 0x3c:
+        s->guid = value;
+        break;
+    case 0x5c:
+        s->gdfifocfg = value;
+        break;
+    case 0x100:
+        s->hptxfsiz = value;
+        break;
+    case 0x400:
+        s->hcfg = value;
+        break;
+    case 0x408:
+        /* Probably RO */
+        break;
+    case 0x410:
+        /* Probably RO */
+        break;
+    case 0x414:
+        /* Probably RO */
+        break;
+    case 0x418:
+        s->haintmsk = value & ((1 << BCM2835_USB_HCHANS) - 1);
+        set_irq = 1;
+        break;
+    case 0x440:
+        if (!(s->hprt0 & hprt0_prtpwr) && (value & hprt0_prtpwr)) {
+            /* Trigger the port status change interrupt on power on */
+            if (s->attached) {
+                s->hprt0 |= hprt0_prtconndet;
+                set_irq = 1;
+                /* Reset the device (that's probably not the right place) */
+                usb_device_reset(s->port.dev);
+                s->reset_done = 1;
+                timer_mod(s->sof_timer, 0);
+            }
+        }
+        s->hprt0 &= ~hprt0_prtpwr;
+        s->hprt0 |= value & hprt0_prtpwr;
+
+        if ((s->hprt0 & hprt0_prtres) ^ (value & hprt0_prtres)) {
+            s->hprt0 |= hprt0_prtenchng;
+            set_irq = 1;
+        }
+        s->hprt0 &= ~(hprt0_prtena | hprt0_prtres);
+        if (value & hprt0_prtres) {
+            s->hprt0 |= hprt0_prtres;
+        } else {
+            s->hprt0 |= hprt0_prtena;
+        }
+
+        /* Interrupt clears */
+        if (value & hprt0_prtconndet) {
+            s->hprt0 &= ~hprt0_prtconndet;
+            set_irq = 1;
+        }
+        if (value & hprt0_prtenchng) {
+            s->hprt0 &= ~hprt0_prtenchng;
+            set_irq = 1;
+        }
+
+        break;
+
+    case 0xe00:
+    case 0x54:
+    case 0x58:
+        break;
+
+    default:
+        if ((offset >= 0x104) && (offset < 0x104 + (15 << 2))) {
+            s->dtxfsiz[(offset - 0x104) >> 2] = value;
+        } else if ((offset >= 0x500) && (offset < 0x500 + 0x20*BCM2835_USB_HCHANS)) {
+            i = (offset - 0x500) >> 5;
+            bcm2835_usb_hchan_write(s, i, offset & 0x1f, value, &set_irq);
+        } else {
+            qemu_log_mask(LOG_GUEST_ERROR,
+                "bcm2835_usb_write: Bad offset %x\n", (int)offset);
+        }
+        break;
+    }
+
+    if (set_irq) {
+        bcm2835_usb_update_irq(s);
+    }
+}
+
+static void bcm2835_usb_attach(USBPort *port1)
+{
+    BCM2835UsbState *s = port1->opaque;
+    s->attached = 1;
+}
+static void bcm2835_usb_detach(USBPort *port1)
+{
+}
+static void bcm2835_usb_child_detach(USBPort *port1, USBDevice *child)
+{
+}
+static void bcm2835_usb_wakeup(USBPort *port1)
+{
+}
+static void bcm2835_usb_async_complete(USBPort *port, USBPacket *packet)
+{
+}
+
+
+static const MemoryRegionOps bcm2835_usb_ops = {
+    .read = bcm2835_usb_read,
+    .write = bcm2835_usb_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const VMStateDescription vmstate_bcm2835_usb = {
+    .name = TYPE_BCM2835_USB,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static USBPortOps bcm2835_usb_port_ops = {
+    .attach = bcm2835_usb_attach,
+    .detach = bcm2835_usb_detach,
+    .child_detach = bcm2835_usb_child_detach,
+    .wakeup = bcm2835_usb_wakeup,
+    .complete = bcm2835_usb_async_complete,
+};
+
+static USBBusOps bcm2835_usb_bus_ops = {
+};
+
+static void bcm2835_usb_init(Object *obj)
+{
+    BCM2835UsbState *s = BCM2835_USB(obj);
+
+    memory_region_init_io(&s->iomem, obj, &bcm2835_usb_ops, s,
+                          TYPE_BCM2835_USB, 0x20000);
+    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
+    sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq);
+}
+
+static void bcm2835_usb_realize(DeviceState *dev, Error **errp)
+{
+    int n;
+    BCM2835UsbState *s = BCM2835_USB(dev);
+    Error *err = NULL;
+    Object *obj;
+
+    obj = object_property_get_link(OBJECT(dev), "dma_mr", &err);
+    if (err || obj == NULL) {
+        error_setg(errp, "bcm2835_usb: required dma_mr property not found");
+        return;
+    }
+
+    s->dma_mr = MEMORY_REGION(obj);
+    address_space_init(&s->dma_as, s->dma_mr, NULL);
+
+    s->gusbcfg = 0x20402700;
+    s->hptxfsiz = 0x02002000;
+    s->hcfg = 0x00000001;
+    s->dcfg = 0x00000000;
+    s->grxfsiz = 0x00001000;
+    s->gnptxfsiz = 0x01001000;
+    for (n = 0; n < 15; n++) {
+        s->dtxfsiz[n] = 0x02002000;
+    }
+    s->gahbcfg = 0x0000000e;
+    s->grstctl = 0x80000000;
+    s->gotgctl = 0x001c0000;
+    s->gotgint = 0;
+    s->gintsts = 0;
+    s->gintmsk = 0;
+    s->gdfifocfg = 0x00000000;
+    s->hprt0 = DWC_HPRT0_PRTSPD_FULL_SPEED << hprt0_prtspd_shift;
+    s->gnptxsts = 0x080100;
+    s->hfnum = 0;
+    s->hptxsts = 0x080200;
+    s->guid = 0x2708A000;
+
+    for (n = 0; n < BCM2835_USB_HCHANS; n++) {
+        s->hchan[n].parent = s;
+        s->hchan[n].index = n;
+
+        s->hchan[n].hcchar = 0;
+        s->hchan[n].hcsplt = 0;
+        s->hchan[n].hcint = 0;
+        s->hchan[n].hcintmsk = 0;
+        s->hchan[n].hctsiz = 0;
+        s->hchan[n].hcdma = 0;
+        s->hchan[n].hcdmab = 0;
+
+        usb_packet_init(&s->hchan[n].packet);
+    }
+
+    s->attached = 0;
+    s->reset_done = 0;
+
+    s->sof_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, bcm2835_usb_sof_tick, s);
+
+    usb_bus_new(&s->bus, sizeof(s->bus), &bcm2835_usb_bus_ops, DEVICE(s));
+    usb_register_port(&s->bus, &s->port, s, 0, &bcm2835_usb_port_ops,
+        USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
+}
+
+static void bcm2835_usb_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = bcm2835_usb_realize;
+    dc->vmsd = &vmstate_bcm2835_usb;
+}
+
+static TypeInfo bcm2835_usb_info = {
+    .name          = TYPE_BCM2835_USB,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(BCM2835UsbState),
+    .class_init    = bcm2835_usb_class_init,
+    .instance_init = bcm2835_usb_init,
+};
+
+static void bcm2835_usb_register_types(void)
+{
+    type_register_static(&bcm2835_usb_info);
+}
+
+type_init(bcm2835_usb_register_types)
diff --git a/hw/usb/bcm2835_usb_regs.h b/hw/usb/bcm2835_usb_regs.h
new file mode 100644
index 0000000000..76f3219b54
--- /dev/null
+++ b/hw/usb/bcm2835_usb_regs.h
@@ -0,0 +1,1061 @@ 
+#ifndef BCM2835_USB_REGS_H
+#define BCM2835_USB_REGS_H
+
+#define __DWC_OTG_REGS_H__
+#define DWC_GLBINTRMASK        0x0001
+#define DWC_DMAENABLE        0x0020
+#define DWC_NPTXEMPTYLVL_EMPTY    0x0080
+#define DWC_NPTXEMPTYLVL_HALFEMPTY    0x0000
+#define DWC_PTXEMPTYLVL_EMPTY    0x0100
+#define DWC_PTXEMPTYLVL_HALFEMPTY    0x0000
+#define DWC_SLAVE_ONLY_ARCH 0
+#define DWC_EXT_DMA_ARCH 1
+#define DWC_INT_DMA_ARCH 2
+#define DWC_MODE_HNP_SRP_CAPABLE    0
+#define DWC_MODE_SRP_ONLY_CAPABLE    1
+#define DWC_MODE_NO_HNP_SRP_CAPABLE        2
+#define DWC_MODE_SRP_CAPABLE_DEVICE        3
+#define DWC_MODE_NO_SRP_CAPABLE_DEVICE    4
+#define DWC_MODE_SRP_CAPABLE_HOST    5
+#define DWC_MODE_NO_SRP_CAPABLE_HOST    6
+
+/* union gotgctl_data */
+#define gotgctl_sesreqscs (1 << 0)
+#define gotgctl_sesreq (1 << 1)
+#define gotgctl_vbvalidoven (1 << 2)
+#define gotgctl_vbvalidovval (1 << 3)
+#define gotgctl_avalidoven (1 << 4)
+#define gotgctl_avalidovval (1 << 5)
+#define gotgctl_bvalidoven (1 << 6)
+#define gotgctl_bvalidovval (1 << 7)
+#define gotgctl_hstnegscs (1 << 8)
+#define gotgctl_hnpreq (1 << 9)
+#define gotgctl_hstsethnpen (1 << 10)
+#define gotgctl_devhnpen (1 << 11)
+#define gotgctl_reserved12_15_shift (12)
+#define gotgctl_reserved12_15_mask (0xf)
+#define gotgctl_conidsts (1 << 16)
+#define gotgctl_dbnctime (1 << 17)
+#define gotgctl_asesvld (1 << 18)
+#define gotgctl_bsesvld (1 << 19)
+#define gotgctl_otgver (1 << 20)
+#define gotgctl_reserved1 (1 << 21)
+#define gotgctl_multvalidbc_shift (22)
+#define gotgctl_multvalidbc_mask (0x1f)
+#define gotgctl_chirpen (1 << 27)
+#define gotgctl_reserved28_31_shift (28)
+#define gotgctl_reserved28_31_mask (0xf)
+
+/* union gotgint_data */
+#define gotgint_reserved0_1_shift (0)
+#define gotgint_reserved0_1_mask (0x3)
+#define gotgint_sesenddet (1 << 2)
+#define gotgint_reserved3_7_shift (3)
+#define gotgint_reserved3_7_mask (0x1f)
+#define gotgint_sesreqsucstschng (1 << 8)
+#define gotgint_hstnegsucstschng (1 << 9)
+#define gotgint_reserved10_16_shift (10)
+#define gotgint_reserved10_16_mask (0x7f)
+#define gotgint_hstnegdet (1 << 17)
+#define gotgint_adevtoutchng (1 << 18)
+#define gotgint_debdone (1 << 19)
+#define gotgint_mvic (1 << 20)
+#define gotgint_reserved31_21_shift (21)
+#define gotgint_reserved31_21_mask (0x7ff)
+
+/* union gahbcfg_data */
+#define gahbcfg_glblintrmsk (1 << 0)
+#define DWC_GAHBCFG_GLBINT_ENABLE        1
+#define gahbcfg_hburstlen_shift (1)
+#define gahbcfg_hburstlen_mask (0xf)
+#define DWC_GAHBCFG_INT_DMA_BURST_SINGLE    0
+#define DWC_GAHBCFG_INT_DMA_BURST_INCR        1
+#define DWC_GAHBCFG_INT_DMA_BURST_INCR4        3
+#define DWC_GAHBCFG_INT_DMA_BURST_INCR8        5
+#define DWC_GAHBCFG_INT_DMA_BURST_INCR16    7
+#define gahbcfg_dmaenable (1 << 5)
+#define DWC_GAHBCFG_DMAENABLE            1
+#define gahbcfg_reserved (1 << 6)
+#define gahbcfg_nptxfemplvl_txfemplvl (1 << 7)
+#define gahbcfg_ptxfemplvl (1 << 8)
+#define DWC_GAHBCFG_TXFEMPTYLVL_EMPTY        1
+#define DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY    0
+#define gahbcfg_reserved9_20_shift (9)
+#define gahbcfg_reserved9_20_mask (0xfff)
+#define gahbcfg_remmemsupp (1 << 21)
+#define gahbcfg_notialldmawrit (1 << 22)
+#define gahbcfg_ahbsingle (1 << 23)
+#define gahbcfg_reserved24_31_shift (24)
+#define gahbcfg_reserved24_31_mask (0xff)
+
+/* union gusbcfg_data */
+#define gusbcfg_toutcal_shift (0)
+#define gusbcfg_toutcal_mask (0x7)
+#define gusbcfg_phyif (1 << 3)
+#define gusbcfg_ulpi_utmi_sel (1 << 4)
+#define gusbcfg_fsintf (1 << 5)
+#define gusbcfg_physel (1 << 6)
+#define gusbcfg_ddrsel (1 << 7)
+#define gusbcfg_srpcap (1 << 8)
+#define gusbcfg_hnpcap (1 << 9)
+#define gusbcfg_usbtrdtim_shift (10)
+#define gusbcfg_usbtrdtim_mask (0xf)
+#define gusbcfg_reserved1 (1 << 14)
+#define gusbcfg_phylpwrclksel (1 << 15)
+#define gusbcfg_otgutmifssel (1 << 16)
+#define gusbcfg_ulpi_fsls (1 << 17)
+#define gusbcfg_ulpi_auto_res (1 << 18)
+#define gusbcfg_ulpi_clk_sus_m (1 << 19)
+#define gusbcfg_ulpi_ext_vbus_drv (1 << 20)
+#define gusbcfg_ulpi_int_vbus_indicator (1 << 21)
+#define gusbcfg_term_sel_dl_pulse (1 << 22)
+#define gusbcfg_indicator_complement (1 << 23)
+#define gusbcfg_indicator_pass_through (1 << 24)
+#define gusbcfg_ulpi_int_prot_dis (1 << 25)
+#define gusbcfg_ic_usb_cap (1 << 26)
+#define gusbcfg_ic_traffic_pull_remove (1 << 27)
+#define gusbcfg_tx_end_delay (1 << 28)
+#define gusbcfg_force_host_mode (1 << 29)
+#define gusbcfg_force_dev_mode (1 << 30)
+#define gusbcfg_reserved31 (1 << 31)
+
+/* union grstctl_data */
+#define grstctl_csftrst (1 << 0)
+#define grstctl_hsftrst (1 << 1)
+#define grstctl_hstfrm (1 << 2)
+#define grstctl_intknqflsh (1 << 3)
+#define grstctl_rxfflsh (1 << 4)
+#define grstctl_txfflsh (1 << 5)
+#define grstctl_txfnum_shift (6)
+#define grstctl_txfnum_mask (0x1f)
+#define grstctl_reserved11_29_shift (11)
+#define grstctl_reserved11_29_mask (0x7ffff)
+#define grstctl_dmareq (1 << 30)
+#define grstctl_ahbidle (1 << 31)
+
+/* union gintmsk_data */
+#define gintmsk_reserved0 (1 << 0)
+#define gintmsk_modemismatch (1 << 1)
+#define gintmsk_otgintr (1 << 2)
+#define gintmsk_sofintr (1 << 3)
+#define gintmsk_rxstsqlvl (1 << 4)
+#define gintmsk_nptxfempty (1 << 5)
+#define gintmsk_ginnakeff (1 << 6)
+#define gintmsk_goutnakeff (1 << 7)
+#define gintmsk_ulpickint (1 << 8)
+#define gintmsk_i2cintr (1 << 9)
+#define gintmsk_erlysuspend (1 << 10)
+#define gintmsk_usbsuspend (1 << 11)
+#define gintmsk_usbreset (1 << 12)
+#define gintmsk_enumdone (1 << 13)
+#define gintmsk_isooutdrop (1 << 14)
+#define gintmsk_eopframe (1 << 15)
+#define gintmsk_restoredone (1 << 16)
+#define gintmsk_epmismatch (1 << 17)
+#define gintmsk_inepintr (1 << 18)
+#define gintmsk_outepintr (1 << 19)
+#define gintmsk_incomplisoin (1 << 20)
+#define gintmsk_incomplisoout (1 << 21)
+#define gintmsk_fetsusp (1 << 22)
+#define gintmsk_resetdet (1 << 23)
+#define gintmsk_portintr (1 << 24)
+#define gintmsk_hcintr (1 << 25)
+#define gintmsk_ptxfempty (1 << 26)
+#define gintmsk_lpmtranrcvd (1 << 27)
+#define gintmsk_conidstschng (1 << 28)
+#define gintmsk_disconnect (1 << 29)
+#define gintmsk_sessreqintr (1 << 30)
+#define gintmsk_wkupintr (1 << 31)
+
+/* union gintsts_data */
+#define DWC_SOF_INTR_MASK 0x0008
+#define DWC_HOST_MODE 1
+#define gintsts_curmode (1 << 0)
+#define gintsts_modemismatch (1 << 1)
+#define gintsts_otgintr (1 << 2)
+#define gintsts_sofintr (1 << 3)
+#define gintsts_rxstsqlvl (1 << 4)
+#define gintsts_nptxfempty (1 << 5)
+#define gintsts_ginnakeff (1 << 6)
+#define gintsts_goutnakeff (1 << 7)
+#define gintsts_ulpickint (1 << 8)
+#define gintsts_i2cintr (1 << 9)
+#define gintsts_erlysuspend (1 << 10)
+#define gintsts_usbsuspend (1 << 11)
+#define gintsts_usbreset (1 << 12)
+#define gintsts_enumdone (1 << 13)
+#define gintsts_isooutdrop (1 << 14)
+#define gintsts_eopframe (1 << 15)
+#define gintsts_restoredone (1 << 16)
+#define gintsts_epmismatch (1 << 17)
+#define gintsts_inepint (1 << 18)
+#define gintsts_outepintr (1 << 19)
+#define gintsts_incomplisoin (1 << 20)
+#define gintsts_incomplisoout (1 << 21)
+#define gintsts_fetsusp (1 << 22)
+#define gintsts_resetdet (1 << 23)
+#define gintsts_portintr (1 << 24)
+#define gintsts_hcintr (1 << 25)
+#define gintsts_ptxfempty (1 << 26)
+#define gintsts_lpmtranrcvd (1 << 27)
+#define gintsts_conidstschng (1 << 28)
+#define gintsts_disconnect (1 << 29)
+#define gintsts_sessreqintr (1 << 30)
+#define gintsts_wkupintr (1 << 31)
+
+/* union device_grxsts_data */
+#define device_grxsts_epnum_shift (0)
+#define device_grxsts_epnum_mask (0xf)
+#define device_grxsts_bcnt_shift (4)
+#define device_grxsts_bcnt_mask (0x7ff)
+#define device_grxsts_dpid_shift (15)
+#define device_grxsts_dpid_mask (0x3)
+#define DWC_STS_DATA_UPDT        0x2    /* OUT Data Packet */
+#define DWC_STS_XFER_COMP        0x3    /* OUT Data Transfer Complete */
+#define DWC_DSTS_GOUT_NAK        0x1    /* Global OUT NAK */
+#define DWC_DSTS_SETUP_COMP        0x4    /* Setup Phase Complete */
+#define DWC_DSTS_SETUP_UPDT 0x6    /* SETUP Packet */
+#define device_grxsts_pktsts_shift (17)
+#define device_grxsts_pktsts_mask (0xf)
+#define device_grxsts_fn_shift (21)
+#define device_grxsts_fn_mask (0xf)
+#define device_grxsts_reserved25_31_shift (25)
+#define device_grxsts_reserved25_31_mask (0x7f)
+
+/* union host_grxsts_data */
+#define host_grxsts_chnum_shift (0)
+#define host_grxsts_chnum_mask (0xf)
+#define host_grxsts_bcnt_shift (4)
+#define host_grxsts_bcnt_mask (0x7ff)
+#define host_grxsts_dpid_shift (15)
+#define host_grxsts_dpid_mask (0x3)
+#define host_grxsts_pktsts_shift (17)
+#define host_grxsts_pktsts_mask (0xf)
+#define DWC_GRXSTS_PKTSTS_IN              0x2
+#define DWC_GRXSTS_PKTSTS_IN_XFER_COMP      0x3
+#define DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR 0x5
+#define DWC_GRXSTS_PKTSTS_CH_HALTED          0x7
+#define host_grxsts_reserved21_31_shift (21)
+#define host_grxsts_reserved21_31_mask (0x7ff)
+
+/* union fifosize_data */
+#define fifosize_startaddr_shift (0)
+#define fifosize_startaddr_mask (0xffff)
+#define fifosize_depth_shift (16)
+#define fifosize_depth_mask (0xffff)
+
+/* union gnptxsts_data */
+#define gnptxsts_nptxfspcavail_shift (0)
+#define gnptxsts_nptxfspcavail_mask (0xffff)
+#define gnptxsts_nptxqspcavail_shift (16)
+#define gnptxsts_nptxqspcavail_mask (0xff)
+#define gnptxsts_nptxqtop_terminate (1 << 24)
+#define gnptxsts_nptxqtop_token_shift (25)
+#define gnptxsts_nptxqtop_token_mask (0x3)
+#define gnptxsts_nptxqtop_chnep_shift (27)
+#define gnptxsts_nptxqtop_chnep_mask (0xf)
+#define gnptxsts_reserved (1 << 31)
+
+/* union dtxfsts_data */
+#define dtxfsts_txfspcavail_shift (0)
+#define dtxfsts_txfspcavail_mask (0xffff)
+#define dtxfsts_reserved_shift (16)
+#define dtxfsts_reserved_mask (0xffff)
+
+/* union gi2cctl_data */
+#define gi2cctl_rwdata_shift (0)
+#define gi2cctl_rwdata_mask (0xff)
+#define gi2cctl_regaddr_shift (8)
+#define gi2cctl_regaddr_mask (0xff)
+#define gi2cctl_addr_shift (16)
+#define gi2cctl_addr_mask (0x7f)
+#define gi2cctl_i2cen (1 << 23)
+#define gi2cctl_ack (1 << 24)
+#define gi2cctl_i2csuspctl (1 << 25)
+#define gi2cctl_i2cdevaddr_shift (26)
+#define gi2cctl_i2cdevaddr_mask (0x3)
+#define gi2cctl_i2cdatse0 (1 << 28)
+#define gi2cctl_reserved (1 << 29)
+#define gi2cctl_rw (1 << 30)
+#define gi2cctl_bsydne (1 << 31)
+
+/* union gpvndctl_data */
+#define gpvndctl_regdata_shift (0)
+#define gpvndctl_regdata_mask (0xff)
+#define gpvndctl_vctrl_shift (8)
+#define gpvndctl_vctrl_mask (0xff)
+#define gpvndctl_regaddr16_21_shift (16)
+#define gpvndctl_regaddr16_21_mask (0x3f)
+#define gpvndctl_regwr (1 << 22)
+#define gpvndctl_reserved23_24_shift (23)
+#define gpvndctl_reserved23_24_mask (0x3)
+#define gpvndctl_newregreq (1 << 25)
+#define gpvndctl_vstsbsy (1 << 26)
+#define gpvndctl_vstsdone (1 << 27)
+#define gpvndctl_reserved28_30_shift (28)
+#define gpvndctl_reserved28_30_mask (0x7)
+#define gpvndctl_disulpidrvr (1 << 31)
+
+/* union ggpio_data */
+#define ggpio_gpi_shift (0)
+#define ggpio_gpi_mask (0xffff)
+#define ggpio_gpo_shift (16)
+#define ggpio_gpo_mask (0xffff)
+
+/* union guid_data */
+#define guid_rwdata_shift (0)
+#define guid_rwdata_mask (0xffffffff)
+
+/* union gsnpsid_data */
+#define gsnpsid_rwdata_shift (0)
+#define gsnpsid_rwdata_mask (0xffffffff)
+
+/* union hwcfg1_data */
+#define hwcfg1_ep_dir0_shift (0)
+#define hwcfg1_ep_dir0_mask (0x3)
+#define hwcfg1_ep_dir1_shift (2)
+#define hwcfg1_ep_dir1_mask (0x3)
+#define hwcfg1_ep_dir2_shift (4)
+#define hwcfg1_ep_dir2_mask (0x3)
+#define hwcfg1_ep_dir3_shift (6)
+#define hwcfg1_ep_dir3_mask (0x3)
+#define hwcfg1_ep_dir4_shift (8)
+#define hwcfg1_ep_dir4_mask (0x3)
+#define hwcfg1_ep_dir5_shift (10)
+#define hwcfg1_ep_dir5_mask (0x3)
+#define hwcfg1_ep_dir6_shift (12)
+#define hwcfg1_ep_dir6_mask (0x3)
+#define hwcfg1_ep_dir7_shift (14)
+#define hwcfg1_ep_dir7_mask (0x3)
+#define hwcfg1_ep_dir8_shift (16)
+#define hwcfg1_ep_dir8_mask (0x3)
+#define hwcfg1_ep_dir9_shift (18)
+#define hwcfg1_ep_dir9_mask (0x3)
+#define hwcfg1_ep_dir10_shift (20)
+#define hwcfg1_ep_dir10_mask (0x3)
+#define hwcfg1_ep_dir11_shift (22)
+#define hwcfg1_ep_dir11_mask (0x3)
+#define hwcfg1_ep_dir12_shift (24)
+#define hwcfg1_ep_dir12_mask (0x3)
+#define hwcfg1_ep_dir13_shift (26)
+#define hwcfg1_ep_dir13_mask (0x3)
+#define hwcfg1_ep_dir14_shift (28)
+#define hwcfg1_ep_dir14_mask (0x3)
+#define hwcfg1_ep_dir15_shift (30)
+#define hwcfg1_ep_dir15_mask (0x3)
+
+/* union hwcfg2_data */
+#define hwcfg2_op_mode_shift (0)
+#define hwcfg2_op_mode_mask (0x7)
+#define DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG 0
+#define DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG 1
+#define DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG 2
+#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3
+#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4
+#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST 5
+#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6
+#define hwcfg2_architecture_shift (3)
+#define hwcfg2_architecture_mask (0x3)
+#define hwcfg2_point2point (1 << 5)
+#define hwcfg2_hs_phy_type_shift (6)
+#define hwcfg2_hs_phy_type_mask (0x3)
+#define DWC_HWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0
+#define DWC_HWCFG2_HS_PHY_TYPE_UTMI 1
+#define DWC_HWCFG2_HS_PHY_TYPE_ULPI 2
+#define DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI 3
+#define hwcfg2_fs_phy_type_shift (8)
+#define hwcfg2_fs_phy_type_mask (0x3)
+#define hwcfg2_num_dev_ep_shift (10)
+#define hwcfg2_num_dev_ep_mask (0xf)
+#define hwcfg2_num_host_chan_shift (14)
+#define hwcfg2_num_host_chan_mask (0xf)
+#define hwcfg2_perio_ep_supported (1 << 18)
+#define hwcfg2_dynamic_fifo (1 << 19)
+#define hwcfg2_multi_proc_int (1 << 20)
+#define hwcfg2_reserved21 (1 << 21)
+#define hwcfg2_nonperio_tx_q_depth_shift (22)
+#define hwcfg2_nonperio_tx_q_depth_mask (0x3)
+#define hwcfg2_host_perio_tx_q_depth_shift (24)
+#define hwcfg2_host_perio_tx_q_depth_mask (0x3)
+#define hwcfg2_dev_token_q_depth_shift (26)
+#define hwcfg2_dev_token_q_depth_mask (0x1f)
+#define hwcfg2_otg_enable_ic_usb (1 << 31)
+
+/* union hwcfg3_data */
+#define hwcfg3_xfer_size_cntr_width_shift (0)
+#define hwcfg3_xfer_size_cntr_width_mask (0xf)
+#define hwcfg3_packet_size_cntr_width_shift (4)
+#define hwcfg3_packet_size_cntr_width_mask (0x7)
+#define hwcfg3_otg_func (1 << 7)
+#define hwcfg3_i2c (1 << 8)
+#define hwcfg3_vendor_ctrl_if (1 << 9)
+#define hwcfg3_optional_features (1 << 10)
+#define hwcfg3_synch_reset_type (1 << 11)
+#define hwcfg3_adp_supp (1 << 12)
+#define hwcfg3_otg_enable_hsic (1 << 13)
+#define hwcfg3_bc_support (1 << 14)
+#define hwcfg3_otg_lpm_en (1 << 15)
+#define hwcfg3_dfifo_depth_shift (16)
+#define hwcfg3_dfifo_depth_mask (0xffff)
+
+/* union hwcfg4_data */
+#define hwcfg4_num_dev_perio_in_ep_shift (0)
+#define hwcfg4_num_dev_perio_in_ep_mask (0xf)
+#define hwcfg4_power_optimiz (1 << 4)
+#define hwcfg4_min_ahb_freq (1 << 5)
+#define hwcfg4_hiber (1 << 6)
+#define hwcfg4_xhiber (1 << 7)
+#define hwcfg4_reserved_shift (8)
+#define hwcfg4_reserved_mask (0x3f)
+#define hwcfg4_utmi_phy_data_width_shift (14)
+#define hwcfg4_utmi_phy_data_width_mask (0x3)
+#define hwcfg4_num_dev_mode_ctrl_ep_shift (16)
+#define hwcfg4_num_dev_mode_ctrl_ep_mask (0xf)
+#define hwcfg4_iddig_filt_en (1 << 20)
+#define hwcfg4_vbus_valid_filt_en (1 << 21)
+#define hwcfg4_a_valid_filt_en (1 << 22)
+#define hwcfg4_b_valid_filt_en (1 << 23)
+#define hwcfg4_session_end_filt_en (1 << 24)
+#define hwcfg4_ded_fifo_en (1 << 25)
+#define hwcfg4_num_in_eps_shift (26)
+#define hwcfg4_num_in_eps_mask (0xf)
+#define hwcfg4_desc_dma (1 << 30)
+#define hwcfg4_desc_dma_dyn (1 << 31)
+
+/* union glpmctl_data */
+#define glpmctl_lpm_cap_en (1 << 0)
+#define glpmctl_appl_resp (1 << 1)
+#define glpmctl_hird_shift (2)
+#define glpmctl_hird_mask (0xf)
+#define glpmctl_rem_wkup_en (1 << 6)
+#define glpmctl_en_utmi_sleep (1 << 7)
+#define glpmctl_hird_thres_shift (8)
+#define glpmctl_hird_thres_mask (0x1f)
+#define glpmctl_lpm_resp_shift (13)
+#define glpmctl_lpm_resp_mask (0x3)
+#define glpmctl_prt_sleep_sts (1 << 15)
+#define glpmctl_sleep_state_resumeok (1 << 16)
+#define glpmctl_lpm_chan_index_shift (17)
+#define glpmctl_lpm_chan_index_mask (0xf)
+#define glpmctl_retry_count_shift (21)
+#define glpmctl_retry_count_mask (0x7)
+#define glpmctl_send_lpm (1 << 24)
+#define glpmctl_retry_count_sts_shift (25)
+#define glpmctl_retry_count_sts_mask (0x7)
+#define glpmctl_reserved28_29_shift (28)
+#define glpmctl_reserved28_29_mask (0x3)
+#define glpmctl_hsic_connect (1 << 30)
+#define glpmctl_inv_sel_hsic (1 << 31)
+
+/* union adpctl_data */
+#define adpctl_prb_dschg_shift (0)
+#define adpctl_prb_dschg_mask (0x3)
+#define adpctl_prb_delta_shift (2)
+#define adpctl_prb_delta_mask (0x3)
+#define adpctl_prb_per_shift (4)
+#define adpctl_prb_per_mask (0x3)
+#define adpctl_rtim_shift (6)
+#define adpctl_rtim_mask (0x7ff)
+#define adpctl_enaprb (1 << 17)
+#define adpctl_enasns (1 << 18)
+#define adpctl_adpres (1 << 19)
+#define adpctl_adpen (1 << 20)
+#define adpctl_adp_prb_int (1 << 21)
+#define adpctl_adp_sns_int (1 << 22)
+#define adpctl_adp_tmout_int (1 << 23)
+#define adpctl_adp_prb_int_msk (1 << 24)
+#define adpctl_adp_sns_int_msk (1 << 25)
+#define adpctl_adp_tmout_int_msk (1 << 26)
+#define adpctl_ar_shift (27)
+#define adpctl_ar_mask (0x3)
+#define adpctl_reserved29_31_shift (29)
+#define adpctl_reserved29_31_mask (0x7)
+
+/* union dcfg_data */
+#define dcfg_devspd_shift (0)
+#define dcfg_devspd_mask (0x3)
+#define dcfg_nzstsouthshk (1 << 2)
+#define DWC_DCFG_SEND_STALL 1
+#define dcfg_ena32khzs (1 << 3)
+#define dcfg_devaddr_shift (4)
+#define dcfg_devaddr_mask (0x7f)
+#define dcfg_perfrint_shift (11)
+#define dcfg_perfrint_mask (0x3)
+#define DWC_DCFG_FRAME_INTERVAL_80 0
+#define DWC_DCFG_FRAME_INTERVAL_85 1
+#define DWC_DCFG_FRAME_INTERVAL_90 2
+#define DWC_DCFG_FRAME_INTERVAL_95 3
+#define dcfg_endevoutnak (1 << 13)
+#define dcfg_reserved14_17_shift (14)
+#define dcfg_reserved14_17_mask (0xf)
+#define dcfg_epmscnt_shift (18)
+#define dcfg_epmscnt_mask (0x1f)
+#define dcfg_descdma (1 << 23)
+#define dcfg_perschintvl_shift (24)
+#define dcfg_perschintvl_mask (0x3)
+#define dcfg_resvalid_shift (26)
+#define dcfg_resvalid_mask (0x3f)
+
+/* union dctl_data */
+#define dctl_rmtwkupsig (1 << 0)
+#define dctl_sftdiscon (1 << 1)
+#define dctl_gnpinnaksts (1 << 2)
+#define dctl_goutnaksts (1 << 3)
+#define dctl_tstctl_shift (4)
+#define dctl_tstctl_mask (0x7)
+#define dctl_sgnpinnak (1 << 7)
+#define dctl_cgnpinnak (1 << 8)
+#define dctl_sgoutnak (1 << 9)
+#define dctl_cgoutnak (1 << 10)
+#define dctl_pwronprgdone (1 << 11)
+#define dctl_reserved (1 << 12)
+#define dctl_gmc_shift (13)
+#define dctl_gmc_mask (0x3)
+#define dctl_ifrmnum (1 << 15)
+#define dctl_nakonbble (1 << 16)
+#define dctl_encontonbna (1 << 17)
+#define dctl_reserved18_31_shift (18)
+#define dctl_reserved18_31_mask (0x3fff)
+
+/* union dsts_data */
+#define dsts_suspsts (1 << 0)
+#define dsts_enumspd_shift (1)
+#define dsts_enumspd_mask (0x3)
+#define DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0
+#define DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1
+#define DWC_DSTS_ENUMSPD_LS_PHY_6MHZ           2
+#define DWC_DSTS_ENUMSPD_FS_PHY_48MHZ           3
+#define dsts_errticerr (1 << 3)
+#define dsts_reserved4_7_shift (4)
+#define dsts_reserved4_7_mask (0xf)
+#define dsts_soffn_shift (8)
+#define dsts_soffn_mask (0x3fff)
+#define dsts_reserved22_31_shift (22)
+#define dsts_reserved22_31_mask (0x3ff)
+
+/* union diepint_data */
+#define diepint_xfercompl (1 << 0)
+#define diepint_epdisabled (1 << 1)
+#define diepint_ahberr (1 << 2)
+#define diepint_timeout (1 << 3)
+#define diepint_intktxfemp (1 << 4)
+#define diepint_intknepmis (1 << 5)
+#define diepint_inepnakeff (1 << 6)
+#define diepint_emptyintr (1 << 7)
+#define diepint_txfifoundrn (1 << 8)
+#define diepint_bna (1 << 9)
+#define diepint_reserved10_12_shift (10)
+#define diepint_reserved10_12_mask (0x7)
+#define diepint_nak (1 << 13)
+#define diepint_reserved14_31_shift (14)
+#define diepint_reserved14_31_mask (0x3ffff)
+
+/* union doepint_data */
+#define doepint_xfercompl (1 << 0)
+#define doepint_epdisabled (1 << 1)
+#define doepint_ahberr (1 << 2)
+#define doepint_setup (1 << 3)
+#define doepint_outtknepdis (1 << 4)
+#define doepint_stsphsercvd (1 << 5)
+#define doepint_back2backsetup (1 << 6)
+#define doepint_reserved7 (1 << 7)
+#define doepint_outpkterr (1 << 8)
+#define doepint_bna (1 << 9)
+#define doepint_reserved10 (1 << 10)
+#define doepint_pktdrpsts (1 << 11)
+#define doepint_babble (1 << 12)
+#define doepint_nak (1 << 13)
+#define doepint_nyet (1 << 14)
+#define doepint_sr (1 << 15)
+#define doepint_reserved16_31_shift (16)
+#define doepint_reserved16_31_mask (0xffff)
+
+/* union daint_data */
+#define daint_in_shift (0)
+#define daint_in_mask (0xffff)
+#define daint_out_shift (16)
+#define daint_out_mask (0xffff)
+#define daint_b_inep0 (1 << 0)
+#define daint_b_inep1 (1 << 1)
+#define daint_b_inep2 (1 << 2)
+#define daint_b_inep3 (1 << 3)
+#define daint_b_inep4 (1 << 4)
+#define daint_b_inep5 (1 << 5)
+#define daint_b_inep6 (1 << 6)
+#define daint_b_inep7 (1 << 7)
+#define daint_b_inep8 (1 << 8)
+#define daint_b_inep9 (1 << 9)
+#define daint_b_inep10 (1 << 10)
+#define daint_b_inep11 (1 << 11)
+#define daint_b_inep12 (1 << 12)
+#define daint_b_inep13 (1 << 13)
+#define daint_b_inep14 (1 << 14)
+#define daint_b_inep15 (1 << 15)
+#define daint_b_outep0 (1 << 16)
+#define daint_b_outep1 (1 << 17)
+#define daint_b_outep2 (1 << 18)
+#define daint_b_outep3 (1 << 19)
+#define daint_b_outep4 (1 << 20)
+#define daint_b_outep5 (1 << 21)
+#define daint_b_outep6 (1 << 22)
+#define daint_b_outep7 (1 << 23)
+#define daint_b_outep8 (1 << 24)
+#define daint_b_outep9 (1 << 25)
+#define daint_b_outep10 (1 << 26)
+#define daint_b_outep11 (1 << 27)
+#define daint_b_outep12 (1 << 28)
+#define daint_b_outep13 (1 << 29)
+#define daint_b_outep14 (1 << 30)
+#define daint_b_outep15 (1 << 31)
+
+/* union dtknq1_data */
+#define dtknq1_intknwptr_shift (0)
+#define dtknq1_intknwptr_mask (0x1f)
+#define dtknq1_reserved05_06_shift (5)
+#define dtknq1_reserved05_06_mask (0x3)
+#define dtknq1_wrap_bit (1 << 7)
+#define dtknq1_epnums0_5_shift (8)
+#define dtknq1_epnums0_5_mask (0xffffff)
+
+/* union dthrctl_data */
+#define dthrctl_non_iso_thr_en (1 << 0)
+#define dthrctl_iso_thr_en (1 << 1)
+#define dthrctl_tx_thr_len_shift (2)
+#define dthrctl_tx_thr_len_mask (0x1ff)
+#define dthrctl_ahb_thr_ratio_shift (11)
+#define dthrctl_ahb_thr_ratio_mask (0x3)
+#define dthrctl_reserved13_15_shift (13)
+#define dthrctl_reserved13_15_mask (0x7)
+#define dthrctl_rx_thr_en (1 << 16)
+#define dthrctl_rx_thr_len_shift (17)
+#define dthrctl_rx_thr_len_mask (0x1ff)
+#define dthrctl_reserved26 (1 << 26)
+#define dthrctl_arbprken (1 << 27)
+#define dthrctl_reserved28_31_shift (28)
+#define dthrctl_reserved28_31_mask (0xf)
+
+/* union depctl_data */
+#define depctl_mps_shift (0)
+#define depctl_mps_mask (0x7ff)
+#define DWC_DEP0CTL_MPS_64     0
+#define DWC_DEP0CTL_MPS_32     1
+#define DWC_DEP0CTL_MPS_16     2
+#define DWC_DEP0CTL_MPS_8     3
+#define depctl_nextep_shift (11)
+#define depctl_nextep_mask (0xf)
+#define depctl_usbactep (1 << 15)
+#define depctl_dpid (1 << 16)
+#define depctl_naksts (1 << 17)
+#define depctl_eptype_shift (18)
+#define depctl_eptype_mask (0x3)
+#define depctl_snp (1 << 20)
+#define depctl_stall (1 << 21)
+#define depctl_txfnum_shift (22)
+#define depctl_txfnum_mask (0xf)
+#define depctl_cnak (1 << 26)
+#define depctl_snak (1 << 27)
+#define depctl_setd0pid (1 << 28)
+#define depctl_setd1pid (1 << 29)
+#define depctl_epdis (1 << 30)
+#define depctl_epena (1 << 31)
+
+/* union deptsiz_data */
+#define deptsiz_xfersize_shift (0)
+#define deptsiz_xfersize_mask (0x7ffff)
+#define MAX_PKT_CNT 1023
+#define deptsiz_pktcnt_shift (19)
+#define deptsiz_pktcnt_mask (0x3ff)
+#define deptsiz_mc_shift (29)
+#define deptsiz_mc_mask (0x3)
+#define deptsiz_reserved (1 << 31)
+
+/* union deptsiz0_data */
+#define deptsiz0_xfersize_shift (0)
+#define deptsiz0_xfersize_mask (0x7f)
+#define deptsiz0_reserved7_18_shift (7)
+#define deptsiz0_reserved7_18_mask (0xfff)
+#define deptsiz0_pktcnt_shift (19)
+#define deptsiz0_pktcnt_mask (0x3)
+#define deptsiz0_reserved21_28_shift (21)
+#define deptsiz0_reserved21_28_mask (0xff)
+#define deptsiz0_supcnt_shift (29)
+#define deptsiz0_supcnt_mask (0x3)
+#define deptsiz0_reserved31 (1 << 31)
+#define BS_HOST_READY    0x0
+#define BS_DMA_BUSY        0x1
+#define BS_DMA_DONE        0x2
+#define BS_HOST_BUSY    0x3
+#define RTS_SUCCESS        0x0
+#define RTS_BUFFLUSH    0x1
+#define RTS_RESERVED    0x2
+#define RTS_BUFERR        0x3
+
+/* union dev_dma_desc_sts */
+#define dev_dma_desc_sts_bytes_shift (0)
+#define dev_dma_desc_sts_bytes_mask (0xffff)
+#define dev_dma_desc_sts_nak (1 << 16)
+#define dev_dma_desc_sts_reserved17_22_shift (17)
+#define dev_dma_desc_sts_reserved17_22_mask (0x3f)
+#define dev_dma_desc_sts_mtrf (1 << 23)
+#define dev_dma_desc_sts_sr (1 << 24)
+#define dev_dma_desc_sts_ioc (1 << 25)
+#define dev_dma_desc_sts_sp (1 << 26)
+#define dev_dma_desc_sts_l (1 << 27)
+#define dev_dma_desc_sts_sts_shift (28)
+#define dev_dma_desc_sts_sts_mask (0x3)
+#define dev_dma_desc_sts_bs_shift (30)
+#define dev_dma_desc_sts_bs_mask (0x3)
+#define dev_dma_desc_sts_b_rxbytes_shift (0)
+#define dev_dma_desc_sts_b_rxbytes_mask (0x7ff)
+#define dev_dma_desc_sts_b_reserved11 (1 << 11)
+#define dev_dma_desc_sts_b_framenum_shift (12)
+#define dev_dma_desc_sts_b_framenum_mask (0x7ff)
+#define dev_dma_desc_sts_b_pid_shift (23)
+#define dev_dma_desc_sts_b_pid_mask (0x3)
+#define dev_dma_desc_sts_b_ioc (1 << 25)
+#define dev_dma_desc_sts_b_sp (1 << 26)
+#define dev_dma_desc_sts_b_l (1 << 27)
+#define dev_dma_desc_sts_b_rxsts_shift (28)
+#define dev_dma_desc_sts_b_rxsts_mask (0x3)
+#define dev_dma_desc_sts_b_bs_shift (30)
+#define dev_dma_desc_sts_b_bs_mask (0x3)
+#define dev_dma_desc_sts_b_b_txbytes_shift (0)
+#define dev_dma_desc_sts_b_b_txbytes_mask (0xfff)
+#define dev_dma_desc_sts_b_b_framenum_shift (12)
+#define dev_dma_desc_sts_b_b_framenum_mask (0x7ff)
+#define dev_dma_desc_sts_b_b_pid_shift (23)
+#define dev_dma_desc_sts_b_b_pid_mask (0x3)
+#define dev_dma_desc_sts_b_b_ioc (1 << 25)
+#define dev_dma_desc_sts_b_b_sp (1 << 26)
+#define dev_dma_desc_sts_b_b_l (1 << 27)
+#define dev_dma_desc_sts_b_b_txsts_shift (28)
+#define dev_dma_desc_sts_b_b_txsts_mask (0x3)
+#define dev_dma_desc_sts_b_b_bs_shift (30)
+#define dev_dma_desc_sts_b_b_bs_mask (0x3)
+#define DWC_DEV_GLOBAL_REG_OFFSET 0x800
+#define DWC_DEV_IN_EP_REG_OFFSET 0x900
+#define DWC_EP_REG_OFFSET 0x20
+#define DWC_DEV_OUT_EP_REG_OFFSET 0xB00
+
+/* union hcfg_data */
+#define hcfg_fslspclksel_shift (0)
+#define hcfg_fslspclksel_mask (0x3)
+#define DWC_HCFG_30_60_MHZ 0
+#define DWC_HCFG_48_MHZ       1
+#define DWC_HCFG_6_MHZ       2
+#define hcfg_fslssupp (1 << 2)
+#define hcfg_reserved3_6_shift (3)
+#define hcfg_reserved3_6_mask (0xf)
+#define hcfg_ena32khzs (1 << 7)
+#define hcfg_resvalid_shift (8)
+#define hcfg_resvalid_mask (0xff)
+#define hcfg_reserved16_22_shift (16)
+#define hcfg_reserved16_22_mask (0x7f)
+#define hcfg_descdma (1 << 23)
+#define hcfg_frlisten_shift (24)
+#define hcfg_frlisten_mask (0x3)
+#define hcfg_perschedena (1 << 26)
+#define hcfg_reserved27_30_shift (27)
+#define hcfg_reserved27_30_mask (0xf)
+#define hcfg_modechtimen (1 << 31)
+
+/* union hfir_data */
+#define hfir_frint_shift (0)
+#define hfir_frint_mask (0xffff)
+#define hfir_hfirrldctrl (1 << 16)
+#define hfir_reserved_shift (17)
+#define hfir_reserved_mask (0x7fff)
+
+/* union hfnum_data */
+#define hfnum_frnum_shift (0)
+#define hfnum_frnum_mask (0xffff)
+#define DWC_HFNUM_MAX_FRNUM 0x3FFF
+#define hfnum_frrem_shift (16)
+#define hfnum_frrem_mask (0xffff)
+
+/* union hptxsts_data */
+#define hptxsts_ptxfspcavail_shift (0)
+#define hptxsts_ptxfspcavail_mask (0xffff)
+#define hptxsts_ptxqspcavail_shift (16)
+#define hptxsts_ptxqspcavail_mask (0xff)
+#define hptxsts_ptxqtop_terminate (1 << 24)
+#define hptxsts_ptxqtop_token_shift (25)
+#define hptxsts_ptxqtop_token_mask (0x3)
+#define hptxsts_ptxqtop_chnum_shift (27)
+#define hptxsts_ptxqtop_chnum_mask (0xf)
+#define hptxsts_ptxqtop_odd (1 << 31)
+
+/* union hprt0_data */
+#define hprt0_prtconnsts (1 << 0)
+#define hprt0_prtconndet (1 << 1)
+#define hprt0_prtena (1 << 2)
+#define hprt0_prtenchng (1 << 3)
+#define hprt0_prtovrcurract (1 << 4)
+#define hprt0_prtovrcurrchng (1 << 5)
+#define hprt0_prtres (1 << 6)
+#define hprt0_prtsusp (1 << 7)
+#define hprt0_prtrst (1 << 8)
+#define hprt0_reserved9 (1 << 9)
+#define hprt0_prtlnsts_shift (10)
+#define hprt0_prtlnsts_mask (0x3)
+#define hprt0_prtpwr (1 << 12)
+#define hprt0_prttstctl_shift (13)
+#define hprt0_prttstctl_mask (0xf)
+#define hprt0_prtspd_shift (17)
+#define hprt0_prtspd_mask (0x3)
+#define DWC_HPRT0_PRTSPD_HIGH_SPEED 0
+#define DWC_HPRT0_PRTSPD_FULL_SPEED 1
+#define DWC_HPRT0_PRTSPD_LOW_SPEED    2
+#define hprt0_reserved19_31_shift (19)
+#define hprt0_reserved19_31_mask (0x1fff)
+
+/* union haint_data */
+#define haint_ch0 (1 << 0)
+#define haint_ch1 (1 << 1)
+#define haint_ch2 (1 << 2)
+#define haint_ch3 (1 << 3)
+#define haint_ch4 (1 << 4)
+#define haint_ch5 (1 << 5)
+#define haint_ch6 (1 << 6)
+#define haint_ch7 (1 << 7)
+#define haint_ch8 (1 << 8)
+#define haint_ch9 (1 << 9)
+#define haint_ch10 (1 << 10)
+#define haint_ch11 (1 << 11)
+#define haint_ch12 (1 << 12)
+#define haint_ch13 (1 << 13)
+#define haint_ch14 (1 << 14)
+#define haint_ch15 (1 << 15)
+#define haint_reserved_shift (16)
+#define haint_reserved_mask (0xffff)
+#define haint_b_chint_shift (0)
+#define haint_b_chint_mask (0xffff)
+#define haint_b_reserved_shift (16)
+#define haint_b_reserved_mask (0xffff)
+
+/* union haintmsk_data */
+#define haintmsk_ch0 (1 << 0)
+#define haintmsk_ch1 (1 << 1)
+#define haintmsk_ch2 (1 << 2)
+#define haintmsk_ch3 (1 << 3)
+#define haintmsk_ch4 (1 << 4)
+#define haintmsk_ch5 (1 << 5)
+#define haintmsk_ch6 (1 << 6)
+#define haintmsk_ch7 (1 << 7)
+#define haintmsk_ch8 (1 << 8)
+#define haintmsk_ch9 (1 << 9)
+#define haintmsk_ch10 (1 << 10)
+#define haintmsk_ch11 (1 << 11)
+#define haintmsk_ch12 (1 << 12)
+#define haintmsk_ch13 (1 << 13)
+#define haintmsk_ch14 (1 << 14)
+#define haintmsk_ch15 (1 << 15)
+#define haintmsk_reserved_shift (16)
+#define haintmsk_reserved_mask (0xffff)
+#define haintmsk_b_chint_shift (0)
+#define haintmsk_b_chint_mask (0xffff)
+#define haintmsk_b_reserved_shift (16)
+#define haintmsk_b_reserved_mask (0xffff)
+
+/* union hcchar_data */
+#define hcchar_mps_shift (0)
+#define hcchar_mps_mask (0x7ff)
+#define hcchar_epnum_shift (11)
+#define hcchar_epnum_mask (0xf)
+#define hcchar_epdir (1 << 15)
+#define hcchar_reserved (1 << 16)
+#define hcchar_lspddev (1 << 17)
+#define hcchar_eptype_shift (18)
+#define hcchar_eptype_mask (0x3)
+#define hcchar_multicnt_shift (20)
+#define hcchar_multicnt_mask (0x3)
+#define hcchar_devaddr_shift (22)
+#define hcchar_devaddr_mask (0x7f)
+#define hcchar_oddfrm (1 << 29)
+#define hcchar_chdis (1 << 30)
+#define hcchar_chen (1 << 31)
+
+/* union hcsplt_data */
+#define hcsplt_prtaddr_shift (0)
+#define hcsplt_prtaddr_mask (0x7f)
+#define hcsplt_hubaddr_shift (7)
+#define hcsplt_hubaddr_mask (0x7f)
+#define hcsplt_xactpos_shift (14)
+#define hcsplt_xactpos_mask (0x3)
+#define DWC_HCSPLIT_XACTPOS_MID 0
+#define DWC_HCSPLIT_XACTPOS_END 1
+#define DWC_HCSPLIT_XACTPOS_BEGIN 2
+#define DWC_HCSPLIT_XACTPOS_ALL 3
+#define hcsplt_compsplt (1 << 16)
+#define hcsplt_reserved_shift (17)
+#define hcsplt_reserved_mask (0x3fff)
+#define hcsplt_spltena (1 << 31)
+
+/* union hcint_data */
+#define hcint_xfercomp (1 << 0)
+#define hcint_chhltd (1 << 1)
+#define hcint_ahberr (1 << 2)
+#define hcint_stall (1 << 3)
+#define hcint_nak (1 << 4)
+#define hcint_ack (1 << 5)
+#define hcint_nyet (1 << 6)
+#define hcint_xacterr (1 << 7)
+#define hcint_bblerr (1 << 8)
+#define hcint_frmovrun (1 << 9)
+#define hcint_datatglerr (1 << 10)
+#define hcint_bna (1 << 11)
+#define hcint_xcs_xact (1 << 12)
+#define hcint_frm_list_roll (1 << 13)
+#define hcint_reserved14_31_shift (14)
+#define hcint_reserved14_31_mask (0x3ffff)
+
+/* union hcintmsk_data */
+#define hcintmsk_xfercompl (1 << 0)
+#define hcintmsk_chhltd (1 << 1)
+#define hcintmsk_ahberr (1 << 2)
+#define hcintmsk_stall (1 << 3)
+#define hcintmsk_nak (1 << 4)
+#define hcintmsk_ack (1 << 5)
+#define hcintmsk_nyet (1 << 6)
+#define hcintmsk_xacterr (1 << 7)
+#define hcintmsk_bblerr (1 << 8)
+#define hcintmsk_frmovrun (1 << 9)
+#define hcintmsk_datatglerr (1 << 10)
+#define hcintmsk_bna (1 << 11)
+#define hcintmsk_xcs_xact (1 << 12)
+#define hcintmsk_frm_list_roll (1 << 13)
+#define hcintmsk_reserved14_31_shift (14)
+#define hcintmsk_reserved14_31_mask (0x3ffff)
+
+/* union hctsiz_data */
+#define hctsiz_xfersize_shift (0)
+#define hctsiz_xfersize_mask (0x7ffff)
+#define hctsiz_pktcnt_shift (19)
+#define hctsiz_pktcnt_mask (0x3ff)
+#define hctsiz_pid_shift (29)
+#define hctsiz_pid_mask (0x3)
+#define DWC_HCTSIZ_DATA0 0
+#define DWC_HCTSIZ_DATA1 2
+#define DWC_HCTSIZ_DATA2 1
+#define DWC_HCTSIZ_MDATA 3
+#define DWC_HCTSIZ_SETUP 3
+#define hctsiz_dopng (1 << 31)
+#define hctsiz_b_schinfo_shift (0)
+#define hctsiz_b_schinfo_mask (0xff)
+#define hctsiz_b_ntd_shift (8)
+#define hctsiz_b_ntd_mask (0xff)
+#define hctsiz_b_reserved16_28_shift (16)
+#define hctsiz_b_reserved16_28_mask (0x1fff)
+#define hctsiz_b_pid_shift (29)
+#define hctsiz_b_pid_mask (0x3)
+#define hctsiz_b_dopng (1 << 31)
+
+/* union hcdma_data */
+#define hcdma_reserved0_2_shift (0)
+#define hcdma_reserved0_2_mask (0x7)
+#define hcdma_ctd_shift (3)
+#define hcdma_ctd_mask (0xff)
+#define hcdma_dma_addr_shift (11)
+#define hcdma_dma_addr_mask (0x1fffff)
+
+/* union host_dma_desc_sts */
+#define host_dma_desc_sts_n_bytes_shift (0)
+#define host_dma_desc_sts_n_bytes_mask (0x1ffff)
+#define host_dma_desc_sts_qtd_offset_shift (17)
+#define host_dma_desc_sts_qtd_offset_mask (0x3f)
+#define host_dma_desc_sts_a_qtd (1 << 23)
+#define host_dma_desc_sts_sup (1 << 24)
+#define host_dma_desc_sts_ioc (1 << 25)
+#define host_dma_desc_sts_eol (1 << 26)
+#define host_dma_desc_sts_reserved27 (1 << 27)
+#define host_dma_desc_sts_sts_shift (28)
+#define host_dma_desc_sts_sts_mask (0x3)
+#define DMA_DESC_STS_PKTERR    1
+#define host_dma_desc_sts_reserved30 (1 << 30)
+#define host_dma_desc_sts_a (1 << 31)
+#define host_dma_desc_sts_b_n_bytes_shift (0)
+#define host_dma_desc_sts_b_n_bytes_mask (0xfff)
+#define host_dma_desc_sts_b_reserved12_24_shift (12)
+#define host_dma_desc_sts_b_reserved12_24_mask (0x1fff)
+#define host_dma_desc_sts_b_ioc (1 << 25)
+#define host_dma_desc_sts_b_reserved26_27_shift (26)
+#define host_dma_desc_sts_b_reserved26_27_mask (0x3)
+#define host_dma_desc_sts_b_sts_shift (28)
+#define host_dma_desc_sts_b_sts_mask (0x3)
+#define host_dma_desc_sts_b_reserved30 (1 << 30)
+#define host_dma_desc_sts_b_a (1 << 31)
+#define    MAX_DMA_DESC_SIZE        131071
+#define MAX_DMA_DESC_NUM_GENERIC    64
+#define MAX_DMA_DESC_NUM_HS_ISOC    256
+#define MAX_FRLIST_EN_NUM        64
+#define DWC_OTG_HOST_GLOBAL_REG_OFFSET 0x400
+#define DWC_OTG_HOST_PORT_REGS_OFFSET 0x440
+#define DWC_OTG_HOST_CHAN_REGS_OFFSET 0x500
+#define DWC_OTG_CHAN_REGS_OFFSET 0x20
+
+/* union pcgcctl_data */
+#define pcgcctl_stoppclk (1 << 0)
+#define pcgcctl_gatehclk (1 << 1)
+#define pcgcctl_pwrclmp (1 << 2)
+#define pcgcctl_rstpdwnmodule (1 << 3)
+#define pcgcctl_reserved (1 << 4)
+#define pcgcctl_enbl_sleep_gating (1 << 5)
+#define pcgcctl_phy_in_sleep (1 << 6)
+#define pcgcctl_deep_sleep (1 << 7)
+#define pcgcctl_resetaftsusp (1 << 8)
+#define pcgcctl_restoremode (1 << 9)
+#define pcgcctl_enbl_extnd_hiber (1 << 10)
+#define pcgcctl_extnd_hiber_pwrclmp (1 << 11)
+#define pcgcctl_extnd_hiber_switch (1 << 12)
+#define pcgcctl_ess_reg_restored (1 << 13)
+#define pcgcctl_prt_clk_sel_shift (14)
+#define pcgcctl_prt_clk_sel_mask (0x3)
+#define pcgcctl_port_power (1 << 16)
+#define pcgcctl_max_xcvrselect_shift (17)
+#define pcgcctl_max_xcvrselect_mask (0x3)
+#define pcgcctl_max_termsel (1 << 19)
+#define pcgcctl_mac_dev_addr_shift (20)
+#define pcgcctl_mac_dev_addr_mask (0x7f)
+#define pcgcctl_p2hd_dev_enum_spd_shift (27)
+#define pcgcctl_p2hd_dev_enum_spd_mask (0x3)
+#define pcgcctl_p2hd_prt_spd_shift (29)
+#define pcgcctl_p2hd_prt_spd_mask (0x3)
+#define pcgcctl_if_dev_mode (1 << 31)
+
+/* union gdfifocfg_data */
+#define gdfifocfg_gdfifocfg_shift (0)
+#define gdfifocfg_gdfifocfg_mask (0xffff)
+#define gdfifocfg_epinfobase_shift (16)
+#define gdfifocfg_epinfobase_mask (0xffff)
+
+/* union gpwrdn_data */
+#define gpwrdn_pmuintsel (1 << 0)
+#define gpwrdn_pmuactv (1 << 1)
+#define gpwrdn_restore (1 << 2)
+#define gpwrdn_pwrdnclmp (1 << 3)
+#define gpwrdn_pwrdnrstn (1 << 4)
+#define gpwrdn_pwrdnswtch (1 << 5)
+#define gpwrdn_dis_vbus (1 << 6)
+#define gpwrdn_lnstschng (1 << 7)
+#define gpwrdn_lnstchng_msk (1 << 8)
+#define gpwrdn_rst_det (1 << 9)
+#define gpwrdn_rst_det_msk (1 << 10)
+#define gpwrdn_disconn_det (1 << 11)
+#define gpwrdn_disconn_det_msk (1 << 12)
+#define gpwrdn_connect_det (1 << 13)
+#define gpwrdn_connect_det_msk (1 << 14)
+#define gpwrdn_srp_det (1 << 15)
+#define gpwrdn_srp_det_msk (1 << 16)
+#define gpwrdn_sts_chngint (1 << 17)
+#define gpwrdn_sts_chngint_msk (1 << 18)
+#define gpwrdn_linestate_shift (19)
+#define gpwrdn_linestate_mask (0x3)
+#define gpwrdn_idsts (1 << 21)
+#define gpwrdn_bsessvld (1 << 22)
+#define gpwrdn_adp_int (1 << 23)
+#define gpwrdn_mult_val_id_bc_shift (24)
+#define gpwrdn_mult_val_id_bc_mask (0x1f)
+#define gpwrdn_reserved29_31_shift (29)
+#define gpwrdn_reserved29_31_mask (0x7)
+
+#endif /* BCM2835_USB_REGS_H */
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 85fc81bf43..3d97b5d489 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -1201,7 +1201,7 @@  static void usb_net_handle_dataout(USBNetState *s, USBPacket *p)
s->out_ptr += sz;

if (!is_rndis(s)) {
-        if (p->iov.size < 64) {
+        /*if (p->iov.size < 64)*/ {
qemu_send_packet(qemu_get_queue(s->nic), s->out_buf, s->out_ptr);
s->out_ptr = 0;
}
diff --git a/include/hw/arm/bcm2835.h b/include/hw/arm/bcm2835.h
new file mode 100644
index 0000000000..9ea8ddd572
--- /dev/null
+++ b/include/hw/arm/bcm2835.h
@@ -0,0 +1,37 @@ 
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * Upstreaming code cleanup [including bcm2835_*] (c) 2013 Jan Petrous
+ *
+ * Rasperry Pi 2 emulation and refactoring Copyright (c) 2015, Microsoft
+ * Written by Andrew Baumann
+ *
+ * Moved to Qemu root from Old Rasp
+ * John Bradley April 2017
+ * 
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#ifndef BCM2835_H
+#define BCM2835_H
+
+#include "hw/arm/arm.h"
+#include "hw/arm/bcm2835_peripherals.h"
+#include "hw/intc/bcm2835_control.h"
+
+#define TYPE_BCM2835 "bcm2835"
+#define BCM2835(obj) OBJECT_CHECK(BCM2835State, (obj), TYPE_BCM2835)
+
+#define BCM2835_NCPUS 1
+
+typedef struct BCM2835State {
+    /*< private >*/
+    DeviceState parent_obj;
+    /*< public >*/
+
+    uint32_t enabled_cpus;
+    ARMCPU cpus[BCM2835_NCPUS];
+ 
+    BCM2835PeripheralState peripherals;
+} BCM2835State;
+
+#endif /* BCM2835_H */
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
index 122b286de7..ef28b51066 100644
--- a/include/hw/arm/bcm2835_peripherals.h
+++ b/include/hw/arm/bcm2835_peripherals.h
@@ -18,12 +18,17 @@ 
#include "hw/display/bcm2835_fb.h"
#include "hw/dma/bcm2835_dma.h"
#include "hw/intc/bcm2835_ic.h"
+#include "hw/misc/bcm2835_mphi.h"
+#include "hw/misc/bcm2835_power.h"
#include "hw/misc/bcm2835_property.h"
#include "hw/misc/bcm2835_rng.h"
#include "hw/misc/bcm2835_mbox.h"
#include "hw/sd/sdhci.h"
#include "hw/sd/bcm2835_sdhost.h"
#include "hw/gpio/bcm2835_gpio.h"
+#include "hw/timer/bcm2835_st.h"
+#include "hw/timer/bcm2835_timer.h"
+#include "hw/usb/bcm2835_usb.h"

#define TYPE_BCM2835_PERIPHERALS "bcm2835-peripherals"
#define BCM2835_PERIPHERALS(obj) \
@@ -43,10 +48,15 @@  typedef struct BCM2835PeripheralState {
BCM2835FBState fb;
BCM2835DMAState dma;
BCM2835ICState ic;
+    BCM2835MphiState mphi;
+    BCM2835PowerState power;
BCM2835PropertyState property;
BCM2835RngState rng;
BCM2835MboxState mboxes;
SDHCIState sdhci;
+    BCM2835StState st;
+    BCM2835TimerState timer;
+    BCM2835UsbState usb;
BCM2835SDHostState sdhost;
BCM2835GpioState gpio;
} BCM2835PeripheralState;
diff --git a/include/hw/gpio/bcm2835_gpio.h b/include/hw/gpio/bcm2835_gpio.h
index 9f8e0c720c..73cfda6a6b 100644
--- a/include/hw/gpio/bcm2835_gpio.h
+++ b/include/hw/gpio/bcm2835_gpio.h
@@ -16,6 +16,8 @@ 

#include "hw/sd/sd.h"

+#include "qemu/PanelEmu.h"
+
typedef struct BCM2835GpioState {
SysBusDevice parent_obj;

@@ -30,6 +32,9 @@  typedef struct BCM2835GpioState {
uint32_t lev0, lev1;
uint8_t sd_fsel;
qemu_irq out[54];
+
+    panel_connection_t panel;
+
} BCM2835GpioState;

#define TYPE_BCM2835_GPIO "bcm2835_gpio"
diff --git a/include/hw/intc/bcm2835_control.h b/include/hw/intc/bcm2835_control.h
new file mode 100644
index 0000000000..6d09b03077
--- /dev/null
+++ b/include/hw/intc/bcm2835_control.h
@@ -0,0 +1,53 @@ 
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * Upstreaming code cleanup [including bcm2835_*] (c) 2013 Jan Petrous
+ *
+ * Rasperry Pi 2 emulation and refactoring Copyright (c) 2015, Microsoft
+ * Written by Andrew Baumann
+ * 
+ * Merge into QEMU root fork John Bradley April 2017
+ * 
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#ifndef BCM2835_CONTROL_H
+#define BCM2835_CONTROL_H
+
+#include "hw/sysbus.h"
+
+/* 4 mailboxes per core, for 16 total */
+#define BCM2835_NCORES 1
+#define BCM2835_MBPERCORE 4
+
+#define TYPE_BCM2835_CONTROL "bcm2836-control"
+#define BCM2835_CONTROL(obj) \
+    OBJECT_CHECK(BCM2835ControlState, (obj), TYPE_BCM2835_CONTROL)
+
+typedef struct BCM2835ControlState {
+    /*< private >*/
+    SysBusDevice busdev;
+    /*< public >*/
+    MemoryRegion iomem;
+
+    /* mailbox state */
+    uint32_t mailboxes[BCM2835_NCORES * BCM2835_MBPERCORE];
+
+    /* interrupt routing/control registers */
+    uint8_t route_gpu_irq, route_gpu_fiq;
+    uint32_t timercontrol[BCM2835_NCORES];
+    uint32_t mailboxcontrol[BCM2835_NCORES];
+
+    /* interrupt status regs (derived from input pins; not visible to user) */
+    bool gpu_irq, gpu_fiq;
+    uint8_t timerirqs[BCM2835_NCORES];
+
+    /* interrupt source registers, post-routing (also input-derived; visible) */
+    uint32_t irqsrc[BCM2835_NCORES];
+    uint32_t fiqsrc[BCM2835_NCORES];
+
+    /* outputs to CPU cores */
+    qemu_irq irq[BCM2835_NCORES];
+    qemu_irq fiq[BCM2835_NCORES];
+} BCM2835ControlState;
+
+#endif
diff --git a/include/hw/intc/bcm2836_control.h b/include/hw/intc/bcm2836_control.h
index 613f3c4186..768b4d4930 100644
--- a/include/hw/intc/bcm2836_control.h
+++ b/include/hw/intc/bcm2836_control.h
@@ -5,6 +5,8 @@ 
* Rasperry Pi 2 emulation and refactoring Copyright (c) 2015, Microsoft
* Written by Andrew Baumann
*
+ * Merge into QEMU root fork John Bradley April 2017
+ *
* This code is licensed under the GNU GPLv2 and later.
*/

diff --git a/include/hw/misc/bcm2835_mphi.h b/include/hw/misc/bcm2835_mphi.h
new file mode 100644
index 0000000000..72824a9ff5
--- /dev/null
+++ b/include/hw/misc/bcm2835_mphi.h
@@ -0,0 +1,28 @@ 
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#ifndef BCM2835_MPHI_H
+#define BCM2835_MPHI_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_BCM2835_MPHI "bcm2835-mphi"
+#define BCM2835_MPHI(obj) \
+        OBJECT_CHECK(BCM2835MphiState, (obj), TYPE_BCM2835_MPHI)
+
+typedef struct {
+    SysBusDevice busdev;
+    MemoryRegion iomem;
+
+    uint32_t mphi_base;
+    uint32_t mphi_ctrl;
+    uint32_t mphi_outdda;
+    uint32_t mphi_outddb;
+    uint32_t mphi_intstat;
+
+    qemu_irq irq;
+} BCM2835MphiState;
+
+#endif
diff --git a/include/hw/misc/bcm2835_power.h b/include/hw/misc/bcm2835_power.h
new file mode 100644
index 0000000000..a19e7f4930
--- /dev/null
+++ b/include/hw/misc/bcm2835_power.h
@@ -0,0 +1,22 @@ 
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#ifndef BCM2835_POWER_H
+#define BCM2835_POWER_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_BCM2835_POWER "bcm2835-power"
+#define BCM2835_POWER(obj) \
+        OBJECT_CHECK(BCM2835PowerState, (obj), TYPE_BCM2835_POWER)
+
+typedef struct {
+    SysBusDevice busdev;
+    MemoryRegion iomem;
+    int pending;
+    qemu_irq mbox_irq;
+} BCM2835PowerState;
+
+#endif
diff --git a/include/hw/timer/bcm2835_st.h b/include/hw/timer/bcm2835_st.h
new file mode 100644
index 0000000000..11dc312711
--- /dev/null
+++ b/include/hw/timer/bcm2835_st.h
@@ -0,0 +1,25 @@ 
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#ifndef BCM2835_ST_H
+#define BCM2835_ST_H
+
+#include "hw/sysbus.h"
+#include "qemu/timer.h"
+
+#define TYPE_BCM2835_ST "bcm2835_st"
+#define BCM2835_ST(obj) OBJECT_CHECK(BCM2835StState, (obj), TYPE_BCM2835_ST)
+
+typedef struct BCM2835StState {
+    SysBusDevice busdev;
+    MemoryRegion iomem;
+    QEMUTimer *timer;
+    uint32_t compare[4];
+    uint32_t match;
+    uint32_t next;
+    qemu_irq irq[4];
+} BCM2835StState;
+
+#endif
diff --git a/include/hw/timer/bcm2835_timer.h b/include/hw/timer/bcm2835_timer.h
new file mode 100644
index 0000000000..e2a0a76f01
--- /dev/null
+++ b/include/hw/timer/bcm2835_timer.h
@@ -0,0 +1,32 @@ 
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#ifndef BCM2835_TIMER_H
+#define BCM2835_TIMER_H
+
+#include "hw/sysbus.h"
+#include "hw/ptimer.h"
+
+#define TYPE_BCM2835_TIMER "bcm2835_timer"
+#define BCM2835_TIMER(obj) \
+        OBJECT_CHECK(BCM2835TimerState, (obj), TYPE_BCM2835_TIMER)
+
+typedef struct {
+    SysBusDevice busdev;
+    MemoryRegion iomem;
+
+    qemu_irq irq;
+
+    uint32_t load;
+    uint32_t control;
+    uint32_t raw_irq;
+    uint32_t prediv;
+    uint32_t frc_value;
+
+    ptimer_state *timer;
+    ptimer_state *frc_timer;
+} BCM2835TimerState;
+
+#endif
diff --git a/include/hw/usb/bcm2835_usb.h b/include/hw/usb/bcm2835_usb.h
new file mode 100644
index 0000000000..246123123b
--- /dev/null
+++ b/include/hw/usb/bcm2835_usb.h
@@ -0,0 +1,78 @@ 
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#ifndef BCM2835_USB_H
+#define BCM2835_USB_H
+
+#include "hw/sysbus.h"
+#include "qemu/timer.h"
+
+#include "hw/usb.h"
+
+#define BCM2835_USB_HCHANS 8
+
+#define TYPE_BCM2835_USB "bcm2835_usb"
+#define BCM2835_USB(obj) \
+        OBJECT_CHECK(BCM2835UsbState, (obj), TYPE_BCM2835_USB)
+
+//typedef struct BCM2835UsbState BCM2835UsbState;
+
+typedef struct {
+    struct BCM2835UsbState_ *parent;
+    int index;
+
+    uint32_t hcchar;
+    uint32_t hcsplt;
+    uint32_t hcint;
+    uint32_t hcintmsk;
+    uint32_t hctsiz;
+    uint32_t hcdma;
+    uint32_t reserved;
+    uint32_t hcdmab;
+
+    USBPacket packet;
+    uint8_t buffer[8192];
+} BCM2835UsbHcState;
+
+typedef struct BCM2835UsbState_ {
+    SysBusDevice busdev;
+    MemoryRegion iomem;
+    MemoryRegion *dma_mr;
+    AddressSpace dma_as;
+
+    USBBus bus;
+    USBPort port;
+    int attached;
+    int reset_done;
+    QEMUTimer *sof_timer;
+
+    uint32_t gusbcfg;
+    uint32_t hptxfsiz;
+    uint32_t hcfg;
+    uint32_t dcfg;
+    uint32_t grxfsiz;
+    uint32_t gnptxfsiz;
+    uint32_t dtxfsiz[15];
+    uint32_t gahbcfg;
+    uint32_t grstctl;
+    uint32_t gotgctl;
+    uint32_t gotgint;
+    uint32_t gintsts;
+    uint32_t gintmsk;
+    uint32_t gdfifocfg;
+    uint32_t hprt0;
+    uint32_t haint;
+    uint32_t haintmsk;
+    uint32_t gnptxsts;
+    uint32_t hfnum;
+    uint32_t hptxsts;
+    uint32_t guid;
+
+    BCM2835UsbHcState hchan[BCM2835_USB_HCHANS];
+
+    qemu_irq irq;
+} BCM2835UsbState;
+
+#endif
diff --git a/include/qemu/PanelEmu.h b/include/qemu/PanelEmu.h
new file mode 100644
index 0000000000..b7a15e64e7
--- /dev/null
+++ b/include/qemu/PanelEmu.h
@@ -0,0 +1,53 @@ 
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/*
+ * File:   PanelEmu.h
+ * Author: John Bradley
+ *
+ * Created on 22 April 2017, 22:26
+ */
+
+#ifndef PANELEMU_H
+#define PANELEMU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define DRIVER_NAME "RDC-GPIO: "
+#define PANEL_NAME "GPIO panel: "
+
+
+#define DEFAULT_PORT 0xb1ff       //45567
+
+#define PANEL_PINS 54
+
+    typedef struct panel_connection {
+        int socket; /* socket we'll connect to the panel with */
+        fd_set fds; /* list of descriptors (only the above socket */
+        char last[PANEL_PINS / 8]; /* we don't want to send updates to the panel
+	                       unless something changed */
+    } panel_connection_t;
+
+    int panel_open(panel_connection_t* h);
+
+    bool panel_read(panel_connection_t* h, uint64_t *pinS);
+    void senddatatopanel(panel_connection_t* h, uint64_t pinS, bool Value);
+    void panel_send_read_command(panel_connection_t* h);
+    void sendpincount(panel_connection_t* h, int Num);
+    void sendenabledmap(panel_connection_t* h, uint64_t pins);
+    void sendinputmap(panel_connection_t* h, uint64_t pins);
+    void sendoutputmap(panel_connection_t* h, uint64_t pins);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PANELEMU_H */
+
diff --git a/util/Makefile.objs b/util/Makefile.objs
index c6205ebf86..8316ed79ba 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -43,3 +43,4 @@  util-obj-y += qdist.o
util-obj-y += qht.o
util-obj-y += range.o
util-obj-y += systemd.o
+util-obj-y += PanelEmu.o
\ No newline at end of file
diff --git a/util/PanelEmu.c b/util/PanelEmu.c
new file mode 100644
index 0000000000..59c87d2747
--- /dev/null
+++ b/util/PanelEmu.c
@@ -0,0 +1,293 @@ 
+/*
+ * Emulation for Rasp PI GPIO via Server connected to via Socket
+ *
+ */
+#include "qemu/osdep.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#ifdef __MINGW32__
+#include <winsock2.h>
+#else
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#endif
+
+
+#include "qemu/PanelEmu.h"
+
+typedef enum
+{
+    MACHINEDESC = 0,
+    PINSTOPANEL = 1,
+    READREQ = 2,
+    PINCOUNT = 3,
+    ENABLEMAP = 4,
+    INPUTMAP = 5,
+    OUTPUTMAP = 6,
+    PINSTOQEMU = 7
+} PacketType;
+
+#define MAXPACKET   255
+
+#define PACKETLEN   0  //Includes Packet Length
+#define PACKETTYPE  1
+
+typedef struct
+{
+    unsigned short int Data[MAXPACKET];
+} CommandPacket;
+
+/*
+ * Hub connections
+ *
+ */
+
+int panel_open(panel_connection_t* h)
+{
+    int rv;
+#ifdef __MINGW32__ 
+    struct sockaddr_in remote;
+#else
+    struct sockaddr_in remote; 
+#endif
+ 
+    int returnval = - 1;
+
+#ifdef __MINGW32__ 
+     printf("__MINGW32__\n");
+#else
+     printf("NOT __MINGW32__\n"); 
+#endif 
+ 
+#ifdef __MINGW32__
+    WSADATA wsadata;
+    if (WSAStartup(MAKEWORD(1, 1), &wsadata) == SOCKET_ERROR) {
+        printf("Error creating socket.\n");
+    }
+    else
+#endif
+    {
+        if ((h->socket = socket(AF_INET, SOCK_STREAM, 0)) != - 1) {
+#ifdef __MINGW32__
+            memset((char *)&remote, 0, sizeof(remote));
+            remote.sin_family = AF_INET;
+            remote.sin_port = htons(DEFAULT_PORT);
+            remote.sin_addr.s_addr = inet_addr("127.0.0.1"); 
+#else
+            bzero((char *)&remote, sizeof(remote));
+            remote.sin_family = AF_INET;
+            remote.sin_port = htons(DEFAULT_PORT);
+            remote.sin_addr.s_addr = inet_addr("127.0.0.1");
+#endif
+            if ((rv=connect(h->socket, (struct sockaddr *) &remote, sizeof (remote))) != - 1) {
+#ifdef __MINGW32__
+                char value = 1;
+                setsockopt(h->socket, IPPROTO_TCP, TCP_NODELAY, &value, sizeof ( value));
+
+#endif
+                FD_ZERO(&h->fds);
+
+                /* Set our connected socket */
+                FD_SET(h->socket, &h->fds);
+
+                printf(PANEL_NAME "Connected OK %d\n",rv);
+                returnval = 0;
+            } else {
+                printf(PANEL_NAME "connection Failes %d\n",rv);
+#ifdef __MINGW32__
+                closesocket(h->socket);
+#else
+                close(h->socket);
+#endif
+                h->socket = - 1;
+            }
+        }
+    }
+    return returnval;
+}
+
+static void panel_command(panel_connection_t *h, CommandPacket *Pkt)
+{
+    if (send(h->socket, (char *) Pkt, Pkt->Data[PACKETLEN], 0) == - 1) {
+        perror(PANEL_NAME "send");
+#ifdef __MINGW32__
+        closesocket(h->socket);
+#else
+        close(h->socket);
+#endif
+        h->socket = - 1; /* act like we never connected */
+    }
+}
+
+/* Wait for values to be read back from panel */
+bool panel_read(panel_connection_t* h, uint64_t* Data)
+{
+    fd_set rfds, efds;
+    int LengthInBuffer;
+    int select_res = 0;
+
+    CommandPacket *PktPtr = (CommandPacket *) malloc(sizeof (CommandPacket));
+    CommandPacket *Pkt;
+    bool NoError = true;
+    bool NewData = false;
+    bool NoData = false;
+    struct timeval timeout;
+
+    int ReadStart = 0;
+
+    timeout.tv_sec = 0;
+    timeout.tv_usec = 0;
+
+    if (h->socket != - 1) {
+        rfds = h->fds;
+        efds = h->fds;
+
+//        printf(PANEL_NAME "panel_read\n");
+
+        Pkt = PktPtr;
+        while (NoError&&! NoData) {
+            select_res = select(h->socket + 1, &rfds, NULL, &efds, &timeout);
+            if (select_res > 0) {
+                if (FD_ISSET(h->socket, &rfds)) {
+                    /* receive more data */
+                    if ((LengthInBuffer = recv(h->socket, (char *) &Pkt[ReadStart], sizeof (*Pkt) - ReadStart, 0)) > 0) {
+                        LengthInBuffer += ReadStart;
+                        for (int i = 0; LengthInBuffer > 0; i ++) {
+                            if (LengthInBuffer >= Pkt->Data[i + PACKETLEN]) {
+                                if (Pkt->Data[i + PACKETTYPE] == PINSTOQEMU) {
+                                    *Data = (uint64_t) Pkt->Data[i + 2];
+                                    *Data |= ((uint64_t) Pkt->Data[i + 3]) << 16;
+                                    *Data |= ((uint64_t) Pkt->Data[i + 4]) << 32;
+                                    *Data |= ((uint64_t) Pkt->Data[i + 5]) << 48;
+
+                                    NewData = true;
+                                } else {
+                                    printf(PANEL_NAME "Invalid data received\n");
+                                }
+                                LengthInBuffer -= Pkt->Data[PACKETLEN];
+                                i += Pkt->Data[PACKETLEN]; //								Pkt=(CommandPacket *)&(Pkt->Data[Pkt->Data[PACKETLEN]]);
+                            } else {
+                                ReadStart = LengthInBuffer;
+                                for (int j = 0; j < LengthInBuffer; j ++) {
+                                    Pkt->Data[j] = Pkt->Data[i + j];
+                                }
+                                printf(PANEL_NAME "Partial Packet Read");
+                            }
+                        }
+                    } else {
+                        if (LengthInBuffer < 0) {
+                            if (errno != EINTR) {
+                                printf(PANEL_NAME "recv");
+                                NoError = FALSE;
+                            }
+                        } else {
+                            printf(PANEL_NAME "closed connection\n");
+                            NoError = FALSE;
+                        }
+                    }
+                }
+            } else if (select_res == 0) {
+                NoData = true;
+            } else if (errno != EINTR) {
+#ifdef __MINGW32__
+                closesocket(h->socket);
+#else
+                close(h->socket);
+#endif
+                h->socket = - 1; /* act like we never connected */
+                perror(PANEL_NAME "select error");
+                NoError = FALSE;
+            }
+        }
+    }
+
+    free(PktPtr);
+
+    return NewData;
+}
+
+void panel_send_read_command(panel_connection_t* h)
+{
+    CommandPacket Pkt;
+
+    Pkt.Data[PACKETLEN] = 4;
+    Pkt.Data[PACKETTYPE] = READREQ;
+
+    panel_command(h, &Pkt);
+}
+
+/* Set a pin to a specified value */
+void senddatatopanel(panel_connection_t* h, uint64_t pin, bool val)
+{
+    CommandPacket Pkt;
+
+    Pkt.Data[PACKETLEN] = (char *) &Pkt.Data[6 + 1]-(char *) &Pkt.Data[0];
+    Pkt.Data[PACKETTYPE] = PINSTOPANEL;
+    Pkt.Data[2] = (unsigned short int) (pin & 0xFFFF);
+    Pkt.Data[3] = (unsigned short int) ((pin >> 16)&0xFFFF);
+    Pkt.Data[4] = (unsigned short int) (pin >> 32 & 0xFFFF);
+    Pkt.Data[5] = (unsigned short int) ((pin >> 48)&0xFFFF);
+    Pkt.Data[6] = val;
+
+    panel_command(h, &Pkt);
+}
+
+void sendpincount(panel_connection_t* h, int val)
+{
+    CommandPacket Pkt;
+
+    Pkt.Data[PACKETLEN] = (char *) &Pkt.Data[2 + 1]-(char *) &Pkt.Data[0];
+    Pkt.Data[PACKETTYPE] = PINCOUNT;
+    Pkt.Data[2] = val;
+
+    panel_command(h, &Pkt);
+}
+
+void sendenabledmap(panel_connection_t* h, uint64_t pin)
+{
+    CommandPacket Pkt;
+
+    Pkt.Data[PACKETLEN] = (char *) &Pkt.Data[5 + 1]-(char *) &Pkt.Data[0];
+    Pkt.Data[PACKETTYPE] = ENABLEMAP;
+    Pkt.Data[2] = (unsigned short int) (pin & 0xFFFF);
+    Pkt.Data[3] = (unsigned short int) ((pin >> 16)&0xFFFF);
+    Pkt.Data[4] = (unsigned short int) (pin >> 32 & 0xFFFF);
+    Pkt.Data[5] = (unsigned short int) ((pin >> 48)&0xFFFF);
+
+    panel_command(h, &Pkt);
+}
+
+void sendinputmap(panel_connection_t* h, uint64_t pin)
+{
+    CommandPacket Pkt;
+
+    Pkt.Data[PACKETLEN] = (char *) &Pkt.Data[5 + 1]-(char *) &Pkt.Data[0];
+    Pkt.Data[PACKETTYPE] = INPUTMAP;
+    Pkt.Data[2] = (unsigned short int) (pin & 0xFFFF);
+    Pkt.Data[3] = (unsigned short int) ((pin >> 16)&0xFFFF);
+    Pkt.Data[4] = (unsigned short int) (pin >> 32 & 0xFFFF);
+    Pkt.Data[5] = (unsigned short int) ((pin >> 48)&0xFFFF);
+
+    panel_command(h, &Pkt);
+}
+
+void sendoutputmap(panel_connection_t* h, uint64_t pin)
+{
+    CommandPacket Pkt;
+
+    Pkt.Data[PACKETLEN] = (char *) &Pkt.Data[5 + 1]-(char *) &Pkt.Data[0];
+    Pkt.Data[PACKETTYPE] = OUTPUTMAP;
+    Pkt.Data[2] = (unsigned short int) (pin & 0xFFFF);
+    Pkt.Data[3] = (unsigned short int) ((pin >> 16)&0xFFFF);
+    Pkt.Data[4] = (unsigned short int) (pin >> 32 & 0xFFFF);
+    Pkt.Data[5] = (unsigned short int) ((pin >> 48)&0xFFFF);
+
+    panel_command(h, &Pkt);
+}
+