diff mbox

[pic32,v3,05/16] pic32: add file pic32_peripherals.h

Message ID 1436163304-6167-6-git-send-email-serge.vakulenko@gmail.com
State New
Headers show

Commit Message

Serge Vakulenko July 6, 2015, 6:14 a.m. UTC
Data definitions and function declarations for simulation
of pic32 microcontrollers.

Signed-off-by: Serge Vakulenko <serge.vakulenko@gmail.com>
---
 hw/mips/pic32_peripherals.h | 210 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 210 insertions(+)
 create mode 100644 hw/mips/pic32_peripherals.h

Comments

Peter Crosthwaite July 6, 2015, 8:02 a.m. UTC | #1
On Sun, Jul 5, 2015 at 11:14 PM, Serge Vakulenko
<serge.vakulenko@gmail.com> wrote:
> Data definitions and function declarations for simulation
> of pic32 microcontrollers.
>
> Signed-off-by: Serge Vakulenko <serge.vakulenko@gmail.com>
> ---
>  hw/mips/pic32_peripherals.h | 210 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 210 insertions(+)
>  create mode 100644 hw/mips/pic32_peripherals.h
>
> diff --git a/hw/mips/pic32_peripherals.h b/hw/mips/pic32_peripherals.h
> new file mode 100644
> index 0000000..4435991
> --- /dev/null
> +++ b/hw/mips/pic32_peripherals.h
> @@ -0,0 +1,210 @@
> +/*
> + * Define memory map for PIC32 microcontroller.
> + *
> + * Copyright (C) 2015 Serge Vakulenko
> + *
> + * Permission to use, copy, modify, and distribute this software
> + * and its documentation for any purpose and without fee is hereby
> + * granted, provided that the above copyright notice appear in all
> + * copies and that both that the copyright notice and this
> + * permission notice and warranty disclaimer appear in supporting
> + * documentation, and that the name of the author not be used in
> + * advertising or publicity pertaining to distribution of the
> + * software without specific, written prior permission.
> + *
> + * The author disclaim all warranties with regard to this
> + * software, including all implied warranties of merchantability
> + * and fitness.  In no event shall the author be liable for any
> + * special, indirect or consequential damages or any damages
> + * whatsoever resulting from loss of use, data or profits, whether
> + * in an action of contract, negligence or other tortious action,
> + * arising out of or in connection with the use or performance of
> + * this software.
> + */
> +#include "hw/sysbus.h"                  /* SysBusDevice */
> +#include "net/net.h"
> +
> +#define IO_MEM_SIZE     (1024*1024)     /* 1 Mbyte */
> +
> +typedef struct _uart_t uart_t;
> +typedef struct _spi_t spi_t;
> +typedef struct _sdcard_t sdcard_t;
> +typedef struct _pic32_t pic32_t;
> +typedef struct _eth_t eth_t;
> +
> +/*
> + * UART private data.
> + */
> +struct _uart_t {

All typenames must be CamelCase.

scripts/checkpatch.pl should catch these.

> +    pic32_t     *mcu;                   /* back pointer to pic32 object */
> +    unsigned    irq;                    /* interrupt number */
> +    int         oactive;                /* output active */
> +    unsigned    sta;                    /* UxSTA address */
> +    unsigned    mode;                   /* UxMODE address */
> +    unsigned    rxbyte;                 /* received byte */
> +    CharDriverState *chr;               /* pointer to serial_hds[i] */
> +    QEMUTimer   *transmit_timer;        /* needed to delay TX interrupt */
> +};
> +
> +/*
> + * SPI private data.
> + */
> +struct _spi_t {
> +    unsigned    buf[4];                 /* transmit and receive buffer */
> +    unsigned    rfifo;                  /* read fifo counter */
> +    unsigned    wfifo;                  /* write fifo counter */
> +    unsigned    irq;                    /* interrupt numbers */
> +    unsigned    con;                    /* SPIxCON address */
> +    unsigned    stat;                   /* SPIxSTAT address */
> +};
> +
> +/*
> + * SD card private data.
> + */
> +struct _sdcard_t {
> +    const char  *name;                  /* Device name */
> +    unsigned    gpio_port;              /* GPIO port number of CS0 signal */
> +    unsigned    gpio_cs;                /* GPIO pin mask of CS0 signal */
> +    unsigned    kbytes;                 /* Disk size */
> +    int         unit;                   /* Index (sd0 or sd1) */
> +    int         fd;                     /* Image file */
> +    int         select;                 /* Selected */
> +    int         read_multiple;          /* Read-multiple mode */
> +    unsigned    blen;                   /* Block length */
> +    unsigned    wbecnt;                 /* Write block erase count */
> +    unsigned    offset;                 /* Read/write offset */
> +    unsigned    count;                  /* Byte count */
> +    unsigned    limit;                  /* Reply length */
> +    unsigned    char buf[1024 + 16];
> +};
> +
> +/*
> + * PIC32 data structure.
> + */
> +struct _pic32_t {
> +    SysBusDevice parent_obj;
> +    MIPSCPU     *cpu;                   /* back pointer to cpu object */
> +    uint32_t    *iomem;                 /* backing storage for I/O area */
> +
> +    int         board_type;             /* board variant */
> +    int         stop_on_reset;          /* halt simulation on soft reset */
> +    unsigned    syskey_unlock;          /* syskey state */
> +
> +#define NUM_UART 6                      /* number of UART ports */
> +    uart_t      uart[NUM_UART];         /* UART data */
> +
> +#define NUM_SPI 6                       /* max number of SPI ports */
> +    spi_t       spi[NUM_SPI];           /* SPI data */
> +
> +    unsigned    sdcard_spi_port;        /* SPI port number of SD card */
> +    sdcard_t    sdcard[2];              /* SD card data */

sd-cards will be off chip. Instead a higher (board?) level should
define the SD cards and the connections.

Regards,
Peter

> +
> +    DeviceState *eth_dev;               /* Ethernet device */
> +    eth_t       *eth;                   /* Ethernet driver data */
> +
> +    void (*irq_raise)(pic32_t *s, int irq); /* set interrupt request */
> +    void (*irq_clear)(pic32_t *s, int irq); /* clear interrupt request */
> +};
> +
> +/*
> + * GPIO routines.
> + */
> +void pic32_gpio_write(pic32_t *s, int unit, unsigned val);
> +
> +/*
> + * UART routines.
> + */
> +void pic32_uart_init(pic32_t *s, int unit, int irq, int sta, int mode);
> +unsigned pic32_uart_get_char(pic32_t *s, int unit);
> +void pic32_uart_put_char(pic32_t *s, int unit, unsigned char data);
> +void pic32_uart_poll_status(pic32_t *s, int unit);
> +void pic32_uart_update_mode(pic32_t *s, int unit);
> +void pic32_uart_update_status(pic32_t *s, int unit);
> +
> +/*
> + * SPI routines.
> + */
> +void pic32_spi_init(pic32_t *s, int unit, int irq, int con, int stat);
> +void pic32_spi_control(pic32_t *s, int unit);
> +unsigned pic32_spi_readbuf(pic32_t *s, int unit);
> +void pic32_spi_writebuf(pic32_t *s, int unit, unsigned val);
> +
> +/*
> + * SD card routines.
> + */
> +void pic32_sdcard_init(pic32_t *s, int unit, const char *name,
> +    const char *filename, int cs_port, int cs_pin);
> +void pic32_sdcard_reset(pic32_t *s);
> +void pic32_sdcard_select(pic32_t *s, int unit, int on);
> +unsigned pic32_sdcard_io(pic32_t *s, unsigned data);
> +
> +/*
> + * Ethernet routines.
> + */
> +void pic32_eth_init(pic32_t *s, NICInfo *nd);
> +void pic32_eth_control(pic32_t *s);
> +void pic32_mii_command(pic32_t *s);
> +void pic32_mii_write(pic32_t *s);
> +
> +/*
> + * Load a binary file in hex or srec format.
> + */
> +int pic32_load_hex_file(const char *filename,
> +    void (*store_byte)(unsigned address, unsigned char byte));
> +
> +/*
> + * Helper defines for i/o switch.
> + */
> +#define VALUE(name)     (s->iomem[(name & 0xfffff) >> 2])
> +
> +#define STORAGE(name)   case name:\
> +                            *namep = #name;
> +
> +#define READONLY(name)  case name:\
> +                            *namep = #name;\
> +                            goto readonly
> +
> +#define WRITEOP(name)   case name:\
> +                            *namep = #name;\
> +                            goto op_##name;\
> +                        case name+4:\
> +                            *namep = #name"CLR";\
> +                            goto op_##name;\
> +                        case name+8:\
> +                            *namep = #name"SET";\
> +                            goto op_##name;\
> +                        case name+12:\
> +                            *namep = #name"INV";\
> +                        op_##name: \
> +                            VALUE(name) = write_op(VALUE(name), data, offset)
> +
> +#define WRITEOPX(name, label) \
> +                        case name:\
> +                            *namep = #name;\
> +                            goto op_##label;\
> +                        case name+4:\
> +                            *namep = #name"CLR";\
> +                            goto op_##label;\
> +                        case name+8:\
> +                            *namep = #name"SET";\
> +                            goto op_##label;\
> +                        case name+12:\
> +                            *namep = #name"INV";\
> +                            goto op_##label
> +
> +#define WRITEOPR(name, romask) \
> +                        case name:\
> +                            *namep = #name;\
> +                            goto op_##name;\
> +                        case name+4:\
> +                            *namep = #name"CLR";\
> +                            goto op_##name;\
> +                        case name+8:\
> +                            *namep = #name"SET";\
> +                            goto op_##name;\
> +                        case name+12:\
> +                            *namep = #name"INV";\
> +                        op_##name: \
> +                            VALUE(name) = (VALUE(name) & (romask)) |\
> +                                (write_op(VALUE(name), data, offset) &\
> +                                    ~(romask))
> --
> 2.2.2
>
>
Aurelien Jarno July 6, 2015, 9:01 a.m. UTC | #2
On 2015-07-05 23:14, Serge Vakulenko wrote:
> Data definitions and function declarations for simulation
> of pic32 microcontrollers.
> 
> Signed-off-by: Serge Vakulenko <serge.vakulenko@gmail.com>
> ---
>  hw/mips/pic32_peripherals.h | 210 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 210 insertions(+)
>  create mode 100644 hw/mips/pic32_peripherals.h
> 
> diff --git a/hw/mips/pic32_peripherals.h b/hw/mips/pic32_peripherals.h
> new file mode 100644
> index 0000000..4435991
> --- /dev/null
> +++ b/hw/mips/pic32_peripherals.h
> @@ -0,0 +1,210 @@
> +/*
> + * Define memory map for PIC32 microcontroller.
> + *
> + * Copyright (C) 2015 Serge Vakulenko
> + *
> + * Permission to use, copy, modify, and distribute this software
> + * and its documentation for any purpose and without fee is hereby
> + * granted, provided that the above copyright notice appear in all
> + * copies and that both that the copyright notice and this
> + * permission notice and warranty disclaimer appear in supporting
> + * documentation, and that the name of the author not be used in
> + * advertising or publicity pertaining to distribution of the
> + * software without specific, written prior permission.
> + *
> + * The author disclaim all warranties with regard to this
> + * software, including all implied warranties of merchantability
> + * and fitness.  In no event shall the author be liable for any
> + * special, indirect or consequential damages or any damages
> + * whatsoever resulting from loss of use, data or profits, whether
> + * in an action of contract, negligence or other tortious action,
> + * arising out of or in connection with the use or performance of
> + * this software.
> + */
> +#include "hw/sysbus.h"                  /* SysBusDevice */
> +#include "net/net.h"
> +
> +#define IO_MEM_SIZE     (1024*1024)     /* 1 Mbyte */
> +
> +typedef struct _uart_t uart_t;
> +typedef struct _spi_t spi_t;
> +typedef struct _sdcard_t sdcard_t;
> +typedef struct _pic32_t pic32_t;
> +typedef struct _eth_t eth_t;
> +
> +/*
> + * UART private data.
> + */
> +struct _uart_t {
> +    pic32_t     *mcu;                   /* back pointer to pic32 object */
> +    unsigned    irq;                    /* interrupt number */
> +    int         oactive;                /* output active */
> +    unsigned    sta;                    /* UxSTA address */
> +    unsigned    mode;                   /* UxMODE address */
> +    unsigned    rxbyte;                 /* received byte */
> +    CharDriverState *chr;               /* pointer to serial_hds[i] */
> +    QEMUTimer   *transmit_timer;        /* needed to delay TX interrupt */
> +};
> +
> +/*
> + * SPI private data.
> + */
> +struct _spi_t {
> +    unsigned    buf[4];                 /* transmit and receive buffer */
> +    unsigned    rfifo;                  /* read fifo counter */
> +    unsigned    wfifo;                  /* write fifo counter */
> +    unsigned    irq;                    /* interrupt numbers */
> +    unsigned    con;                    /* SPIxCON address */
> +    unsigned    stat;                   /* SPIxSTAT address */
> +};
> +
> +/*
> + * SD card private data.
> + */
> +struct _sdcard_t {
> +    const char  *name;                  /* Device name */
> +    unsigned    gpio_port;              /* GPIO port number of CS0 signal */
> +    unsigned    gpio_cs;                /* GPIO pin mask of CS0 signal */
> +    unsigned    kbytes;                 /* Disk size */
> +    int         unit;                   /* Index (sd0 or sd1) */
> +    int         fd;                     /* Image file */
> +    int         select;                 /* Selected */
> +    int         read_multiple;          /* Read-multiple mode */
> +    unsigned    blen;                   /* Block length */
> +    unsigned    wbecnt;                 /* Write block erase count */
> +    unsigned    offset;                 /* Read/write offset */
> +    unsigned    count;                  /* Byte count */
> +    unsigned    limit;                  /* Reply length */
> +    unsigned    char buf[1024 + 16];
> +};
> +
> +/*
> + * PIC32 data structure.
> + */
> +struct _pic32_t {
> +    SysBusDevice parent_obj;
> +    MIPSCPU     *cpu;                   /* back pointer to cpu object */
> +    uint32_t    *iomem;                 /* backing storage for I/O area */
> +
> +    int         board_type;             /* board variant */
> +    int         stop_on_reset;          /* halt simulation on soft reset */
> +    unsigned    syskey_unlock;          /* syskey state */
> +
> +#define NUM_UART 6                      /* number of UART ports */
> +    uart_t      uart[NUM_UART];         /* UART data */
> +
> +#define NUM_SPI 6                       /* max number of SPI ports */
> +    spi_t       spi[NUM_SPI];           /* SPI data */
> +
> +    unsigned    sdcard_spi_port;        /* SPI port number of SD card */
> +    sdcard_t    sdcard[2];              /* SD card data */
> +
> +    DeviceState *eth_dev;               /* Ethernet device */
> +    eth_t       *eth;                   /* Ethernet driver data */
> +
> +    void (*irq_raise)(pic32_t *s, int irq); /* set interrupt request */
> +    void (*irq_clear)(pic32_t *s, int irq); /* clear interrupt request */
> +};

