[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH pic32 v3 08/16] pic32: add file mips_pic32mx7.c
From: |
Serge Vakulenko |
Subject: |
[Qemu-devel] [PATCH pic32 v3 08/16] pic32: add file mips_pic32mx7.c |
Date: |
Sun, 5 Jul 2015 23:14:56 -0700 |
This file implements a platform for Microchip PIC32MX7 microcontroller,
with three boards (machine types) supported:
pic32mx7-explorer16 PIC32MX7 microcontroller on Microchip Explorer-16 board
pic32mx7-max32 PIC32MX7 microcontroller on chipKIT Max32 board
pic32mx7-maximite PIC32MX7 microcontroller on Geoff's Maximite computer
Signed-off-by: Serge Vakulenko <address@hidden>
---
hw/mips/mips_pic32mx7.c | 1641 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 1641 insertions(+)
create mode 100644 hw/mips/mips_pic32mx7.c
diff --git a/hw/mips/mips_pic32mx7.c b/hw/mips/mips_pic32mx7.c
new file mode 100644
index 0000000..21dd115
--- /dev/null
+++ b/hw/mips/mips_pic32mx7.c
@@ -0,0 +1,1641 @@
+/*
+ * QEMU support for Microchip PIC32MX7 microcontroller.
+ *
+ * Copyright (c) 2015 Serge Vakulenko
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "hw/i386/pc.h"
+#include "hw/char/serial.h"
+#include "hw/mips/cpudevs.h"
+#include "sysemu/char.h"
+#include "hw/loader.h"
+#include "qemu/error-report.h"
+#include "hw/empty_slot.h"
+#include <termios.h>
+
+#define PIC32MX7
+#include "pic32mx.h"
+#include "pic32_peripherals.h"
+
+/* Hardware addresses */
+#define PROGRAM_FLASH_START 0x1d000000
+#define BOOT_FLASH_START 0x1fc00000
+#define DATA_MEM_START 0x00000000
+#define IO_MEM_START 0x1f800000
+
+#define PROGRAM_FLASH_SIZE (512*1024) /* 512 kbytes */
+#define BOOT_FLASH_SIZE (12*1024) /* 12 kbytes */
+#define DATA_MEM_SIZE (128*1024) /* 128 kbytes */
+#define USER_MEM_START 0xbf000000
+
+#define TYPE_MIPS_PIC32 "mips-pic32mx7"
+
+/*
+ * Board variants.
+ */
+enum {
+ BOARD_MAX32, /* chipKIT Max32 board */
+ BOARD_MAXIMITE, /* Geoff's Maximite board */
+ BOARD_EXPLORER16, /* Microchip Explorer-16 board */
+};
+
+static const char *board_name[] = {
+ "chipKIT Max32",
+ "Geoff's Maximite Computer",
+ "Microchip Explorer16",
+};
+
+/*
+ * Pointers to Flash memory contents.
+ */
+static char *prog_ptr;
+static char *boot_ptr;
+
+#define BOOTMEM(addr) ((uint32_t *) boot_ptr)[(addr & 0xffff) >> 2]
+
+/*
+ * TODO: add option to enable tracing.
+ */
+#define TRACE 0
+
+/*
+ * PIC32MX7 specific table:
+ * translate IRQ number to interrupt vector.
+ */
+static const int irq_to_vector[] = {
+ PIC32_VECT_CT, /* 0 - Core Timer Interrupt */
+ PIC32_VECT_CS0, /* 1 - Core Software Interrupt 0 */
+ PIC32_VECT_CS1, /* 2 - Core Software Interrupt 1 */
+ PIC32_VECT_INT0, /* 3 - External Interrupt 0 */
+ PIC32_VECT_T1, /* 4 - Timer1 */
+ PIC32_VECT_IC1, /* 5 - Input Capture 1 */
+ PIC32_VECT_OC1, /* 6 - Output Compare 1 */
+ PIC32_VECT_INT1, /* 7 - External Interrupt 1 */
+ PIC32_VECT_T2, /* 8 - Timer2 */
+ PIC32_VECT_IC2, /* 9 - Input Capture 2 */
+ PIC32_VECT_OC2, /* 10 - Output Compare 2 */
+ PIC32_VECT_INT2, /* 11 - External Interrupt 2 */
+ PIC32_VECT_T3, /* 12 - Timer3 */
+ PIC32_VECT_IC3, /* 13 - Input Capture 3 */
+ PIC32_VECT_OC3, /* 14 - Output Compare 3 */
+ PIC32_VECT_INT3, /* 15 - External Interrupt 3 */
+ PIC32_VECT_T4, /* 16 - Timer4 */
+ PIC32_VECT_IC4, /* 17 - Input Capture 4 */
+ PIC32_VECT_OC4, /* 18 - Output Compare 4 */
+ PIC32_VECT_INT4, /* 19 - External Interrupt 4 */
+ PIC32_VECT_T5, /* 20 - Timer5 */
+ PIC32_VECT_IC5, /* 21 - Input Capture 5 */
+ PIC32_VECT_OC5, /* 22 - Output Compare 5 */
+ PIC32_VECT_SPI1, /* 23 - SPI1 Fault */
+ PIC32_VECT_SPI1, /* 24 - SPI1 Transfer Done */
+ PIC32_VECT_SPI1, /* 25 - SPI1 Receive Done */
+
+ PIC32_VECT_U1 | /* 26 - UART1 Error */
+ PIC32_VECT_SPI3 | /* 26 - SPI3 Fault */
+ PIC32_VECT_I2C3, /* 26 - I2C3 Bus Collision Event */
+
+ PIC32_VECT_U1 | /* 27 - UART1 Receiver */
+ PIC32_VECT_SPI3 | /* 27 - SPI3 Transfer Done */
+ PIC32_VECT_I2C3, /* 27 - I2C3 Slave Event */
+
+ PIC32_VECT_U1 | /* 28 - UART1 Transmitter */
+ PIC32_VECT_SPI3 | /* 28 - SPI3 Receive Done */
+ PIC32_VECT_I2C3, /* 28 - I2C3 Master Event */
+
+ PIC32_VECT_I2C1, /* 29 - I2C1 Bus Collision Event */
+ PIC32_VECT_I2C1, /* 30 - I2C1 Slave Event */
+ PIC32_VECT_I2C1, /* 31 - I2C1 Master Event */
+ PIC32_VECT_CN, /* 32 - Input Change Interrupt */
+ PIC32_VECT_AD1, /* 33 - ADC1 Convert Done */
+ PIC32_VECT_PMP, /* 34 - Parallel Master Port */
+ PIC32_VECT_CMP1, /* 35 - Comparator Interrupt */
+ PIC32_VECT_CMP2, /* 36 - Comparator Interrupt */
+
+ PIC32_VECT_U3 | /* 37 - UART3 Error */
+ PIC32_VECT_SPI2 | /* 37 - SPI2 Fault */
+ PIC32_VECT_I2C4, /* 37 - I2C4 Bus Collision Event */
+
+ PIC32_VECT_U3 | /* 38 - UART3 Receiver */
+ PIC32_VECT_SPI2 | /* 38 - SPI2 Transfer Done */
+ PIC32_VECT_I2C4, /* 38 - I2C4 Slave Event */
+
+ PIC32_VECT_U3 | /* 39 - UART3 Transmitter */
+ PIC32_VECT_SPI2 | /* 39 - SPI2 Receive Done */
+ PIC32_VECT_I2C4, /* 39 - I2C4 Master Event */
+
+ PIC32_VECT_U2 | /* 40 - UART2 Error */
+ PIC32_VECT_SPI4 | /* 40 - SPI4 Fault */
+ PIC32_VECT_I2C5, /* 40 - I2C5 Bus Collision Event */
+
+ PIC32_VECT_U2 | /* 41 - UART2 Receiver */
+ PIC32_VECT_SPI4 | /* 41 - SPI4 Transfer Done */
+ PIC32_VECT_I2C5, /* 41 - I2C5 Slave Event */
+
+ PIC32_VECT_U2 | /* 42 - UART2 Transmitter */
+ PIC32_VECT_SPI4 | /* 42 - SPI4 Receive Done */
+ PIC32_VECT_I2C5, /* 42 - I2C5 Master Event */
+
+ PIC32_VECT_I2C2, /* 43 - I2C2 Bus Collision Event */
+ PIC32_VECT_I2C2, /* 44 - I2C2 Slave Event */
+ PIC32_VECT_I2C2, /* 45 - I2C2 Master Event */
+ PIC32_VECT_FSCM, /* 46 - Fail-Safe Clock Monitor */
+ PIC32_VECT_RTCC, /* 47 - Real-Time Clock and Calendar */
+ PIC32_VECT_DMA0, /* 48 - DMA Channel 0 */
+ PIC32_VECT_DMA1, /* 49 - DMA Channel 1 */
+ PIC32_VECT_DMA2, /* 50 - DMA Channel 2 */
+ PIC32_VECT_DMA3, /* 51 - DMA Channel 3 */
+ PIC32_VECT_DMA4, /* 52 - DMA Channel 4 */
+ PIC32_VECT_DMA5, /* 53 - DMA Channel 5 */
+ PIC32_VECT_DMA6, /* 54 - DMA Channel 6 */
+ PIC32_VECT_DMA7, /* 55 - DMA Channel 7 */
+ PIC32_VECT_FCE, /* 56 - Flash Control Event */
+ PIC32_VECT_USB, /* 57 - USB */
+ PIC32_VECT_CAN1, /* 58 - Control Area Network 1 */
+ PIC32_VECT_CAN2, /* 59 - Control Area Network 2 */
+ PIC32_VECT_ETH, /* 60 - Ethernet Interrupt */
+ PIC32_VECT_IC1, /* 61 - Input Capture 1 Error */
+ PIC32_VECT_IC2, /* 62 - Input Capture 2 Error */
+ PIC32_VECT_IC3, /* 63 - Input Capture 3 Error */
+ PIC32_VECT_IC4, /* 64 - Input Capture 4 Error */
+ PIC32_VECT_IC5, /* 65 - Input Capture 5 Error */
+ PIC32_VECT_PMP, /* 66 - Parallel Master Port Error */
+ PIC32_VECT_U4, /* 67 - UART4 Error */
+ PIC32_VECT_U4, /* 68 - UART4 Receiver */
+ PIC32_VECT_U4, /* 69 - UART4 Transmitter */
+ PIC32_VECT_U6, /* 70 - UART6 Error */
+ PIC32_VECT_U6, /* 71 - UART6 Receiver */
+ PIC32_VECT_U6, /* 72 - UART6 Transmitter */
+ PIC32_VECT_U5, /* 73 - UART5 Error */
+ PIC32_VECT_U5, /* 74 - UART5 Receiver */
+ PIC32_VECT_U5, /* 75 - UART5 Transmitter */
+};
+
+static void update_irq_status(pic32_t *s)
+{
+ /* Assume no interrupts pending. */
+ int cause_ripl = 0;
+ int vector = 0;
+ CPUMIPSState *env = &s->cpu->env;
+ int current_ripl = (env->CP0_Cause >> (CP0Ca_IP + 2)) & 0x3f;
+
+ VALUE(INTSTAT) = 0;
+
+ if ((VALUE(IFS0) & VALUE(IEC0)) ||
+ (VALUE(IFS1) & VALUE(IEC1)) ||
+ (VALUE(IFS2) & VALUE(IEC2)))
+ {
+ /* Find the most prioritive pending interrupt,
+ * it's vector and level. */
+ int irq;
+ for (irq = 0; irq < sizeof(irq_to_vector)/sizeof(int); irq++) {
+ int n = irq >> 5;
+
+ if (((VALUE(IFS(n)) & VALUE(IEC(n))) >> (irq & 31)) & 1) {
+ /* Interrupt is pending. */
+ int v = irq_to_vector[irq];
+ if (v < 0) {
+ continue;
+ }
+
+ int level = VALUE(IPC(v >> 2));
+ level >>= 2 + (v & 3) * 8;
+ level &= 7;
+ if (level > cause_ripl) {
+ vector = v;
+ cause_ripl = level;
+ }
+ }
+ }
+ VALUE(INTSTAT) = vector | (cause_ripl << 8);
+ }
+
+ if (cause_ripl == current_ripl) {
+ return;
+ }
+
+ if (TRACE) {
+ fprintf(qemu_logfile, "--- Priority level Cause.RIPL = %u\n",
+ cause_ripl);
+ }
+
+ /*
+ * Modify Cause.RIPL field and take EIC interrupt.
+ */
+ env->CP0_Cause &= ~(0x3f << (CP0Ca_IP + 2));
+ env->CP0_Cause |= cause_ripl << (CP0Ca_IP + 2);
+ cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HARD);
+}
+
+/*
+ * Set interrupt flag status
+ */
+static void irq_raise(pic32_t *s, int irq)
+{
+ if (VALUE(IFS(irq >> 5)) & (1 << (irq & 31))) {
+ return;
+ }
+
+ VALUE(IFS(irq >> 5)) |= 1 << (irq & 31);
+ update_irq_status(s);
+}
+
+/*
+ * Clear interrupt flag status
+ */
+static void irq_clear(pic32_t *s, int irq)
+{
+ if (!(VALUE(IFS(irq >> 5)) & (1 << (irq & 31)))) {
+ return;
+ }
+
+ VALUE(IFS(irq >> 5)) &= ~(1 << (irq & 31));
+ update_irq_status(s);
+}
+
+/*
+ * Timer interrupt or soft interrupt.
+ */
+static void pic32_irq_request(void *opaque, int num, int raise)
+{
+ pic32_t *s = opaque;
+ CPUMIPSState *env = &s->cpu->env;
+
+ if (raise) {
+ if (TRACE) {
+ if (num == 0)
+ fprintf(qemu_logfile, "--- %08x: Timer interrupt\n",
+ env->active_tc.PC);
+ else
+ fprintf(qemu_logfile, "--- %08x: Soft interrupt %u\n",
+ env->active_tc.PC, num-1);
+ }
+ irq_raise(s, num);
+ } else {
+ if (TRACE) {
+ if (num == 0)
+ fprintf(qemu_logfile, "--- %08x: Clear timer interrupt\n",
+ env->active_tc.PC);
+ else
+ fprintf(qemu_logfile, "--- %08x: Clear soft interrupt %u\n",
+ env->active_tc.PC, num-1);
+ }
+ irq_clear(s, num);
+ }
+}
+
+/*
+ * Perform an assign/clear/set/invert operation.
+ */
+static inline unsigned write_op(int a, int b, int op)
+{
+ switch (op & 0xc) {
+ case 0x0: /* Assign */
+ a = b;
+ break;
+ case 0x4: /* Clear */
+ a &= ~b;
+ break;
+ case 0x8: /* Set */
+ a |= b;
+ break;
+ case 0xc: /* Invert */
+ a ^= b;
+ break;
+ }
+ return a;
+}
+
+static void io_reset(pic32_t *s)
+{
+ int i;
+
+ /*
+ * Bus matrix control registers.
+ */
+ VALUE(BMXCON) = 0x001f0041; /* Bus Matrix Control */
+ VALUE(BMXDKPBA) = 0; /* Data RAM kernel program base */
+ VALUE(BMXDUDBA) = 0; /* Data RAM user data base address */
+ VALUE(BMXDUPBA) = 0; /* Data RAM user program base */
+ VALUE(BMXPUPBA) = 0; /* Program Flash user program base */
+ VALUE(BMXDRMSZ) = 128 * 1024; /* Data RAM memory size */
+ VALUE(BMXPFMSZ) = 512 * 1024; /* Program Flash memory size */
+ VALUE(BMXBOOTSZ) = 12 * 1024; /* Boot Flash size */
+
+ /*
+ * Prefetch controller.
+ */
+ VALUE(CHECON) = 0x00000007;
+
+ /*
+ * System controller.
+ */
+ VALUE(OSCTUN) = 0;
+ VALUE(DDPCON) = 0;
+ VALUE(SYSKEY) = 0;
+ VALUE(RCON) = 0;
+ VALUE(RSWRST) = 0;
+ s->syskey_unlock = 0;
+
+ /*
+ * Analog to digital converter.
+ */
+ VALUE(AD1CON1) = 0; /* Control register 1 */
+ VALUE(AD1CON2) = 0; /* Control register 2 */
+ VALUE(AD1CON3) = 0; /* Control register 3 */
+ VALUE(AD1CHS) = 0; /* Channel select */
+ VALUE(AD1CSSL) = 0; /* Input scan selection */
+ VALUE(AD1PCFG) = 0; /* Port configuration */
+
+ /*
+ * General purpose IO signals.
+ * All pins are inputs, high, open drains and pullups disabled.
+ * No interrupts on change.
+ */
+ VALUE(TRISA) = 0xFFFF; /* Port A: mask of inputs */
+ VALUE(PORTA) = 0xFFFF; /* Port A: read inputs, write outputs */
+ VALUE(LATA) = 0xFFFF; /* Port A: read/write outputs */
+ VALUE(ODCA) = 0; /* Port A: open drain configuration */
+ VALUE(TRISB) = 0xFFFF; /* Port B: mask of inputs */
+ VALUE(PORTB) = 0xFFFF; /* Port B: read inputs, write outputs */
+ VALUE(LATB) = 0xFFFF; /* Port B: read/write outputs */
+ VALUE(ODCB) = 0; /* Port B: open drain configuration */
+ VALUE(TRISC) = 0xFFFF; /* Port C: mask of inputs */
+ VALUE(PORTC) = 0xFFFF; /* Port C: read inputs, write outputs */
+ VALUE(LATC) = 0xFFFF; /* Port C: read/write outputs */
+ VALUE(ODCC) = 0; /* Port C: open drain configuration */
+ VALUE(TRISD) = 0xFFFF; /* Port D: mask of inputs */
+ VALUE(PORTD) = 0xFFFF; /* Port D: read inputs, write outputs */
+ VALUE(LATD) = 0xFFFF; /* Port D: read/write outputs */
+ VALUE(ODCD) = 0; /* Port D: open drain configuration */
+ VALUE(TRISE) = 0xFFFF; /* Port E: mask of inputs */
+ VALUE(PORTE) = 0xFFFF; /* Port D: read inputs, write outputs */
+ VALUE(LATE) = 0xFFFF; /* Port E: read/write outputs */
+ VALUE(ODCE) = 0; /* Port E: open drain configuration */
+ VALUE(TRISF) = 0xFFFF; /* Port F: mask of inputs */
+ VALUE(PORTF) = 0xFFFF; /* Port F: read inputs, write outputs */
+ VALUE(LATF) = 0xFFFF; /* Port F: read/write outputs */
+ VALUE(ODCF) = 0; /* Port F: open drain configuration */
+ VALUE(TRISG) = 0xFFFF; /* Port G: mask of inputs */
+ VALUE(PORTG) = 0xFFFF; /* Port G: read inputs, write outputs */
+ VALUE(LATG) = 0xFFFF; /* Port G: read/write outputs */
+ VALUE(ODCG) = 0; /* Port G: open drain configuration */
+ VALUE(CNCON) = 0; /* Interrupt-on-change control */
+ VALUE(CNEN) = 0; /* Input change interrupt enable */
+ VALUE(CNPUE) = 0; /* Input pin pull-up enable */
+
+ /*
+ * Reset UARTs.
+ */
+ VALUE(U1MODE) = 0;
+ VALUE(U1STA) = PIC32_USTA_RIDLE | PIC32_USTA_TRMT;
+ VALUE(U1TXREG) = 0;
+ VALUE(U1RXREG) = 0;
+ VALUE(U1BRG) = 0;
+ VALUE(U2MODE) = 0;
+ VALUE(U2STA) = PIC32_USTA_RIDLE | PIC32_USTA_TRMT;
+ VALUE(U2TXREG) = 0;
+ VALUE(U2RXREG) = 0;
+ VALUE(U2BRG) = 0;
+ VALUE(U3MODE) = 0;
+ VALUE(U3STA) = PIC32_USTA_RIDLE | PIC32_USTA_TRMT;
+ VALUE(U3TXREG) = 0;
+ VALUE(U3RXREG) = 0;
+ VALUE(U3BRG) = 0;
+ VALUE(U4MODE) = 0;
+ VALUE(U4STA) = PIC32_USTA_RIDLE | PIC32_USTA_TRMT;
+ VALUE(U4TXREG) = 0;
+ VALUE(U4RXREG) = 0;
+ VALUE(U4BRG) = 0;
+ VALUE(U5MODE) = 0;
+ VALUE(U5STA) = PIC32_USTA_RIDLE | PIC32_USTA_TRMT;
+ VALUE(U5TXREG) = 0;
+ VALUE(U5RXREG) = 0;
+ VALUE(U5BRG) = 0;
+ VALUE(U6MODE) = 0;
+ VALUE(U6STA) = PIC32_USTA_RIDLE | PIC32_USTA_TRMT;
+ VALUE(U6TXREG) = 0;
+ VALUE(U6RXREG) = 0;
+ VALUE(U6BRG) = 0;
+
+ /*
+ * Reset SPI.
+ */
+ VALUE(SPI1CON) = 0;
+ VALUE(SPI1STAT) = PIC32_SPISTAT_SPITBE; /* Transmit buffer is empty */
+ VALUE(SPI1BRG) = 0;
+
+ VALUE(SPI2CON) = 0;
+ VALUE(SPI2STAT) = PIC32_SPISTAT_SPITBE; /* Transmit buffer is empty */
+ VALUE(SPI2BRG) = 0;
+
+ VALUE(SPI3CON) = 0;
+ VALUE(SPI3STAT) = PIC32_SPISTAT_SPITBE; /* Transmit buffer is empty */
+ VALUE(SPI3BRG) = 0;
+
+ VALUE(SPI4CON) = 0;
+ VALUE(SPI4STAT) = PIC32_SPISTAT_SPITBE; /* Transmit buffer is empty */
+ VALUE(SPI4BRG) = 0;
+
+ for (i = 0; i < NUM_SPI; i++) {
+ s->spi[i].rfifo = 0;
+ s->spi[i].wfifo = 0;
+ }
+}
+
+static unsigned io_read32(pic32_t *s, unsigned offset, const char **namep)
+{
+ unsigned *bufp = &VALUE(offset);
+
+ switch (offset) {
+ /*-------------------------------------------------------------------------
+ * Bus matrix control registers.
+ */
+ STORAGE(BMXCON); break; /* Bus Mmatrix Control */
+ STORAGE(BMXDKPBA); break; /* Data RAM kernel program base address */
+ STORAGE(BMXDUDBA); break; /* Data RAM user data base address */
+ STORAGE(BMXDUPBA); break; /* Data RAM user program base address */
+ STORAGE(BMXPUPBA); break; /* Program Flash user program base address */
+ STORAGE(BMXDRMSZ); break; /* Data RAM memory size */
+ STORAGE(BMXPFMSZ); break; /* Program Flash memory size */
+ STORAGE(BMXBOOTSZ); break; /* Boot Flash size */
+
+ /*-------------------------------------------------------------------------
+ * Interrupt controller registers.
+ */
+ STORAGE(INTCON); break; /* Interrupt Control */
+ STORAGE(INTSTAT); break; /* Interrupt Status */
+ STORAGE(IFS0); break; /* IFS(0..2) - Interrupt Flag Status */
+ STORAGE(IFS1); break;
+ STORAGE(IFS2); break;
+ STORAGE(IEC0); break; /* IEC(0..2) - Interrupt Enable Control */
+ STORAGE(IEC1); break;
+ STORAGE(IEC2); break;
+ STORAGE(IPC0); break; /* IPC(0..11) - Interrupt Priority Control */
+ STORAGE(IPC1); break;
+ STORAGE(IPC2); break;
+ STORAGE(IPC3); break;
+ STORAGE(IPC4); break;
+ STORAGE(IPC5); break;
+ STORAGE(IPC6); break;
+ STORAGE(IPC7); break;
+ STORAGE(IPC8); break;
+ STORAGE(IPC9); break;
+ STORAGE(IPC10); break;
+ STORAGE(IPC11); break;
+ STORAGE(IPC12); break;
+
+ /*-------------------------------------------------------------------------
+ * Prefetch controller.
+ */
+ STORAGE(CHECON); break; /* Prefetch Control */
+
+ /*-------------------------------------------------------------------------
+ * System controller.
+ */
+ STORAGE(OSCCON); break; /* Oscillator Control */
+ STORAGE(OSCTUN); break; /* Oscillator Tuning */
+ STORAGE(DDPCON); break; /* Debug Data Port Control */
+ STORAGE(DEVID); break; /* Device Identifier */
+ STORAGE(SYSKEY); break; /* System Key */
+ STORAGE(RCON); break; /* Reset Control */
+ STORAGE(RSWRST); /* Software Reset */
+ if ((VALUE(RSWRST) & 1) && s->stop_on_reset) {
+ exit(0);
+ }
+ break;
+
+ /*-------------------------------------------------------------------------
+ * DMA controller.
+ */
+ STORAGE(DMACON); break; /* DMA Control */
+ STORAGE(DMASTAT); break; /* DMA Status */
+ STORAGE(DMAADDR); break; /* DMA Address */
+
+ /*-------------------------------------------------------------------------
+ * Analog to digital converter.
+ */
+ STORAGE(AD1CON1); break; /* Control register 1 */
+ STORAGE(AD1CON2); break; /* Control register 2 */
+ STORAGE(AD1CON3); break; /* Control register 3 */
+ STORAGE(AD1CHS); break; /* Channel select */
+ STORAGE(AD1CSSL); break; /* Input scan selection */
+ STORAGE(AD1PCFG); break; /* Port configuration */
+ STORAGE(ADC1BUF0); break; /* Result words */
+ STORAGE(ADC1BUF1); break;
+ STORAGE(ADC1BUF2); break;
+ STORAGE(ADC1BUF3); break;
+ STORAGE(ADC1BUF4); break;
+ STORAGE(ADC1BUF5); break;
+ STORAGE(ADC1BUF6); break;
+ STORAGE(ADC1BUF7); break;
+ STORAGE(ADC1BUF8); break;
+ STORAGE(ADC1BUF9); break;
+ STORAGE(ADC1BUFA); break;
+ STORAGE(ADC1BUFB); break;
+ STORAGE(ADC1BUFC); break;
+ STORAGE(ADC1BUFD); break;
+ STORAGE(ADC1BUFE); break;
+ STORAGE(ADC1BUFF); break;
+
+ /*--------------------------------------
+ * USB registers.
+ */
+ STORAGE(U1OTGIR); break; /* OTG interrupt flags */
+ STORAGE(U1OTGIE); break; /* OTG interrupt enable */
+ STORAGE(U1OTGSTAT); break; /* Comparator and pin status */
+ STORAGE(U1OTGCON); break; /* Resistor and pin control */
+ STORAGE(U1PWRC); break; /* Power control */
+ STORAGE(U1IR); break; /* Pending interrupt */
+ STORAGE(U1IE); break; /* Interrupt enable */
+ STORAGE(U1EIR); break; /* Pending error interrupt */
+ STORAGE(U1EIE); break; /* Error interrupt enable */
+ STORAGE(U1STAT); break; /* Status FIFO */
+ STORAGE(U1CON); break; /* Control */
+ STORAGE(U1ADDR); break; /* Address */
+ STORAGE(U1BDTP1); break; /* Buffer descriptor table pointer 1 */
+ STORAGE(U1FRML); break; /* Frame counter low */
+ STORAGE(U1FRMH); break; /* Frame counter high */
+ STORAGE(U1TOK); break; /* Host control */
+ STORAGE(U1SOF); break; /* SOF counter */
+ STORAGE(U1BDTP2); break; /* Buffer descriptor table pointer 2 */
+ STORAGE(U1BDTP3); break; /* Buffer descriptor table pointer 3 */
+ STORAGE(U1CNFG1); break; /* Debug and idle */
+ STORAGE(U1EP(0)); break; /* Endpoint control */
+ STORAGE(U1EP(1)); break;
+ STORAGE(U1EP(2)); break;
+ STORAGE(U1EP(3)); break;
+ STORAGE(U1EP(4)); break;
+ STORAGE(U1EP(5)); break;
+ STORAGE(U1EP(6)); break;
+ STORAGE(U1EP(7)); break;
+ STORAGE(U1EP(8)); break;
+ STORAGE(U1EP(9)); break;
+ STORAGE(U1EP(10)); break;
+ STORAGE(U1EP(11)); break;
+ STORAGE(U1EP(12)); break;
+ STORAGE(U1EP(13)); break;
+ STORAGE(U1EP(14)); break;
+ STORAGE(U1EP(15)); break;
+
+ /*-------------------------------------------------------------------------
+ * General purpose IO signals.
+ */
+ STORAGE(TRISA); break; /* Port A: mask of inputs */
+ STORAGE(PORTA); break; /* Port A: read inputs */
+ STORAGE(LATA); break; /* Port A: read outputs */
+ STORAGE(ODCA); break; /* Port A: open drain configuration */
+ STORAGE(TRISB); break; /* Port B: mask of inputs */
+ STORAGE(PORTB); break; /* Port B: read inputs */
+ STORAGE(LATB); break; /* Port B: read outputs */
+ STORAGE(ODCB); break; /* Port B: open drain configuration */
+ STORAGE(TRISC); break; /* Port C: mask of inputs */
+ STORAGE(PORTC); break; /* Port C: read inputs */
+ STORAGE(LATC); break; /* Port C: read outputs */
+ STORAGE(ODCC); break; /* Port C: open drain configuration */
+ STORAGE(TRISD); break; /* Port D: mask of inputs */
+ STORAGE(PORTD); break; /* Port D: read inputs */
+ STORAGE(LATD); break; /* Port D: read outputs */
+ STORAGE(ODCD); break; /* Port D: open drain configuration */
+ STORAGE(TRISE); break; /* Port E: mask of inputs */
+ STORAGE(PORTE); break; /* Port E: read inputs */
+ STORAGE(LATE); break; /* Port E: read outputs */
+ STORAGE(ODCE); break; /* Port E: open drain configuration */
+ STORAGE(TRISF); break; /* Port F: mask of inputs */
+ STORAGE(PORTF); break; /* Port F: read inputs */
+ STORAGE(LATF); break; /* Port F: read outputs */
+ STORAGE(ODCF); break; /* Port F: open drain configuration */
+ STORAGE(TRISG); break; /* Port G: mask of inputs */
+ STORAGE(PORTG); break; /* Port G: read inputs */
+ STORAGE(LATG); break; /* Port G: read outputs */
+ STORAGE(ODCG); break; /* Port G: open drain configuration */
+ STORAGE(CNCON); break; /* Interrupt-on-change control */
+ STORAGE(CNEN); break; /* Input change interrupt enable */
+ STORAGE(CNPUE); break; /* Input pin pull-up enable */
+
+ /*-------------------------------------------------------------------------
+ * UART 1.
+ */
+ STORAGE(U1RXREG); /* Receive data */
+ *bufp = pic32_uart_get_char(s, 0);
+ break;
+ STORAGE(U1BRG); break; /* Baud rate */
+ STORAGE(U1MODE); break; /* Mode */
+ STORAGE(U1STA); /* Status and control */
+ pic32_uart_poll_status(s, 0);
+ break;
+ STORAGE(U1TXREG); *bufp = 0; break; /* Transmit */
+ STORAGE(U1MODECLR); *bufp = 0; break;
+ STORAGE(U1MODESET); *bufp = 0; break;
+ STORAGE(U1MODEINV); *bufp = 0; break;
+ STORAGE(U1STACLR); *bufp = 0; break;
+ STORAGE(U1STASET); *bufp = 0; break;
+ STORAGE(U1STAINV); *bufp = 0; break;
+ STORAGE(U1BRGCLR); *bufp = 0; break;
+ STORAGE(U1BRGSET); *bufp = 0; break;
+ STORAGE(U1BRGINV); *bufp = 0; break;
+
+ /*-------------------------------------------------------------------------
+ * UART 2.
+ */
+ STORAGE(U2RXREG); /* Receive data */
+ *bufp = pic32_uart_get_char(s, 1);
+ break;
+ STORAGE(U2BRG); break; /* Baud rate */
+ STORAGE(U2MODE); break; /* Mode */
+ STORAGE(U2STA); /* Status and control */
+ pic32_uart_poll_status(s, 1);
+ break;
+ STORAGE(U2TXREG); *bufp = 0; break; /* Transmit */
+ STORAGE(U2MODECLR); *bufp = 0; break;
+ STORAGE(U2MODESET); *bufp = 0; break;
+ STORAGE(U2MODEINV); *bufp = 0; break;
+ STORAGE(U2STACLR); *bufp = 0; break;
+ STORAGE(U2STASET); *bufp = 0; break;
+ STORAGE(U2STAINV); *bufp = 0; break;
+ STORAGE(U2BRGCLR); *bufp = 0; break;
+ STORAGE(U2BRGSET); *bufp = 0; break;
+ STORAGE(U2BRGINV); *bufp = 0; break;
+
+ /*-------------------------------------------------------------------------
+ * UART 3.
+ */
+ STORAGE(U3RXREG); /* Receive data */
+ *bufp = pic32_uart_get_char(s, 2);
+ break;
+ STORAGE(U3BRG); break; /* Baud rate */
+ STORAGE(U3MODE); break; /* Mode */
+ STORAGE(U3STA); /* Status and control */
+ pic32_uart_poll_status(s, 2);
+ break;
+ STORAGE(U3TXREG); *bufp = 0; break; /* Transmit */
+ STORAGE(U3MODECLR); *bufp = 0; break;
+ STORAGE(U3MODESET); *bufp = 0; break;
+ STORAGE(U3MODEINV); *bufp = 0; break;
+ STORAGE(U3STACLR); *bufp = 0; break;
+ STORAGE(U3STASET); *bufp = 0; break;
+ STORAGE(U3STAINV); *bufp = 0; break;
+ STORAGE(U3BRGCLR); *bufp = 0; break;
+ STORAGE(U3BRGSET); *bufp = 0; break;
+ STORAGE(U3BRGINV); *bufp = 0; break;
+
+ /*-------------------------------------------------------------------------
+ * UART 4.
+ */
+ STORAGE(U4RXREG); /* Receive data */
+ *bufp = pic32_uart_get_char(s, 3);
+ break;
+ STORAGE(U4BRG); break; /* Baud rate */
+ STORAGE(U4MODE); break; /* Mode */
+ STORAGE(U4STA); /* Status and control */
+ pic32_uart_poll_status(s, 3);
+ break;
+ STORAGE(U4TXREG); *bufp = 0; break; /* Transmit */
+ STORAGE(U4MODECLR); *bufp = 0; break;
+ STORAGE(U4MODESET); *bufp = 0; break;
+ STORAGE(U4MODEINV); *bufp = 0; break;
+ STORAGE(U4STACLR); *bufp = 0; break;
+ STORAGE(U4STASET); *bufp = 0; break;
+ STORAGE(U4STAINV); *bufp = 0; break;
+ STORAGE(U4BRGCLR); *bufp = 0; break;
+ STORAGE(U4BRGSET); *bufp = 0; break;
+ STORAGE(U4BRGINV); *bufp = 0; break;
+
+ /*-------------------------------------------------------------------------
+ * UART 5.
+ */
+ STORAGE(U5RXREG); /* Receive data */
+ *bufp = pic32_uart_get_char(s, 4);
+ break;
+ STORAGE(U5BRG); break; /* Baud rate */
+ STORAGE(U5MODE); break; /* Mode */
+ STORAGE(U5STA); /* Status and control */
+ pic32_uart_poll_status(s, 4);
+ break;
+ STORAGE(U5TXREG); *bufp = 0; break; /* Transmit */
+ STORAGE(U5MODECLR); *bufp = 0; break;
+ STORAGE(U5MODESET); *bufp = 0; break;
+ STORAGE(U5MODEINV); *bufp = 0; break;
+ STORAGE(U5STACLR); *bufp = 0; break;
+ STORAGE(U5STASET); *bufp = 0; break;
+ STORAGE(U5STAINV); *bufp = 0; break;
+ STORAGE(U5BRGCLR); *bufp = 0; break;
+ STORAGE(U5BRGSET); *bufp = 0; break;
+ STORAGE(U5BRGINV); *bufp = 0; break;
+
+ /*-------------------------------------------------------------------------
+ * UART 6.
+ */
+ STORAGE(U6RXREG); /* Receive data */
+ *bufp = pic32_uart_get_char(s, 5);
+ break;
+ STORAGE(U6BRG); break; /* Baud rate */
+ STORAGE(U6MODE); break; /* Mode */
+ STORAGE(U6STA); /* Status and control */
+ pic32_uart_poll_status(s, 5);
+ break;
+ STORAGE(U6TXREG); *bufp = 0; break; /* Transmit */
+ STORAGE(U6MODECLR); *bufp = 0; break;
+ STORAGE(U6MODESET); *bufp = 0; break;
+ STORAGE(U6MODEINV); *bufp = 0; break;
+ STORAGE(U6STACLR); *bufp = 0; break;
+ STORAGE(U6STASET); *bufp = 0; break;
+ STORAGE(U6STAINV); *bufp = 0; break;
+ STORAGE(U6BRGCLR); *bufp = 0; break;
+ STORAGE(U6BRGSET); *bufp = 0; break;
+ STORAGE(U6BRGINV); *bufp = 0; break;
+
+ /*-------------------------------------------------------------------------
+ * SPI 1.
+ */
+ STORAGE(SPI1CON); break; /* Control */
+ STORAGE(SPI1CONCLR); *bufp = 0; break;
+ STORAGE(SPI1CONSET); *bufp = 0; break;
+ STORAGE(SPI1CONINV); *bufp = 0; break;
+ STORAGE(SPI1STAT); break; /* Status */
+ STORAGE(SPI1STATCLR); *bufp = 0; break;
+ STORAGE(SPI1STATSET); *bufp = 0; break;
+ STORAGE(SPI1STATINV); *bufp = 0; break;
+ STORAGE(SPI1BUF); /* Buffer */
+ *bufp = pic32_spi_readbuf(s, 0);
+ break;
+ STORAGE(SPI1BRG); break; /* Baud rate */
+ STORAGE(SPI1BRGCLR); *bufp = 0; break;
+ STORAGE(SPI1BRGSET); *bufp = 0; break;
+ STORAGE(SPI1BRGINV); *bufp = 0; break;
+
+ /*-------------------------------------------------------------------------
+ * SPI 2.
+ */
+ STORAGE(SPI2CON); break; /* Control */
+ STORAGE(SPI2CONCLR); *bufp = 0; break;
+ STORAGE(SPI2CONSET); *bufp = 0; break;
+ STORAGE(SPI2CONINV); *bufp = 0; break;
+ STORAGE(SPI2STAT); break; /* Status */
+ STORAGE(SPI2STATCLR); *bufp = 0; break;
+ STORAGE(SPI2STATSET); *bufp = 0; break;
+ STORAGE(SPI2STATINV); *bufp = 0; break;
+ STORAGE(SPI2BUF); /* Buffer */
+ *bufp = pic32_spi_readbuf(s, 1);
+ break;
+ STORAGE(SPI2BRG); break; /* Baud rate */
+ STORAGE(SPI2BRGCLR); *bufp = 0; break;
+ STORAGE(SPI2BRGSET); *bufp = 0; break;
+ STORAGE(SPI2BRGINV); *bufp = 0; break;
+
+ /*-------------------------------------------------------------------------
+ * SPI 3.
+ */
+ STORAGE(SPI3CON); break; /* Control */
+ STORAGE(SPI3CONCLR); *bufp = 0; break;
+ STORAGE(SPI3CONSET); *bufp = 0; break;
+ STORAGE(SPI3CONINV); *bufp = 0; break;
+ STORAGE(SPI3STAT); break; /* Status */
+ STORAGE(SPI3STATCLR); *bufp = 0; break;
+ STORAGE(SPI3STATSET); *bufp = 0; break;
+ STORAGE(SPI3STATINV); *bufp = 0; break;
+ STORAGE(SPI3BUF); /* SPIx Buffer */
+ *bufp = pic32_spi_readbuf(s, 2);
+ break;
+ STORAGE(SPI3BRG); break; /* Baud rate */
+ STORAGE(SPI3BRGCLR); *bufp = 0; break;
+ STORAGE(SPI3BRGSET); *bufp = 0; break;
+ STORAGE(SPI3BRGINV); *bufp = 0; break;
+
+ /*-------------------------------------------------------------------------
+ * SPI 4.
+ */
+ STORAGE(SPI4CON); break; /* Control */
+ STORAGE(SPI4CONCLR); *bufp = 0; break;
+ STORAGE(SPI4CONSET); *bufp = 0; break;
+ STORAGE(SPI4CONINV); *bufp = 0; break;
+ STORAGE(SPI4STAT); break; /* Status */
+ STORAGE(SPI4STATCLR); *bufp = 0; break;
+ STORAGE(SPI4STATSET); *bufp = 0; break;
+ STORAGE(SPI4STATINV); *bufp = 0; break;
+ STORAGE(SPI4BUF); /* Buffer */
+ *bufp = pic32_spi_readbuf(s, 3);
+ break;
+ STORAGE(SPI4BRG); break; /* Baud rate */
+ STORAGE(SPI4BRGCLR); *bufp = 0; break;
+ STORAGE(SPI4BRGSET); *bufp = 0; break;
+ STORAGE(SPI4BRGINV); *bufp = 0; break;
+
+ default:
+ printf("--- Read 1f8%05x: peripheral register not supported\n",
+ offset);
+ if (TRACE) {
+ fprintf(qemu_logfile,
+ "--- Read 1f8%05x: peripheral register not supported\n",
+ offset);
+ }
+ exit(1);
+ }
+ return *bufp;
+}
+
+static void io_write32(pic32_t *s, unsigned offset, unsigned data,
+ const char **namep)
+{
+ unsigned *bufp = &VALUE(offset);
+
+ switch (offset) {
+ /*-------------------------------------------------------------------------
+ * Bus matrix control registers.
+ */
+ WRITEOP(BMXCON); return; /* Bus Matrix Control */
+ STORAGE(BMXDKPBA); break; /* Data RAM kernel program base address */
+ STORAGE(BMXDUDBA); break; /* Data RAM user data base address */
+ STORAGE(BMXDUPBA); break; /* Data RAM user program base address */
+ STORAGE(BMXPUPBA); break; /* Program Flash user program base address */
+ READONLY(BMXDRMSZ); /* Data RAM memory size */
+ READONLY(BMXPFMSZ); /* Program Flash memory size */
+ READONLY(BMXBOOTSZ); /* Boot Flash size */
+
+ /*-------------------------------------------------------------------------
+ * Interrupt controller registers.
+ */
+ WRITEOP(INTCON); return; /* Interrupt Control */
+ READONLY(INTSTAT); /* Interrupt Status */
+ WRITEOP(IPTMR); return; /* Temporal Proximity Timer */
+ WRITEOP(IFS0); goto irq; /* IFS(0..2) - Interrupt Flag Status */
+ WRITEOP(IFS1); goto irq;
+ WRITEOP(IFS2); goto irq;
+ WRITEOP(IEC0); goto irq; /* IEC(0..2) - Interrupt Enable Control */
+ WRITEOP(IEC1); goto irq;
+ WRITEOP(IEC2); goto irq;
+ WRITEOP(IPC0); goto irq; /* IPC(0..11) - Interrupt Priority Control */
+ WRITEOP(IPC1); goto irq;
+ WRITEOP(IPC2); goto irq;
+ WRITEOP(IPC3); goto irq;
+ WRITEOP(IPC4); goto irq;
+ WRITEOP(IPC5); goto irq;
+ WRITEOP(IPC6); goto irq;
+ WRITEOP(IPC7); goto irq;
+ WRITEOP(IPC8); goto irq;
+ WRITEOP(IPC9); goto irq;
+ WRITEOP(IPC10); goto irq;
+ WRITEOP(IPC11); goto irq;
+ WRITEOP(IPC12);
+irq: update_irq_status(s);
+ return;
+
+ /*-------------------------------------------------------------------------
+ * Prefetch controller.
+ */
+ WRITEOP(CHECON); /* Prefetch Control */
+ return;
+
+ /*-------------------------------------------------------------------------
+ * System controller.
+ */
+ WRITEOPR(OSCCON, PIC32_OSCCON_UNUSED); /* Oscillator Control */
+ break;
+ WRITEOPR(OSCTUN, PIC32_OSCTUN_UNUSED); /* Oscillator Tuning */
+ break;
+ STORAGE(DDPCON); /* Debug Data Port Control */
+ break;
+ READONLY(DEVID); /* Device Identifier */
+
+ STORAGE(SYSKEY); /* System Key */
+ /* Unlock state machine. */
+ if (s->syskey_unlock == 0 && VALUE(SYSKEY) == 0xaa996655) {
+ s->syskey_unlock = 1;
+ }
+ if (s->syskey_unlock == 1 && VALUE(SYSKEY) == 0x556699aa) {
+ s->syskey_unlock = 2;
+ } else {
+ s->syskey_unlock = 0;
+ }
+ break;
+ WRITEOPR(RCON, PIC32_RCON_UNUSED); /* Reset Control */
+ break;
+ WRITEOP(RSWRST); /* Software Reset */
+ if (s->syskey_unlock == 2 && (VALUE(RSWRST) & 1)) {
+ /* Reset CPU. */
+ qemu_system_reset_request();
+
+ /* Reset all devices */
+ io_reset(s);
+ pic32_sdcard_reset(s);
+ }
+ break;
+
+ /*-------------------------------------------------------------------------
+ * DMA controller.
+ */
+ WRITEOP(DMACON); return; /* DMA Control */
+ STORAGE(DMASTAT); break; /* DMA Status */
+ STORAGE(DMAADDR); break; /* DMA Address */
+
+ /*-------------------------------------------------------------------------
+ * Analog to digital converter.
+ */
+ WRITEOP(AD1CON1); return; /* Control register 1 */
+ WRITEOP(AD1CON2); return; /* Control register 2 */
+ WRITEOP(AD1CON3); return; /* Control register 3 */
+ WRITEOP(AD1CHS); return; /* Channel select */
+ WRITEOP(AD1CSSL); return; /* Input scan selection */
+ WRITEOP(AD1PCFG); return; /* Port configuration */
+ READONLY(ADC1BUF0); /* Result words */
+ READONLY(ADC1BUF1);
+ READONLY(ADC1BUF2);
+ READONLY(ADC1BUF3);
+ READONLY(ADC1BUF4);
+ READONLY(ADC1BUF5);
+ READONLY(ADC1BUF6);
+ READONLY(ADC1BUF7);
+ READONLY(ADC1BUF8);
+ READONLY(ADC1BUF9);
+ READONLY(ADC1BUFA);
+ READONLY(ADC1BUFB);
+ READONLY(ADC1BUFC);
+ READONLY(ADC1BUFD);
+ READONLY(ADC1BUFE);
+ READONLY(ADC1BUFF);
+
+ /*--------------------------------------
+ * USB registers.
+ */
+ STORAGE(U1OTGIR); /* OTG interrupt flags */
+ VALUE(U1OTGIR) = 0;
+ return;
+ STORAGE(U1OTGIE); break; /* OTG interrupt enable */
+ READONLY(U1OTGSTAT); /* Comparator and pin status */
+ STORAGE(U1OTGCON); break; /* Resistor and pin control */
+ STORAGE(U1PWRC); break; /* Power control */
+ STORAGE(U1IR); /* Pending interrupt */
+ VALUE(U1IR) = 0;
+ return;
+ STORAGE(U1IE); break; /* Interrupt enable */
+ STORAGE(U1EIR); /* Pending error interrupt */
+ VALUE(U1EIR) = 0;
+ return;
+ STORAGE(U1EIE); break; /* Error interrupt enable */
+ READONLY(U1STAT); /* Status FIFO */
+ STORAGE(U1CON); break; /* Control */
+ STORAGE(U1ADDR); break; /* Address */
+ STORAGE(U1BDTP1); break; /* Buffer descriptor table pointer 1 */
+ READONLY(U1FRML); /* Frame counter low */
+ READONLY(U1FRMH); /* Frame counter high */
+ STORAGE(U1TOK); break; /* Host control */
+ STORAGE(U1SOF); break; /* SOF counter */
+ STORAGE(U1BDTP2); break; /* Buffer descriptor table pointer 2 */
+ STORAGE(U1BDTP3); break; /* Buffer descriptor table pointer 3 */
+ STORAGE(U1CNFG1); break; /* Debug and idle */
+ STORAGE(U1EP(0)); break; /* Endpoint control */
+ STORAGE(U1EP(1)); break;
+ STORAGE(U1EP(2)); break;
+ STORAGE(U1EP(3)); break;
+ STORAGE(U1EP(4)); break;
+ STORAGE(U1EP(5)); break;
+ STORAGE(U1EP(6)); break;
+ STORAGE(U1EP(7)); break;
+ STORAGE(U1EP(8)); break;
+ STORAGE(U1EP(9)); break;
+ STORAGE(U1EP(10)); break;
+ STORAGE(U1EP(11)); break;
+ STORAGE(U1EP(12)); break;
+ STORAGE(U1EP(13)); break;
+ STORAGE(U1EP(14)); break;
+ STORAGE(U1EP(15)); break;
+
+ /*-------------------------------------------------------------------------
+ * General purpose IO signals.
+ */
+ WRITEOP(TRISA); return; /* Port A: mask of inputs */
+ WRITEOPX(PORTA, LATA); /* Port A: write outputs */
+ WRITEOP(LATA); /* Port A: write outputs */
+ pic32_gpio_write(s, 0, VALUE(LATA));
+ return;
+ WRITEOP(ODCA); return; /* Port A: open drain configuration */
+ WRITEOP(TRISB); return; /* Port B: mask of inputs */
+ WRITEOPX(PORTB, LATB); /* Port B: write outputs */
+ WRITEOP(LATB); /* Port B: write outputs */
+ pic32_gpio_write(s, 1, VALUE(LATB));
+ return;
+ WRITEOP(ODCB); return; /* Port B: open drain configuration */
+ WRITEOP(TRISC); return; /* Port C: mask of inputs */
+ WRITEOPX(PORTC, LATC); /* Port C: write outputs */
+ WRITEOP(LATC); /* Port C: write outputs */
+ pic32_gpio_write(s, 2, VALUE(LATC));
+ return;
+ WRITEOP(ODCC); return; /* Port C: open drain configuration */
+ WRITEOP(TRISD); return; /* Port D: mask of inputs */
+ WRITEOPX(PORTD, LATD); /* Port D: write outputs */
+ WRITEOP(LATD); /* Port D: write outputs */
+ pic32_gpio_write(s, 3, VALUE(LATD));
+ return;
+ WRITEOP(ODCD); return; /* Port D: open drain configuration */
+ WRITEOP(TRISE); return; /* Port E: mask of inputs */
+ WRITEOPX(PORTE, LATE); /* Port E: write outputs */
+ WRITEOP(LATE); /* Port E: write outputs */
+ pic32_gpio_write(s, 4, VALUE(LATE));
+ return;
+ WRITEOP(ODCE); return; /* Port E: open drain configuration */
+ WRITEOP(TRISF); return; /* Port F: mask of inputs */
+ WRITEOPX(PORTF, LATF); /* Port F: write outputs */
+ WRITEOP(LATF); /* Port F: write outputs */
+ pic32_gpio_write(s, 5, VALUE(LATF));
+ return;
+ WRITEOP(ODCF); return; /* Port F: open drain configuration */
+ WRITEOP(TRISG); return; /* Port G: mask of inputs */
+ WRITEOPX(PORTG, LATG); /* Port G: write outputs */
+ WRITEOP(LATG); /* Port G: write outputs */
+ pic32_gpio_write(s, 6, VALUE(LATG));
+ return;
+ WRITEOP(ODCG); return; /* Port G: open drain configuration */
+ WRITEOP(CNCON); return; /* Interrupt-on-change control */
+ WRITEOP(CNEN); return; /* Input change interrupt enable */
+ WRITEOP(CNPUE); return; /* Input pin pull-up enable */
+
+ /*-------------------------------------------------------------------------
+ * UART 1.
+ */
+ STORAGE(U1TXREG); /* Transmit */
+ pic32_uart_put_char(s, 0, data);
+ break;
+ WRITEOP(U1MODE); /* Mode */
+ pic32_uart_update_mode(s, 0);
+ return;
+ WRITEOPR(U1STA, /* Status and control */
+ PIC32_USTA_URXDA | PIC32_USTA_FERR | PIC32_USTA_PERR |
+ PIC32_USTA_RIDLE | PIC32_USTA_TRMT | PIC32_USTA_UTXBF);
+ pic32_uart_update_status(s, 0);
+ return;
+ WRITEOP(U1BRG); return; /* Baud rate */
+ READONLY(U1RXREG); /* Receive */
+
+ /*-------------------------------------------------------------------------
+ * UART 2.
+ */
+ STORAGE(U2TXREG); /* Transmit */
+ pic32_uart_put_char(s, 1, data);
+ break;
+ WRITEOP(U2MODE); /* Mode */
+ pic32_uart_update_mode(s, 1);
+ return;
+ WRITEOPR(U2STA, /* Status and control */
+ PIC32_USTA_URXDA | PIC32_USTA_FERR | PIC32_USTA_PERR |
+ PIC32_USTA_RIDLE | PIC32_USTA_TRMT | PIC32_USTA_UTXBF);
+ pic32_uart_update_status(s, 1);
+ return;
+ WRITEOP(U2BRG); return; /* Baud rate */
+ READONLY(U2RXREG); /* Receive */
+
+ /*-------------------------------------------------------------------------
+ * UART 3.
+ */
+ STORAGE(U3TXREG); /* Transmit */
+ pic32_uart_put_char(s, 2, data);
+ break;
+ WRITEOP(U3MODE); /* Mode */
+ pic32_uart_update_mode(s, 2);
+ return;
+ WRITEOPR(U3STA, /* Status and control */
+ PIC32_USTA_URXDA | PIC32_USTA_FERR | PIC32_USTA_PERR |
+ PIC32_USTA_RIDLE | PIC32_USTA_TRMT | PIC32_USTA_UTXBF);
+ pic32_uart_update_status(s, 2);
+ return;
+ WRITEOP(U3BRG); return; /* Baud rate */
+ READONLY(U3RXREG); /* Receive */
+
+ /*-------------------------------------------------------------------------
+ * UART 4.
+ */
+ STORAGE(U4TXREG); /* Transmit */
+ pic32_uart_put_char(s, 3, data);
+ break;
+ WRITEOP(U4MODE); /* Mode */
+ pic32_uart_update_mode(s, 3);
+ return;
+ WRITEOPR(U4STA, /* Status and control */
+ PIC32_USTA_URXDA | PIC32_USTA_FERR | PIC32_USTA_PERR |
+ PIC32_USTA_RIDLE | PIC32_USTA_TRMT | PIC32_USTA_UTXBF);
+ pic32_uart_update_status(s, 3);
+ return;
+ WRITEOP(U4BRG); return; /* Baud rate */
+ READONLY(U4RXREG); /* Receive */
+
+ /*-------------------------------------------------------------------------
+ * UART 5.
+ */
+ STORAGE(U5TXREG); /* Transmit */
+ pic32_uart_put_char(s, 4, data);
+ break;
+ WRITEOP(U5MODE); /* Mode */
+ pic32_uart_update_mode(s, 4);
+ return;
+ WRITEOPR(U5STA, /* Status and control */
+ PIC32_USTA_URXDA | PIC32_USTA_FERR | PIC32_USTA_PERR |
+ PIC32_USTA_RIDLE | PIC32_USTA_TRMT | PIC32_USTA_UTXBF);
+ pic32_uart_update_status(s, 4);
+ return;
+ WRITEOP(U5BRG); return; /* Baud rate */
+ READONLY(U5RXREG); /* Receive */
+
+ /*-------------------------------------------------------------------------
+ * UART 6.
+ */
+ STORAGE(U6TXREG); /* Transmit */
+ pic32_uart_put_char(s, 5, data);
+ break;
+ WRITEOP(U6MODE); /* Mode */
+ pic32_uart_update_mode(s, 5);
+ return;
+ WRITEOPR(U6STA, /* Status and control */
+ PIC32_USTA_URXDA | PIC32_USTA_FERR | PIC32_USTA_PERR |
+ PIC32_USTA_RIDLE | PIC32_USTA_TRMT | PIC32_USTA_UTXBF);
+ pic32_uart_update_status(s, 5);
+ return;
+ WRITEOP(U6BRG); return; /* Baud rate */
+ READONLY(U6RXREG); /* Receive */
+
+ /*-------------------------------------------------------------------------
+ * SPI.
+ */
+ WRITEOP(SPI1CON); /* Control */
+ pic32_spi_control(s, 0);
+ return;
+ WRITEOPR(SPI1STAT, ~PIC32_SPISTAT_SPIROV); /* Status */
+ return; /* Only ROV bit writable */
+ STORAGE(SPI1BUF); /* Buffer */
+ pic32_spi_writebuf(s, 0, data);
+ return;
+ WRITEOP(SPI1BRG); return; /* Baud rate */
+ WRITEOP(SPI2CON); /* Control */
+ pic32_spi_control(s, 1);
+ return;
+ WRITEOPR(SPI2STAT, ~PIC32_SPISTAT_SPIROV); /* Status */
+ return; /* Only ROV bit writable */
+ STORAGE(SPI2BUF); /* Buffer */
+ pic32_spi_writebuf(s, 1, data);
+ return;
+ WRITEOP(SPI2BRG); return; /* Baud rate */
+ WRITEOP(SPI3CON); /* Control */
+ pic32_spi_control(s, 2);
+ return;
+ WRITEOPR(SPI3STAT, ~PIC32_SPISTAT_SPIROV); /* Status */
+ return; /* Only ROV bit writable */
+ STORAGE(SPI3BUF); /* Buffer */
+ pic32_spi_writebuf(s, 2, data);
+ return;
+ WRITEOP(SPI3BRG); return; /* Baud rate */
+ WRITEOP(SPI4CON); /* Control */
+ pic32_spi_control(s, 3);
+ return;
+ WRITEOPR(SPI4STAT, ~PIC32_SPISTAT_SPIROV); /* Status */
+ return; /* Only ROV bit writable */
+ STORAGE(SPI4BUF); /* Buffer */
+ pic32_spi_writebuf(s, 3, data);
+ return;
+ WRITEOP(SPI4BRG); return; /* Baud rate */
+
+ default:
+ printf("--- Write %08x to 1f8%05x: peripheral register not
supported\n",
+ data, offset);
+ if (TRACE) {
+ fprintf(qemu_logfile,
+ "--- Write %08x to 1f8%05x: peripheral register not supported\n",
+ data, offset);
+ }
+ exit(1);
+readonly:
+ printf("--- Write %08x to %s: readonly register\n",
+ data, *namep);
+ if (TRACE) {
+ fprintf(qemu_logfile, "--- Write %08x to %s: readonly register\n",
+ data, *namep);
+ }
+ *namep = 0;
+ return;
+ }
+ *bufp = data;
+}
+
+static uint64_t pic32_io_read(void *opaque, hwaddr addr, unsigned bytes)
+{
+ pic32_t *s = opaque;
+ uint32_t offset = addr & 0xfffff;
+ const char *name = "???";
+ uint32_t data = 0;
+
+ data = io_read32(s, offset & ~3, &name);
+ switch (bytes) {
+ case 1:
+ offset &= 3;
+ if (offset != 0) {
+ /* Unaligned read. */
+ data >>= offset * 8;
+ }
+ data = (uint8_t) data;
+ if (TRACE) {
+ fprintf(qemu_logfile, "--- I/O Read %02x from %s\n", data, name);
+ }
+ break;
+ case 2:
+ if (offset & 2) {
+ /* Unaligned read. */
+ data >>= 16;
+ }
+ data = (uint16_t) data;
+ if (TRACE) {
+ fprintf(qemu_logfile, "--- I/O Read %04x from %s\n", data, name);
+ }
+ break;
+ default:
+ if (TRACE) {
+ fprintf(qemu_logfile, "--- I/O Read %08x from %s\n", data, name);
+ }
+ break;
+ }
+ return data;
+}
+
+static void pic32_io_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned bytes)
+{
+ pic32_t *s = opaque;
+ uint32_t offset = addr & 0xfffff;
+ const char *name = "???";
+
+ /* Fetch data and align to word format. */
+ switch (bytes) {
+ case 1:
+ data = (uint8_t) data;
+ data <<= (offset & 3) * 8;
+ break;
+ case 2:
+ data = (uint16_t) data;
+ data <<= (offset & 2) * 8;
+ break;
+ }
+ io_write32(s, offset & ~3, data, &name);
+
+ if (TRACE && name != 0) {
+ fprintf(qemu_logfile, "--- I/O Write %08x to %s\n",
+ (uint32_t) data, name);
+ }
+}
+
+/*
+ * This function is called when the processor is stopped
+ * on WAIT instruction, waiting for external interrupt.
+ */
+static void pic32_exec_exit(CPUState *cs)
+{
+ MIPSCPU *cpu = MIPS_CPU(cs);
+ CPUMIPSState *env = &cpu->env;
+
+ if (cs->halted && !(env->CP0_Status & (1 << CP0St_IE))) {
+ /* WAIT instruction with interrupts disabled - halt the simulation. */
+ qemu_system_shutdown_request();
+ }
+}
+
+static const MemoryRegionOps pic32_io_ops = {
+ .read = pic32_io_read,
+ .write = pic32_io_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void main_cpu_reset(void *opaque)
+{
+ MIPSCPU *cpu = opaque;
+ CPUMIPSState *env = &cpu->env;
+ int i;
+
+ cpu_reset(CPU(cpu));
+
+ /* Adjust the initial configuration for M4K core. */
+ env->CP0_IntCtl = 0;
+ env->CP0_Debug = (1 << CP0DB_CNT) | (3 << CP0DB_VER);
+ for (i = 0; i < 7; i++) {
+ env->CP0_WatchHi[i] = 0;
+ }
+}
+
+static void store_byte(unsigned address, unsigned char byte)
+{
+ if (address >= PROGRAM_FLASH_START &&
+ address < PROGRAM_FLASH_START + PROGRAM_FLASH_SIZE) {
+ /*printf("Store %02x to program memory %08x\n", byte, address);*/
+ prog_ptr[address & 0xfffff] = byte;
+ return;
+ }
+
+ if (address >= BOOT_FLASH_START &&
+ address < BOOT_FLASH_START + BOOT_FLASH_SIZE) {
+ /*printf("Store %02x to boot memory %08x\n", byte, address);*/
+ boot_ptr[address & 0xffff] = byte;
+ return;
+ }
+
+ printf("Bad hex file: "
+ "incorrect address %08X, must be %08X-%08X or %08X-%08X\n",
+ address, PROGRAM_FLASH_START,
+ PROGRAM_FLASH_START + PROGRAM_FLASH_SIZE - 1,
+ BOOT_FLASH_START, BOOT_FLASH_START + BOOT_FLASH_SIZE - 1);
+ exit(1);
+}
+
+/*
+ * Ignore ^C and ^\ signals and pass these characters to the target.
+ */
+static void pic32_pass_signal_chars(void)
+{
+ struct termios tty;
+
+ tcgetattr(0, &tty);
+ tty.c_lflag &= ~ISIG;
+ tcsetattr(0, TCSANOW, &tty);
+}
+
+static void pic32_init(MachineState *machine, int board_type)
+{
+ const char *cpu_model = machine->cpu_model;
+ unsigned ram_size = DATA_MEM_SIZE;
+ MemoryRegion *system_memory = get_system_memory();
+ MemoryRegion *ram_main = g_new(MemoryRegion, 1);
+ MemoryRegion *prog_mem = g_new(MemoryRegion, 1);
+ MemoryRegion *boot_mem = g_new(MemoryRegion, 1);
+ MemoryRegion *io_mem = g_new(MemoryRegion, 1);
+ MIPSCPU *cpu;
+ CPUMIPSState *env;
+
+ DeviceState *dev = qdev_create(NULL, TYPE_MIPS_PIC32);
+ pic32_t *s = OBJECT_CHECK(pic32_t, dev, TYPE_MIPS_PIC32);
+ s->board_type = board_type;
+ s->stop_on_reset = 1; /* halt simulation on soft reset */
+ s->iomem = g_malloc0(IO_MEM_SIZE); /* backing storage for I/O area */
+
+ qdev_init_nofail(dev);
+
+ /* Init CPU. */
+ if (!cpu_model) {
+ cpu_model = "M4K";
+ }
+ printf("Board: %s\n", board_name[board_type]);
+ if (qemu_logfile) {
+ fprintf(qemu_logfile, "Board: %s\n", board_name[board_type]);
+ }
+
+ printf("Processor: %s\n", cpu_model);
+ if (qemu_logfile) {
+ fprintf(qemu_logfile, "Processor: %s\n", cpu_model);
+ }
+
+ cpu = cpu_mips_init(cpu_model);
+ if (!cpu) {
+ fprintf(stderr, "Unable to find CPU definition\n");
+ exit(1);
+ }
+ s->cpu = cpu;
+ env = &cpu->env;
+
+ /* Register RAM */
+ printf("RAM size: %u kbytes\n", ram_size / 1024);
+ if (qemu_logfile) {
+ fprintf(qemu_logfile, "RAM size: %u kbytes\n", ram_size / 1024);
+ }
+
+ memory_region_init_ram(ram_main, NULL, "kernel.ram",
+ ram_size, &error_abort);
+ vmstate_register_ram_global(ram_main);
+ memory_region_add_subregion(system_memory, DATA_MEM_START, ram_main);
+
+ /* Alias for user space 96 kbytes.
+ * For MX family only. */
+ MemoryRegion *ram_user = g_new(MemoryRegion, 1);
+ memory_region_init_alias(ram_user, NULL, "user.ram",
+ ram_main, 0x8000, ram_size - 0x8000);
+ memory_region_add_subregion(system_memory,
+ USER_MEM_START + 0x8000, ram_user);
+
+ /* Special function registers. */
+ memory_region_init_io(io_mem, NULL, &pic32_io_ops, s,
+ "io", IO_MEM_SIZE);
+ memory_region_add_subregion(system_memory, IO_MEM_START, io_mem);
+
+ /*
+ * Map the flash memory.
+ */
+ memory_region_init_ram(boot_mem, NULL, "boot.flash",
+ BOOT_FLASH_SIZE, &error_abort);
+ memory_region_init_ram(prog_mem, NULL, "prog.flash",
+ PROGRAM_FLASH_SIZE, &error_abort);
+
+ /* Load a Flash memory image. */
+ if (!machine->kernel_filename) {
+ error_report("No -kernel argument was specified.");
+ exit(1);
+ }
+ prog_ptr = memory_region_get_ram_ptr(prog_mem);
+ boot_ptr = memory_region_get_ram_ptr(boot_mem);
+ if (bios_name) {
+ pic32_load_hex_file(bios_name, store_byte);
+ }
+ pic32_load_hex_file(machine->kernel_filename, store_byte);
+
+ memory_region_set_readonly(boot_mem, true);
+ memory_region_set_readonly(prog_mem, true);
+ memory_region_add_subregion(system_memory, BOOT_FLASH_START, boot_mem);
+ memory_region_add_subregion(system_memory, PROGRAM_FLASH_START, prog_mem);
+
+ /* Init internal devices */
+ s->irq_raise = irq_raise;
+ s->irq_clear = irq_clear;
+ qemu_register_reset(main_cpu_reset, cpu);
+
+ /* Setup interrupt controller in EIC mode. */
+ qemu_irq *qi = qemu_allocate_irqs(pic32_irq_request, s, 3);
+ env->eic_timer_irq = qi[0];
+ env->eic_soft_irq[0] = qi[1];
+ env->eic_soft_irq[1] = qi[2];
+ env->CP0_Config3 |= 1 << CP0C3_VEIC;
+
+ /* CPU runs at 80MHz.
+ * Count register increases at half this rate. */
+ cpu_mips_clock_init(env, 40*1000*1000);
+
+ /* Setup callback for CPU halt. */
+ MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(cpu);
+ CPUClass *cc = CPU_CLASS(mcc);
+ cc->cpu_exec_exit = pic32_exec_exit;
+
+ /*
+ * Initialize board-specific parameters.
+ */
+ int cs0_port, cs0_pin, cs1_port, cs1_pin;
+ switch (board_type) {
+ default:
+ case BOARD_MAX32:
+ BOOTMEM(DEVCFG0) = 0xffffff7f; /* Max32 board */
+ BOOTMEM(DEVCFG1) = 0x5bfd6aff; /* console on UART1 */
+ BOOTMEM(DEVCFG2) = 0xd979f8f9;
+ BOOTMEM(DEVCFG3) = 0xffff0722;
+ VALUE(DEVID) = 0x04307053; /* MX795F512L */
+ VALUE(OSCCON) = 0x01453320; /* external oscillator 8MHz */
+ s->sdcard_spi_port = 1; /* SD card at SPI2, */
+ cs0_port = 2; cs0_pin = 14; /* select0 at C14, */
+ cs1_port = 3; cs1_pin = 1; /* select1 at D1 */
+ break;
+ case BOARD_MAXIMITE:
+ /* TODO: get real data from Maximite board */
+ BOOTMEM(DEVCFG0) = 0xffffff7f;
+ BOOTMEM(DEVCFG1) = 0x5bfd6aff; /* console on UART1 */
+ BOOTMEM(DEVCFG2) = 0xd979f8f9;
+ BOOTMEM(DEVCFG3) = 0xffff0722;
+ VALUE(DEVID) = 0x04307053; /* MX795F512L */
+ VALUE(OSCCON) = 0x01453320; /* external oscillator 8MHz */
+ s->sdcard_spi_port = 3; /* SD card at SPI4, */
+ cs0_port = 4; cs0_pin = 0; /* select0 at E0, */
+ cs1_port = -1; cs1_pin = -1; /* select1 not available */
+ break;
+ case BOARD_EXPLORER16:
+ /* TODO: get real data from Explorer16 board */
+ BOOTMEM(DEVCFG0) = 0xffffff7f;
+ BOOTMEM(DEVCFG1) = 0x5bfd6aff; /* console on UART2 */
+ BOOTMEM(DEVCFG2) = 0xd979f8f9;
+ BOOTMEM(DEVCFG3) = 0xffff0722;
+ VALUE(DEVID) = 0x04307053; /* MX795F512L */
+ VALUE(OSCCON) = 0x01453320; /* external oscillator 8MHz */
+ s->sdcard_spi_port = 0; /* SD card at SPI1, */
+ cs0_port = 1; cs0_pin = 1; /* select0 at B1, */
+ cs1_port = 1; cs1_pin = 2; /* select1 at B2 */
+ break;
+ }
+
+ /* UARTs */
+ pic32_uart_init(s, 0, PIC32_IRQ_U1E, U1STA, U1MODE);
+ pic32_uart_init(s, 1, PIC32_IRQ_U2E, U2STA, U2MODE);
+ pic32_uart_init(s, 2, PIC32_IRQ_U3E, U3STA, U3MODE);
+ pic32_uart_init(s, 3, PIC32_IRQ_U4E, U4STA, U4MODE);
+ pic32_uart_init(s, 4, PIC32_IRQ_U5E, U5STA, U5MODE);
+ pic32_uart_init(s, 5, PIC32_IRQ_U6E, U6STA, U6MODE);
+
+ /* SPIs */
+ pic32_spi_init(s, 0, PIC32_IRQ_SPI1E, SPI1CON, SPI1STAT);
+ pic32_spi_init(s, 1, PIC32_IRQ_SPI2E, SPI2CON, SPI2STAT);
+ pic32_spi_init(s, 2, PIC32_IRQ_SPI3E, SPI3CON, SPI3STAT);
+ pic32_spi_init(s, 3, PIC32_IRQ_SPI4E, SPI4CON, SPI4STAT);
+
+ /*
+ * Load SD card images.
+ * Use options:
+ * -sd filename
+ * or -hda filename
+ * and -hdb filename
+ */
+ const char *sd0_file = 0, *sd1_file = 0;
+ DriveInfo *dinfo = drive_get(IF_IDE, 0, 0);
+ if (dinfo) {
+ sd0_file = qemu_opt_get(dinfo->opts, "file");
+ dinfo->is_default = 1;
+
+ dinfo = drive_get(IF_IDE, 0, 1);
+ if (dinfo) {
+ sd1_file = qemu_opt_get(dinfo->opts, "file");
+ dinfo->is_default = 1;
+ }
+ }
+ if (!sd0_file) {
+ dinfo = drive_get(IF_SD, 0, 0);
+ if (dinfo) {
+ sd0_file = qemu_opt_get(dinfo->opts, "file");
+ dinfo->is_default = 1;
+ }
+ }
+ pic32_sdcard_init(s, 0, "sd0", sd0_file, cs0_port, cs0_pin);
+ pic32_sdcard_init(s, 1, "sd1", sd1_file, cs1_port, cs1_pin);
+
+ io_reset(s);
+ pic32_sdcard_reset(s);
+ pic32_pass_signal_chars();
+}
+
+static void pic32_init_max32(MachineState *machine)
+{
+ pic32_init(machine, BOARD_MAX32);
+}
+
+static void pic32_init_maximite(MachineState *machine)
+{
+ pic32_init(machine, BOARD_MAXIMITE);
+}
+
+static void pic32_init_explorer16(MachineState *machine)
+{
+ pic32_init(machine, BOARD_EXPLORER16);
+}
+
+static int pic32_sysbus_device_init(SysBusDevice *sysbusdev)
+{
+ return 0;
+}
+
+static void pic32_class_init(ObjectClass *klass, void *data)
+{
+ SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+ k->init = pic32_sysbus_device_init;
+}
+
+static const TypeInfo pic32_device = {
+ .name = TYPE_MIPS_PIC32,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(pic32_t),
+ .class_init = pic32_class_init,
+};
+
+static void pic32_register_types(void)
+{
+ type_register_static(&pic32_device);
+}
+
+static QEMUMachine pic32_board[3] = {
+ {
+ .name = "pic32mx7-max32",
+ .desc = "PIC32MX7 microcontroller on chipKIT Max32 board",
+ .init = pic32_init_max32,
+ .max_cpus = 1,
+ },
+ {
+ .name = "pic32mx7-maximite",
+ .desc = "PIC32MX7 microcontroller on Geoff's Maximite board",
+ .init = pic32_init_maximite,
+ .max_cpus = 1,
+ },
+ {
+ .name = "pic32mx7-explorer16",
+ .desc = "PIC32MX7 microcontroller on Microchip Explorer-16
board",
+ .init = pic32_init_explorer16,
+ .max_cpus = 1,
+ },
+};
+
+static void pic32_machine_init(void)
+{
+ qemu_register_machine(&pic32_board[0]);
+ qemu_register_machine(&pic32_board[1]);
+ qemu_register_machine(&pic32_board[2]);
+}
+
+type_init(pic32_register_types)
+machine_init(pic32_machine_init);
--
2.2.2
- [Qemu-devel] [PATCH pic32 v3 04/16] pic32: add two MIPS processor variants: M4K and microAptivUP, (continued)
- [Qemu-devel] [PATCH pic32 v3 04/16] pic32: add two MIPS processor variants: M4K and microAptivUP, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 05/16] pic32: add file pic32_peripherals.h, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 06/16] pic32: add file pic32mx.h, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 10/16] pic32: add file pic32_load_hex.c, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 12/16] pic32: add file pic32_gpio.c, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 11/16] pic32: add file pic32_uart.c, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 08/16] pic32: add file mips_pic32mx7.c,
Serge Vakulenko <=
- [Qemu-devel] [PATCH pic32 v3 13/16] pic32: add file pic32_spi.c, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 07/16] pic32: add file pic32mz.h, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 14/16] pic32: add file pic32_sdcard.c, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 16/16] pic32: update makefiles to cover pic32 support, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 15/16] pic32: add file pic32_ethernet.c, Serge Vakulenko, 2015/07/06
- [Qemu-devel] [PATCH pic32 v3 09/16] pic32: add file mips_pic32mz.c, Serge Vakulenko, 2015/07/06