I don't think this is the correct way of modeling the PIC32 peripherals.
Instead of modeling one "big PIC32 peripheral", you should model single
UART, Ethernet device, SPI port, etc. separately. They have their own
address space and IRQ, so each one will have their own ioread/iowrite
function.

Then you can instanciate the peripherals depending on the
micro-controller you emulate (for example 2 UART for the PIC32MX4 or 6
UART for the PIC32MX7) instead of relying on #ifdef at compilation time.

Aurelien
Peter Crosthwaite July 6, 2015, 5:04 p.m. UTC | #3
On Mon, Jul 6, 2015 at 2:01 AM, Aurelien Jarno <aurelien@aurel32.net> wrote:
> On 2015-07-05 23:14, Serge Vakulenko wrote:
>> Data definitions and function declarations for simulation
>> of pic32 microcontrollers.
>>
>> Signed-off-by: Serge Vakulenko <serge.vakulenko@gmail.com>
>> ---
>>  hw/mips/pic32_peripherals.h | 210 ++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 210 insertions(+)
>>  create mode 100644 hw/mips/pic32_peripherals.h
>>
>> diff --git a/hw/mips/pic32_peripherals.h b/hw/mips/pic32_peripherals.h
>> new file mode 100644
>> index 0000000..4435991
>> --- /dev/null
>> +++ b/hw/mips/pic32_peripherals.h
>> @@ -0,0 +1,210 @@
>> +/*
>> + * Define memory map for PIC32 microcontroller.
>> + *
>> + * Copyright (C) 2015 Serge Vakulenko
>> + *
>> + * Permission to use, copy, modify, and distribute this software
>> + * and its documentation for any purpose and without fee is hereby
>> + * granted, provided that the above copyright notice appear in all
>> + * copies and that both that the copyright notice and this
>> + * permission notice and warranty disclaimer appear in supporting
>> + * documentation, and that the name of the author not be used in
>> + * advertising or publicity pertaining to distribution of the
>> + * software without specific, written prior permission.
>> + *
>> + * The author disclaim all warranties with regard to this
>> + * software, including all implied warranties of merchantability
>> + * and fitness.  In no event shall the author be liable for any
>> + * special, indirect or consequential damages or any damages
>> + * whatsoever resulting from loss of use, data or profits, whether
>> + * in an action of contract, negligence or other tortious action,
>> + * arising out of or in connection with the use or performance of
>> + * this software.
>> + */
>> +#include "hw/sysbus.h"                  /* SysBusDevice */
>> +#include "net/net.h"
>> +
>> +#define IO_MEM_SIZE     (1024*1024)     /* 1 Mbyte */
>> +
>> +typedef struct _uart_t uart_t;
>> +typedef struct _spi_t spi_t;
>> +typedef struct _sdcard_t sdcard_t;
>> +typedef struct _pic32_t pic32_t;
>> +typedef struct _eth_t eth_t;
>> +
>> +/*
>> + * UART private data.
>> + */
>> +struct _uart_t {
>> +    pic32_t     *mcu;                   /* back pointer to pic32 object */
>> +    unsigned    irq;                    /* interrupt number */
>> +    int         oactive;                /* output active */
>> +    unsigned    sta;                    /* UxSTA address */
>> +    unsigned    mode;                   /* UxMODE address */
>> +    unsigned    rxbyte;                 /* received byte */
>> +    CharDriverState *chr;               /* pointer to serial_hds[i] */
>> +    QEMUTimer   *transmit_timer;        /* needed to delay TX interrupt */
>> +};
>> +
>> +/*
>> + * SPI private data.
>> + */
>> +struct _spi_t {
>> +    unsigned    buf[4];                 /* transmit and receive buffer */
>> +    unsigned    rfifo;                  /* read fifo counter */
>> +    unsigned    wfifo;                  /* write fifo counter */
>> +    unsigned    irq;                    /* interrupt numbers */
>> +    unsigned    con;                    /* SPIxCON address */
>> +    unsigned    stat;                   /* SPIxSTAT address */
>> +};
>> +
>> +/*
>> + * SD card private data.
>> + */
>> +struct _sdcard_t {
>> +    const char  *name;                  /* Device name */
>> +    unsigned    gpio_port;              /* GPIO port number of CS0 signal */
>> +    unsigned    gpio_cs;                /* GPIO pin mask of CS0 signal */
>> +    unsigned    kbytes;                 /* Disk size */
>> +    int         unit;                   /* Index (sd0 or sd1) */
>> +    int         fd;                     /* Image file */
>> +    int         select;                 /* Selected */
>> +    int         read_multiple;          /* Read-multiple mode */
>> +    unsigned    blen;                   /* Block length */
>> +    unsigned    wbecnt;                 /* Write block erase count */
>> +    unsigned    offset;                 /* Read/write offset */
>> +    unsigned    count;                  /* Byte count */
>> +    unsigned    limit;                  /* Reply length */
>> +    unsigned    char buf[1024 + 16];
>> +};
>> +
>> +/*
>> + * PIC32 data structure.
>> + */
>> +struct _pic32_t {
>> +    SysBusDevice parent_obj;
>> +    MIPSCPU     *cpu;                   /* back pointer to cpu object */
>> +    uint32_t    *iomem;                 /* backing storage for I/O area */
>> +
>> +    int         board_type;             /* board variant */
>> +    int         stop_on_reset;          /* halt simulation on soft reset */
>> +    unsigned    syskey_unlock;          /* syskey state */
>> +
>> +#define NUM_UART 6                      /* number of UART ports */
>> +    uart_t      uart[NUM_UART];         /* UART data */
>> +
>> +#define NUM_SPI 6                       /* max number of SPI ports */
>> +    spi_t       spi[NUM_SPI];           /* SPI data */
>> +
>> +    unsigned    sdcard_spi_port;        /* SPI port number of SD card */
>> +    sdcard_t    sdcard[2];              /* SD card data */
>> +
>> +    DeviceState *eth_dev;               /* Ethernet device */
>> +    eth_t       *eth;                   /* Ethernet driver data */
>> +
>> +    void (*irq_raise)(pic32_t *s, int irq); /* set interrupt request */
>> +    void (*irq_clear)(pic32_t *s, int irq); /* clear interrupt request */
>> +};
>
> I don't think this is the correct way of modeling the PIC32 peripherals.
> Instead of modeling one "big PIC32 peripheral", you should model single
> UART, Ethernet device, SPI port, etc. separately. They have their own
> address space and IRQ, so each one will have their own ioread/iowrite
> function.
>
> Then you can instanciate the peripherals depending on the
> micro-controller you emulate (for example 2 UART for the PIC32MX4 or 6
> UART for the PIC32MX7) instead of relying on #ifdef at compilation time.
>

Further to that you should use the QOM system to define peripherals as
objects. I'm guessing that there are also self-contained chips that in
turn are on boards, which will give you three level of heirachy.

1: Devices - these should be self contained and not have awareness of
each other. UART, Enet, intc (even CPUs) etc.
2: SoC level - this is the complete microcontroller part containing
CPU and peripherals (n CPUs, m UARTS etc.).
3: Board level - the machine with the SoC and the external devs (SD cards etc)

Have a look at the recent STM32F/netduino series for ARM which add all
of these and connects them together. This patch range in good reading:

da6bd92 netduino2: Add the Netduino 2 Machine
db63552 stm32f205: Add the stm32f205 SoC
bbbbd90 stm32f2xx_SYSCFG: Add the stm32f2xx SYSCFG
73af5d1 stm32f2xx_USART: Add the stm32f2xx USART Controller
be28470 stm32f2xx_timer: Add the stm32f2xx Timer

Regards,
Peter

> Aurelien
>
> --
> Aurelien Jarno                          GPG: 4096R/1DDD8C9B
> aurelien@aurel32.net                 http://www.aurel32.net
>
diff mbox

Patch

diff --git a/hw/mips/pic32_peripherals.h b/hw/mips/pic32_peripherals.h
new file mode 100644
index 0000000..4435991
--- /dev/null
+++ b/hw/mips/pic32_peripherals.h
@@ -0,0 +1,210 @@ 
+/*
+ * Define memory map for PIC32 microcontroller.
+ *
+ * Copyright (C) 2015 Serge Vakulenko
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice appear in all
+ * copies and that both that the copyright notice and this
+ * permission notice and warranty disclaimer appear in supporting
+ * documentation, and that the name of the author not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * The author disclaim all warranties with regard to this
+ * software, including all implied warranties of merchantability
+ * and fitness.  In no event shall the author be liable for any
+ * special, indirect or consequential damages or any damages
+ * whatsoever resulting from loss of use, data or profits, whether
+ * in an action of contract, negligence or other tortious action,
+ * arising out of or in connection with the use or performance of
+ * this software.
+ */
+#include "hw/sysbus.h"                  /* SysBusDevice */
+#include "net/net.h"
+
+#define IO_MEM_SIZE     (1024*1024)     /* 1 Mbyte */
+
+typedef struct _uart_t uart_t;
+typedef struct _spi_t spi_t;
+typedef struct _sdcard_t sdcard_t;
+typedef struct _pic32_t pic32_t;
+typedef struct _eth_t eth_t;
+
+/*
+ * UART private data.
+ */
+struct _uart_t {
+    pic32_t     *mcu;                   /* back pointer to pic32 object */
+    unsigned    irq;                    /* interrupt number */
+    int         oactive;                /* output active */
+    unsigned    sta;                    /* UxSTA address */
+    unsigned    mode;                   /* UxMODE address */
+    unsigned    rxbyte;                 /* received byte */
+    CharDriverState *chr;               /* pointer to serial_hds[i] */
+    QEMUTimer   *transmit_timer;        /* needed to delay TX interrupt */
+};
+
+/*
+ * SPI private data.
+ */
+struct _spi_t {
+    unsigned    buf[4];                 /* transmit and receive buffer */
+    unsigned    rfifo;                  /* read fifo counter */
+    unsigned    wfifo;                  /* write fifo counter */
+    unsigned    irq;                    /* interrupt numbers */
+    unsigned    con;                    /* SPIxCON address */
+    unsigned    stat;                   /* SPIxSTAT address */
+};
+
+/*
+ * SD card private data.
+ */
+struct _sdcard_t {
+    const char  *name;                  /* Device name */
+    unsigned    gpio_port;              /* GPIO port number of CS0 signal */
+    unsigned    gpio_cs;                /* GPIO pin mask of CS0 signal */
+    unsigned    kbytes;                 /* Disk size */
+    int         unit;                   /* Index (sd0 or sd1) */
+    int         fd;                     /* Image file */
+    int         select;                 /* Selected */
+    int         read_multiple;          /* Read-multiple mode */
+    unsigned    blen;                   /* Block length */
+    unsigned    wbecnt;                 /* Write block erase count */
+    unsigned    offset;                 /* Read/write offset */
+    unsigned    count;                  /* Byte count */
+    unsigned    limit;                  /* Reply length */
+    unsigned    char buf[1024 + 16];
+};
+
+/*
+ * PIC32 data structure.
+ */
+struct _pic32_t {
+    SysBusDevice parent_obj;
+    MIPSCPU     *cpu;                   /* back pointer to cpu object */
+    uint32_t    *iomem;                 /* backing storage for I/O area */
+
+    int         board_type;             /* board variant */
+    int         stop_on_reset;          /* halt simulation on soft reset */
+    unsigned    syskey_unlock;          /* syskey state */
+
+#define NUM_UART 6                      /* number of UART ports */
+    uart_t      uart[NUM_UART];         /* UART data */
+
+#define NUM_SPI 6                       /* max number of SPI ports */
+    spi_t       spi[NUM_SPI];           /* SPI data */
+
+    unsigned    sdcard_spi_port;        /* SPI port number of SD card */
+    sdcard_t    sdcard[2];              /* SD card data */
+
+    DeviceState *eth_dev;               /* Ethernet device */
+    eth_t       *eth;                   /* Ethernet driver data */
+
+    void (*irq_raise)(pic32_t *s, int irq); /* set interrupt request */
+    void (*irq_clear)(pic32_t *s, int irq); /* clear interrupt request */
+};
+
+/*
+ * GPIO routines.
+ */
+void pic32_gpio_write(pic32_t *s, int unit, unsigned val);
+
+/*
+ * UART routines.
+ */
+void pic32_uart_init(pic32_t *s, int unit, int irq, int sta, int mode);
+unsigned pic32_uart_get_char(pic32_t *s, int unit);
+void pic32_uart_put_char(pic32_t *s, int unit, unsigned char data);
+void pic32_uart_poll_status(pic32_t *s, int unit);
+void pic32_uart_update_mode(pic32_t *s, int unit);
+void pic32_uart_update_status(pic32_t *s, int unit);
+
+/*
+ * SPI routines.
+ */
+void pic32_spi_init(pic32_t *s, int unit, int irq, int con, int stat);
+void pic32_spi_control(pic32_t *s, int unit);
+unsigned pic32_spi_readbuf(pic32_t *s, int unit);
+void pic32_spi_writebuf(pic32_t *s, int unit, unsigned val);
+
+/*
+ * SD card routines.
+ */
+void pic32_sdcard_init(pic32_t *s, int unit, const char *name,
+    const char *filename, int cs_port, int cs_pin);
+void pic32_sdcard_reset(pic32_t *s);
+void pic32_sdcard_select(pic32_t *s, int unit, int on);
+unsigned pic32_sdcard_io(pic32_t *s, unsigned data);
+
+/*
+ * Ethernet routines.
+ */
+void pic32_eth_init(pic32_t *s, NICInfo *nd);
+void pic32_eth_control(pic32_t *s);
+void pic32_mii_command(pic32_t *s);
+void pic32_mii_write(pic32_t *s);
+
+/*
+ * Load a binary file in hex or srec format.
+ */
+int pic32_load_hex_file(const char *filename,
+    void (*store_byte)(unsigned address, unsigned char byte));
+
+/*
+ * Helper defines for i/o switch.
+ */
+#define VALUE(name)     (s->iomem[(name & 0xfffff) >> 2])
+
+#define STORAGE(name)   case name:\
+                            *namep = #name;
+
+#define READONLY(name)  case name:\
+                            *namep = #name;\
+                            goto readonly
+
+#define WRITEOP(name)   case name:\
+                            *namep = #name;\
+                            goto op_##name;\
+                        case name+4:\
+                            *namep = #name"CLR";\
+                            goto op_##name;\
+                        case name+8:\
+                            *namep = #name"SET";\
+                            goto op_##name;\
+                        case name+12:\
+                            *namep = #name"INV";\
+                        op_##name: \
+                            VALUE(name) = write_op(VALUE(name), data, offset)
+
+#define WRITEOPX(name, label) \
+                        case name:\
+                            *namep = #name;\
+                            goto op_##label;\
+                        case name+4:\
+                            *namep = #name"CLR";\
+                            goto op_##label;\
+                        case name+8:\
+                            *namep = #name"SET";\
+                            goto op_##label;\
+                        case name+12:\
+                            *namep = #name"INV";\
+                            goto op_##label
+
+#define WRITEOPR(name, romask) \
+                        case name:\
+                            *namep = #name;\
+                            goto op_##name;\
+                        case name+4:\
+                            *namep = #name"CLR";\
+                            goto op_##name;\
+                        case name+8:\
+                            *namep = #name"SET";\
+                            goto op_##name;\
+                        case name+12:\
+                            *namep = #name"INV";\
+                        op_##name: \
+                            VALUE(name) = (VALUE(name) & (romask)) |\
+                                (write_op(VALUE(name), data, offset) &\
+                                    ~(romask))