[Qemu-devel] [PATCH v3 2/7] MIPS: Initial support of vt82686b south bridge used by fulong mini pc

2010-06-04 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.target |2 +-
 hw/pci_ids.h|8 +
 hw/vt82c686.c   |  579 +++
 hw/vt82c686.h   |   11 +
 4 files changed, 599 insertions(+), 1 deletions(-)
 create mode 100644 hw/vt82c686.c
 create mode 100644 hw/vt82c686.h

diff --git a/Makefile.target b/Makefile.target
index ac36e2c..92ba282 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -221,7 +221,7 @@ obj-mips-y += vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
-obj-mips-$(CONFIG_FULONG) += bonito.o
+obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/hw/pci_ids.h b/hw/pci_ids.h
index fe7a121..39e9f1d 100644
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@ -78,6 +78,14 @@
 
 #define PCI_VENDOR_ID_XILINX 0x10ee
 
+#define PCI_VENDOR_ID_VIA0x1106
+#define PCI_DEVICE_ID_VIA_ISA_BRIDGE 0x0686
+#define PCI_DEVICE_ID_VIA_IDE0x0571
+#define PCI_DEVICE_ID_VIA_UHCI   0x3038
+#define PCI_DEVICE_ID_VIA_ACPI   0x3057
+#define PCI_DEVICE_ID_VIA_AC97   0x3058
+#define PCI_DEVICE_ID_VIA_MC97   0x3068
+
 #define PCI_VENDOR_ID_MARVELL0x11ab
 
 #define PCI_VENDOR_ID_ENSONIQ0x1274
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
new file mode 100644
index 000..d7d9eaf
--- /dev/null
+++ b/hw/vt82c686.c
@@ -0,0 +1,579 @@
+/*
+ * VT82C686B south bridge support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2009 chenming (chenm...@rdc.faw.com.cn)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ * This code is licensed under the GNU GPL v2.
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "vt82c686.h"
+#include "i2c.h"
+#include "smbus.h"
+#include "pci.h"
+#include "isa.h"
+#include "sysbus.h"
+#include "mips.h"
+#include "apm.h"
+#include "acpi.h"
+#include "pm_smbus.h"
+
+typedef uint32_t pci_addr_t;
+#include "pci_host.h"
+//#define DEBUG_VT82C686B
+
+#ifdef DEBUG_VT82C686B
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, 
##__VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+typedef struct SuperIOConfig
+{
+uint8_t config[0xff];
+uint8_t index;
+uint8_t data;
+} SuperIOConfig;
+
+typedef struct VT82C686BState {
+PCIDevice dev;
+SuperIOConfig *superio_conf;
+} VT82C686BState;
+
+static void superio_ioport_writeb(void *opaque, uint32_t addr, uint32_t data)
+{
+int can_write;
+SuperIOConfig *superio_conf = (SuperIOConfig *)opaque;
+
+DPRINTF("superio_ioport_writeb  address 0x%x  val 0x%x  \n", addr, data);
+if (addr == 0x3f0) {
+superio_conf->index = data & 0xff;
+} else {
+/* 0x3f1 */
+switch (superio_conf->index) {
+case 0x00 ... 0xdf:
+case 0xe4:
+case 0xe5:
+case 0xe9 ... 0xed:
+case 0xf3:
+case 0xf5:
+case 0xf7:
+case 0xf9 ... 0xfb:
+case 0xfd ... 0xff:
+can_write = 0;
+break;
+default:
+can_write = 1;
+
+if (can_write) {
+switch (superio_conf->index) {
+case 0xe7:
+if ((data & 0xff) != 0xfe) {
+DPRINTF("chage uart 1 base. unsupported yet \n");
+}
+break;
+case 0xe8:
+if ((data & 0xff) != 0xbe) {
+DPRINTF("chage uart 2 base. unsupported yet \n");
+}
+break;
+
+default:
+superio_conf->config[superio_conf->index] = data & 0xff;
+}
+}
+}
+superio_conf->config[superio_conf->index] = data & 0xff;
+}
+}
+
+static uint32_t superio_ioport_readb(void *opaque, uint32_t addr)
+{
+SuperIOConfig *superio_conf = (SuperIOConfig *)opaque;
+
+DPRINTF("superio_ioport_readb  address 0x%x   \n", addr);
+return (superio_conf->config[superio_conf->index]);
+}
+
+static void vt82c686b_reset(void * opaque)
+{
+PCIDevice *d = opaque;
+uint8_t *pci_conf = d->config;
+VT82C686BState *vt82c = DO_UPCAST(VT82C686BState, dev, d);
+
+pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0);
+pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
+pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
+
+pci_conf[0x48] = 0x01; /* Miscellaneous Control 3 */
+pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */
+pci_conf[0x4f] = 0x03; /* DMA/Master Mem Access Control 3 */

[Qemu-devel] [PATCH v3 4/7] MIPS: Initial support of VIA USB controller used by fulong mini pc

2010-06-04 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 hw/usb-uhci.c |   20 
 hw/usb-uhci.h |1 +
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 624d55b..feb44e6 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1152,6 +1152,16 @@ static int usb_uhci_piix4_initfn(PCIDevice *dev)
 return usb_uhci_common_initfn(s);
 }
 
+static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
+{
+UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
+uint8_t *pci_conf = s->dev.config;
+
+pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
+pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_UHCI);
+return usb_uhci_common_initfn(s);
+}
+
 static PCIDeviceInfo uhci_info[] = {
 {
 .qdev.name= "piix3-usb-uhci",
@@ -1164,6 +1174,11 @@ static PCIDeviceInfo uhci_info[] = {
 .qdev.vmsd= &vmstate_uhci,
 .init = usb_uhci_piix4_initfn,
 },{
+.qdev.name= "vt82c686b-usb-uhci",
+.qdev.size= sizeof(UHCIState),
+.qdev.vmsd= &vmstate_uhci,
+.init = usb_uhci_vt82c686b_initfn,
+},{
 /* end of list */
 }
 };
@@ -1183,3 +1198,8 @@ void usb_uhci_piix4_init(PCIBus *bus, int devfn)
 {
 pci_create_simple(bus, devfn, "piix4-usb-uhci");
 }
+
+void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn)
+{
+pci_create_simple(bus, devfn, "vt82c686b-usb-uhci");
+}
diff --git a/hw/usb-uhci.h b/hw/usb-uhci.h
index 911948e..3e4d377 100644
--- a/hw/usb-uhci.h
+++ b/hw/usb-uhci.h
@@ -5,5 +5,6 @@
 
 void usb_uhci_piix3_init(PCIBus *bus, int devfn);
 void usb_uhci_piix4_init(PCIBus *bus, int devfn);
+void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn);
 
 #endif
-- 
1.7.0.4




[Qemu-devel] [PATCH v3 5/7] MIPS: Initial support of fulong mini pc (CPU definition)

2010-06-04 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 target-mips/mips-defs.h  |4 
 target-mips/translate_init.c |   35 +++
 2 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h
index c57de02..38594da 100644
--- a/target-mips/mips-defs.h
+++ b/target-mips/mips-defs.h
@@ -40,6 +40,8 @@
 #defineASE_SMARTMIPS   0x0004
 
 /* Chip specific instructions. */
+#defineINSN_LOONGSON2E  0x2000
+#defineINSN_LOONGSON2F  0x4000
 #defineINSN_VR54XX 0x8000
 
 /* MIPS CPU defines. */
@@ -48,6 +50,8 @@
 #defineCPU_MIPS3   (CPU_MIPS2 | ISA_MIPS3)
 #defineCPU_MIPS4   (CPU_MIPS3 | ISA_MIPS4)
 #defineCPU_VR54XX  (CPU_MIPS4 | INSN_VR54XX)
+#defineCPU_LOONGSON2E  (CPU_MIPS3 | INSN_LOONGSON2E)
+#defineCPU_LOONGSON2F  (CPU_MIPS3 | INSN_LOONGSON2F)
 
 #defineCPU_MIPS5   (CPU_MIPS4 | ISA_MIPS5)
 
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index b79ed56..0d9899e 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -454,6 +454,41 @@ static const mips_def_t mips_defs[] =
 .insn_flags = CPU_MIPS64R2 | ASE_MIPS3D,
 .mmu_type = MMU_TYPE_R4000,
 },
+{
+.name = "Loongson-2E",
+.CP0_PRid = 0x6302,
+/*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/
+.CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) | (0x1<<5) 
|
+   (0x1<<4) | (0x1<<1),
+/* Note: Config1 is only used internally, Loongson-2E has only 
Config0. */
+.CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
+.SYNCI_Step = 16,
+.CCRes = 2,
+.CP0_Status_rw_bitmask = 0x35D0,
+.CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV),
+.SEGBITS = 40,
+.PABITS = 40,
+.insn_flags = CPU_LOONGSON2E,
+.mmu_type = MMU_TYPE_R4000,
+},
+{
+  .name = "Loongson-2F",
+  .CP0_PRid = 0x6303,
+  /*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/
+  .CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) | (0x1<<5) |
+ (0x1<<4) | (0x1<<1),
+  /* Note: Config1 is only used internally, Loongson-2F has only Config0. 
*/
+  .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
+  .SYNCI_Step = 16,
+  .CCRes = 2,
+  .CP0_Status_rw_bitmask = 0xF5D0FF1F,   /*bit5:7 not writeable*/
+  .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV),
+  .SEGBITS = 40,
+  .PABITS = 40,
+  .insn_flags = CPU_LOONGSON2F,
+  .mmu_type = MMU_TYPE_R4000,
+},
+
 #endif
 };
 
-- 
1.7.0.4




[Qemu-devel] [PATCH v3 6/7] MIPS: Initial support of fulong mini pc (machine construction)

2010-06-04 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.target|2 +-
 hw/mips_fulong2e.c |  402 
 2 files changed, 403 insertions(+), 1 deletions(-)
 create mode 100644 hw/mips_fulong2e.c

diff --git a/Makefile.target b/Makefile.target
index 92ba282..f203c6b 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -221,7 +221,7 @@ obj-mips-y += vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
-obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o
+obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
new file mode 100644
index 000..1b54236
--- /dev/null
+++ b/hw/mips_fulong2e.c
@@ -0,0 +1,402 @@
+/*
+ * QEMU fulong 2e mini pc support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2009 chenming (chenm...@rdc.faw.com.cn)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ * This code is licensed under the GNU GPL v2.
+ */
+
+/*
+ * Fulong 2e mini pc is based on ICT/ST Loongson 2e CPU (MIPS III like, 800MHz)
+ * http://www.linux-mips.org/wiki/Fulong
+ *
+ * Loongson 2e user manual:
+ * http://www.loongsondeveloper.com/doc/Loongson2EUserGuide.pdf
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "fdc.h"
+#include "net.h"
+#include "boards.h"
+#include "smbus.h"
+#include "block.h"
+#include "flash.h"
+#include "mips.h"
+#include "mips_cpudevs.h"
+#include "pci.h"
+#include "usb-uhci.h"
+#include "qemu-char.h"
+#include "sysemu.h"
+#include "audio/audio.h"
+#include "qemu-log.h"
+#include "loader.h"
+#include "mips-bios.h"
+#include "ide.h"
+#include "elf.h"
+#include "vt82c686.h"
+#include "mc146818rtc.h"
+
+#define DEBUG_FULONG2E_INIT
+
+#define ENVP_ADDR   0x80002000l
+#define ENVP_NB_ENTRIES16
+#define ENVP_ENTRY_SIZE256
+
+#define MAX_IDE_BUS 2
+#define FULONG_BIOSNAME "pmon_fulong2e.bin"
+
+/* PCI SLOT in fulong 2e */
+#define FULONG2E_VIA_SLOT5
+#define FULONG2E_ATI_SLOT6
+#define FULONG2E_RTL8139_SLOT7
+
+static PITState *pit;
+
+static struct _loaderparams {
+int ram_size;
+const char *kernel_filename;
+const char *kernel_cmdline;
+const char *initrd_filename;
+} loaderparams;
+
+static void prom_set(uint32_t* prom_buf, int index, const char *string, ...)
+{
+va_list ap;
+int32_t table_addr;
+
+if (index >= ENVP_NB_ENTRIES)
+return;
+
+if (string == NULL) {
+prom_buf[index] = 0;
+return;
+}
+
+table_addr = sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
+prom_buf[index] = tswap32(ENVP_ADDR + table_addr);
+
+va_start(ap, string);
+vsnprintf((char *)prom_buf + table_addr, ENVP_ENTRY_SIZE, string, ap);
+va_end(ap);
+}
+
+static int64_t load_kernel (CPUState *env)
+{
+int64_t kernel_entry, kernel_low, kernel_high;
+int index = 0;
+long initrd_size;
+ram_addr_t initrd_offset;
+uint32_t *prom_buf;
+long prom_size;
+
+if (load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, NULL,
+ (uint64_t *)&kernel_entry, (uint64_t *)&kernel_low,
+ (uint64_t *)&kernel_high, 0, ELF_MACHINE, 1) < 0) {
+fprintf(stderr, "qemu: could not load kernel '%s'\n",
+loaderparams.kernel_filename);
+exit(1);
+}
+
+/* load initrd */
+initrd_size = 0;
+initrd_offset = 0;
+if (loaderparams.initrd_filename) {
+initrd_size = get_image_size (loaderparams.initrd_filename);
+if (initrd_size > 0) {
+initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & 
TARGET_PAGE_MASK;
+if (initrd_offset + initrd_size > ram_size) {
+fprintf(stderr,
+"qemu: memory too small for initial ram disk '%s'\n",
+loaderparams.initrd_filename);
+exit(1);
+}
+initrd_size = load_image_targphys(loaderparams.initrd_filename,
+ initrd_offset, ram_size - initrd_offset);
+}
+if (initrd_size == (target_ulong) -1) {
+fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
+loaderparams.initrd_filename);
+exit(1);
+}
+}
+
+/* Setup prom parameters. */
+prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t) + ENVP_ENTRY_SIZE);
+prom_buf = qemu_malloc(prom_size);
+
+prom_set(prom_buf, index++, loaderparams.kernel_filename);
+if (initrd_size > 0) {
+prom

[Qemu-devel] [PATCH v3 3/7] MIPS: Initial support of VIA IDE controller used by fulong mini pc

2010-06-04 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.objs|1 +
 default-configs/mips64el-softmmu.mak |1 +
 hw/ide.h |1 +
 hw/ide/via.c |  176 ++
 4 files changed, 179 insertions(+), 0 deletions(-)
 create mode 100644 hw/ide/via.c

diff --git a/Makefile.objs b/Makefile.objs
index 9796dcb..ad9a825 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -200,6 +200,7 @@ hw-obj-$(CONFIG_IDE_ISA) += ide/isa.o
 hw-obj-$(CONFIG_IDE_PIIX) += ide/piix.o
 hw-obj-$(CONFIG_IDE_CMD646) += ide/cmd646.o
 hw-obj-$(CONFIG_IDE_MACIO) += ide/macio.o
+hw-obj-$(CONFIG_IDE_VIA) += ide/via.o
 
 # SCSI layer
 hw-obj-y += lsi53c895a.o
diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index d35d923..85b7838 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -21,6 +21,7 @@ CONFIG_IDE_QDEV=y
 CONFIG_IDE_PCI=y
 CONFIG_IDE_ISA=y
 CONFIG_IDE_PIIX=y
+CONFIG_IDE_VIA=y
 CONFIG_NE2000_ISA=y
 CONFIG_SOUND=y
 CONFIG_VIRTIO_PCI=y
diff --git a/hw/ide.h b/hw/ide.h
index 0e7d540..bb635b6 100644
--- a/hw/ide.h
+++ b/hw/ide.h
@@ -12,6 +12,7 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
  int secondary_ide_enabled);
 void pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 void pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
+void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 
 /* ide-macio.c */
 int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
diff --git a/hw/ide/via.c b/hw/ide/via.c
new file mode 100644
index 000..bc3b44e
--- /dev/null
+++ b/hw/ide/via.c
@@ -0,0 +1,176 @@
+/*
+ * QEMU IDE Emulation: PCI VIA82C686B support.
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2006 Openedhand Ltd.
+ * Copyright (c) 2010 Huacai Chen 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include "block.h"
+#include "block_int.h"
+#include "sysemu.h"
+#include "dma.h"
+
+#include 
+
+static uint32_t bmdma_readb(void *opaque, uint32_t addr)
+{
+BMDMAState *bm = opaque;
+uint32_t val;
+
+switch (addr & 3) {
+case 0:
+val = bm->cmd;
+break;
+case 2:
+val = bm->status;
+break;
+default:
+val = 0xff;
+break;
+}
+#ifdef DEBUG_IDE
+printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
+#endif
+return val;
+}
+
+static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+BMDMAState *bm = opaque;
+#ifdef DEBUG_IDE
+printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
+#endif
+switch (addr & 3) {
+case 2:
+bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 
0x06);
+break;
+default:;
+}
+}
+
+static void bmdma_map(PCIDevice *pci_dev, int region_num,
+pcibus_t addr, pcibus_t size, int type)
+{
+PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
+int i;
+
+for(i = 0;i < 2; i++) {
+BMDMAState *bm = &d->bmdma[i];
+d->bus[i].bmdma = bm;
+bm->bus = d->bus+i;
+qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm);
+
+register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
+
+register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
+register_ioport_read(addr, 4, 1, bmdma_readb, bm);
+
+register_ioport_write(addr + 4, 4, 1, bmdma_addr_writeb, bm);
+register_ioport_read(addr + 4, 4, 1, bmdma_addr_readb, bm);
+register_ioport_write(addr + 4, 4, 2, bmdma_addr_writew, bm);
+register_ioport_read(addr + 4, 4, 2, bmdma_addr_readw, bm);
+register_ioport_write(addr + 4, 4, 4, bmdma_addr_wri

[Qemu-devel] [PATCH v3 1/7] MIPS: Initial support of bonito north bridge used by fulong mini pc

2010-06-04 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.target  |1 +
 default-configs/mips64el-softmmu.mak |1 +
 hw/bonito.c  |  816 ++
 hw/mips.h|3 +
 4 files changed, 821 insertions(+), 0 deletions(-)
 create mode 100644 hw/bonito.c

diff --git a/Makefile.target b/Makefile.target
index d06c679..ac36e2c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -221,6 +221,7 @@ obj-mips-y += vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
+obj-mips-$(CONFIG_FULONG) += bonito.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index b372c1d..d35d923 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -29,3 +29,4 @@ CONFIG_DP8393X=y
 CONFIG_DS1225Y=y
 CONFIG_MIPSNET=y
 CONFIG_PFLASH_CFI01=y
+CONFIG_FULONG=y
diff --git a/hw/bonito.c b/hw/bonito.c
new file mode 100644
index 000..4f21042
--- /dev/null
+++ b/hw/bonito.c
@@ -0,0 +1,816 @@
+/*
+ * bonito north bridge support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ *
+ * This code is licensed under the GNU GPL v2.
+ */
+
+/*
+ * fulong 2e mini pc has a bonito north bridge.
+ */
+
+/* what is the meaning of devfn in qemu and IDSEL in bonito northbridge?
+ *
+ * devfn   pci_slot<<3  + funno
+ * one pci bus can have 32 devices and each device can have 8 functions.
+ *
+ * In bonito north bridge, pci slot = IDSEL bit - 12.
+ * For example, PCI_IDSEL_VIA686B = 17,
+ * pci slot = 17-12=5
+ *
+ * so
+ * VT686B_FUN0's devfn = (5<<3)+0
+ * VT686B_FUN1's devfn = (5<<3)+1
+ *
+ * qemu also uses pci address for north bridge to access pci config register.
+ * bus_no   [23:16]
+ * dev_no   [15:11]
+ * fun_no   [10:8]
+ * reg_no   [7:2]
+ *
+ * so function bonito_sbridge_pciaddr for the translation from
+ * north bridge address to pci address.
+ */
+
+#include 
+
+#include "hw.h"
+#include "pci.h"
+#include "pc.h"
+#include "mips.h"
+#include "pci_host.h"
+
+//#define DEBUG_BONITO
+
+#ifdef DEBUG_BONITO
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, 
##__VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+/* from linux soure code. include/asm-mips/mips-boards/bonito64.h*/
+#define BONITO_BOOT_BASE0x1fc0
+#define BONITO_BOOT_SIZE0x0010
+#define BONITO_BOOT_TOP (BONITO_BOOT_BASE+BONITO_BOOT_SIZE-1)
+#define BONITO_FLASH_BASE   0x1c00
+#define BONITO_FLASH_SIZE   0x0300
+#define BONITO_FLASH_TOP(BONITO_FLASH_BASE+BONITO_FLASH_SIZE-1)
+#define BONITO_SOCKET_BASE  0x1f80
+#define BONITO_SOCKET_SIZE  0x0040
+#define BONITO_SOCKET_TOP   (BONITO_SOCKET_BASE+BONITO_SOCKET_SIZE-1)
+#define BONITO_REG_BASE 0x1fe0
+#define BONITO_REG_SIZE 0x0004
+#define BONITO_REG_TOP  (BONITO_REG_BASE+BONITO_REG_SIZE-1)
+#define BONITO_DEV_BASE 0x1ff0
+#define BONITO_DEV_SIZE 0x0010
+#define BONITO_DEV_TOP  (BONITO_DEV_BASE+BONITO_DEV_SIZE-1)
+#define BONITO_PCILO_BASE   0x1000
+#define BONITO_PCILO_BASE_VA0xb000
+#define BONITO_PCILO_SIZE   0x0c00
+#define BONITO_PCILO_TOP(BONITO_PCILO_BASE+BONITO_PCILO_SIZE-1)
+#define BONITO_PCILO0_BASE  0x1000
+#define BONITO_PCILO1_BASE  0x1400
+#define BONITO_PCILO2_BASE  0x1800
+#define BONITO_PCIHI_BASE   0x2000
+#define BONITO_PCIHI_SIZE   0x2000
+#define BONITO_PCIHI_TOP(BONITO_PCIHI_BASE+BONITO_PCIHI_SIZE-1)
+#define BONITO_PCIIO_BASE   0x1fd0
+#define BONITO_PCIIO_BASE_VA0xbfd0
+#define BONITO_PCIIO_SIZE   0x0001
+#define BONITO_PCIIO_TOP(BONITO_PCIIO_BASE+BONITO_PCIIO_SIZE-1)
+#define BONITO_PCICFG_BASE  0x1fe8
+#define BONITO_PCICFG_SIZE  0x0008
+#define BONITO_PCICFG_TOP   (BONITO_PCICFG_BASE+BONITO_PCICFG_SIZE-1)
+
+
+#define BONITO_PCICONFIGBASE0x00
+#define BONITO_REGBASE  0x100
+
+#define BONITO_PCICONFIG_BASE   (BONITO_PCICONFIGBASE+BONITO_REG_BASE)
+#define BONITO_PCICONFIG_SIZE   (0x100)
+
+#define BONITO_INTERNAL_REG_BASE  (BONITO_REGBASE+BONITO_REG_BASE)
+#define BONITO_INTERNAL_REG_SIZE  (0x70)
+
+#define BONITO_SPCICONFIG_BASE  (BONITO_PCICFG_BASE)
+#define BONITO_SPCICONFIG_SIZE  (BONITO_PCICFG_SIZE)
+
+
+
+/* 1. Bonito h/w Configuration */
+/* Power on register */
+
+#define BONITO_BONPONCFG(0x00 >> 2)  /* 0x100 */
+#define BONITO_BONGENCFG_OFFSET 0x4
+#define BONITO_BONGENCFG(BONITO_BONGENCFG_OFFSET>>2)   /*0x104 */
+
+/* 2. IO & IDE configuration */
+#define BONITO_IODEVCFG (0x08 >> 2)  /* 0x108 */
+
+/* 3. IO & I

[Qemu-devel] [PATCH v4 1/7] MIPS: Initial support of bonito north bridge used by fulong mini pc

2010-06-05 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.target  |1 +
 default-configs/mips64el-softmmu.mak |1 +
 hw/bonito.c  |  808 ++
 hw/mips.h|3 +
 4 files changed, 813 insertions(+), 0 deletions(-)
 create mode 100644 hw/bonito.c

diff --git a/Makefile.target b/Makefile.target
index d06c679..ac36e2c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -221,6 +221,7 @@ obj-mips-y += vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
+obj-mips-$(CONFIG_FULONG) += bonito.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index b372c1d..d35d923 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -29,3 +29,4 @@ CONFIG_DP8393X=y
 CONFIG_DS1225Y=y
 CONFIG_MIPSNET=y
 CONFIG_PFLASH_CFI01=y
+CONFIG_FULONG=y
diff --git a/hw/bonito.c b/hw/bonito.c
new file mode 100644
index 000..9dda7ab
--- /dev/null
+++ b/hw/bonito.c
@@ -0,0 +1,808 @@
+/*
+ * bonito north bridge support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ *
+ * This code is licensed under the GNU GPL v2.
+ */
+
+/*
+ * fulong 2e mini pc has a bonito north bridge.
+ */
+
+/* what is the meaning of devfn in qemu and IDSEL in bonito northbridge?
+ *
+ * devfn   pci_slot<<3  + funno
+ * one pci bus can have 32 devices and each device can have 8 functions.
+ *
+ * In bonito north bridge, pci slot = IDSEL bit - 12.
+ * For example, PCI_IDSEL_VIA686B = 17,
+ * pci slot = 17-12=5
+ *
+ * so
+ * VT686B_FUN0's devfn = (5<<3)+0
+ * VT686B_FUN1's devfn = (5<<3)+1
+ *
+ * qemu also uses pci address for north bridge to access pci config register.
+ * bus_no   [23:16]
+ * dev_no   [15:11]
+ * fun_no   [10:8]
+ * reg_no   [7:2]
+ *
+ * so function bonito_sbridge_pciaddr for the translation from
+ * north bridge address to pci address.
+ */
+
+#include 
+
+#include "hw.h"
+#include "pci.h"
+#include "pc.h"
+#include "mips.h"
+#include "pci_host.h"
+
+//#define DEBUG_BONITO
+
+#ifdef DEBUG_BONITO
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, 
##__VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+/* from linux soure code. include/asm-mips/mips-boards/bonito64.h*/
+#define BONITO_BOOT_BASE0x1fc0
+#define BONITO_BOOT_SIZE0x0010
+#define BONITO_BOOT_TOP (BONITO_BOOT_BASE+BONITO_BOOT_SIZE-1)
+#define BONITO_FLASH_BASE   0x1c00
+#define BONITO_FLASH_SIZE   0x0300
+#define BONITO_FLASH_TOP(BONITO_FLASH_BASE+BONITO_FLASH_SIZE-1)
+#define BONITO_SOCKET_BASE  0x1f80
+#define BONITO_SOCKET_SIZE  0x0040
+#define BONITO_SOCKET_TOP   (BONITO_SOCKET_BASE+BONITO_SOCKET_SIZE-1)
+#define BONITO_REG_BASE 0x1fe0
+#define BONITO_REG_SIZE 0x0004
+#define BONITO_REG_TOP  (BONITO_REG_BASE+BONITO_REG_SIZE-1)
+#define BONITO_DEV_BASE 0x1ff0
+#define BONITO_DEV_SIZE 0x0010
+#define BONITO_DEV_TOP  (BONITO_DEV_BASE+BONITO_DEV_SIZE-1)
+#define BONITO_PCILO_BASE   0x1000
+#define BONITO_PCILO_BASE_VA0xb000
+#define BONITO_PCILO_SIZE   0x0c00
+#define BONITO_PCILO_TOP(BONITO_PCILO_BASE+BONITO_PCILO_SIZE-1)
+#define BONITO_PCILO0_BASE  0x1000
+#define BONITO_PCILO1_BASE  0x1400
+#define BONITO_PCILO2_BASE  0x1800
+#define BONITO_PCIHI_BASE   0x2000
+#define BONITO_PCIHI_SIZE   0x2000
+#define BONITO_PCIHI_TOP(BONITO_PCIHI_BASE+BONITO_PCIHI_SIZE-1)
+#define BONITO_PCIIO_BASE   0x1fd0
+#define BONITO_PCIIO_BASE_VA0xbfd0
+#define BONITO_PCIIO_SIZE   0x0001
+#define BONITO_PCIIO_TOP(BONITO_PCIIO_BASE+BONITO_PCIIO_SIZE-1)
+#define BONITO_PCICFG_BASE  0x1fe8
+#define BONITO_PCICFG_SIZE  0x0008
+#define BONITO_PCICFG_TOP   (BONITO_PCICFG_BASE+BONITO_PCICFG_SIZE-1)
+
+
+#define BONITO_PCICONFIGBASE0x00
+#define BONITO_REGBASE  0x100
+
+#define BONITO_PCICONFIG_BASE   (BONITO_PCICONFIGBASE+BONITO_REG_BASE)
+#define BONITO_PCICONFIG_SIZE   (0x100)
+
+#define BONITO_INTERNAL_REG_BASE  (BONITO_REGBASE+BONITO_REG_BASE)
+#define BONITO_INTERNAL_REG_SIZE  (0x70)
+
+#define BONITO_SPCICONFIG_BASE  (BONITO_PCICFG_BASE)
+#define BONITO_SPCICONFIG_SIZE  (BONITO_PCICFG_SIZE)
+
+
+
+/* 1. Bonito h/w Configuration */
+/* Power on register */
+
+#define BONITO_BONPONCFG(0x00 >> 2)  /* 0x100 */
+#define BONITO_BONGENCFG_OFFSET 0x4
+#define BONITO_BONGENCFG(BONITO_BONGENCFG_OFFSET>>2)   /*0x104 */
+
+/* 2. IO & IDE configuration */
+#define BONITO_IODEVCFG (0x08 >> 2)  /* 0x108 */
+
+/* 3. IO & I

[Qemu-devel] [PATCH v4 3/7] MIPS: Initial support of VIA IDE controller used by fulong mini pc

2010-06-05 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.objs|1 +
 default-configs/mips64el-softmmu.mak |1 +
 hw/ide.h |1 +
 hw/ide/via.c |  191 ++
 4 files changed, 194 insertions(+), 0 deletions(-)
 create mode 100644 hw/ide/via.c

diff --git a/Makefile.objs b/Makefile.objs
index 9796dcb..ad9a825 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -200,6 +200,7 @@ hw-obj-$(CONFIG_IDE_ISA) += ide/isa.o
 hw-obj-$(CONFIG_IDE_PIIX) += ide/piix.o
 hw-obj-$(CONFIG_IDE_CMD646) += ide/cmd646.o
 hw-obj-$(CONFIG_IDE_MACIO) += ide/macio.o
+hw-obj-$(CONFIG_IDE_VIA) += ide/via.o
 
 # SCSI layer
 hw-obj-y += lsi53c895a.o
diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index d35d923..85b7838 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -21,6 +21,7 @@ CONFIG_IDE_QDEV=y
 CONFIG_IDE_PCI=y
 CONFIG_IDE_ISA=y
 CONFIG_IDE_PIIX=y
+CONFIG_IDE_VIA=y
 CONFIG_NE2000_ISA=y
 CONFIG_SOUND=y
 CONFIG_VIRTIO_PCI=y
diff --git a/hw/ide.h b/hw/ide.h
index 0e7d540..bb635b6 100644
--- a/hw/ide.h
+++ b/hw/ide.h
@@ -12,6 +12,7 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
  int secondary_ide_enabled);
 void pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 void pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
+void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 
 /* ide-macio.c */
 int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
diff --git a/hw/ide/via.c b/hw/ide/via.c
new file mode 100644
index 000..f99dfcc
--- /dev/null
+++ b/hw/ide/via.c
@@ -0,0 +1,191 @@
+/*
+ * QEMU IDE Emulation: PCI VIA82C686B support.
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2006 Openedhand Ltd.
+ * Copyright (c) 2010 Huacai Chen 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include "block.h"
+#include "block_int.h"
+#include "sysemu.h"
+#include "dma.h"
+
+#include 
+
+static uint32_t bmdma_readb(void *opaque, uint32_t addr)
+{
+BMDMAState *bm = opaque;
+uint32_t val;
+
+switch (addr & 3) {
+case 0:
+val = bm->cmd;
+break;
+case 2:
+val = bm->status;
+break;
+default:
+val = 0xff;
+break;
+}
+#ifdef DEBUG_IDE
+printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
+#endif
+return val;
+}
+
+static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+BMDMAState *bm = opaque;
+#ifdef DEBUG_IDE
+printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
+#endif
+switch (addr & 3) {
+case 2:
+bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 
0x06);
+break;
+default:;
+}
+}
+
+static void bmdma_map(PCIDevice *pci_dev, int region_num,
+pcibus_t addr, pcibus_t size, int type)
+{
+PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
+int i;
+
+for(i = 0;i < 2; i++) {
+BMDMAState *bm = &d->bmdma[i];
+d->bus[i].bmdma = bm;
+bm->bus = d->bus+i;
+qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm);
+
+register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
+
+register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
+register_ioport_read(addr, 4, 1, bmdma_readb, bm);
+
+register_ioport_write(addr + 4, 4, 1, bmdma_addr_writeb, bm);
+register_ioport_read(addr + 4, 4, 1, bmdma_addr_readb, bm);
+register_ioport_write(addr + 4, 4, 2, bmdma_addr_writew, bm);
+register_ioport_read(addr + 4, 4, 2, bmdma_addr_readw, bm);
+register_ioport_write(addr + 4, 4, 4, bmdma_addr_wri

[Qemu-devel] [PATCH v4 4/7] MIPS: Initial support of VIA USB controller used by fulong mini pc

2010-06-05 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 hw/usb-uhci.c |   29 +
 hw/usb-uhci.h |1 +
 2 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 624d55b..91d827e 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1149,6 +1149,25 @@ static int usb_uhci_piix4_initfn(PCIDevice *dev)
 
 pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_2);
+pci_set_byte(pci_conf + PCI_LATENCY_TIMER, 0x16);
+
+/* USB misc control 1/2 */
+pci_set_long(pci_conf + 0x40,0x1000);
+/* PM capability */
+pci_set_long(pci_conf + 0x80,0x00020001);
+/* USB legacy support  */
+pci_set_long(pci_conf + 0xc0,0x2000);
+
+return usb_uhci_common_initfn(s);
+}
+
+static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
+{
+UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
+uint8_t *pci_conf = s->dev.config;
+
+pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
+pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_UHCI);
 return usb_uhci_common_initfn(s);
 }
 
@@ -1164,6 +1183,11 @@ static PCIDeviceInfo uhci_info[] = {
 .qdev.vmsd= &vmstate_uhci,
 .init = usb_uhci_piix4_initfn,
 },{
+.qdev.name= "vt82c686b-usb-uhci",
+.qdev.size= sizeof(UHCIState),
+.qdev.vmsd= &vmstate_uhci,
+.init = usb_uhci_vt82c686b_initfn,
+},{
 /* end of list */
 }
 };
@@ -1183,3 +1207,8 @@ void usb_uhci_piix4_init(PCIBus *bus, int devfn)
 {
 pci_create_simple(bus, devfn, "piix4-usb-uhci");
 }
+
+void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn)
+{
+pci_create_simple(bus, devfn, "vt82c686b-usb-uhci");
+}
diff --git a/hw/usb-uhci.h b/hw/usb-uhci.h
index 911948e..3e4d377 100644
--- a/hw/usb-uhci.h
+++ b/hw/usb-uhci.h
@@ -5,5 +5,6 @@
 
 void usb_uhci_piix3_init(PCIBus *bus, int devfn);
 void usb_uhci_piix4_init(PCIBus *bus, int devfn);
+void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn);
 
 #endif
-- 
1.7.0.4




[Qemu-devel] [PATCH v4 6/7] MIPS: Initial support of fulong mini pc (machine construction)

2010-06-05 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.target|2 +-
 hw/mips_fulong2e.c |  402 
 2 files changed, 403 insertions(+), 1 deletions(-)
 create mode 100644 hw/mips_fulong2e.c

diff --git a/Makefile.target b/Makefile.target
index 92ba282..f203c6b 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -221,7 +221,7 @@ obj-mips-y += vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
-obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o
+obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
new file mode 100644
index 000..1b54236
--- /dev/null
+++ b/hw/mips_fulong2e.c
@@ -0,0 +1,402 @@
+/*
+ * QEMU fulong 2e mini pc support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2009 chenming (chenm...@rdc.faw.com.cn)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ * This code is licensed under the GNU GPL v2.
+ */
+
+/*
+ * Fulong 2e mini pc is based on ICT/ST Loongson 2e CPU (MIPS III like, 800MHz)
+ * http://www.linux-mips.org/wiki/Fulong
+ *
+ * Loongson 2e user manual:
+ * http://www.loongsondeveloper.com/doc/Loongson2EUserGuide.pdf
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "fdc.h"
+#include "net.h"
+#include "boards.h"
+#include "smbus.h"
+#include "block.h"
+#include "flash.h"
+#include "mips.h"
+#include "mips_cpudevs.h"
+#include "pci.h"
+#include "usb-uhci.h"
+#include "qemu-char.h"
+#include "sysemu.h"
+#include "audio/audio.h"
+#include "qemu-log.h"
+#include "loader.h"
+#include "mips-bios.h"
+#include "ide.h"
+#include "elf.h"
+#include "vt82c686.h"
+#include "mc146818rtc.h"
+
+#define DEBUG_FULONG2E_INIT
+
+#define ENVP_ADDR   0x80002000l
+#define ENVP_NB_ENTRIES16
+#define ENVP_ENTRY_SIZE256
+
+#define MAX_IDE_BUS 2
+#define FULONG_BIOSNAME "pmon_fulong2e.bin"
+
+/* PCI SLOT in fulong 2e */
+#define FULONG2E_VIA_SLOT5
+#define FULONG2E_ATI_SLOT6
+#define FULONG2E_RTL8139_SLOT7
+
+static PITState *pit;
+
+static struct _loaderparams {
+int ram_size;
+const char *kernel_filename;
+const char *kernel_cmdline;
+const char *initrd_filename;
+} loaderparams;
+
+static void prom_set(uint32_t* prom_buf, int index, const char *string, ...)
+{
+va_list ap;
+int32_t table_addr;
+
+if (index >= ENVP_NB_ENTRIES)
+return;
+
+if (string == NULL) {
+prom_buf[index] = 0;
+return;
+}
+
+table_addr = sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
+prom_buf[index] = tswap32(ENVP_ADDR + table_addr);
+
+va_start(ap, string);
+vsnprintf((char *)prom_buf + table_addr, ENVP_ENTRY_SIZE, string, ap);
+va_end(ap);
+}
+
+static int64_t load_kernel (CPUState *env)
+{
+int64_t kernel_entry, kernel_low, kernel_high;
+int index = 0;
+long initrd_size;
+ram_addr_t initrd_offset;
+uint32_t *prom_buf;
+long prom_size;
+
+if (load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, NULL,
+ (uint64_t *)&kernel_entry, (uint64_t *)&kernel_low,
+ (uint64_t *)&kernel_high, 0, ELF_MACHINE, 1) < 0) {
+fprintf(stderr, "qemu: could not load kernel '%s'\n",
+loaderparams.kernel_filename);
+exit(1);
+}
+
+/* load initrd */
+initrd_size = 0;
+initrd_offset = 0;
+if (loaderparams.initrd_filename) {
+initrd_size = get_image_size (loaderparams.initrd_filename);
+if (initrd_size > 0) {
+initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & 
TARGET_PAGE_MASK;
+if (initrd_offset + initrd_size > ram_size) {
+fprintf(stderr,
+"qemu: memory too small for initial ram disk '%s'\n",
+loaderparams.initrd_filename);
+exit(1);
+}
+initrd_size = load_image_targphys(loaderparams.initrd_filename,
+ initrd_offset, ram_size - initrd_offset);
+}
+if (initrd_size == (target_ulong) -1) {
+fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
+loaderparams.initrd_filename);
+exit(1);
+}
+}
+
+/* Setup prom parameters. */
+prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t) + ENVP_ENTRY_SIZE);
+prom_buf = qemu_malloc(prom_size);
+
+prom_set(prom_buf, index++, loaderparams.kernel_filename);
+if (initrd_size > 0) {
+prom

[Qemu-devel] [PATCH v4 2/7] MIPS: Initial support of vt82686b south bridge used by fulong mini pc

2010-06-05 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.target |2 +-
 hw/pci_ids.h|8 +
 hw/vt82c686.c   |  567 +++
 hw/vt82c686.h   |   11 +
 4 files changed, 587 insertions(+), 1 deletions(-)
 create mode 100644 hw/vt82c686.c
 create mode 100644 hw/vt82c686.h

diff --git a/Makefile.target b/Makefile.target
index ac36e2c..92ba282 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -221,7 +221,7 @@ obj-mips-y += vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
-obj-mips-$(CONFIG_FULONG) += bonito.o
+obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/hw/pci_ids.h b/hw/pci_ids.h
index fe7a121..39e9f1d 100644
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@ -78,6 +78,14 @@
 
 #define PCI_VENDOR_ID_XILINX 0x10ee
 
+#define PCI_VENDOR_ID_VIA0x1106
+#define PCI_DEVICE_ID_VIA_ISA_BRIDGE 0x0686
+#define PCI_DEVICE_ID_VIA_IDE0x0571
+#define PCI_DEVICE_ID_VIA_UHCI   0x3038
+#define PCI_DEVICE_ID_VIA_ACPI   0x3057
+#define PCI_DEVICE_ID_VIA_AC97   0x3058
+#define PCI_DEVICE_ID_VIA_MC97   0x3068
+
 #define PCI_VENDOR_ID_MARVELL0x11ab
 
 #define PCI_VENDOR_ID_ENSONIQ0x1274
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
new file mode 100644
index 000..12221b7
--- /dev/null
+++ b/hw/vt82c686.c
@@ -0,0 +1,567 @@
+/*
+ * VT82C686B south bridge support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2009 chenming (chenm...@rdc.faw.com.cn)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ * This code is licensed under the GNU GPL v2.
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "vt82c686.h"
+#include "i2c.h"
+#include "smbus.h"
+#include "pci.h"
+#include "isa.h"
+#include "sysbus.h"
+#include "mips.h"
+#include "apm.h"
+#include "acpi.h"
+#include "pm_smbus.h"
+
+typedef uint32_t pci_addr_t;
+#include "pci_host.h"
+//#define DEBUG_VT82C686B
+
+#ifdef DEBUG_VT82C686B
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, 
##__VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+typedef struct SuperIOConfig
+{
+uint8_t config[0xff];
+uint8_t index;
+uint8_t data;
+} SuperIOConfig;
+
+typedef struct VT82C686BState {
+PCIDevice dev;
+SuperIOConfig *superio_conf;
+} VT82C686BState;
+
+static void superio_ioport_writeb(void *opaque, uint32_t addr, uint32_t data)
+{
+int can_write;
+SuperIOConfig *superio_conf = (SuperIOConfig *)opaque;
+
+DPRINTF("superio_ioport_writeb  address 0x%x  val 0x%x  \n", addr, data);
+if (addr == 0x3f0) {
+superio_conf->index = data & 0xff;
+} else {
+/* 0x3f1 */
+switch (superio_conf->index) {
+case 0x00 ... 0xdf:
+case 0xe4:
+case 0xe5:
+case 0xe9 ... 0xed:
+case 0xf3:
+case 0xf5:
+case 0xf7:
+case 0xf9 ... 0xfb:
+case 0xfd ... 0xff:
+can_write = 0;
+break;
+default:
+can_write = 1;
+
+if (can_write) {
+switch (superio_conf->index) {
+case 0xe7:
+if ((data & 0xff) != 0xfe) {
+DPRINTF("chage uart 1 base. unsupported yet \n");
+}
+break;
+case 0xe8:
+if ((data & 0xff) != 0xbe) {
+DPRINTF("chage uart 2 base. unsupported yet \n");
+}
+break;
+
+default:
+superio_conf->config[superio_conf->index] = data & 0xff;
+}
+}
+}
+superio_conf->config[superio_conf->index] = data & 0xff;
+}
+}
+
+static uint32_t superio_ioport_readb(void *opaque, uint32_t addr)
+{
+SuperIOConfig *superio_conf = (SuperIOConfig *)opaque;
+
+DPRINTF("superio_ioport_readb  address 0x%x   \n", addr);
+return (superio_conf->config[superio_conf->index]);
+}
+
+static void vt82c686b_reset(void * opaque)
+{
+PCIDevice *d = opaque;
+uint8_t *pci_conf = d->config;
+VT82C686BState *vt82c = DO_UPCAST(VT82C686BState, dev, d);
+
+pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0);
+pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
+pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
+
+pci_conf[0x48] = 0x01; /* Miscellaneous Control 3 */
+pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */
+pci_conf[0x4f] = 0x03; /* DMA/Master Mem Access Control 3 */

[Qemu-devel] [PATCH v4 5/7] MIPS: Initial support of fulong mini pc (CPU definition)

2010-06-05 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 target-mips/mips-defs.h  |4 
 target-mips/translate_init.c |   35 +++
 2 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h
index c57de02..38594da 100644
--- a/target-mips/mips-defs.h
+++ b/target-mips/mips-defs.h
@@ -40,6 +40,8 @@
 #defineASE_SMARTMIPS   0x0004
 
 /* Chip specific instructions. */
+#defineINSN_LOONGSON2E  0x2000
+#defineINSN_LOONGSON2F  0x4000
 #defineINSN_VR54XX 0x8000
 
 /* MIPS CPU defines. */
@@ -48,6 +50,8 @@
 #defineCPU_MIPS3   (CPU_MIPS2 | ISA_MIPS3)
 #defineCPU_MIPS4   (CPU_MIPS3 | ISA_MIPS4)
 #defineCPU_VR54XX  (CPU_MIPS4 | INSN_VR54XX)
+#defineCPU_LOONGSON2E  (CPU_MIPS3 | INSN_LOONGSON2E)
+#defineCPU_LOONGSON2F  (CPU_MIPS3 | INSN_LOONGSON2F)
 
 #defineCPU_MIPS5   (CPU_MIPS4 | ISA_MIPS5)
 
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index b79ed56..0d9899e 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -454,6 +454,41 @@ static const mips_def_t mips_defs[] =
 .insn_flags = CPU_MIPS64R2 | ASE_MIPS3D,
 .mmu_type = MMU_TYPE_R4000,
 },
+{
+.name = "Loongson-2E",
+.CP0_PRid = 0x6302,
+/*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/
+.CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) | (0x1<<5) 
|
+   (0x1<<4) | (0x1<<1),
+/* Note: Config1 is only used internally, Loongson-2E has only 
Config0. */
+.CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
+.SYNCI_Step = 16,
+.CCRes = 2,
+.CP0_Status_rw_bitmask = 0x35D0,
+.CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV),
+.SEGBITS = 40,
+.PABITS = 40,
+.insn_flags = CPU_LOONGSON2E,
+.mmu_type = MMU_TYPE_R4000,
+},
+{
+  .name = "Loongson-2F",
+  .CP0_PRid = 0x6303,
+  /*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/
+  .CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) | (0x1<<5) |
+ (0x1<<4) | (0x1<<1),
+  /* Note: Config1 is only used internally, Loongson-2F has only Config0. 
*/
+  .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
+  .SYNCI_Step = 16,
+  .CCRes = 2,
+  .CP0_Status_rw_bitmask = 0xF5D0FF1F,   /*bit5:7 not writeable*/
+  .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV),
+  .SEGBITS = 40,
+  .PABITS = 40,
+  .insn_flags = CPU_LOONGSON2F,
+  .mmu_type = MMU_TYPE_R4000,
+},
+
 #endif
 };
 
-- 
1.7.0.4




[Qemu-devel] [PATCH v5 1/6] MIPS: Initial support of bonito north bridge used by fulong mini pc

2010-06-22 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.target  |1 +
 default-configs/mips64el-softmmu.mak |1 +
 hw/bonito.c  |  809 ++
 hw/mips.h|3 +
 4 files changed, 814 insertions(+), 0 deletions(-)
 create mode 100644 hw/bonito.c

diff --git a/Makefile.target b/Makefile.target
index 478b89d..36de833 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -221,6 +221,7 @@ obj-mips-y += vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
+obj-mips-$(CONFIG_FULONG) += bonito.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index b372c1d..d35d923 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -29,3 +29,4 @@ CONFIG_DP8393X=y
 CONFIG_DS1225Y=y
 CONFIG_MIPSNET=y
 CONFIG_PFLASH_CFI01=y
+CONFIG_FULONG=y
diff --git a/hw/bonito.c b/hw/bonito.c
new file mode 100644
index 000..8b81032
--- /dev/null
+++ b/hw/bonito.c
@@ -0,0 +1,809 @@
+/*
+ * bonito north bridge support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ *
+ * This code is licensed under the GNU GPL v2.
+ */
+
+/*
+ * fulong 2e mini pc has a bonito north bridge.
+ */
+
+/* what is the meaning of devfn in qemu and IDSEL in bonito northbridge?
+ *
+ * devfn   pci_slot<<3  + funno
+ * one pci bus can have 32 devices and each device can have 8 functions.
+ *
+ * In bonito north bridge, pci slot = IDSEL bit - 12.
+ * For example, PCI_IDSEL_VIA686B = 17,
+ * pci slot = 17-12=5
+ *
+ * so
+ * VT686B_FUN0's devfn = (5<<3)+0
+ * VT686B_FUN1's devfn = (5<<3)+1
+ *
+ * qemu also uses pci address for north bridge to access pci config register.
+ * bus_no   [23:16]
+ * dev_no   [15:11]
+ * fun_no   [10:8]
+ * reg_no   [7:2]
+ *
+ * so function bonito_sbridge_pciaddr for the translation from
+ * north bridge address to pci address.
+ */
+
+#include 
+
+#include "hw.h"
+#include "pci.h"
+#include "pc.h"
+#include "mips.h"
+#include "pci_host.h"
+#include "sysemu.h"
+
+//#define DEBUG_BONITO
+
+#ifdef DEBUG_BONITO
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, 
##__VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+/* from linux soure code. include/asm-mips/mips-boards/bonito64.h*/
+#define BONITO_BOOT_BASE0x1fc0
+#define BONITO_BOOT_SIZE0x0010
+#define BONITO_BOOT_TOP (BONITO_BOOT_BASE+BONITO_BOOT_SIZE-1)
+#define BONITO_FLASH_BASE   0x1c00
+#define BONITO_FLASH_SIZE   0x0300
+#define BONITO_FLASH_TOP(BONITO_FLASH_BASE+BONITO_FLASH_SIZE-1)
+#define BONITO_SOCKET_BASE  0x1f80
+#define BONITO_SOCKET_SIZE  0x0040
+#define BONITO_SOCKET_TOP   (BONITO_SOCKET_BASE+BONITO_SOCKET_SIZE-1)
+#define BONITO_REG_BASE 0x1fe0
+#define BONITO_REG_SIZE 0x0004
+#define BONITO_REG_TOP  (BONITO_REG_BASE+BONITO_REG_SIZE-1)
+#define BONITO_DEV_BASE 0x1ff0
+#define BONITO_DEV_SIZE 0x0010
+#define BONITO_DEV_TOP  (BONITO_DEV_BASE+BONITO_DEV_SIZE-1)
+#define BONITO_PCILO_BASE   0x1000
+#define BONITO_PCILO_BASE_VA0xb000
+#define BONITO_PCILO_SIZE   0x0c00
+#define BONITO_PCILO_TOP(BONITO_PCILO_BASE+BONITO_PCILO_SIZE-1)
+#define BONITO_PCILO0_BASE  0x1000
+#define BONITO_PCILO1_BASE  0x1400
+#define BONITO_PCILO2_BASE  0x1800
+#define BONITO_PCIHI_BASE   0x2000
+#define BONITO_PCIHI_SIZE   0x2000
+#define BONITO_PCIHI_TOP(BONITO_PCIHI_BASE+BONITO_PCIHI_SIZE-1)
+#define BONITO_PCIIO_BASE   0x1fd0
+#define BONITO_PCIIO_BASE_VA0xbfd0
+#define BONITO_PCIIO_SIZE   0x0001
+#define BONITO_PCIIO_TOP(BONITO_PCIIO_BASE+BONITO_PCIIO_SIZE-1)
+#define BONITO_PCICFG_BASE  0x1fe8
+#define BONITO_PCICFG_SIZE  0x0008
+#define BONITO_PCICFG_TOP   (BONITO_PCICFG_BASE+BONITO_PCICFG_SIZE-1)
+
+
+#define BONITO_PCICONFIGBASE0x00
+#define BONITO_REGBASE  0x100
+
+#define BONITO_PCICONFIG_BASE   (BONITO_PCICONFIGBASE+BONITO_REG_BASE)
+#define BONITO_PCICONFIG_SIZE   (0x100)
+
+#define BONITO_INTERNAL_REG_BASE  (BONITO_REGBASE+BONITO_REG_BASE)
+#define BONITO_INTERNAL_REG_SIZE  (0x70)
+
+#define BONITO_SPCICONFIG_BASE  (BONITO_PCICFG_BASE)
+#define BONITO_SPCICONFIG_SIZE  (BONITO_PCICFG_SIZE)
+
+
+
+/* 1. Bonito h/w Configuration */
+/* Power on register */
+
+#define BONITO_BONPONCFG(0x00 >> 2)  /* 0x100 */
+#define BONITO_BONGENCFG_OFFSET 0x4
+#define BONITO_BONGENCFG(BONITO_BONGENCFG_OFFSET>>2)   /*0x104 */
+
+/* 2. IO & IDE configuration */
+#define BONITO_IODEVCFG (0x08 >> 2)  

[Qemu-devel] [PATCH v5 4/6] MIPS: Initial support of VIA USB controller used by fulong mini pc

2010-06-22 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 hw/usb-uhci.c |   29 +
 hw/usb-uhci.h |1 +
 2 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 624d55b..accfe2e 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1149,6 +1149,25 @@ static int usb_uhci_piix4_initfn(PCIDevice *dev)
 
 pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_2);
+pci_set_byte(pci_conf + PCI_LATENCY_TIMER, 0x16);
+
+/* USB misc control 1/2 */
+pci_set_long(pci_conf + 0x40,0x1000);
+/* PM capability */
+pci_set_long(pci_conf + 0x80,0x00020001);
+/* USB legacy support  */
+pci_set_long(pci_conf + 0xc0,0x2000);
+
+return usb_uhci_common_initfn(s);
+}
+
+static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
+{
+UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
+uint8_t *pci_conf = s->dev.config;
+
+pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
+pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_UHCI);
 return usb_uhci_common_initfn(s);
 }
 
@@ -1164,6 +1183,11 @@ static PCIDeviceInfo uhci_info[] = {
 .qdev.vmsd= &vmstate_uhci,
 .init = usb_uhci_piix4_initfn,
 },{
+.qdev.name= "vt82c686b-usb-uhci",
+.qdev.size= sizeof(UHCIState),
+.qdev.vmsd= &vmstate_uhci,
+.init = usb_uhci_vt82c686b_initfn,
+},{
 /* end of list */
 }
 };
@@ -1183,3 +1207,8 @@ void usb_uhci_piix4_init(PCIBus *bus, int devfn)
 {
 pci_create_simple(bus, devfn, "piix4-usb-uhci");
 }
+
+void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn)
+{
+pci_create_simple(bus, devfn, "vt82c686b-usb-uhci");
+}
diff --git a/hw/usb-uhci.h b/hw/usb-uhci.h
index 911948e..3e4d377 100644
--- a/hw/usb-uhci.h
+++ b/hw/usb-uhci.h
@@ -5,5 +5,6 @@
 
 void usb_uhci_piix3_init(PCIBus *bus, int devfn);
 void usb_uhci_piix4_init(PCIBus *bus, int devfn);
+void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn);
 
 #endif
-- 
1.7.0.4




[Qemu-devel] [PATCH v5 2/6] MIPS: Initial support of vt82686b south bridge used by fulong mini pc

2010-06-22 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.target |2 +-
 hw/pci_ids.h|8 +
 hw/vt82c686.c   |  569 +++
 hw/vt82c686.h   |   11 +
 4 files changed, 589 insertions(+), 1 deletions(-)
 create mode 100644 hw/vt82c686.c
 create mode 100644 hw/vt82c686.h

diff --git a/Makefile.target b/Makefile.target
index 36de833..4b23e6d 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -221,7 +221,7 @@ obj-mips-y += vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
-obj-mips-$(CONFIG_FULONG) += bonito.o
+obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/hw/pci_ids.h b/hw/pci_ids.h
index fe7a121..39e9f1d 100644
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@ -78,6 +78,14 @@
 
 #define PCI_VENDOR_ID_XILINX 0x10ee
 
+#define PCI_VENDOR_ID_VIA0x1106
+#define PCI_DEVICE_ID_VIA_ISA_BRIDGE 0x0686
+#define PCI_DEVICE_ID_VIA_IDE0x0571
+#define PCI_DEVICE_ID_VIA_UHCI   0x3038
+#define PCI_DEVICE_ID_VIA_ACPI   0x3057
+#define PCI_DEVICE_ID_VIA_AC97   0x3058
+#define PCI_DEVICE_ID_VIA_MC97   0x3068
+
 #define PCI_VENDOR_ID_MARVELL0x11ab
 
 #define PCI_VENDOR_ID_ENSONIQ0x1274
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
new file mode 100644
index 000..e7aca0c
--- /dev/null
+++ b/hw/vt82c686.c
@@ -0,0 +1,569 @@
+/*
+ * VT82C686B south bridge support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2009 chenming (chenm...@rdc.faw.com.cn)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ * This code is licensed under the GNU GPL v2.
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "vt82c686.h"
+#include "i2c.h"
+#include "smbus.h"
+#include "pci.h"
+#include "isa.h"
+#include "sysbus.h"
+#include "mips.h"
+#include "apm.h"
+#include "acpi.h"
+#include "pm_smbus.h"
+#include "sysemu.h"
+#include "qemu-timer.h"
+
+typedef uint32_t pci_addr_t;
+#include "pci_host.h"
+//#define DEBUG_VT82C686B
+
+#ifdef DEBUG_VT82C686B
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, 
##__VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+typedef struct SuperIOConfig
+{
+uint8_t config[0xff];
+uint8_t index;
+uint8_t data;
+} SuperIOConfig;
+
+typedef struct VT82C686BState {
+PCIDevice dev;
+SuperIOConfig *superio_conf;
+} VT82C686BState;
+
+static void superio_ioport_writeb(void *opaque, uint32_t addr, uint32_t data)
+{
+int can_write;
+SuperIOConfig *superio_conf = (SuperIOConfig *)opaque;
+
+DPRINTF("superio_ioport_writeb  address 0x%x  val 0x%x  \n", addr, data);
+if (addr == 0x3f0) {
+superio_conf->index = data & 0xff;
+} else {
+/* 0x3f1 */
+switch (superio_conf->index) {
+case 0x00 ... 0xdf:
+case 0xe4:
+case 0xe5:
+case 0xe9 ... 0xed:
+case 0xf3:
+case 0xf5:
+case 0xf7:
+case 0xf9 ... 0xfb:
+case 0xfd ... 0xff:
+can_write = 0;
+break;
+default:
+can_write = 1;
+
+if (can_write) {
+switch (superio_conf->index) {
+case 0xe7:
+if ((data & 0xff) != 0xfe) {
+DPRINTF("chage uart 1 base. unsupported yet \n");
+}
+break;
+case 0xe8:
+if ((data & 0xff) != 0xbe) {
+DPRINTF("chage uart 2 base. unsupported yet \n");
+}
+break;
+
+default:
+superio_conf->config[superio_conf->index] = data & 0xff;
+}
+}
+}
+superio_conf->config[superio_conf->index] = data & 0xff;
+}
+}
+
+static uint32_t superio_ioport_readb(void *opaque, uint32_t addr)
+{
+SuperIOConfig *superio_conf = (SuperIOConfig *)opaque;
+
+DPRINTF("superio_ioport_readb  address 0x%x   \n", addr);
+return (superio_conf->config[superio_conf->index]);
+}
+
+static void vt82c686b_reset(void * opaque)
+{
+PCIDevice *d = opaque;
+uint8_t *pci_conf = d->config;
+VT82C686BState *vt82c = DO_UPCAST(VT82C686BState, dev, d);
+
+pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0);
+pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
+pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
+
+pci_conf[0x48] = 0x01; /* Miscellaneous Control 3 */
+pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */
+

[Qemu-devel] [PATCH v5 3/6] MIPS: Initial support of VIA IDE controller used by fulong mini pc

2010-06-22 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.objs|1 +
 default-configs/mips64el-softmmu.mak |1 +
 hw/ide.h |1 +
 hw/ide/via.c |  191 ++
 4 files changed, 194 insertions(+), 0 deletions(-)
 create mode 100644 hw/ide/via.c

diff --git a/Makefile.objs b/Makefile.objs
index 2bfb6d1..ddd1d10 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -202,6 +202,7 @@ hw-obj-$(CONFIG_IDE_ISA) += ide/isa.o
 hw-obj-$(CONFIG_IDE_PIIX) += ide/piix.o
 hw-obj-$(CONFIG_IDE_CMD646) += ide/cmd646.o
 hw-obj-$(CONFIG_IDE_MACIO) += ide/macio.o
+hw-obj-$(CONFIG_IDE_VIA) += ide/via.o
 
 # SCSI layer
 hw-obj-y += lsi53c895a.o
diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index d35d923..85b7838 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -21,6 +21,7 @@ CONFIG_IDE_QDEV=y
 CONFIG_IDE_PCI=y
 CONFIG_IDE_ISA=y
 CONFIG_IDE_PIIX=y
+CONFIG_IDE_VIA=y
 CONFIG_NE2000_ISA=y
 CONFIG_SOUND=y
 CONFIG_VIRTIO_PCI=y
diff --git a/hw/ide.h b/hw/ide.h
index 0e7d540..bb635b6 100644
--- a/hw/ide.h
+++ b/hw/ide.h
@@ -12,6 +12,7 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
  int secondary_ide_enabled);
 void pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 void pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
+void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 
 /* ide-macio.c */
 int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
diff --git a/hw/ide/via.c b/hw/ide/via.c
new file mode 100644
index 000..d933caf
--- /dev/null
+++ b/hw/ide/via.c
@@ -0,0 +1,191 @@
+/*
+ * QEMU IDE Emulation: PCI VIA82C686B support.
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2006 Openedhand Ltd.
+ * Copyright (c) 2010 Huacai Chen 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include "block.h"
+#include "block_int.h"
+#include "sysemu.h"
+#include "dma.h"
+
+#include 
+
+static uint32_t bmdma_readb(void *opaque, uint32_t addr)
+{
+BMDMAState *bm = opaque;
+uint32_t val;
+
+switch (addr & 3) {
+case 0:
+val = bm->cmd;
+break;
+case 2:
+val = bm->status;
+break;
+default:
+val = 0xff;
+break;
+}
+#ifdef DEBUG_IDE
+printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
+#endif
+return val;
+}
+
+static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+BMDMAState *bm = opaque;
+#ifdef DEBUG_IDE
+printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
+#endif
+switch (addr & 3) {
+case 2:
+bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 
0x06);
+break;
+default:;
+}
+}
+
+static void bmdma_map(PCIDevice *pci_dev, int region_num,
+pcibus_t addr, pcibus_t size, int type)
+{
+PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
+int i;
+
+for(i = 0;i < 2; i++) {
+BMDMAState *bm = &d->bmdma[i];
+d->bus[i].bmdma = bm;
+bm->bus = d->bus+i;
+qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm);
+
+register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
+
+register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
+register_ioport_read(addr, 4, 1, bmdma_readb, bm);
+
+register_ioport_write(addr + 4, 4, 1, bmdma_addr_writeb, bm);
+register_ioport_read(addr + 4, 4, 1, bmdma_addr_readb, bm);
+register_ioport_write(addr + 4, 4, 2, bmdma_addr_writew, bm);
+register_ioport_read(addr + 4, 4, 2, bmdma_addr_readw, bm);
+register_ioport_write(addr + 4, 4, 4, bmdma_addr_wri

[Qemu-devel] [PATCH v5 5/6] MIPS: Initial support of fulong mini pc (CPU definition)

2010-06-22 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 target-mips/mips-defs.h  |4 
 target-mips/translate_init.c |   35 +++
 2 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h
index a7f4697..bf094a3 100644
--- a/target-mips/mips-defs.h
+++ b/target-mips/mips-defs.h
@@ -41,6 +41,8 @@
 #defineASE_MICROMIPS   0x0008
 
 /* Chip specific instructions. */
+#defineINSN_LOONGSON2E  0x2000
+#defineINSN_LOONGSON2F  0x4000
 #defineINSN_VR54XX 0x8000
 
 /* MIPS CPU defines. */
@@ -49,6 +51,8 @@
 #defineCPU_MIPS3   (CPU_MIPS2 | ISA_MIPS3)
 #defineCPU_MIPS4   (CPU_MIPS3 | ISA_MIPS4)
 #defineCPU_VR54XX  (CPU_MIPS4 | INSN_VR54XX)
+#defineCPU_LOONGSON2E  (CPU_MIPS3 | INSN_LOONGSON2E)
+#defineCPU_LOONGSON2F  (CPU_MIPS3 | INSN_LOONGSON2F)
 
 #defineCPU_MIPS5   (CPU_MIPS4 | ISA_MIPS5)
 
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index b79ed56..0d9899e 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -454,6 +454,41 @@ static const mips_def_t mips_defs[] =
 .insn_flags = CPU_MIPS64R2 | ASE_MIPS3D,
 .mmu_type = MMU_TYPE_R4000,
 },
+{
+.name = "Loongson-2E",
+.CP0_PRid = 0x6302,
+/*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/
+.CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) | (0x1<<5) 
|
+   (0x1<<4) | (0x1<<1),
+/* Note: Config1 is only used internally, Loongson-2E has only 
Config0. */
+.CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
+.SYNCI_Step = 16,
+.CCRes = 2,
+.CP0_Status_rw_bitmask = 0x35D0,
+.CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV),
+.SEGBITS = 40,
+.PABITS = 40,
+.insn_flags = CPU_LOONGSON2E,
+.mmu_type = MMU_TYPE_R4000,
+},
+{
+  .name = "Loongson-2F",
+  .CP0_PRid = 0x6303,
+  /*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/
+  .CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) | (0x1<<5) |
+ (0x1<<4) | (0x1<<1),
+  /* Note: Config1 is only used internally, Loongson-2F has only Config0. 
*/
+  .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
+  .SYNCI_Step = 16,
+  .CCRes = 2,
+  .CP0_Status_rw_bitmask = 0xF5D0FF1F,   /*bit5:7 not writeable*/
+  .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV),
+  .SEGBITS = 40,
+  .PABITS = 40,
+  .insn_flags = CPU_LOONGSON2F,
+  .mmu_type = MMU_TYPE_R4000,
+},
+
 #endif
 };
 
-- 
1.7.0.4




[Qemu-devel] [PATCH v5 6/6] MIPS: Initial support of fulong mini pc (machine construction)

2010-06-22 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.target|2 +-
 hw/mips_fulong2e.c |  416 
 2 files changed, 417 insertions(+), 1 deletions(-)
 create mode 100644 hw/mips_fulong2e.c

diff --git a/Makefile.target b/Makefile.target
index 4b23e6d..a4c8e8e 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -221,7 +221,7 @@ obj-mips-y += vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
-obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o
+obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
new file mode 100644
index 000..d03c897
--- /dev/null
+++ b/hw/mips_fulong2e.c
@@ -0,0 +1,416 @@
+/*
+ * QEMU fulong 2e mini pc support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2009 chenming (chenm...@rdc.faw.com.cn)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ * This code is licensed under the GNU GPL v2.
+ */
+
+/*
+ * Fulong 2e mini pc is based on ICT/ST Loongson 2e CPU (MIPS III like, 800MHz)
+ * http://www.linux-mips.org/wiki/Fulong
+ *
+ * Loongson 2e user manual:
+ * http://www.loongsondeveloper.com/doc/Loongson2EUserGuide.pdf
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "fdc.h"
+#include "net.h"
+#include "boards.h"
+#include "smbus.h"
+#include "block.h"
+#include "flash.h"
+#include "mips.h"
+#include "mips_cpudevs.h"
+#include "pci.h"
+#include "usb-uhci.h"
+#include "qemu-char.h"
+#include "sysemu.h"
+#include "audio/audio.h"
+#include "qemu-log.h"
+#include "loader.h"
+#include "mips-bios.h"
+#include "ide.h"
+#include "elf.h"
+#include "vt82c686.h"
+#include "mc146818rtc.h"
+
+#define DEBUG_FULONG2E_INIT
+
+#define ENVP_ADDR   0x80002000l
+#define ENVP_NB_ENTRIES16
+#define ENVP_ENTRY_SIZE256
+
+#define MAX_IDE_BUS 2
+
+/*
+ * PMON is not part of qemu and released with BSD license, anyone
+ * who want to build a pmon binary please first git-clone the source
+ * from the git repository at:
+ * http://www.loongson.cn/support/git/pmon
+ * Then follow the "Compile Guide" available at:
+ * http://dev.lemote.com/code/pmon
+ *
+ * Notes:
+ * 1, don't use the source at http://dev.lemote.com/http_git/pmon.git
+ * 2, use "Bonito2edev" to replace "dir_corresponding_to_your_target_hardware"
+ * in the "Compile Guide".
+ */
+#define FULONG_BIOSNAME "pmon_fulong2e.bin"
+
+/* PCI SLOT in fulong 2e */
+#define FULONG2E_VIA_SLOT5
+#define FULONG2E_ATI_SLOT6
+#define FULONG2E_RTL8139_SLOT7
+
+static PITState *pit;
+
+static struct _loaderparams {
+int ram_size;
+const char *kernel_filename;
+const char *kernel_cmdline;
+const char *initrd_filename;
+} loaderparams;
+
+static void prom_set(uint32_t* prom_buf, int index, const char *string, ...)
+{
+va_list ap;
+int32_t table_addr;
+
+if (index >= ENVP_NB_ENTRIES)
+return;
+
+if (string == NULL) {
+prom_buf[index] = 0;
+return;
+}
+
+table_addr = sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
+prom_buf[index] = tswap32(ENVP_ADDR + table_addr);
+
+va_start(ap, string);
+vsnprintf((char *)prom_buf + table_addr, ENVP_ENTRY_SIZE, string, ap);
+va_end(ap);
+}
+
+static int64_t load_kernel (CPUState *env)
+{
+int64_t kernel_entry, kernel_low, kernel_high;
+int index = 0;
+long initrd_size;
+ram_addr_t initrd_offset;
+uint32_t *prom_buf;
+long prom_size;
+
+if (load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, NULL,
+ (uint64_t *)&kernel_entry, (uint64_t *)&kernel_low,
+ (uint64_t *)&kernel_high, 0, ELF_MACHINE, 1) < 0) {
+fprintf(stderr, "qemu: could not load kernel '%s'\n",
+loaderparams.kernel_filename);
+exit(1);
+}
+
+/* load initrd */
+initrd_size = 0;
+initrd_offset = 0;
+if (loaderparams.initrd_filename) {
+initrd_size = get_image_size (loaderparams.initrd_filename);
+if (initrd_size > 0) {
+initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & 
TARGET_PAGE_MASK;
+if (initrd_offset + initrd_size > ram_size) {
+fprintf(stderr,
+"qemu: memory too small for initial ram disk '%s'\n",
+loaderparams.initrd_filename);
+exit(1);
+}
+initrd_size = load_image_targphys(loaderparams.initrd_filename,
+ initrd_offset,

[Qemu-devel] [PATCH v6 2/6] Initial support of vt82686b south bridge used by fulong mini pc

2010-06-28 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.target |2 +-
 hw/pci_ids.h|8 +
 hw/vt82c686.c   |  597 +++
 hw/vt82c686.h   |   11 +
 4 files changed, 617 insertions(+), 1 deletions(-)
 create mode 100644 hw/vt82c686.c
 create mode 100644 hw/vt82c686.h

diff --git a/Makefile.target b/Makefile.target
index eb852d4..caabacd 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -221,7 +221,7 @@ obj-mips-y += vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
-obj-mips-$(CONFIG_FULONG) += bonito.o
+obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/hw/pci_ids.h b/hw/pci_ids.h
index fe7a121..39e9f1d 100644
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@ -78,6 +78,14 @@
 
 #define PCI_VENDOR_ID_XILINX 0x10ee
 
+#define PCI_VENDOR_ID_VIA0x1106
+#define PCI_DEVICE_ID_VIA_ISA_BRIDGE 0x0686
+#define PCI_DEVICE_ID_VIA_IDE0x0571
+#define PCI_DEVICE_ID_VIA_UHCI   0x3038
+#define PCI_DEVICE_ID_VIA_ACPI   0x3057
+#define PCI_DEVICE_ID_VIA_AC97   0x3058
+#define PCI_DEVICE_ID_VIA_MC97   0x3068
+
 #define PCI_VENDOR_ID_MARVELL0x11ab
 
 #define PCI_VENDOR_ID_ENSONIQ0x1274
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
new file mode 100644
index 000..a0c5747
--- /dev/null
+++ b/hw/vt82c686.c
@@ -0,0 +1,597 @@
+/*
+ * VT82C686B south bridge support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2009 chenming (chenm...@rdc.faw.com.cn)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ * This code is licensed under the GNU GPL v2.
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "vt82c686.h"
+#include "i2c.h"
+#include "smbus.h"
+#include "pci.h"
+#include "isa.h"
+#include "sysbus.h"
+#include "mips.h"
+#include "apm.h"
+#include "acpi.h"
+#include "pm_smbus.h"
+#include "sysemu.h"
+#include "qemu-timer.h"
+
+typedef uint32_t pci_addr_t;
+#include "pci_host.h"
+//#define DEBUG_VT82C686B
+
+#ifdef DEBUG_VT82C686B
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, 
##__VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+typedef struct SuperIOConfig
+{
+uint8_t config[0xff];
+uint8_t index;
+uint8_t data;
+} SuperIOConfig;
+
+typedef struct VT82C686BState {
+PCIDevice dev;
+SuperIOConfig superio_conf;
+} VT82C686BState;
+
+static void superio_ioport_writeb(void *opaque, uint32_t addr, uint32_t data)
+{
+int can_write;
+SuperIOConfig *superio_conf = opaque;
+
+DPRINTF("superio_ioport_writeb  address 0x%x  val 0x%x  \n", addr, data);
+if (addr == 0x3f0) {
+superio_conf->index = data & 0xff;
+} else {
+/* 0x3f1 */
+switch (superio_conf->index) {
+case 0x00 ... 0xdf:
+case 0xe4:
+case 0xe5:
+case 0xe9 ... 0xed:
+case 0xf3:
+case 0xf5:
+case 0xf7:
+case 0xf9 ... 0xfb:
+case 0xfd ... 0xff:
+can_write = 0;
+break;
+default:
+can_write = 1;
+
+if (can_write) {
+switch (superio_conf->index) {
+case 0xe7:
+if ((data & 0xff) != 0xfe) {
+DPRINTF("chage uart 1 base. unsupported yet \n");
+}
+break;
+case 0xe8:
+if ((data & 0xff) != 0xbe) {
+DPRINTF("chage uart 2 base. unsupported yet \n");
+}
+break;
+
+default:
+superio_conf->config[superio_conf->index] = data & 0xff;
+}
+}
+}
+superio_conf->config[superio_conf->index] = data & 0xff;
+}
+}
+
+static uint32_t superio_ioport_readb(void *opaque, uint32_t addr)
+{
+SuperIOConfig *superio_conf = opaque;
+
+DPRINTF("superio_ioport_readb  address 0x%x   \n", addr);
+return (superio_conf->config[superio_conf->index]);
+}
+
+static void vt82c686b_reset(void * opaque)
+{
+PCIDevice *d = opaque;
+uint8_t *pci_conf = d->config;
+VT82C686BState *vt82c = DO_UPCAST(VT82C686BState, dev, d);
+
+pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0);
+pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
+pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
+
+pci_conf[0x48] = 0x01; /* Miscellaneous Control 3 */
+pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */
+pci_conf[0x4f] = 0x03; /*

[Qemu-devel] [PATCH v6 4/6] MIPS: Initial support of VIA USB controller used by fulong mini pc

2010-06-28 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 hw/usb-uhci.c |   28 
 hw/usb-uhci.h |1 +
 2 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 624d55b..3eb9832 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1152,6 +1152,24 @@ static int usb_uhci_piix4_initfn(PCIDevice *dev)
 return usb_uhci_common_initfn(s);
 }
 
+static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
+{
+UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
+uint8_t *pci_conf = s->dev.config;
+
+pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
+pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_UHCI);
+
+/* USB misc control 1/2 */
+pci_set_long(pci_conf + 0x40,0x1000);
+/* PM capability */
+pci_set_long(pci_conf + 0x80,0x00020001);
+/* USB legacy support  */
+pci_set_long(pci_conf + 0xc0,0x2000);
+
+return usb_uhci_common_initfn(s);
+}
+
 static PCIDeviceInfo uhci_info[] = {
 {
 .qdev.name= "piix3-usb-uhci",
@@ -1164,6 +1182,11 @@ static PCIDeviceInfo uhci_info[] = {
 .qdev.vmsd= &vmstate_uhci,
 .init = usb_uhci_piix4_initfn,
 },{
+.qdev.name= "vt82c686b-usb-uhci",
+.qdev.size= sizeof(UHCIState),
+.qdev.vmsd= &vmstate_uhci,
+.init = usb_uhci_vt82c686b_initfn,
+},{
 /* end of list */
 }
 };
@@ -1183,3 +1206,8 @@ void usb_uhci_piix4_init(PCIBus *bus, int devfn)
 {
 pci_create_simple(bus, devfn, "piix4-usb-uhci");
 }
+
+void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn)
+{
+pci_create_simple(bus, devfn, "vt82c686b-usb-uhci");
+}
diff --git a/hw/usb-uhci.h b/hw/usb-uhci.h
index 911948e..3e4d377 100644
--- a/hw/usb-uhci.h
+++ b/hw/usb-uhci.h
@@ -5,5 +5,6 @@
 
 void usb_uhci_piix3_init(PCIBus *bus, int devfn);
 void usb_uhci_piix4_init(PCIBus *bus, int devfn);
+void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn);
 
 #endif
-- 
1.7.0.4




[Qemu-devel] [PATCH v6 5/6] MIPS: Initial support of fulong mini pc (CPU definition)

2010-06-28 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 target-mips/mips-defs.h  |4 
 target-mips/translate_init.c |   35 +++
 2 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h
index a7f4697..bf094a3 100644
--- a/target-mips/mips-defs.h
+++ b/target-mips/mips-defs.h
@@ -41,6 +41,8 @@
 #defineASE_MICROMIPS   0x0008
 
 /* Chip specific instructions. */
+#defineINSN_LOONGSON2E  0x2000
+#defineINSN_LOONGSON2F  0x4000
 #defineINSN_VR54XX 0x8000
 
 /* MIPS CPU defines. */
@@ -49,6 +51,8 @@
 #defineCPU_MIPS3   (CPU_MIPS2 | ISA_MIPS3)
 #defineCPU_MIPS4   (CPU_MIPS3 | ISA_MIPS4)
 #defineCPU_VR54XX  (CPU_MIPS4 | INSN_VR54XX)
+#defineCPU_LOONGSON2E  (CPU_MIPS3 | INSN_LOONGSON2E)
+#defineCPU_LOONGSON2F  (CPU_MIPS3 | INSN_LOONGSON2F)
 
 #defineCPU_MIPS5   (CPU_MIPS4 | ISA_MIPS5)
 
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index b79ed56..0d9899e 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -454,6 +454,41 @@ static const mips_def_t mips_defs[] =
 .insn_flags = CPU_MIPS64R2 | ASE_MIPS3D,
 .mmu_type = MMU_TYPE_R4000,
 },
+{
+.name = "Loongson-2E",
+.CP0_PRid = 0x6302,
+/*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/
+.CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) | (0x1<<5) 
|
+   (0x1<<4) | (0x1<<1),
+/* Note: Config1 is only used internally, Loongson-2E has only 
Config0. */
+.CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
+.SYNCI_Step = 16,
+.CCRes = 2,
+.CP0_Status_rw_bitmask = 0x35D0,
+.CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV),
+.SEGBITS = 40,
+.PABITS = 40,
+.insn_flags = CPU_LOONGSON2E,
+.mmu_type = MMU_TYPE_R4000,
+},
+{
+  .name = "Loongson-2F",
+  .CP0_PRid = 0x6303,
+  /*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/
+  .CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) | (0x1<<5) |
+ (0x1<<4) | (0x1<<1),
+  /* Note: Config1 is only used internally, Loongson-2F has only Config0. 
*/
+  .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
+  .SYNCI_Step = 16,
+  .CCRes = 2,
+  .CP0_Status_rw_bitmask = 0xF5D0FF1F,   /*bit5:7 not writeable*/
+  .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV),
+  .SEGBITS = 40,
+  .PABITS = 40,
+  .insn_flags = CPU_LOONGSON2F,
+  .mmu_type = MMU_TYPE_R4000,
+},
+
 #endif
 };
 
-- 
1.7.0.4




[Qemu-devel] [PATCH v6 1/6] MIPS: Initial support of bonito north bridge used by fulong mini pc

2010-06-28 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.target  |1 +
 default-configs/mips64el-softmmu.mak |1 +
 hw/bonito.c  |  809 ++
 hw/mips.h|3 +
 4 files changed, 814 insertions(+), 0 deletions(-)
 create mode 100644 hw/bonito.c

diff --git a/Makefile.target b/Makefile.target
index f64702b..eb852d4 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -221,6 +221,7 @@ obj-mips-y += vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
+obj-mips-$(CONFIG_FULONG) += bonito.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index b372c1d..d35d923 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -29,3 +29,4 @@ CONFIG_DP8393X=y
 CONFIG_DS1225Y=y
 CONFIG_MIPSNET=y
 CONFIG_PFLASH_CFI01=y
+CONFIG_FULONG=y
diff --git a/hw/bonito.c b/hw/bonito.c
new file mode 100644
index 000..8b81032
--- /dev/null
+++ b/hw/bonito.c
@@ -0,0 +1,809 @@
+/*
+ * bonito north bridge support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ *
+ * This code is licensed under the GNU GPL v2.
+ */
+
+/*
+ * fulong 2e mini pc has a bonito north bridge.
+ */
+
+/* what is the meaning of devfn in qemu and IDSEL in bonito northbridge?
+ *
+ * devfn   pci_slot<<3  + funno
+ * one pci bus can have 32 devices and each device can have 8 functions.
+ *
+ * In bonito north bridge, pci slot = IDSEL bit - 12.
+ * For example, PCI_IDSEL_VIA686B = 17,
+ * pci slot = 17-12=5
+ *
+ * so
+ * VT686B_FUN0's devfn = (5<<3)+0
+ * VT686B_FUN1's devfn = (5<<3)+1
+ *
+ * qemu also uses pci address for north bridge to access pci config register.
+ * bus_no   [23:16]
+ * dev_no   [15:11]
+ * fun_no   [10:8]
+ * reg_no   [7:2]
+ *
+ * so function bonito_sbridge_pciaddr for the translation from
+ * north bridge address to pci address.
+ */
+
+#include 
+
+#include "hw.h"
+#include "pci.h"
+#include "pc.h"
+#include "mips.h"
+#include "pci_host.h"
+#include "sysemu.h"
+
+//#define DEBUG_BONITO
+
+#ifdef DEBUG_BONITO
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, 
##__VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+/* from linux soure code. include/asm-mips/mips-boards/bonito64.h*/
+#define BONITO_BOOT_BASE0x1fc0
+#define BONITO_BOOT_SIZE0x0010
+#define BONITO_BOOT_TOP (BONITO_BOOT_BASE+BONITO_BOOT_SIZE-1)
+#define BONITO_FLASH_BASE   0x1c00
+#define BONITO_FLASH_SIZE   0x0300
+#define BONITO_FLASH_TOP(BONITO_FLASH_BASE+BONITO_FLASH_SIZE-1)
+#define BONITO_SOCKET_BASE  0x1f80
+#define BONITO_SOCKET_SIZE  0x0040
+#define BONITO_SOCKET_TOP   (BONITO_SOCKET_BASE+BONITO_SOCKET_SIZE-1)
+#define BONITO_REG_BASE 0x1fe0
+#define BONITO_REG_SIZE 0x0004
+#define BONITO_REG_TOP  (BONITO_REG_BASE+BONITO_REG_SIZE-1)
+#define BONITO_DEV_BASE 0x1ff0
+#define BONITO_DEV_SIZE 0x0010
+#define BONITO_DEV_TOP  (BONITO_DEV_BASE+BONITO_DEV_SIZE-1)
+#define BONITO_PCILO_BASE   0x1000
+#define BONITO_PCILO_BASE_VA0xb000
+#define BONITO_PCILO_SIZE   0x0c00
+#define BONITO_PCILO_TOP(BONITO_PCILO_BASE+BONITO_PCILO_SIZE-1)
+#define BONITO_PCILO0_BASE  0x1000
+#define BONITO_PCILO1_BASE  0x1400
+#define BONITO_PCILO2_BASE  0x1800
+#define BONITO_PCIHI_BASE   0x2000
+#define BONITO_PCIHI_SIZE   0x2000
+#define BONITO_PCIHI_TOP(BONITO_PCIHI_BASE+BONITO_PCIHI_SIZE-1)
+#define BONITO_PCIIO_BASE   0x1fd0
+#define BONITO_PCIIO_BASE_VA0xbfd0
+#define BONITO_PCIIO_SIZE   0x0001
+#define BONITO_PCIIO_TOP(BONITO_PCIIO_BASE+BONITO_PCIIO_SIZE-1)
+#define BONITO_PCICFG_BASE  0x1fe8
+#define BONITO_PCICFG_SIZE  0x0008
+#define BONITO_PCICFG_TOP   (BONITO_PCICFG_BASE+BONITO_PCICFG_SIZE-1)
+
+
+#define BONITO_PCICONFIGBASE0x00
+#define BONITO_REGBASE  0x100
+
+#define BONITO_PCICONFIG_BASE   (BONITO_PCICONFIGBASE+BONITO_REG_BASE)
+#define BONITO_PCICONFIG_SIZE   (0x100)
+
+#define BONITO_INTERNAL_REG_BASE  (BONITO_REGBASE+BONITO_REG_BASE)
+#define BONITO_INTERNAL_REG_SIZE  (0x70)
+
+#define BONITO_SPCICONFIG_BASE  (BONITO_PCICFG_BASE)
+#define BONITO_SPCICONFIG_SIZE  (BONITO_PCICFG_SIZE)
+
+
+
+/* 1. Bonito h/w Configuration */
+/* Power on register */
+
+#define BONITO_BONPONCFG(0x00 >> 2)  /* 0x100 */
+#define BONITO_BONGENCFG_OFFSET 0x4
+#define BONITO_BONGENCFG(BONITO_BONGENCFG_OFFSET>>2)   /*0x104 */
+
+/* 2. IO & IDE configuration */
+#define BONITO_IODEVCFG (0x08 >> 2)  

[Qemu-devel] [PATCH v6 6/6] MIPS: Initial support of fulong mini pc (machine construction)

2010-06-28 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.target|2 +-
 hw/mips_fulong2e.c |  416 
 2 files changed, 417 insertions(+), 1 deletions(-)
 create mode 100644 hw/mips_fulong2e.c

diff --git a/Makefile.target b/Makefile.target
index caabacd..2423c76 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -221,7 +221,7 @@ obj-mips-y += vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
-obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o
+obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
new file mode 100644
index 000..d03c897
--- /dev/null
+++ b/hw/mips_fulong2e.c
@@ -0,0 +1,416 @@
+/*
+ * QEMU fulong 2e mini pc support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2009 chenming (chenm...@rdc.faw.com.cn)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ * This code is licensed under the GNU GPL v2.
+ */
+
+/*
+ * Fulong 2e mini pc is based on ICT/ST Loongson 2e CPU (MIPS III like, 800MHz)
+ * http://www.linux-mips.org/wiki/Fulong
+ *
+ * Loongson 2e user manual:
+ * http://www.loongsondeveloper.com/doc/Loongson2EUserGuide.pdf
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "fdc.h"
+#include "net.h"
+#include "boards.h"
+#include "smbus.h"
+#include "block.h"
+#include "flash.h"
+#include "mips.h"
+#include "mips_cpudevs.h"
+#include "pci.h"
+#include "usb-uhci.h"
+#include "qemu-char.h"
+#include "sysemu.h"
+#include "audio/audio.h"
+#include "qemu-log.h"
+#include "loader.h"
+#include "mips-bios.h"
+#include "ide.h"
+#include "elf.h"
+#include "vt82c686.h"
+#include "mc146818rtc.h"
+
+#define DEBUG_FULONG2E_INIT
+
+#define ENVP_ADDR   0x80002000l
+#define ENVP_NB_ENTRIES16
+#define ENVP_ENTRY_SIZE256
+
+#define MAX_IDE_BUS 2
+
+/*
+ * PMON is not part of qemu and released with BSD license, anyone
+ * who want to build a pmon binary please first git-clone the source
+ * from the git repository at:
+ * http://www.loongson.cn/support/git/pmon
+ * Then follow the "Compile Guide" available at:
+ * http://dev.lemote.com/code/pmon
+ *
+ * Notes:
+ * 1, don't use the source at http://dev.lemote.com/http_git/pmon.git
+ * 2, use "Bonito2edev" to replace "dir_corresponding_to_your_target_hardware"
+ * in the "Compile Guide".
+ */
+#define FULONG_BIOSNAME "pmon_fulong2e.bin"
+
+/* PCI SLOT in fulong 2e */
+#define FULONG2E_VIA_SLOT5
+#define FULONG2E_ATI_SLOT6
+#define FULONG2E_RTL8139_SLOT7
+
+static PITState *pit;
+
+static struct _loaderparams {
+int ram_size;
+const char *kernel_filename;
+const char *kernel_cmdline;
+const char *initrd_filename;
+} loaderparams;
+
+static void prom_set(uint32_t* prom_buf, int index, const char *string, ...)
+{
+va_list ap;
+int32_t table_addr;
+
+if (index >= ENVP_NB_ENTRIES)
+return;
+
+if (string == NULL) {
+prom_buf[index] = 0;
+return;
+}
+
+table_addr = sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
+prom_buf[index] = tswap32(ENVP_ADDR + table_addr);
+
+va_start(ap, string);
+vsnprintf((char *)prom_buf + table_addr, ENVP_ENTRY_SIZE, string, ap);
+va_end(ap);
+}
+
+static int64_t load_kernel (CPUState *env)
+{
+int64_t kernel_entry, kernel_low, kernel_high;
+int index = 0;
+long initrd_size;
+ram_addr_t initrd_offset;
+uint32_t *prom_buf;
+long prom_size;
+
+if (load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, NULL,
+ (uint64_t *)&kernel_entry, (uint64_t *)&kernel_low,
+ (uint64_t *)&kernel_high, 0, ELF_MACHINE, 1) < 0) {
+fprintf(stderr, "qemu: could not load kernel '%s'\n",
+loaderparams.kernel_filename);
+exit(1);
+}
+
+/* load initrd */
+initrd_size = 0;
+initrd_offset = 0;
+if (loaderparams.initrd_filename) {
+initrd_size = get_image_size (loaderparams.initrd_filename);
+if (initrd_size > 0) {
+initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & 
TARGET_PAGE_MASK;
+if (initrd_offset + initrd_size > ram_size) {
+fprintf(stderr,
+"qemu: memory too small for initial ram disk '%s'\n",
+loaderparams.initrd_filename);
+exit(1);
+}
+initrd_size = load_image_targphys(loaderparams.initrd_filename,
+ initrd_offset,

[Qemu-devel] [PATCH v6 3/6] MIPS: Initial support of VIA IDE controller used by fulong mini pc

2010-06-28 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.objs|1 +
 default-configs/mips64el-softmmu.mak |1 +
 hw/ide.h |1 +
 hw/ide/via.c |  191 ++
 4 files changed, 194 insertions(+), 0 deletions(-)
 create mode 100644 hw/ide/via.c

diff --git a/Makefile.objs b/Makefile.objs
index 53fb68e..67a0c23 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -202,6 +202,7 @@ hw-obj-$(CONFIG_IDE_ISA) += ide/isa.o
 hw-obj-$(CONFIG_IDE_PIIX) += ide/piix.o
 hw-obj-$(CONFIG_IDE_CMD646) += ide/cmd646.o
 hw-obj-$(CONFIG_IDE_MACIO) += ide/macio.o
+hw-obj-$(CONFIG_IDE_VIA) += ide/via.o
 
 # SCSI layer
 hw-obj-y += lsi53c895a.o
diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index d35d923..85b7838 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -21,6 +21,7 @@ CONFIG_IDE_QDEV=y
 CONFIG_IDE_PCI=y
 CONFIG_IDE_ISA=y
 CONFIG_IDE_PIIX=y
+CONFIG_IDE_VIA=y
 CONFIG_NE2000_ISA=y
 CONFIG_SOUND=y
 CONFIG_VIRTIO_PCI=y
diff --git a/hw/ide.h b/hw/ide.h
index 0e7d540..bb635b6 100644
--- a/hw/ide.h
+++ b/hw/ide.h
@@ -12,6 +12,7 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
  int secondary_ide_enabled);
 void pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 void pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
+void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 
 /* ide-macio.c */
 int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
diff --git a/hw/ide/via.c b/hw/ide/via.c
new file mode 100644
index 000..d933caf
--- /dev/null
+++ b/hw/ide/via.c
@@ -0,0 +1,191 @@
+/*
+ * QEMU IDE Emulation: PCI VIA82C686B support.
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2006 Openedhand Ltd.
+ * Copyright (c) 2010 Huacai Chen 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include "block.h"
+#include "block_int.h"
+#include "sysemu.h"
+#include "dma.h"
+
+#include 
+
+static uint32_t bmdma_readb(void *opaque, uint32_t addr)
+{
+BMDMAState *bm = opaque;
+uint32_t val;
+
+switch (addr & 3) {
+case 0:
+val = bm->cmd;
+break;
+case 2:
+val = bm->status;
+break;
+default:
+val = 0xff;
+break;
+}
+#ifdef DEBUG_IDE
+printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
+#endif
+return val;
+}
+
+static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+BMDMAState *bm = opaque;
+#ifdef DEBUG_IDE
+printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
+#endif
+switch (addr & 3) {
+case 2:
+bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 
0x06);
+break;
+default:;
+}
+}
+
+static void bmdma_map(PCIDevice *pci_dev, int region_num,
+pcibus_t addr, pcibus_t size, int type)
+{
+PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
+int i;
+
+for(i = 0;i < 2; i++) {
+BMDMAState *bm = &d->bmdma[i];
+d->bus[i].bmdma = bm;
+bm->bus = d->bus+i;
+qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm);
+
+register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
+
+register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
+register_ioport_read(addr, 4, 1, bmdma_readb, bm);
+
+register_ioport_write(addr + 4, 4, 1, bmdma_addr_writeb, bm);
+register_ioport_read(addr + 4, 4, 1, bmdma_addr_readb, bm);
+register_ioport_write(addr + 4, 4, 2, bmdma_addr_writew, bm);
+register_ioport_read(addr + 4, 4, 2, bmdma_addr_readw, bm);
+register_ioport_write(addr + 4, 4, 4, bmdma_addr_wri

[Qemu-devel] [RFC][PATCH] PCI: fix pci_to_cpu_addr() issue

2010-06-30 Thread Huacai Chen
It seems like software may both use CPU address or PCI address to access a PCI
device. For example, Bonito north bridge map PCI memory space at 0x1000 ~ 
0x1C00. PMON code use 0x ~ 0x0C00, but Linux kernel code use 
0x1000 ~ 0x1C00 to access devices. If set pci_mem_base to 0, PMON can't
work, but if set pci_mem_base to 0x1000, Linux can't access PCI. So I make
this patch to make both cases works.

However, I don't know whether the modification will break other archs, so
request for comments here.

Signed-off-by: Huacai Chen 
---
 hw/pci.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 7787005..50e3572 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -672,7 +672,7 @@ PCIDevice *pci_register_device(PCIBus *bus, const char 
*name,
 static target_phys_addr_t pci_to_cpu_addr(PCIBus *bus,
   target_phys_addr_t addr)
 {
-return addr + bus->mem_base;
+return addr | bus->mem_base;
 }
 
 static void pci_unregister_io_regions(PCIDevice *pci_dev)
-- 
1.7.0.4




[Qemu-devel] [PATCH] Remove incorrect pci_mem_base setting in bonito northbridge

2010-07-14 Thread Huacai Chen
This mistake makes PCI devices can't work correctly.

Signed-off-by: Huacai Chen 
---
 hw/bonito.c |1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/hw/bonito.c b/hw/bonito.c
index 8b81032..dcf0311 100644
--- a/hw/bonito.c
+++ b/hw/bonito.c
@@ -775,7 +775,6 @@ PCIBus *bonito_init(qemu_irq *pic)
  pci_bonito_map_irq, pic, 0x28, 32);
 pcihost->bus = b;
 qdev_init_nofail(dev);
-pci_bus_set_mem_base(pcihost->bus, 0x1000);
 
 d = pci_create_simple(b, PCI_DEVFN(0, 0), "Bonito");
 s = DO_UPCAST(PCIBonitoState, dev, d);
-- 
1.7.0.4




[Qemu-devel] [PATCH resend 2/6] MIPS: Initial support of vt82686b south bridge used by fulong mini pc

2010-05-12 Thread Huacai Chen
resend by git send-email to avoid line-wrapping

Signed-off-by: Huacai Chen 
---
 Makefile.target |2 +-
 hw/pc.h |7 +
 hw/pci_ids.h|8 +
 hw/vt82c686.c   |  786 +++
 4 files changed, 802 insertions(+), 1 deletions(-)
 create mode 100644 hw/vt82c686.c

diff --git a/Makefile.target b/Makefile.target
index 63d9f49..4fc1290 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -220,7 +220,7 @@ obj-mips-y += dma.o vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o pckbd.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
-obj-mips-$(CONFIG_FULONG) += bonito.o
+obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/hw/pc.h b/hw/pc.h
index d11a576..8951609 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -115,6 +115,13 @@ void i440fx_init_memory_mappings(PCII440FXState *d);
 extern PCIDevice *piix4_dev;
 int piix4_init(PCIBus *bus, int devfn);
 
+/* vt82c686.c */
+int vt82c686b_init(PCIBus * bus, int devfn);
+void vt82c686b_ac97_init(PCIBus *bus, int devfn);
+void vt82c686b_mc97_init(PCIBus *bus, int devfn);
+i2c_bus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
+qemu_irq sci_irq);
+
 /* vga.c */
 enum vga_retrace_method {
 VGA_RETRACE_DUMB,
diff --git a/hw/pci_ids.h b/hw/pci_ids.h
index fe7a121..39e9f1d 100644
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@ -78,6 +78,14 @@
 
 #define PCI_VENDOR_ID_XILINX 0x10ee
 
+#define PCI_VENDOR_ID_VIA0x1106
+#define PCI_DEVICE_ID_VIA_ISA_BRIDGE 0x0686
+#define PCI_DEVICE_ID_VIA_IDE0x0571
+#define PCI_DEVICE_ID_VIA_UHCI   0x3038
+#define PCI_DEVICE_ID_VIA_ACPI   0x3057
+#define PCI_DEVICE_ID_VIA_AC97   0x3058
+#define PCI_DEVICE_ID_VIA_MC97   0x3068
+
 #define PCI_VENDOR_ID_MARVELL0x11ab
 
 #define PCI_VENDOR_ID_ENSONIQ0x1274
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
new file mode 100644
index 000..1045467
--- /dev/null
+++ b/hw/vt82c686.c
@@ -0,0 +1,786 @@
+/*
+ * VT82C686B south bridge support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2009 chenming (chenm...@rdc.faw.com.cn)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ * This code is licensed under the GNU GPL v2.
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "i2c.h"
+#include "smbus.h"
+#include "pci.h"
+#include "isa.h"
+#include "sysbus.h"
+#include "mips.h"
+
+typedef uint32_t pci_addr_t;
+#include "pci_host.h"
+//#define DEBUG_VT82C686B
+
+#ifdef DEBUG_VT82C686B
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, 
##__VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+typedef struct SuperIOConfig
+{
+uint8_t config[0xff];
+uint8_t index;
+uint8_t data;
+} SuperIOConfig;
+
+typedef struct VT82C686BState {
+PCIDevice dev;
+SuperIOConfig *superio_conf;
+} VT82C686BState;
+
+uint32_t smb_data[16];
+static void superio_ioport_writeb(void *opaque, uint32_t addr, uint32_t data)
+{
+int can_write;
+SuperIOConfig *superio_conf = (SuperIOConfig *)opaque;
+
+DPRINTF("superio_ioport_writeb  address 0x%x  val 0x%x  \n", addr, data);
+if (addr == 0x3f0) {
+superio_conf->index = data & 0xff;
+} else {
+/* 0x3f1 */
+switch (superio_conf->index) {
+case 0x00 ... 0xdf:
+case 0xe4:
+case 0xe5:
+case 0xe9 ... 0xed:
+case 0xf3:
+case 0xf5:
+case 0xf7:
+case 0xf9 ... 0xfb:
+case 0xfd ... 0xff:
+can_write = 0;
+break;
+default:
+can_write = 1;
+
+if (can_write) {
+switch (superio_conf->index) {
+case 0xe7:
+if ((data & 0xff) != 0xfe) {
+DPRINTF("chage uart 1 base. unsupported yet \n");
+}
+break;
+case 0xe8:
+if ((data & 0xff) != 0xbe) {
+DPRINTF("chage uart 2 base. unsupported yet \n");
+}
+break;
+
+default:
+superio_conf->config[superio_conf->index] = data & 0xff;
+}
+}
+}
+superio_conf->config[superio_conf->index] = data & 0xff;
+}
+}
+
+static uint32_t superio_ioport_readb(void *opaque, uint32_t addr)
+{
+SuperIOConfig *superio_conf = (SuperIOConfig *)opaque;
+
+DPRINTF("superio_ioport_readb  address 0x%x   \n", addr);
+return (superio_conf->config[superio_conf->index]);
+}
+
+static void vt82c686b_reset(void * opaque)
+{
+PCIDevice *d = opaque;
+uint8_t *pci_conf = d->config;
+VT82C686BState *vt82

[Qemu-devel] [PATCH resend 5/6] MIPS: Initial support of fulong mini pc (CPU definition, machine construction, etc.)

2010-05-12 Thread Huacai Chen
resend by git send-email to avoid line-wrapping

Signed-off-by: Huacai Chen 
---
 Makefile.target  |2 +-
 hw/mips_fulong2e.c   |  420 ++
 target-mips/translate_init.c |   35 
 3 files changed, 456 insertions(+), 1 deletions(-)
 create mode 100644 hw/mips_fulong2e.c

diff --git a/Makefile.target b/Makefile.target
index 4fc1290..7a9d93b 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -220,7 +220,7 @@ obj-mips-y += dma.o vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o pckbd.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
-obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o
+obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
new file mode 100644
index 000..3f6d25b
--- /dev/null
+++ b/hw/mips_fulong2e.c
@@ -0,0 +1,420 @@
+/*
+ * QEMU fulong 2e mini pc support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2009 chenming (chenm...@rdc.faw.com.cn)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ * This code is licensed under the GNU GPL v2.
+ */
+
+/*
+ * Fulong 2e mini pc is based on ICT/ST Loongson 2e CPU (MIPS III like, 800MHz)
+ * http://www.linux-mips.org/wiki/Fulong
+ *
+ * Loongson 2e user manual:
+ * http://www.loongsondeveloper.com/doc/Loongson2EUserGuide.pdf
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "fdc.h"
+#include "net.h"
+#include "boards.h"
+#include "smbus.h"
+#include "block.h"
+#include "flash.h"
+#include "mips.h"
+#include "mips_cpudevs.h"
+#include "pci.h"
+#include "usb-uhci.h"
+#include "qemu-char.h"
+#include "sysemu.h"
+#include "audio/audio.h"
+#include "qemu-log.h"
+#include "loader.h"
+#include "mips-bios.h"
+#include "ide.h"
+#include "elf.h"
+
+#define DEBUG_FULONG2E_INIT
+
+#define ENVP_ADDR   0x80002000l
+#define ENVP_NB_ENTRIES16
+#define ENVP_ENTRY_SIZE256
+
+#define MAX_IDE_BUS 2
+
+/* PCI SLOT in fulong 2e */
+#define FULONG2E_VIA_SLOT5
+#define FULONG2E_ATI_SLOT6
+#define FULONG2E_RTL8139_SLOT7
+
+static PITState *pit;
+
+static struct _loaderparams {
+int ram_size;
+const char *kernel_filename;
+const char *kernel_cmdline;
+const char *initrd_filename;
+} loaderparams;
+
+static void mips_qemu_writel (void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+if ((addr & 0x) == 0 && val == 42)
+qemu_system_reset_request ();
+else if ((addr & 0x) == 4 && val == 42)
+qemu_system_shutdown_request ();
+}
+
+static uint32_t mips_qemu_readl (void *opaque, target_phys_addr_t addr)
+{
+return 0;
+}
+
+static CPUWriteMemoryFunc *mips_qemu_write[] = {
+mips_qemu_writel,
+mips_qemu_writel,
+mips_qemu_writel,
+};
+
+static CPUReadMemoryFunc *mips_qemu_read[] = {
+mips_qemu_readl,
+mips_qemu_readl,
+mips_qemu_readl,
+};
+static int mips_qemu_iomemtype = 0;
+
+static void prom_set(uint32_t* prom_buf, int index, const char *string, ...)
+{
+va_list ap;
+int32_t table_addr;
+
+if (index >= ENVP_NB_ENTRIES)
+return;
+
+if (string == NULL) {
+prom_buf[index] = 0;
+return;
+}
+
+table_addr = sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
+prom_buf[index] = tswap32(ENVP_ADDR + table_addr);
+
+va_start(ap, string);
+vsnprintf((char *)prom_buf + table_addr, ENVP_ENTRY_SIZE, string, ap);
+va_end(ap);
+}
+
+static int64_t load_kernel (CPUState *env)
+{
+int64_t kernel_entry, kernel_low, kernel_high;
+int index = 0;
+long initrd_size;
+ram_addr_t initrd_offset;
+uint32_t *prom_buf;
+long prom_size;
+
+if (load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, NULL,
+ (uint64_t *)&kernel_entry, (uint64_t *)&kernel_low,
+ (uint64_t *)&kernel_high, 0, ELF_MACHINE, 1) < 0) {
+fprintf(stderr, "qemu: could not load kernel '%s'\n",
+loaderparams.kernel_filename);
+exit(1);
+}
+
+/* load initrd */
+initrd_size = 0;
+initrd_offset = 0;
+if (loaderparams.initrd_filename) {
+initrd_size = get_image_size (loaderparams.initrd_filename);
+if (initrd_size > 0) {
+initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & 
TARGET_PAGE_MASK;
+if (initrd_offset + initrd_size > ram_size) {
+fprintf(stderr,
+"qemu: memory too small for initial ram disk '%s'\n",
+loaderparams.initrd_filename);
+exit(1);
+ 

[Qemu-devel] [PATCH resend 4/6] MIPS: Initial support of VIA USB controller used by fulong mini pc

2010-05-12 Thread Huacai Chen
resend by git send-email to avoid line-wrapping

Signed-off-by: Huacai Chen 
---
 hw/usb-uhci.c |   30 ++
 hw/usb-uhci.h |1 +
 2 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 624d55b..5fd5388 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1152,6 +1152,26 @@ static int usb_uhci_piix4_initfn(PCIDevice *dev)
 return usb_uhci_common_initfn(s);
 }
 
+static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
+{
+UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
+uint8_t *pci_conf = s->dev.config;
+
+pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
+pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_UHCI);
+
+pci_set_long(pci_conf + 0x0c,0x1600);
+pci_set_long(pci_conf + 0x20,0x0301);
+pci_set_long(pci_conf + 0x34,0x1080);
+pci_set_long(pci_conf + 0x3c,0x0004);
+pci_set_long(pci_conf + 0x40,0x1000);
+pci_set_long(pci_conf + 0x60,0x0010);
+pci_set_long(pci_conf + 0x80,0x00020001);
+pci_set_long(pci_conf + 0xc0,0x2000);
+
+return usb_uhci_common_initfn(s);
+}
+
 static PCIDeviceInfo uhci_info[] = {
 {
 .qdev.name= "piix3-usb-uhci",
@@ -1164,6 +1184,11 @@ static PCIDeviceInfo uhci_info[] = {
 .qdev.vmsd= &vmstate_uhci,
 .init = usb_uhci_piix4_initfn,
 },{
+.qdev.name= "vt82c686b-usb-uhci",
+.qdev.size= sizeof(UHCIState),
+.qdev.vmsd= &vmstate_uhci,
+.init = usb_uhci_vt82c686b_initfn,
+},{
 /* end of list */
 }
 };
@@ -1183,3 +1208,8 @@ void usb_uhci_piix4_init(PCIBus *bus, int devfn)
 {
 pci_create_simple(bus, devfn, "piix4-usb-uhci");
 }
+
+void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn)
+{
+pci_create_simple(bus, devfn, "vt82c686b-usb-uhci");
+}
diff --git a/hw/usb-uhci.h b/hw/usb-uhci.h
index 911948e..3e4d377 100644
--- a/hw/usb-uhci.h
+++ b/hw/usb-uhci.h
@@ -5,5 +5,6 @@
 
 void usb_uhci_piix3_init(PCIBus *bus, int devfn);
 void usb_uhci_piix4_init(PCIBus *bus, int devfn);
+void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn);
 
 #endif
-- 
1.7.0.4




[Qemu-devel] [PATCH resend 1/6] MIPS: Initial support of bonito north bridge used by fulong mini pc

2010-05-12 Thread Huacai Chen
resend by git send-email to avoid line-wrapping

Signed-off-by: Huacai Chen 
---
 Makefile.target  |1 +
 default-configs/mips64el-softmmu.mak |1 +
 hw/bonito.c  |  950 ++
 hw/mips.h|3 +
 4 files changed, 955 insertions(+), 0 deletions(-)
 create mode 100644 hw/bonito.c

diff --git a/Makefile.target b/Makefile.target
index c092900..63d9f49 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -220,6 +220,7 @@ obj-mips-y += dma.o vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o pckbd.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
+obj-mips-$(CONFIG_FULONG) += bonito.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index b9b8c71..970568c 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -26,3 +26,4 @@ CONFIG_DP8393X=y
 CONFIG_DS1225Y=y
 CONFIG_MIPSNET=y
 CONFIG_PFLASH_CFI01=y
+CONFIG_FULONG=y
diff --git a/hw/bonito.c b/hw/bonito.c
new file mode 100644
index 000..246c12a
--- /dev/null
+++ b/hw/bonito.c
@@ -0,0 +1,950 @@
+/*
+ * bonito north bridge support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ *
+ * This code is licensed under the GNU GPL v2.
+ */
+
+/*
+ * fulong 2e mini pc has a bonito north bridge.
+ */
+
+/* what is the meaning of devfn in qemu and IDSEL in bonito northbridge?
+ *
+ * devfn   pci_slot<<3  + funno
+ * one pci bus can have 32 devices and each device can have 8 functions.
+ *
+ * In bonito north bridge, pci slot = IDSEL bit - 12.
+ * For example, PCI_IDSEL_VIA686B = 17,
+ * pci slot = 17-12=5
+ *
+ * so
+ * VT686B_FUN0's devfn = (5<<3)+0
+ * VT686B_FUN1's devfn = (5<<3)+1
+ *
+ * qemu also uses pci address for north bridge to access pci config register.
+ * bus_no   [23:16]
+ * dev_no   [15:11]
+ * fun_no   [10:8]
+ * reg_no   [7:2]
+ *
+ * so function bonito_sbridge_pciaddr for the translation from
+ * north bridge address to pci address.
+ */
+
+#include 
+
+#include "hw.h"
+#include "pci.h"
+#include "pc.h"
+#include "mips.h"
+
+typedef target_phys_addr_t pci_addr_t;
+#include "pci_host.h"
+
+//#define DEBUG_BONITO
+
+#ifdef DEBUG_BONITO
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, 
##__VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+/* from linux soure code. include/asm-mips/mips-boards/bonito64.h*/
+#define BONITO_BOOT_BASE0x1fc0
+#define BONITO_BOOT_SIZE0x0010
+#define BONITO_BOOT_TOP (BONITO_BOOT_BASE+BONITO_BOOT_SIZE-1)
+#define BONITO_FLASH_BASE   0x1c00
+#define BONITO_FLASH_SIZE   0x0300
+#define BONITO_FLASH_TOP(BONITO_FLASH_BASE+BONITO_FLASH_SIZE-1)
+#define BONITO_SOCKET_BASE  0x1f80
+#define BONITO_SOCKET_SIZE  0x0040
+#define BONITO_SOCKET_TOP   (BONITO_SOCKET_BASE+BONITO_SOCKET_SIZE-1)
+#define BONITO_REG_BASE 0x1fe0
+#define BONITO_REG_SIZE 0x0004
+#define BONITO_REG_TOP  (BONITO_REG_BASE+BONITO_REG_SIZE-1)
+#define BONITO_DEV_BASE 0x1ff0
+#define BONITO_DEV_SIZE 0x0010
+#define BONITO_DEV_TOP  (BONITO_DEV_BASE+BONITO_DEV_SIZE-1)
+#define BONITO_PCILO_BASE   0x1000
+#define BONITO_PCILO_BASE_VA0xb000
+#define BONITO_PCILO_SIZE   0x0c00
+#define BONITO_PCILO_TOP(BONITO_PCILO_BASE+BONITO_PCILO_SIZE-1)
+#define BONITO_PCILO0_BASE  0x1000
+#define BONITO_PCILO1_BASE  0x1400
+#define BONITO_PCILO2_BASE  0x1800
+#define BONITO_PCIHI_BASE   0x2000
+#define BONITO_PCIHI_SIZE   0x2000
+#define BONITO_PCIHI_TOP(BONITO_PCIHI_BASE+BONITO_PCIHI_SIZE-1)
+#define BONITO_PCIIO_BASE   0x1fd0
+#define BONITO_PCIIO_BASE_VA0xbfd0
+#define BONITO_PCIIO_SIZE   0x0001
+#define BONITO_PCIIO_TOP(BONITO_PCIIO_BASE+BONITO_PCIIO_SIZE-1)
+#define BONITO_PCICFG_BASE  0x1fe8
+#define BONITO_PCICFG_SIZE  0x0008
+#define BONITO_PCICFG_TOP   (BONITO_PCICFG_BASE+BONITO_PCICFG_SIZE-1)
+
+
+#define BONITO_PCICONFIGBASE0x00
+#define BONITO_REGBASE  0x100
+
+#define BONITO_PCICONFIG_BASE   (BONITO_PCICONFIGBASE+BONITO_REG_BASE)
+#define BONITO_PCICONFIG_SIZE   (0x100)
+
+#define BONITO_INTERNAL_REG_BASE  (BONITO_REGBASE+BONITO_REG_BASE)
+#define BONITO_INTERNAL_REG_SIZE  (0x70)
+
+#define BONITO_SPCICONFIG_BASE  (BONITO_PCICFG_BASE)
+#define BONITO_SPCICONFIG_SIZE  (BONITO_PCICFG_SIZE)
+
+
+
+/* 1. Bonito h/w Configuration */
+/* Power on register */
+
+#define BONITO_BONPONCFG(0x00 >> 2)  /* 0x100 */
+#define BONITO_BONGENCFG_OFFSET 0x4
+#define BONITO_BONGENCFG(BONITO_BONGENCFG_OFFSET>>2)   /*0x104 */
+
+/* 2. IO &a

[Qemu-devel] [PATCH resend 3/6] MIPS: Initial support of VIA IDE controller used by fulong mini pc

2010-05-12 Thread Huacai Chen
resend by git send-email to avoid line-wrapping

Signed-off-by: Huacai Chen 
---
 Makefile.objs|1 +
 default-configs/mips64el-softmmu.mak |1 +
 hw/ide.h |1 +
 hw/ide/via.c |  185 ++
 4 files changed, 188 insertions(+), 0 deletions(-)
 create mode 100644 hw/ide/via.c

diff --git a/Makefile.objs b/Makefile.objs
index ecdd53e..75be9ce 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -195,6 +195,7 @@ hw-obj-$(CONFIG_IDE_ISA) += ide/isa.o
 hw-obj-$(CONFIG_IDE_PIIX) += ide/piix.o
 hw-obj-$(CONFIG_IDE_CMD646) += ide/cmd646.o
 hw-obj-$(CONFIG_IDE_MACIO) += ide/macio.o
+hw-obj-$(CONFIG_IDE_VIA) += ide/via.o
 
 # SCSI layer
 hw-obj-y += lsi53c895a.o
diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index 970568c..8399c85 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -18,6 +18,7 @@ CONFIG_IDE_QDEV=y
 CONFIG_IDE_PCI=y
 CONFIG_IDE_ISA=y
 CONFIG_IDE_PIIX=y
+CONFIG_IDE_VIA=y
 CONFIG_NE2000_ISA=y
 CONFIG_SOUND=y
 CONFIG_VIRTIO_PCI=y
diff --git a/hw/ide.h b/hw/ide.h
index 0e7d540..bb635b6 100644
--- a/hw/ide.h
+++ b/hw/ide.h
@@ -12,6 +12,7 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
  int secondary_ide_enabled);
 void pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 void pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
+void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 
 /* ide-macio.c */
 int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
diff --git a/hw/ide/via.c b/hw/ide/via.c
new file mode 100644
index 000..f76763c
--- /dev/null
+++ b/hw/ide/via.c
@@ -0,0 +1,185 @@
+/*
+ * QEMU IDE Emulation: PCI VIA82C686B support.
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2006 Openedhand Ltd.
+ * Copyright (c) 2010 Huacai Chen 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include "block.h"
+#include "block_int.h"
+#include "sysemu.h"
+#include "dma.h"
+
+#include 
+
+static uint32_t bmdma_readb(void *opaque, uint32_t addr)
+{
+BMDMAState *bm = opaque;
+uint32_t val;
+
+switch (addr & 3) {
+case 0:
+val = bm->cmd;
+break;
+case 2:
+val = bm->status;
+break;
+default:
+val = 0xff;
+break;
+}
+#ifdef DEBUG_IDE
+printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
+#endif
+return val;
+}
+
+static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+BMDMAState *bm = opaque;
+#ifdef DEBUG_IDE
+printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
+#endif
+switch (addr & 3) {
+case 2:
+bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 
0x06);
+break;
+default:;
+}
+}
+
+static void bmdma_map(PCIDevice *pci_dev, int region_num,
+pcibus_t addr, pcibus_t size, int type)
+{
+PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
+int i;
+
+for(i = 0;i < 2; i++) {
+BMDMAState *bm = &d->bmdma[i];
+d->bus[i].bmdma = bm;
+bm->bus = d->bus+i;
+qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm);
+
+register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
+
+register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
+register_ioport_read(addr, 4, 1, bmdma_readb, bm);
+
+register_ioport_write(addr + 4, 4, 1, bmdma_addr_writeb, bm);
+register_ioport_read(addr + 4, 4, 1, bmdma_addr_readb, bm);
+register_ioport_write(addr + 4, 4, 2, bmdma_addr_writew, bm);
+register_ioport_read(addr + 4, 4, 2, bmdma_addr_readw, bm);
+regist

[Qemu-devel] [PATCH v2 1/6] MIPS: Initial support of bonito north bridge used by fulong mini pc

2010-05-19 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.target  |1 +
 default-configs/mips64el-softmmu.mak |1 +
 hw/bonito.c  |  950 ++
 hw/mips.h|3 +
 4 files changed, 955 insertions(+), 0 deletions(-)
 create mode 100644 hw/bonito.c

diff --git a/Makefile.target b/Makefile.target
index a22484e..247a2eb 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -221,6 +221,7 @@ obj-mips-y += dma.o vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o pckbd.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
+obj-mips-$(CONFIG_FULONG) += bonito.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index 6fa54a3..b731c74 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -27,3 +27,4 @@ CONFIG_DP8393X=y
 CONFIG_DS1225Y=y
 CONFIG_MIPSNET=y
 CONFIG_PFLASH_CFI01=y
+CONFIG_FULONG=y
diff --git a/hw/bonito.c b/hw/bonito.c
new file mode 100644
index 000..246c12a
--- /dev/null
+++ b/hw/bonito.c
@@ -0,0 +1,950 @@
+/*
+ * bonito north bridge support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ *
+ * This code is licensed under the GNU GPL v2.
+ */
+
+/*
+ * fulong 2e mini pc has a bonito north bridge.
+ */
+
+/* what is the meaning of devfn in qemu and IDSEL in bonito northbridge?
+ *
+ * devfn   pci_slot<<3  + funno
+ * one pci bus can have 32 devices and each device can have 8 functions.
+ *
+ * In bonito north bridge, pci slot = IDSEL bit - 12.
+ * For example, PCI_IDSEL_VIA686B = 17,
+ * pci slot = 17-12=5
+ *
+ * so
+ * VT686B_FUN0's devfn = (5<<3)+0
+ * VT686B_FUN1's devfn = (5<<3)+1
+ *
+ * qemu also uses pci address for north bridge to access pci config register.
+ * bus_no   [23:16]
+ * dev_no   [15:11]
+ * fun_no   [10:8]
+ * reg_no   [7:2]
+ *
+ * so function bonito_sbridge_pciaddr for the translation from
+ * north bridge address to pci address.
+ */
+
+#include 
+
+#include "hw.h"
+#include "pci.h"
+#include "pc.h"
+#include "mips.h"
+
+typedef target_phys_addr_t pci_addr_t;
+#include "pci_host.h"
+
+//#define DEBUG_BONITO
+
+#ifdef DEBUG_BONITO
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, 
##__VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+/* from linux soure code. include/asm-mips/mips-boards/bonito64.h*/
+#define BONITO_BOOT_BASE0x1fc0
+#define BONITO_BOOT_SIZE0x0010
+#define BONITO_BOOT_TOP (BONITO_BOOT_BASE+BONITO_BOOT_SIZE-1)
+#define BONITO_FLASH_BASE   0x1c00
+#define BONITO_FLASH_SIZE   0x0300
+#define BONITO_FLASH_TOP(BONITO_FLASH_BASE+BONITO_FLASH_SIZE-1)
+#define BONITO_SOCKET_BASE  0x1f80
+#define BONITO_SOCKET_SIZE  0x0040
+#define BONITO_SOCKET_TOP   (BONITO_SOCKET_BASE+BONITO_SOCKET_SIZE-1)
+#define BONITO_REG_BASE 0x1fe0
+#define BONITO_REG_SIZE 0x0004
+#define BONITO_REG_TOP  (BONITO_REG_BASE+BONITO_REG_SIZE-1)
+#define BONITO_DEV_BASE 0x1ff0
+#define BONITO_DEV_SIZE 0x0010
+#define BONITO_DEV_TOP  (BONITO_DEV_BASE+BONITO_DEV_SIZE-1)
+#define BONITO_PCILO_BASE   0x1000
+#define BONITO_PCILO_BASE_VA0xb000
+#define BONITO_PCILO_SIZE   0x0c00
+#define BONITO_PCILO_TOP(BONITO_PCILO_BASE+BONITO_PCILO_SIZE-1)
+#define BONITO_PCILO0_BASE  0x1000
+#define BONITO_PCILO1_BASE  0x1400
+#define BONITO_PCILO2_BASE  0x1800
+#define BONITO_PCIHI_BASE   0x2000
+#define BONITO_PCIHI_SIZE   0x2000
+#define BONITO_PCIHI_TOP(BONITO_PCIHI_BASE+BONITO_PCIHI_SIZE-1)
+#define BONITO_PCIIO_BASE   0x1fd0
+#define BONITO_PCIIO_BASE_VA0xbfd0
+#define BONITO_PCIIO_SIZE   0x0001
+#define BONITO_PCIIO_TOP(BONITO_PCIIO_BASE+BONITO_PCIIO_SIZE-1)
+#define BONITO_PCICFG_BASE  0x1fe8
+#define BONITO_PCICFG_SIZE  0x0008
+#define BONITO_PCICFG_TOP   (BONITO_PCICFG_BASE+BONITO_PCICFG_SIZE-1)
+
+
+#define BONITO_PCICONFIGBASE0x00
+#define BONITO_REGBASE  0x100
+
+#define BONITO_PCICONFIG_BASE   (BONITO_PCICONFIGBASE+BONITO_REG_BASE)
+#define BONITO_PCICONFIG_SIZE   (0x100)
+
+#define BONITO_INTERNAL_REG_BASE  (BONITO_REGBASE+BONITO_REG_BASE)
+#define BONITO_INTERNAL_REG_SIZE  (0x70)
+
+#define BONITO_SPCICONFIG_BASE  (BONITO_PCICFG_BASE)
+#define BONITO_SPCICONFIG_SIZE  (BONITO_PCICFG_SIZE)
+
+
+
+/* 1. Bonito h/w Configuration */
+/* Power on register */
+
+#define BONITO_BONPONCFG(0x00 >> 2)  /* 0x100 */
+#define BONITO_BONGENCFG_OFFSET 0x4
+#define BONITO_BONGENCFG(BONITO_BONGENCFG_OFFSET>>2)   /*0x104 */
+
+/* 2. IO & IDE configuration */
+#define BONITO_IODEVCFG   

[Qemu-devel] [PATCH v2 2/6] MIPS: Initial support of vt82686b south bridge used by fulong mini pc

2010-05-19 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.target |2 +-
 hw/pc.h |7 +
 hw/pci_ids.h|8 +
 hw/vt82c686.c   |  786 +++
 4 files changed, 802 insertions(+), 1 deletions(-)
 create mode 100644 hw/vt82c686.c

diff --git a/Makefile.target b/Makefile.target
index 247a2eb..9ed4a8d 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -221,7 +221,7 @@ obj-mips-y += dma.o vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o pckbd.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
-obj-mips-$(CONFIG_FULONG) += bonito.o
+obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/hw/pc.h b/hw/pc.h
index 654b7b3..7f0730b 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -143,6 +143,13 @@ void i440fx_init_memory_mappings(PCII440FXState *d);
 extern PCIDevice *piix4_dev;
 int piix4_init(PCIBus *bus, int devfn);
 
+/* vt82c686.c */
+int vt82c686b_init(PCIBus * bus, int devfn);
+void vt82c686b_ac97_init(PCIBus *bus, int devfn);
+void vt82c686b_mc97_init(PCIBus *bus, int devfn);
+i2c_bus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
+qemu_irq sci_irq);
+
 /* vga.c */
 enum vga_retrace_method {
 VGA_RETRACE_DUMB,
diff --git a/hw/pci_ids.h b/hw/pci_ids.h
index fe7a121..39e9f1d 100644
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@ -78,6 +78,14 @@
 
 #define PCI_VENDOR_ID_XILINX 0x10ee
 
+#define PCI_VENDOR_ID_VIA0x1106
+#define PCI_DEVICE_ID_VIA_ISA_BRIDGE 0x0686
+#define PCI_DEVICE_ID_VIA_IDE0x0571
+#define PCI_DEVICE_ID_VIA_UHCI   0x3038
+#define PCI_DEVICE_ID_VIA_ACPI   0x3057
+#define PCI_DEVICE_ID_VIA_AC97   0x3058
+#define PCI_DEVICE_ID_VIA_MC97   0x3068
+
 #define PCI_VENDOR_ID_MARVELL0x11ab
 
 #define PCI_VENDOR_ID_ENSONIQ0x1274
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
new file mode 100644
index 000..1045467
--- /dev/null
+++ b/hw/vt82c686.c
@@ -0,0 +1,786 @@
+/*
+ * VT82C686B south bridge support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2009 chenming (chenm...@rdc.faw.com.cn)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ * This code is licensed under the GNU GPL v2.
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "i2c.h"
+#include "smbus.h"
+#include "pci.h"
+#include "isa.h"
+#include "sysbus.h"
+#include "mips.h"
+
+typedef uint32_t pci_addr_t;
+#include "pci_host.h"
+//#define DEBUG_VT82C686B
+
+#ifdef DEBUG_VT82C686B
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, 
##__VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+typedef struct SuperIOConfig
+{
+uint8_t config[0xff];
+uint8_t index;
+uint8_t data;
+} SuperIOConfig;
+
+typedef struct VT82C686BState {
+PCIDevice dev;
+SuperIOConfig *superio_conf;
+} VT82C686BState;
+
+uint32_t smb_data[16];
+static void superio_ioport_writeb(void *opaque, uint32_t addr, uint32_t data)
+{
+int can_write;
+SuperIOConfig *superio_conf = (SuperIOConfig *)opaque;
+
+DPRINTF("superio_ioport_writeb  address 0x%x  val 0x%x  \n", addr, data);
+if (addr == 0x3f0) {
+superio_conf->index = data & 0xff;
+} else {
+/* 0x3f1 */
+switch (superio_conf->index) {
+case 0x00 ... 0xdf:
+case 0xe4:
+case 0xe5:
+case 0xe9 ... 0xed:
+case 0xf3:
+case 0xf5:
+case 0xf7:
+case 0xf9 ... 0xfb:
+case 0xfd ... 0xff:
+can_write = 0;
+break;
+default:
+can_write = 1;
+
+if (can_write) {
+switch (superio_conf->index) {
+case 0xe7:
+if ((data & 0xff) != 0xfe) {
+DPRINTF("chage uart 1 base. unsupported yet \n");
+}
+break;
+case 0xe8:
+if ((data & 0xff) != 0xbe) {
+DPRINTF("chage uart 2 base. unsupported yet \n");
+}
+break;
+
+default:
+superio_conf->config[superio_conf->index] = data & 0xff;
+}
+}
+}
+superio_conf->config[superio_conf->index] = data & 0xff;
+}
+}
+
+static uint32_t superio_ioport_readb(void *opaque, uint32_t addr)
+{
+SuperIOConfig *superio_conf = (SuperIOConfig *)opaque;
+
+DPRINTF("superio_ioport_readb  address 0x%x   \n", addr);
+return (superio_conf->config[superio_conf->index]);
+}
+
+static void vt82c686b_reset(void * opaque)
+{
+PCIDevice *d = opaque;
+uint8_t *pci_conf = d->config;
+VT82C686BState *vt82c = DO_UPCAST(VT82C686BState, dev, d

[Qemu-devel] [PATCH v2 3/6] MIPS: Initial support of VIA IDE controller used by fulong mini pc

2010-05-19 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.objs|1 +
 default-configs/mips64el-softmmu.mak |1 +
 hw/ide.h |1 +
 hw/ide/via.c |  185 ++
 4 files changed, 188 insertions(+), 0 deletions(-)
 create mode 100644 hw/ide/via.c

diff --git a/Makefile.objs b/Makefile.objs
index acbaf22..3291e3a 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -196,6 +196,7 @@ hw-obj-$(CONFIG_IDE_ISA) += ide/isa.o
 hw-obj-$(CONFIG_IDE_PIIX) += ide/piix.o
 hw-obj-$(CONFIG_IDE_CMD646) += ide/cmd646.o
 hw-obj-$(CONFIG_IDE_MACIO) += ide/macio.o
+hw-obj-$(CONFIG_IDE_VIA) += ide/via.o
 
 # SCSI layer
 hw-obj-y += lsi53c895a.o
diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index b731c74..bf19577 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -19,6 +19,7 @@ CONFIG_IDE_QDEV=y
 CONFIG_IDE_PCI=y
 CONFIG_IDE_ISA=y
 CONFIG_IDE_PIIX=y
+CONFIG_IDE_VIA=y
 CONFIG_NE2000_ISA=y
 CONFIG_SOUND=y
 CONFIG_VIRTIO_PCI=y
diff --git a/hw/ide.h b/hw/ide.h
index 0e7d540..bb635b6 100644
--- a/hw/ide.h
+++ b/hw/ide.h
@@ -12,6 +12,7 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
  int secondary_ide_enabled);
 void pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 void pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
+void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 
 /* ide-macio.c */
 int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
diff --git a/hw/ide/via.c b/hw/ide/via.c
new file mode 100644
index 000..33a0b90
--- /dev/null
+++ b/hw/ide/via.c
@@ -0,0 +1,185 @@
+/*
+ * QEMU IDE Emulation: PCI VIA82C686B support.
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2006 Openedhand Ltd.
+ * Copyright (c) 2010 Huacai Chen 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include "block.h"
+#include "block_int.h"
+#include "sysemu.h"
+#include "dma.h"
+
+#include 
+
+static uint32_t bmdma_readb(void *opaque, uint32_t addr)
+{
+BMDMAState *bm = opaque;
+uint32_t val;
+
+switch (addr & 3) {
+case 0:
+val = bm->cmd;
+break;
+case 2:
+val = bm->status;
+break;
+default:
+val = 0xff;
+break;
+}
+#ifdef DEBUG_IDE
+printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
+#endif
+return val;
+}
+
+static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+BMDMAState *bm = opaque;
+#ifdef DEBUG_IDE
+printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
+#endif
+switch (addr & 3) {
+case 2:
+bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 
0x06);
+break;
+default:;
+}
+}
+
+static void bmdma_map(PCIDevice *pci_dev, int region_num,
+pcibus_t addr, pcibus_t size, int type)
+{
+PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
+int i;
+
+for(i = 0;i < 2; i++) {
+BMDMAState *bm = &d->bmdma[i];
+d->bus[i].bmdma = bm;
+bm->bus = d->bus+i;
+qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm);
+
+register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
+
+register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
+register_ioport_read(addr, 4, 1, bmdma_readb, bm);
+
+register_ioport_write(addr + 4, 4, 1, bmdma_addr_writeb, bm);
+register_ioport_read(addr + 4, 4, 1, bmdma_addr_readb, bm);
+register_ioport_write(addr + 4, 4, 2, bmdma_addr_writew, bm);
+register_ioport_read(addr + 4, 4, 2, bmdma_addr_readw, bm);
+register_ioport_write(addr + 4, 4, 4, bmdma_addr_wri

[Qemu-devel] [PATCH v2 4/6] MIPS: Initial support of VIA USB controller used by fulong mini pc

2010-05-19 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 hw/usb-uhci.c |   30 ++
 hw/usb-uhci.h |1 +
 2 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 624d55b..5fd5388 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1152,6 +1152,26 @@ static int usb_uhci_piix4_initfn(PCIDevice *dev)
 return usb_uhci_common_initfn(s);
 }
 
+static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
+{
+UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
+uint8_t *pci_conf = s->dev.config;
+
+pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
+pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_UHCI);
+
+pci_set_long(pci_conf + 0x0c,0x1600);
+pci_set_long(pci_conf + 0x20,0x0301);
+pci_set_long(pci_conf + 0x34,0x1080);
+pci_set_long(pci_conf + 0x3c,0x0004);
+pci_set_long(pci_conf + 0x40,0x1000);
+pci_set_long(pci_conf + 0x60,0x0010);
+pci_set_long(pci_conf + 0x80,0x00020001);
+pci_set_long(pci_conf + 0xc0,0x2000);
+
+return usb_uhci_common_initfn(s);
+}
+
 static PCIDeviceInfo uhci_info[] = {
 {
 .qdev.name= "piix3-usb-uhci",
@@ -1164,6 +1184,11 @@ static PCIDeviceInfo uhci_info[] = {
 .qdev.vmsd= &vmstate_uhci,
 .init = usb_uhci_piix4_initfn,
 },{
+.qdev.name= "vt82c686b-usb-uhci",
+.qdev.size= sizeof(UHCIState),
+.qdev.vmsd= &vmstate_uhci,
+.init = usb_uhci_vt82c686b_initfn,
+},{
 /* end of list */
 }
 };
@@ -1183,3 +1208,8 @@ void usb_uhci_piix4_init(PCIBus *bus, int devfn)
 {
 pci_create_simple(bus, devfn, "piix4-usb-uhci");
 }
+
+void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn)
+{
+pci_create_simple(bus, devfn, "vt82c686b-usb-uhci");
+}
diff --git a/hw/usb-uhci.h b/hw/usb-uhci.h
index 911948e..3e4d377 100644
--- a/hw/usb-uhci.h
+++ b/hw/usb-uhci.h
@@ -5,5 +5,6 @@
 
 void usb_uhci_piix3_init(PCIBus *bus, int devfn);
 void usb_uhci_piix4_init(PCIBus *bus, int devfn);
+void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn);
 
 #endif
-- 
1.7.0.4




[Qemu-devel] [PATCH v2 5/6] MIPS: Initial support of fulong mini pc (CPU definition, machine construction, etc.)

2010-05-19 Thread Huacai Chen
Signed-off-by: Huacai Chen 
---
 Makefile.target  |2 +-
 hw/mips_fulong2e.c   |  421 ++
 target-mips/translate_init.c |   35 
 3 files changed, 457 insertions(+), 1 deletions(-)
 create mode 100644 hw/mips_fulong2e.c

diff --git a/Makefile.target b/Makefile.target
index 9ed4a8d..db4badd 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -221,7 +221,7 @@ obj-mips-y += dma.o vga.o i8259.o
 obj-mips-y += g364fb.o jazz_led.o
 obj-mips-y += gt64xxx.o pckbd.o mc146818rtc.o
 obj-mips-y += piix4.o cirrus_vga.o
-obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o
+obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o
 
 obj-microblaze-y = petalogix_s3adsp1800_mmu.o
 
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
new file mode 100644
index 000..3e6ed7e
--- /dev/null
+++ b/hw/mips_fulong2e.c
@@ -0,0 +1,421 @@
+/*
+ * QEMU fulong 2e mini pc support
+ *
+ * Copyright (c) 2008 yajin (ya...@vm-kernel.org)
+ * Copyright (c) 2009 chenming (chenm...@rdc.faw.com.cn)
+ * Copyright (c) 2010 Huacai Chen (zltjiang...@gmail.com)
+ * This code is licensed under the GNU GPL v2.
+ */
+
+/*
+ * Fulong 2e mini pc is based on ICT/ST Loongson 2e CPU (MIPS III like, 800MHz)
+ * http://www.linux-mips.org/wiki/Fulong
+ *
+ * Loongson 2e user manual:
+ * http://www.loongsondeveloper.com/doc/Loongson2EUserGuide.pdf
+ */
+
+#include "hw.h"
+#include "pc.h"
+#include "fdc.h"
+#include "net.h"
+#include "boards.h"
+#include "smbus.h"
+#include "block.h"
+#include "flash.h"
+#include "mips.h"
+#include "mips_cpudevs.h"
+#include "pci.h"
+#include "usb-uhci.h"
+#include "qemu-char.h"
+#include "sysemu.h"
+#include "audio/audio.h"
+#include "qemu-log.h"
+#include "loader.h"
+#include "mips-bios.h"
+#include "ide.h"
+#include "elf.h"
+#include "mc146818rtc.h"
+
+#define DEBUG_FULONG2E_INIT
+
+#define ENVP_ADDR   0x80002000l
+#define ENVP_NB_ENTRIES16
+#define ENVP_ENTRY_SIZE256
+
+#define MAX_IDE_BUS 2
+
+/* PCI SLOT in fulong 2e */
+#define FULONG2E_VIA_SLOT5
+#define FULONG2E_ATI_SLOT6
+#define FULONG2E_RTL8139_SLOT7
+
+static PITState *pit;
+
+static struct _loaderparams {
+int ram_size;
+const char *kernel_filename;
+const char *kernel_cmdline;
+const char *initrd_filename;
+} loaderparams;
+
+static void mips_qemu_writel (void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+if ((addr & 0x) == 0 && val == 42)
+qemu_system_reset_request ();
+else if ((addr & 0x) == 4 && val == 42)
+qemu_system_shutdown_request ();
+}
+
+static uint32_t mips_qemu_readl (void *opaque, target_phys_addr_t addr)
+{
+return 0;
+}
+
+static CPUWriteMemoryFunc *mips_qemu_write[] = {
+mips_qemu_writel,
+mips_qemu_writel,
+mips_qemu_writel,
+};
+
+static CPUReadMemoryFunc *mips_qemu_read[] = {
+mips_qemu_readl,
+mips_qemu_readl,
+mips_qemu_readl,
+};
+static int mips_qemu_iomemtype = 0;
+
+static void prom_set(uint32_t* prom_buf, int index, const char *string, ...)
+{
+va_list ap;
+int32_t table_addr;
+
+if (index >= ENVP_NB_ENTRIES)
+return;
+
+if (string == NULL) {
+prom_buf[index] = 0;
+return;
+}
+
+table_addr = sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
+prom_buf[index] = tswap32(ENVP_ADDR + table_addr);
+
+va_start(ap, string);
+vsnprintf((char *)prom_buf + table_addr, ENVP_ENTRY_SIZE, string, ap);
+va_end(ap);
+}
+
+static int64_t load_kernel (CPUState *env)
+{
+int64_t kernel_entry, kernel_low, kernel_high;
+int index = 0;
+long initrd_size;
+ram_addr_t initrd_offset;
+uint32_t *prom_buf;
+long prom_size;
+
+if (load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, NULL,
+ (uint64_t *)&kernel_entry, (uint64_t *)&kernel_low,
+ (uint64_t *)&kernel_high, 0, ELF_MACHINE, 1) < 0) {
+fprintf(stderr, "qemu: could not load kernel '%s'\n",
+loaderparams.kernel_filename);
+exit(1);
+}
+
+/* load initrd */
+initrd_size = 0;
+initrd_offset = 0;
+if (loaderparams.initrd_filename) {
+initrd_size = get_image_size (loaderparams.initrd_filename);
+if (initrd_size > 0) {
+initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & 
TARGET_PAGE_MASK;
+if (initrd_offset + initrd_size > ram_size) {
+fprintf(stderr,
+"qemu: memory too small for initial ram disk '%s'\n",
+loaderparams.initrd_filename);
+exit(1);
+   

Re: problem with qemu-system-loongarch64

2022-08-11 Thread Huacai Chen
Hi, all,

On Fri, Aug 12, 2022 at 10:26 AM gaosong  wrote:
>
> CC: Huacai Chen 
>
> On 2022/8/11 下午9:24, Waldemar Brodkorb wrote:
> > Hi Qemu developers,
> >
> > I am trying to bootup a loongarch64 Linux kernel in Qemu 7.1.0-rc2.
> > The problem is I get no output when using following command:
> > qemu-system-loongarch64 -M virt -nographic -kernel vmlinux
> >
> > You can find my vmlinux initramfs here:
> > https://debug.openadk.org/vmlinux
> >
> > It is cross-compiled with binutils 2.39, gcc 12.1, glibc 2.36 and
> > Linux 5.19. I use the provided defconfig loongson3_defconfig for the
> > kernel build.
> >
> > Any hint what I can do to get a bootable Linux image?
The official v5.19 still lacks boot support now, please use this one:
https://github.com/loongson/linux/commits/loongarch-next

Huacai
> >
> > best regards
> >   Waldemar
>



Re: [PATCH 1/4] hw/intc/loongarch_ipi: Bring back all 4 IPI mailboxes

2023-05-21 Thread Huacai Chen
Hi, Jiaxun,

Rename loongarch_ipi to loongson_ipi? It will be shared by both MIPS
and LoongArch in your series.


Huacai

On Sun, May 21, 2023 at 6:24 PM Jiaxun Yang  wrote:
>
> As per "Loongson 3A5000/3B5000 Processor Reference Manual",
> Loongson 3A5000's IPI implementation have 4 mailboxes per
> core.
>
> However, in 78464f023b54 ("hw/loongarch/virt: Modify ipi as
> percpu device"), the number of IPI mailboxes was reduced to
> one, which mismatches actual hardware.
>
> It won't affect LoongArch based system as LoongArch boot code
> only uses the first mailbox, however MIPS based Loongson boot
> code uses all 4 mailboxes.
>
> Fixes: 78464f023b54 ("hw/loongarch/virt: Modify ipi as percpu device")
> Signed-off-by: Jiaxun Yang 
> ---
>  hw/intc/loongarch_ipi.c | 6 +++---
>  include/hw/intc/loongarch_ipi.h | 4 +++-
>  2 files changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
> index d6ab91721ea1..3e453816524e 100644
> --- a/hw/intc/loongarch_ipi.c
> +++ b/hw/intc/loongarch_ipi.c
> @@ -238,14 +238,14 @@ static void loongarch_ipi_init(Object *obj)
>
>  static const VMStateDescription vmstate_ipi_core = {
>  .name = "ipi-single",
> -.version_id = 1,
> -.minimum_version_id = 1,
> +.version_id = 2,
> +.minimum_version_id = 2,
>  .fields = (VMStateField[]) {
>  VMSTATE_UINT32(status, IPICore),
>  VMSTATE_UINT32(en, IPICore),
>  VMSTATE_UINT32(set, IPICore),
>  VMSTATE_UINT32(clear, IPICore),
> -VMSTATE_UINT32_ARRAY(buf, IPICore, 2),
> +VMSTATE_UINT32_ARRAY(buf, IPICore, IPI_MBX_NUM * 2),
>  VMSTATE_END_OF_LIST()
>  }
>  };
> diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h
> index 664e050b926e..6c6194786e80 100644
> --- a/include/hw/intc/loongarch_ipi.h
> +++ b/include/hw/intc/loongarch_ipi.h
> @@ -28,6 +28,8 @@
>  #define MAIL_SEND_OFFSET  0
>  #define ANY_SEND_OFFSET   (IOCSR_ANY_SEND - IOCSR_MAIL_SEND)
>
> +#define IPI_MBX_NUM   4
> +
>  #define TYPE_LOONGARCH_IPI "loongarch_ipi"
>  OBJECT_DECLARE_SIMPLE_TYPE(LoongArchIPI, LOONGARCH_IPI)
>
> @@ -37,7 +39,7 @@ typedef struct IPICore {
>  uint32_t set;
>  uint32_t clear;
>  /* 64bit buf divide into 2 32bit buf */
> -uint32_t buf[2];
> +uint32_t buf[IPI_MBX_NUM * 2];
>  qemu_irq irq;
>  } IPICore;
>
> --
> 2.39.2 (Apple Git-143)
>



Re: [PATCH v1 15/25] Deprecate 32 bit big-endian MIPS

2022-08-29 Thread Huacai Chen
Reviewed-by: Huacai Chen 

On Tue, Aug 30, 2022 at 7:39 AM Philippe Mathieu-Daudé  wrote:
>
> Hi Alex,
>
> (+Aleksandar/Huacai)
>
> On 26/8/22 19:21, Alex Bennée wrote:
> > It's becoming harder to maintain a cross-compiler to test this host
> > architecture as the old stable Debian 10 ("Buster") moved into LTS
> > which supports fewer architectures. For now:
> >
> >- mark it's deprecation in the docs
> >- downgrade the containers to build TCG tests only
> >- drop the cross builds from our CI
> >
> > Users with an appropriate toolchain and user-space can still take
> > their chances building it.
> >
> > Signed-off-by: Alex Bennée 
> > ---
> >   docs/about/build-platforms.rst|  2 +-
> >   docs/about/deprecated.rst | 13 ++
> >   .gitlab-ci.d/container-cross.yml  |  1 -
> >   .gitlab-ci.d/crossbuilds.yml  | 14 ---
> >   tests/docker/Makefile.include |  5 +--
> >   .../dockerfiles/debian-mips-cross.docker  | 40 +--
> >   6 files changed, 27 insertions(+), 48 deletions(-)
> >
> > diff --git a/docs/about/build-platforms.rst b/docs/about/build-platforms.rst
> > index 26028756d0..1ca9144a7d 100644
> > --- a/docs/about/build-platforms.rst
> > +++ b/docs/about/build-platforms.rst
> > @@ -41,7 +41,7 @@ Those hosts are officially supported, with various 
> > accelerators:
> >- Accelerators
> >  * - Arm
> >- kvm (64 bit only), tcg, xen
> > -   * - MIPS
> > +   * - MIPS (LE only)
> >- kvm, tcg
> >  * - PPC
> >- kvm, tcg
> > diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
> > index 91b03115ee..22c2f4f4de 100644
> > --- a/docs/about/deprecated.rst
> > +++ b/docs/about/deprecated.rst
> > @@ -213,6 +213,19 @@ MIPS ``Trap-and-Emul`` KVM support (since 6.0)
> >   The MIPS ``Trap-and-Emul`` KVM host and guest support has been removed
> >   from Linux upstream kernel, declare it deprecated.
> >
> > +Host Architectures
> > +--
> > +
> > +BE MIPS (since 7.2)
> > +'''''''''''''''''''
> > +
> > +A Debian 10 ("Buster") moved into LTS the big endian 32 bit version of
> > +MIPS moved out of support making it hard to maintain our
> > +cross-compilation CI tests of the architecture. As we no longer have
> > +CI coverage support may bitrot away before the deprecation process
> > +completes. The little endian variants of MIPS (both 32 and 64 bit) are
> > +still a supported host architecture.
>
> For completeness we should update meson.build to consider
> host_machine.endian() and adapt this section:
>
>
>if not supported_cpus.contains(cpu)
>  message()
>  warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
>  message()
>  message('CPU host architecture ' + cpu + ' support is not currently
> maintained.')
>...
>
> This can be done later, and I might be able to do so in few weeks,
> so meanwhile (with Thomas comment addressed):
> Reviewed-by: Philippe Mathieu-Daudé 



Re: [RFC v3 1/2] target/loongarch: Add loongson binary translation feature

2024-07-03 Thread Huacai Chen
On Wed, Jul 3, 2024 at 3:51 PM Jiaxun Yang  wrote:
>
>
>
> 在2024年7月1日七月 下午2:57,Jiaxun Yang写道:
> > 在2024年5月30日五月 上午7:49,Bibo Mao写道:
> >> Loongson Binary Translation (LBT) is used to accelerate binary
> >> translation, which contains 4 scratch registers (scr0 to scr3), x86/ARM
> >> eflags (eflags) and x87 fpu stack pointer (ftop).
> >>
> >> Now LBT feature is added in kvm mode, not supported in TCG mode since
> >> it is not emulated. Feature variable lbt is added with OnOffAuto type,
> >> If lbt feature is not supported with KVM host, it reports error if there
> >> is lbt=on command line.
> >>
> >> If there is no any command line about lbt parameter, it checks whether
> >> KVM host supports lbt feature and set the corresponding value in cpucfg.
> >>
> >> Signed-off-by: Bibo Mao 
> > Hi Bibo,
> >
> > I was going across recent LoongArch changes and this comes into my 
> > attention:
> >
> >> ---
> >>  target/loongarch/cpu.c| 53 +++
> >>  target/loongarch/cpu.h|  6 +++
> >>  target/loongarch/kvm/kvm.c| 26 +
> >>  target/loongarch/kvm/kvm_loongarch.h  | 16 
> >>  target/loongarch/loongarch-qmp-cmds.c |  2 +-
> >>  5 files changed, 102 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
> >> index b5c1ec94af..14265b6667 100644
> >> --- a/target/loongarch/cpu.c
> >> +++ b/target/loongarch/cpu.c
> >> @@ -571,6 +571,30 @@ static void loongarch_cpu_disas_set_info(CPUState
> >> *s, disassemble_info *info)
> >>  info->print_insn = print_insn_loongarch;
> >>  }
> >>
> >> +static void loongarch_cpu_check_lbt(CPUState *cs, Error **errp)
> >> +{
> >> +CPULoongArchState *env = cpu_env(cs);
> >> +LoongArchCPU *cpu = LOONGARCH_CPU(cs);
> >> +bool kvm_supported;
> >> +
> >> +kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_LBT);
> >
> > IMHO if there is no global states that should be saved/restored VM wise,
> > this should be handled at per CPU level, preferably with CPUCFG flags hint.
> >
> > We should minimize non-privilege KVM feature bits to prevent hindering
> > asymmetry ISA system.
>
> + Huacai for further discussion
>
> Hi Bibo, Huacai,
>
> I investigated the topic further and went through the thread on kernel side.
>
> I think Huacai and me are all on the same page that we should unify the 
> interface for per-CPU
> level feature probing and setting interface. Huacai purposed converting all 
> features to VM feature
> but I still believe CPUCFG is the best interface.
>
> To probe LBT before actual vcpu creation, we can borrow the approach used by 
> other architectures
> (kvm_arm_create_scratch_host_vcpu() & kvm_riscv_create_scratch_vcpu()).
>
> Kernel will reject setting unknown CPUCFG bits with -EINVAL, so to probe LBT 
> we just need to perform
> KVM_SET_REGS to scratch vcpu with LBT set to see if it's valid for kernel. 
> There is no need for any other
> probing interface.
>
> I do think scratch CPU interface is also necessary if we are going to 
> implement cpu = host.
>
> Huacai, would you agree with me?
For me the important thing is consistency, all vm-features or all
vcpu-features are both accepted.

Huacai

>
> Thanks
> - Jiaxun
>
> >
> > Thanks
> > - Jiaxun
> >
> > --
> > - Jiaxun
>
> --
> - Jiaxun



Re: LoongArch without CONFIG_ACPI and CONFIG_EFI

2024-09-06 Thread Huacai Chen
On Sat, Sep 7, 2024 at 9:44 AM maobibo  wrote:
>
> Add huacai who is maintainer of Loongarch Linux kernel.
>
> On 2024/9/6 下午10:55, Jason A. Donenfeld wrote:
> > Hi,
> >
> > It appears that as of QEMU 9.1, it's possible to boot LoongArch machines
> > that don't provide EFI or ACPI.
> >
> > Would you consider removing the `select ACPI` and `select EFI` from the
> > arch Kconfig, so that kernels built for this minimal QEMU environment
> > can be a bit leaner and quicker to build?
Very difficult, at least removing EFI is difficult. Even if booting to
a FDT environment, we still get information from EFI now.

Huacai

> >
> > Jason
> >
>



[PATCH for-5.1 1/7] configure: Add KVM target support for MIPS64

2020-04-27 Thread Huacai Chen
Preparing for Loongson-3 virtualization, add KVM target support for
MIPS64 in configure script.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 configure | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure b/configure
index 23b5e93..7581e65 100755
--- a/configure
+++ b/configure
@@ -198,7 +198,7 @@ supported_kvm_target() {
 arm:arm | aarch64:aarch64 | \
 i386:i386 | i386:x86_64 | i386:x32 | \
 x86_64:i386 | x86_64:x86_64 | x86_64:x32 | \
-mips:mips | mipsel:mips | \
+mips:mips | mipsel:mips | mips64:mips | mips64el:mips | \
 ppc:ppc | ppc64:ppc | ppc:ppc64 | ppc64:ppc64 | ppc64:ppc64le | \
 s390x:s390x)
 return 0
-- 
2.7.0




[PATCH for-5.1 2/7] hw/mips: Implement the kvm_type() hook in MachineClass

2020-04-27 Thread Huacai Chen
MIPS has two types of KVM: TE & VZ, and TE is the default type. Now we
can't create a VZ guest in QEMU because it lacks the kvm_type() hook in
MachineClass. Besides, libvirt uses a null-machine to detect the kvm
capability, so by default it will return "KVM not supported" on a VZ
platform. Thus, null-machine also need the kvm_type() hook.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 hw/core/Makefile.objs  |  2 +-
 hw/core/null-machine.c |  4 
 hw/mips/Makefile.objs  |  2 +-
 hw/mips/common.c   | 29 +
 include/hw/mips/mips.h |  3 +++
 5 files changed, 38 insertions(+), 2 deletions(-)
 create mode 100644 hw/mips/common.c

diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index 6215e7c..7cfef1f 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -16,10 +16,10 @@ common-obj-$(CONFIG_SOFTMMU) += vm-change-state-handler.o
 common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
 common-obj-$(CONFIG_SOFTMMU) += sysbus.o
 common-obj-$(CONFIG_SOFTMMU) += machine.o
-common-obj-$(CONFIG_SOFTMMU) += null-machine.o
 common-obj-$(CONFIG_SOFTMMU) += loader.o
 common-obj-$(CONFIG_SOFTMMU) += machine-hmp-cmds.o
 common-obj-$(CONFIG_SOFTMMU) += numa.o
+obj-$(CONFIG_SOFTMMU) += null-machine.o
 obj-$(CONFIG_SOFTMMU) += machine-qmp-cmds.o
 
 common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c
index cb47d9d..94a36f9 100644
--- a/hw/core/null-machine.c
+++ b/hw/core/null-machine.c
@@ -17,6 +17,7 @@
 #include "sysemu/sysemu.h"
 #include "exec/address-spaces.h"
 #include "hw/core/cpu.h"
+#include "hw/mips/mips.h"
 
 static void machine_none_init(MachineState *mch)
 {
@@ -50,6 +51,9 @@ static void machine_none_machine_init(MachineClass *mc)
 mc->max_cpus = 1;
 mc->default_ram_size = 0;
 mc->default_ram_id = "ram";
+#ifdef TARGET_MIPS
+mc->kvm_type = mips_kvm_type;
+#endif
 }
 
 DEFINE_MACHINE("none", machine_none_machine_init)
diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs
index 525809a..2f7795b 100644
--- a/hw/mips/Makefile.objs
+++ b/hw/mips/Makefile.objs
@@ -1,4 +1,4 @@
-obj-y += addr.o mips_int.o
+obj-y += addr.o common.o mips_int.o
 obj-$(CONFIG_R4K) += mips_r4k.o
 obj-$(CONFIG_MALTA) += gt64xxx_pci.o mips_malta.o
 obj-$(CONFIG_MIPSSIM) += mips_mipssim.o
diff --git a/hw/mips/common.c b/hw/mips/common.c
new file mode 100644
index 000..eb0c649
--- /dev/null
+++ b/hw/mips/common.c
@@ -0,0 +1,29 @@
+/*
+ * Common MIPS routines
+ *
+ * Copyright (c) 2020 Huacai Chen (che...@lemote.com)
+ * This code is licensed under the GNU GPL v2.
+ */
+
+#include 
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/boards.h"
+#include "hw/mips/mips.h"
+#include "sysemu/kvm_int.h"
+
+int mips_kvm_type(MachineState *machine, const char *vm_type)
+{
+int r;
+KVMState *s = KVM_STATE(machine->accelerator);;
+
+r = kvm_check_extension(s, KVM_CAP_MIPS_VZ);
+if (r > 0)
+return KVM_VM_MIPS_VZ;
+
+r = kvm_check_extension(s, KVM_CAP_MIPS_TE);
+if (r > 0)
+return KVM_VM_MIPS_TE;
+
+return -1;
+}
diff --git a/include/hw/mips/mips.h b/include/hw/mips/mips.h
index 0af4c3d..2ac0580 100644
--- a/include/hw/mips/mips.h
+++ b/include/hw/mips/mips.h
@@ -20,4 +20,7 @@ void rc4030_dma_write(void *dma, uint8_t *buf, int len);
 
 DeviceState *rc4030_init(rc4030_dma **dmas, IOMMUMemoryRegion **dma_mr);
 
+/* common.c */
+int mips_kvm_type(MachineState *machine, const char *vm_type);
+
 #endif
-- 
2.7.0




[PATCH for-5.1 3/7] hw/mips: Add CPU IRQ3 delivery for KVM

2020-04-27 Thread Huacai Chen
Currently, KVM/MIPS only deliver I/O interrupt via IP2, this patch add
IP2 delivery as well, because Loongson-3 based machine use both IRQ2
(CPU's IP2) and IRQ3 (CPU's IP3).

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 hw/mips/mips_int.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/hw/mips/mips_int.c b/hw/mips/mips_int.c
index 796730b..5526219 100644
--- a/hw/mips/mips_int.c
+++ b/hw/mips/mips_int.c
@@ -48,16 +48,14 @@ static void cpu_mips_irq_request(void *opaque, int irq, int 
level)
 if (level) {
 env->CP0_Cause |= 1 << (irq + CP0Ca_IP);
 
-if (kvm_enabled() && irq == 2) {
+if (kvm_enabled() && (irq == 2 || irq == 3))
 kvm_mips_set_interrupt(cpu, irq, level);
-}
 
 } else {
 env->CP0_Cause &= ~(1 << (irq + CP0Ca_IP));
 
-if (kvm_enabled() && irq == 2) {
+if (kvm_enabled() && (irq == 2 || irq == 3))
 kvm_mips_set_interrupt(cpu, irq, level);
-}
 }
 
 if (env->CP0_Cause & CP0Ca_IP_mask) {
-- 
2.7.0




[PATCH for-5.1 4/7] target/mips: Add Loongson-3 CPU definition

2020-04-27 Thread Huacai Chen
Loongson-3 CPU family include Loongson-3A R1/R2/R3/R4 and Loongson-3B
R1/R2. Loongson-3A R4 is the newest and its ISA is almost the superset
of all others. To reduce complexity, we just define a "Loongson-3A" CPU
which is corresponding to Loongson-3A R4. Loongson-3A has CONFIG6 and
CONFIG7, so add their bit-fields as well.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 target/mips/cpu.h| 28 ++
 target/mips/internal.h   |  2 ++
 target/mips/mips-defs.h  |  7 --
 target/mips/translate.c  |  2 ++
 target/mips/translate_init.inc.c | 51 
 5 files changed, 88 insertions(+), 2 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 94d01ea..0b3c987 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -940,7 +940,35 @@ struct CPUMIPSState {
 #define CP0C5_UFR  2
 #define CP0C5_NFExists 0
 int32_t CP0_Config6;
+int32_t CP0_Config6_rw_bitmask;
+#define CP0C6_BPPASS  31
+#define CP0C6_KPOS24
+#define CP0C6_KE  23
+#define CP0C6_VTLBONLY22
+#define CP0C6_LASX21
+#define CP0C6_SSEN20
+#define CP0C6_DISDRTIME   19
+#define CP0C6_PIXNUEN 18
+#define CP0C6_SCRAND  17
+#define CP0C6_LLEXCEN 16
+#define CP0C6_DISVC   15
+#define CP0C6_VCLRU   14
+#define CP0C6_DCLRU   13
+#define CP0C6_PIXUEN  12
+#define CP0C6_DISBLKLYEN  11
+#define CP0C6_UMEMUALEN   10
+#define CP0C6_SFBEN   8
+#define CP0C6_FLTINT  7
+#define CP0C6_VLTINT  6
+#define CP0C6_DISBTB  5
+#define CP0C6_STPREFCTL   2
+#define CP0C6_INSTPREF1
+#define CP0C6_DATAPREF0
 int32_t CP0_Config7;
+int64_t CP0_Config7_rw_bitmask;
+#define CP0C7_NAPCGEN   2
+#define CP0C7_UNIMUEN   1
+#define CP0C7_VFPUCGEN  0
 uint64_t CP0_LLAddr;
 uint64_t CP0_MAAR[MIPS_MAAR_MAX];
 int32_t CP0_MAARI;
diff --git a/target/mips/internal.h b/target/mips/internal.h
index 1bf274b..7853cb1 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -36,7 +36,9 @@ struct mips_def_t {
 int32_t CP0_Config5;
 int32_t CP0_Config5_rw_bitmask;
 int32_t CP0_Config6;
+int32_t CP0_Config6_rw_bitmask;
 int32_t CP0_Config7;
+int32_t CP0_Config7_rw_bitmask;
 target_ulong CP0_LLAddr_rw_bitmask;
 int CP0_LLAddr_shift;
 int32_t SYNCI_Step;
diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h
index a831bb4..c2c96db 100644
--- a/target/mips/mips-defs.h
+++ b/target/mips/mips-defs.h
@@ -51,8 +51,9 @@
  */
 #define INSN_LOONGSON2E   0x0001ULL
 #define INSN_LOONGSON2F   0x0002ULL
-#define INSN_VR54XX   0x0004ULL
-#define INSN_R59000x0008ULL
+#define INSN_LOONGSON3A   0x0004ULL
+#define INSN_VR54XX   0x0008ULL
+#define INSN_R59000x0010ULL
 /*
  *   bits 56-63: vendor-specific ASEs
  */
@@ -94,6 +95,8 @@
 /* Wave Computing: "nanoMIPS" */
 #define CPU_NANOMIPS32  (CPU_MIPS32R6 | ISA_NANOMIPS32)
 
+#define CPU_LOONGSON3A  (CPU_MIPS64R2 | INSN_LOONGSON3A)
+
 /*
  * Strictly follow the architecture standard:
  * - Disallow "special" instruction handling for PMON/SPIM.
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 25b595a..2caf4cb 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -31206,7 +31206,9 @@ void cpu_state_reset(CPUMIPSState *env)
 env->CP0_Config5 = env->cpu_model->CP0_Config5;
 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
 env->CP0_Config6 = env->cpu_model->CP0_Config6;
+env->CP0_Config6_rw_bitmask = env->cpu_model->CP0_Config6_rw_bitmask;
 env->CP0_Config7 = env->cpu_model->CP0_Config7;
+env->CP0_Config7_rw_bitmask = env->cpu_model->CP0_Config7_rw_bitmask;
 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
  << env->cpu_model->CP0_LLAddr_shift;
 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
diff --git a/target/mips/translate_init.inc.c b/target/mips/translate_init.inc.c
index 6d145a9..a32412d 100644
--- a/target/mips/translate_init.inc.c
+++ b/target/mips/translate_init.inc.c
@@ -802,6 +802,57 @@ const mips_def_t mips_defs[] =
 .mmu_type = MMU_TYPE_R4000,
 },
 {
+.name = "Loongson-3A",
+.CP0_PRid = 0x14C000,
+/* 64KB I-cache and d-cache. 4 way with 32 bit cache line size.  */
+.CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) |
+   (MMU_TYPE_R4000 << CP0C0_MT),
+.CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) |
+   (2 << CP0C1_IS) 

[PATCH for-5.1 5/7] target/mips: Add more CP0 register for save/restore

2020-04-27 Thread Huacai Chen
Add more CP0 register for save/restore, including: EBase, XContext,
PageGrain, PWBase, PWSize, PWField, PWCtl, Config*, KScratch1~KScratch6.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 target/mips/kvm.c | 212 ++
 target/mips/machine.c |   2 +
 2 files changed, 214 insertions(+)

diff --git a/target/mips/kvm.c b/target/mips/kvm.c
index de3e26e..96cfa10 100644
--- a/target/mips/kvm.c
+++ b/target/mips/kvm.c
@@ -245,10 +245,16 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U64 | (8 * (_R) + (_S)))
 
 #define KVM_REG_MIPS_CP0_INDEX  MIPS_CP0_32(0, 0)
+#define KVM_REG_MIPS_CP0_RANDOM MIPS_CP0_32(1, 0)
 #define KVM_REG_MIPS_CP0_CONTEXTMIPS_CP0_64(4, 0)
 #define KVM_REG_MIPS_CP0_USERLOCAL  MIPS_CP0_64(4, 2)
 #define KVM_REG_MIPS_CP0_PAGEMASK   MIPS_CP0_32(5, 0)
+#define KVM_REG_MIPS_CP0_PAGEGRAIN  MIPS_CP0_32(5, 1)
+#define KVM_REG_MIPS_CP0_PWBASE MIPS_CP0_64(5, 5)
+#define KVM_REG_MIPS_CP0_PWFIELDMIPS_CP0_64(5, 6)
+#define KVM_REG_MIPS_CP0_PWSIZE MIPS_CP0_64(5, 7)
 #define KVM_REG_MIPS_CP0_WIRED  MIPS_CP0_32(6, 0)
+#define KVM_REG_MIPS_CP0_PWCTL  MIPS_CP0_32(6, 6)
 #define KVM_REG_MIPS_CP0_HWRENA MIPS_CP0_32(7, 0)
 #define KVM_REG_MIPS_CP0_BADVADDR   MIPS_CP0_64(8, 0)
 #define KVM_REG_MIPS_CP0_COUNT  MIPS_CP0_32(9, 0)
@@ -258,13 +264,22 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 #define KVM_REG_MIPS_CP0_CAUSE  MIPS_CP0_32(13, 0)
 #define KVM_REG_MIPS_CP0_EPCMIPS_CP0_64(14, 0)
 #define KVM_REG_MIPS_CP0_PRID   MIPS_CP0_32(15, 0)
+#define KVM_REG_MIPS_CP0_EBASE  MIPS_CP0_64(15, 1)
 #define KVM_REG_MIPS_CP0_CONFIG MIPS_CP0_32(16, 0)
 #define KVM_REG_MIPS_CP0_CONFIG1MIPS_CP0_32(16, 1)
 #define KVM_REG_MIPS_CP0_CONFIG2MIPS_CP0_32(16, 2)
 #define KVM_REG_MIPS_CP0_CONFIG3MIPS_CP0_32(16, 3)
 #define KVM_REG_MIPS_CP0_CONFIG4MIPS_CP0_32(16, 4)
 #define KVM_REG_MIPS_CP0_CONFIG5MIPS_CP0_32(16, 5)
+#define KVM_REG_MIPS_CP0_CONFIG6MIPS_CP0_32(16, 6)
+#define KVM_REG_MIPS_CP0_XCONTEXT   MIPS_CP0_64(20, 0)
 #define KVM_REG_MIPS_CP0_ERROREPC   MIPS_CP0_64(30, 0)
+#define KVM_REG_MIPS_CP0_KSCRATCH1  MIPS_CP0_64(31, 2)
+#define KVM_REG_MIPS_CP0_KSCRATCH2  MIPS_CP0_64(31, 3)
+#define KVM_REG_MIPS_CP0_KSCRATCH3  MIPS_CP0_64(31, 4)
+#define KVM_REG_MIPS_CP0_KSCRATCH4  MIPS_CP0_64(31, 5)
+#define KVM_REG_MIPS_CP0_KSCRATCH5  MIPS_CP0_64(31, 6)
+#define KVM_REG_MIPS_CP0_KSCRATCH6  MIPS_CP0_64(31, 7)
 
 static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
int32_t *addr)
@@ -394,6 +409,29 @@ static inline int kvm_mips_get_one_ureg64(CPUState *cs, 
uint64_t reg_id,
  (1U << CP0C5_UFE) | \
  (1U << CP0C5_FRE) | \
  (1U << CP0C5_UFR))
+#define KVM_REG_MIPS_CP0_CONFIG6_MASK   ((1U << CP0C6_BPPASS) | \
+ (0x3fU << CP0C6_KPOS) | \
+ (1U << CP0C6_KE) | \
+ (1U << CP0C6_VTLBONLY) | \
+ (1U << CP0C6_LASX) | \
+ (1U << CP0C6_SSEN) | \
+ (1U << CP0C6_DISDRTIME) | \
+ (1U << CP0C6_PIXNUEN) | \
+ (1U << CP0C6_SCRAND) | \
+ (1U << CP0C6_LLEXCEN) | \
+ (1U << CP0C6_DISVC) | \
+ (1U << CP0C6_VCLRU) | \
+ (1U << CP0C6_DCLRU) | \
+ (1U << CP0C6_PIXUEN) | \
+ (1U << CP0C6_DISBLKLYEN) | \
+ (1U << CP0C6_UMEMUALEN) | \
+ (1U << CP0C6_SFBEN) | \
+ (1U << CP0C6_FLTINT) | \
+ (1U << CP0C6_VLTINT) | \
+ (1U << CP0C6_DISBTB) | \
+ (3U << CP0C6_STPREFCTL) | \
+ (1U << CP0C6_INSTPREF) | \
+ (1U << CP0C6_DATAPREF))
 
 static inline int kvm_mips_change_one_reg(CPUState *cs, uint64_t reg_id,
   int32_t *addr, int32_t mask)
@@ -729,6 +767,11 @@ static int kvm

[PATCH for-5.1 6/7] hw/mips: Add Loongson-3 machine support (with KVM)

2020-04-27 Thread Huacai Chen
Add Loongson-3 based machine support, it use i8259 as the interrupt
controler and use GPEX as the pci controller. Currently it can only
work with KVM, but we will add TCG support in future.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 default-configs/mips64el-softmmu.mak |   1 +
 hw/mips/Kconfig  |  10 +
 hw/mips/Makefile.objs|   1 +
 hw/mips/mips_loongson3.c | 869 +++
 4 files changed, 881 insertions(+)
 create mode 100644 hw/mips/mips_loongson3.c

diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index 8b0c9b1..fc798e4 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -3,6 +3,7 @@
 include mips-softmmu-common.mak
 CONFIG_IDE_VIA=y
 CONFIG_FULONG=y
+CONFIG_LOONGSON3=y
 CONFIG_ATI_VGA=y
 CONFIG_RTL8139_PCI=y
 CONFIG_JAZZ=y
diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index 2c2adbc..6f16b16 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -44,6 +44,16 @@ config JAZZ
 config FULONG
 bool
 
+config LOONGSON3
+bool
+select PCKBD
+select SERIAL
+select ISA_BUS
+select PCI_EXPRESS_GENERIC_BRIDGE
+select VIRTIO_VGA
+select QXL if SPICE
+select MSI_NONBROKEN
+
 config MIPS_CPS
 bool
 select PTIMER
diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs
index 2f7795b..f9bc8f5 100644
--- a/hw/mips/Makefile.objs
+++ b/hw/mips/Makefile.objs
@@ -4,5 +4,6 @@ obj-$(CONFIG_MALTA) += gt64xxx_pci.o mips_malta.o
 obj-$(CONFIG_MIPSSIM) += mips_mipssim.o
 obj-$(CONFIG_JAZZ) += mips_jazz.o
 obj-$(CONFIG_FULONG) += mips_fulong2e.o
+obj-$(CONFIG_LOONGSON3) += mips_loongson3.o
 obj-$(CONFIG_MIPS_CPS) += cps.o
 obj-$(CONFIG_MIPS_BOSTON) += boston.o
diff --git a/hw/mips/mips_loongson3.c b/hw/mips/mips_loongson3.c
new file mode 100644
index 000..a45c9ec
--- /dev/null
+++ b/hw/mips/mips_loongson3.c
@@ -0,0 +1,869 @@
+/*
+ * Generic Loongson-3 Platform support
+ *
+ * Copyright (c) 2015-2020 Huacai Chen (che...@lemote.com)
+ * This code is licensed under the GNU GPL v2.
+ *
+ * Contributions are licensed under the terms of the GNU GPL,
+ * version 2 or (at your option) any later version.
+ */
+
+/*
+ * Generic PC Platform based on Loongson-3 CPU (MIPS64R2 with extensions,
+ * 800~2000MHz)
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "elf.h"
+#include "hw/boards.h"
+#include "hw/block/flash.h"
+#include "hw/char/serial.h"
+#include "hw/mips/mips.h"
+#include "hw/mips/cpudevs.h"
+#include "hw/intc/i8259.h"
+#include "hw/loader.h"
+#include "hw/ide.h"
+#include "hw/isa/superio.h"
+#include "hw/pci/msi.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_host.h"
+#include "hw/pci-host/gpex.h"
+#include "hw/rtc/mc146818rtc.h"
+#include "net/net.h"
+#include "exec/address-spaces.h"
+#include "sysemu/qtest.h"
+#include "sysemu/reset.h"
+#include "sysemu/runstate.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+
+#define INITRD_OFFSET  0x0400
+#define BOOTPARAM_ADDR 0x8ff0
+#define BOOTPARAM_PHYADDR  0x0ff0
+#define CFG_ADDR   0x0f10
+#define FW_CONF_ADDR   0x0fff
+#define PM_MMIO_ADDR   0x1008
+#define PM_MMIO_SIZE   0x100
+#define PM_CNTL_MODE   0x10
+
+#define PHYS_TO_VIRT(x) ((x) | ~(target_ulong)0x7fff)
+
+/* Loongson-3 has a 2MB flash rom */
+#define BIOS_SIZE   (2 * MiB)
+#define LOONGSON_MAX_VCPUS  16
+
+#define LOONGSON3_BIOSNAME "bios_loongson3.bin"
+
+#define PCIE_IRQ_BASE 3
+
+#define VIRT_PCI_IO_BASE0x1800ul
+#define VIRT_PCI_IO_SIZE0x000cul
+#define VIRT_PCI_MEM_BASE   0x4000ul
+#define VIRT_PCI_MEM_SIZE   0x4000ul
+#define VIRT_PCI_ECAM_BASE  0x1a00ul
+#define VIRT_PCI_ECAM_SIZE  0x0200ul
+
+#define align(x) (((x) + 63) & ~63)
+
+struct efi_memory_map_loongson {
+uint16_t vers;   /* version of efi_memory_map */
+uint32_t nr_map; /* number of memory_maps */
+uint32_t mem_freq;   /* memory frequence */
+struct mem_map{
+uint32_t node_id;/* node_id which memory attached to */
+uint32_t mem_type;   /* system memory, pci memory, pci io, etc. */
+uint64_t mem_start;  /* memory map start address */
+uint32_t mem_size;   /* each memory_map size, not the total size */
+} map[128];
+} __attribute__((packed));
+
+enum loongson_cpu_type {
+Legacy_2E = 0x0,
+Legacy_2F = 0x1,
+Legacy_3A = 0x2,
+Legacy_3B = 0x3,
+Legacy_1A = 0x4,
+Legacy_1B = 0x5,
+Legacy_2G

[PATCH for-5.1 7/7] MAINTAINERS: Add myself as Loongson-3 maintainer

2020-04-27 Thread Huacai Chen
Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 MAINTAINERS | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index aa9a057..efe840b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1080,6 +1080,12 @@ F: hw/isa/vt82c686.c
 F: hw/pci-host/bonito.c
 F: include/hw/isa/vt82c686.h
 
+Loongson-3
+M: Huacai Chen 
+S: Maintained
+F: hw/mips/mips_loongson3.c
+F: hw/pci-host/ls7a.c
+
 Boston
 M: Paul Burton 
 R: Aleksandar Rikalo 
-- 
2.7.0




Re: [PATCH for-5.1 5/7] target/mips: Add more CP0 register for save/restore

2020-04-28 Thread Huacai Chen
Hi, Aleksandar,

On Wed, Apr 29, 2020 at 3:10 AM Aleksandar Markovic
 wrote:
>
> пон, 27. апр 2020. у 11:36 Huacai Chen  је написао/ла:
> >
> > Add more CP0 register for save/restore, including: EBase, XContext,
> > PageGrain, PWBase, PWSize, PWField, PWCtl, Config*, KScratch1~KScratch6.
> >
> > Signed-off-by: Huacai Chen 
> > Co-developed-by: Jiaxun Yang 
> > ---
> >  target/mips/kvm.c | 212 
> > ++
> >  target/mips/machine.c |   2 +
> >  2 files changed, 214 insertions(+)
> >
> > diff --git a/target/mips/kvm.c b/target/mips/kvm.c
> > index de3e26e..96cfa10 100644
> > --- a/target/mips/kvm.c
> > +++ b/target/mips/kvm.c
> > @@ -245,10 +245,16 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, 
> > int level)
> >  (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U64 | (8 * (_R) + (_S)))
> >
> >  #define KVM_REG_MIPS_CP0_INDEX  MIPS_CP0_32(0, 0)
> > +#define KVM_REG_MIPS_CP0_RANDOM MIPS_CP0_32(1, 0)
> >  #define KVM_REG_MIPS_CP0_CONTEXTMIPS_CP0_64(4, 0)
> >  #define KVM_REG_MIPS_CP0_USERLOCAL  MIPS_CP0_64(4, 2)
> >  #define KVM_REG_MIPS_CP0_PAGEMASK   MIPS_CP0_32(5, 0)
> > +#define KVM_REG_MIPS_CP0_PAGEGRAIN  MIPS_CP0_32(5, 1)
> > +#define KVM_REG_MIPS_CP0_PWBASE MIPS_CP0_64(5, 5)
> > +#define KVM_REG_MIPS_CP0_PWFIELDMIPS_CP0_64(5, 6)
> > +#define KVM_REG_MIPS_CP0_PWSIZE MIPS_CP0_64(5, 7)
> >  #define KVM_REG_MIPS_CP0_WIRED  MIPS_CP0_32(6, 0)
> > +#define KVM_REG_MIPS_CP0_PWCTL  MIPS_CP0_32(6, 6)
> >  #define KVM_REG_MIPS_CP0_HWRENA MIPS_CP0_32(7, 0)
> >  #define KVM_REG_MIPS_CP0_BADVADDR   MIPS_CP0_64(8, 0)
> >  #define KVM_REG_MIPS_CP0_COUNT  MIPS_CP0_32(9, 0)
> > @@ -258,13 +264,22 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, 
> > int level)
> >  #define KVM_REG_MIPS_CP0_CAUSE  MIPS_CP0_32(13, 0)
> >  #define KVM_REG_MIPS_CP0_EPCMIPS_CP0_64(14, 0)
> >  #define KVM_REG_MIPS_CP0_PRID   MIPS_CP0_32(15, 0)
> > +#define KVM_REG_MIPS_CP0_EBASE  MIPS_CP0_64(15, 1)
> >  #define KVM_REG_MIPS_CP0_CONFIG MIPS_CP0_32(16, 0)
> >  #define KVM_REG_MIPS_CP0_CONFIG1MIPS_CP0_32(16, 1)
> >  #define KVM_REG_MIPS_CP0_CONFIG2MIPS_CP0_32(16, 2)
> >  #define KVM_REG_MIPS_CP0_CONFIG3MIPS_CP0_32(16, 3)
> >  #define KVM_REG_MIPS_CP0_CONFIG4MIPS_CP0_32(16, 4)
> >  #define KVM_REG_MIPS_CP0_CONFIG5MIPS_CP0_32(16, 5)
> > +#define KVM_REG_MIPS_CP0_CONFIG6MIPS_CP0_32(16, 6)
> > +#define KVM_REG_MIPS_CP0_XCONTEXT   MIPS_CP0_64(20, 0)
> >  #define KVM_REG_MIPS_CP0_ERROREPC   MIPS_CP0_64(30, 0)
> > +#define KVM_REG_MIPS_CP0_KSCRATCH1  MIPS_CP0_64(31, 2)
> > +#define KVM_REG_MIPS_CP0_KSCRATCH2  MIPS_CP0_64(31, 3)
> > +#define KVM_REG_MIPS_CP0_KSCRATCH3  MIPS_CP0_64(31, 4)
> > +#define KVM_REG_MIPS_CP0_KSCRATCH4  MIPS_CP0_64(31, 5)
> > +#define KVM_REG_MIPS_CP0_KSCRATCH5  MIPS_CP0_64(31, 6)
> > +#define KVM_REG_MIPS_CP0_KSCRATCH6  MIPS_CP0_64(31, 7)
> >
> >  static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
> > int32_t *addr)
> > @@ -394,6 +409,29 @@ static inline int kvm_mips_get_one_ureg64(CPUState 
> > *cs, uint64_t reg_id,
> >   (1U << CP0C5_UFE) | \
> >   (1U << CP0C5_FRE) | \
> >   (1U << CP0C5_UFR))
> > +#define KVM_REG_MIPS_CP0_CONFIG6_MASK   ((1U << CP0C6_BPPASS) | \
> > + (0x3fU << CP0C6_KPOS) | \
> > + (1U << CP0C6_KE) | \
> > + (1U << CP0C6_VTLBONLY) | \
> > + (1U << CP0C6_LASX) | \
> > + (1U << CP0C6_SSEN) | \
> > + (1U << CP0C6_DISDRTIME) | \
> > + (1U << CP0C6_PIXNUEN) | \
> > + (1U << CP0C6_SCRAND) | \
> > + (1U << CP0C6_LLEXCEN) | \
> > + (1U << CP0C6_DISVC) | \
> > + (1U << CP0C6_VCLRU) | \
> > + (1U << CP0C6_DCLRU) | \
> > +  

Re: [PATCH for-5.1 6/7] hw/mips: Add Loongson-3 machine support (with KVM)

2020-04-28 Thread Huacai Chen
Hi, Aleksandr,

On Wed, Apr 29, 2020 at 3:23 AM Aleksandar Markovic
 wrote:
>
> Hi. Huacei.
>
> Please expand commit message with the description of the machine
> internal organization (several paragraphs).
>
> Also, please include command line for starting the machine. More than
> one example is better than only one.
>
> Specifically, can you explicitly say what is your KVM setup, so that
> anyone could repro it?
>
> Good health to people from China!
>
Thank you very much, I will improve that in V2.

> Yours,
> Aleksandar
>
> пон, 27. апр 2020. у 11:36 Huacai Chen  је написао/ла:
> >
> > Add Loongson-3 based machine support, it use i8259 as the interrupt
> > controler and use GPEX as the pci controller. Currently it can only
> > work with KVM, but we will add TCG support in future.
> >
> > Signed-off-by: Huacai Chen 
> > Co-developed-by: Jiaxun Yang 
> > ---
> >  default-configs/mips64el-softmmu.mak |   1 +
> >  hw/mips/Kconfig  |  10 +
> >  hw/mips/Makefile.objs|   1 +
> >  hw/mips/mips_loongson3.c | 869 
> > +++
> >  4 files changed, 881 insertions(+)
> >  create mode 100644 hw/mips/mips_loongson3.c
> >
> > diff --git a/default-configs/mips64el-softmmu.mak 
> > b/default-configs/mips64el-softmmu.mak
> > index 8b0c9b1..fc798e4 100644
> > --- a/default-configs/mips64el-softmmu.mak
> > +++ b/default-configs/mips64el-softmmu.mak
> > @@ -3,6 +3,7 @@
> >  include mips-softmmu-common.mak
> >  CONFIG_IDE_VIA=y
> >  CONFIG_FULONG=y
> > +CONFIG_LOONGSON3=y
> >  CONFIG_ATI_VGA=y
> >  CONFIG_RTL8139_PCI=y
> >  CONFIG_JAZZ=y
> > diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
> > index 2c2adbc..6f16b16 100644
> > --- a/hw/mips/Kconfig
> > +++ b/hw/mips/Kconfig
> > @@ -44,6 +44,16 @@ config JAZZ
> >  config FULONG
> >  bool
> >
> > +config LOONGSON3
> > +bool
> > +select PCKBD
> > +select SERIAL
> > +select ISA_BUS
> > +select PCI_EXPRESS_GENERIC_BRIDGE
> > +select VIRTIO_VGA
> > +select QXL if SPICE
> > +select MSI_NONBROKEN
> > +
> >  config MIPS_CPS
> >  bool
> >  select PTIMER
> > diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs
> > index 2f7795b..f9bc8f5 100644
> > --- a/hw/mips/Makefile.objs
> > +++ b/hw/mips/Makefile.objs
> > @@ -4,5 +4,6 @@ obj-$(CONFIG_MALTA) += gt64xxx_pci.o mips_malta.o
> >  obj-$(CONFIG_MIPSSIM) += mips_mipssim.o
> >  obj-$(CONFIG_JAZZ) += mips_jazz.o
> >  obj-$(CONFIG_FULONG) += mips_fulong2e.o
> > +obj-$(CONFIG_LOONGSON3) += mips_loongson3.o
> >  obj-$(CONFIG_MIPS_CPS) += cps.o
> >  obj-$(CONFIG_MIPS_BOSTON) += boston.o
> > diff --git a/hw/mips/mips_loongson3.c b/hw/mips/mips_loongson3.c
> > new file mode 100644
> > index 000..a45c9ec
> > --- /dev/null
> > +++ b/hw/mips/mips_loongson3.c
> > @@ -0,0 +1,869 @@
> > +/*
> > + * Generic Loongson-3 Platform support
> > + *
> > + * Copyright (c) 2015-2020 Huacai Chen (che...@lemote.com)
> > + * This code is licensed under the GNU GPL v2.
> > + *
> > + * Contributions are licensed under the terms of the GNU GPL,
> > + * version 2 or (at your option) any later version.
> > + */
> > +
> > +/*
> > + * Generic PC Platform based on Loongson-3 CPU (MIPS64R2 with extensions,
> > + * 800~2000MHz)
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu-common.h"
> > +#include "qemu/units.h"
> > +#include "qapi/error.h"
> > +#include "cpu.h"
> > +#include "elf.h"
> > +#include "hw/boards.h"
> > +#include "hw/block/flash.h"
> > +#include "hw/char/serial.h"
> > +#include "hw/mips/mips.h"
> > +#include "hw/mips/cpudevs.h"
> > +#include "hw/intc/i8259.h"
> > +#include "hw/loader.h"
> > +#include "hw/ide.h"
> > +#include "hw/isa/superio.h"
> > +#include "hw/pci/msi.h"
> > +#include "hw/pci/pci.h"
> > +#include "hw/pci/pci_host.h"
> > +#include "hw/pci-host/gpex.h"
> > +#include "hw/rtc/mc146818rtc.h"
> > +#include "net/net.h"
> > +#include "exec/address-spaces.h"
> > +#include "sysemu/qtest.h"
> > +#include "sysemu/reset.h"
> > +#include "sysemu/runstate.h"
> > +#include "

Re: [PATCH for-5.1 3/7] hw/mips: Add CPU IRQ3 delivery for KVM

2020-04-28 Thread Huacai Chen
Hi, Philippe and Aleksandar,

I'm not refusing to change my patch, but I have two questions:
1, Why we should identify Loongson-3 to deliver IP3? It seems that
deliver all IPs (IP2~IP7) unconditionally is harmless as well.
2, How to identify Loongson-3 by Config6/Config7? Loongson-3 is not
the only processor which has Config6/Config7.

Huacai

On Wed, Apr 29, 2020 at 2:58 AM Aleksandar Markovic
 wrote:
>
> уто, 28. апр 2020. у 10:21 chen huacai  је написао/ла:
> >
> > Hi, Philippe,
> >
> > On Mon, Apr 27, 2020 at 5:57 PM Philippe Mathieu-Daudé  
> > wrote:
> > >
> > > On 4/27/20 11:33 AM, Huacai Chen wrote:
> > > > Currently, KVM/MIPS only deliver I/O interrupt via IP2, this patch add
> > > > IP2 delivery as well, because Loongson-3 based machine use both IRQ2
> > > > (CPU's IP2) and IRQ3 (CPU's IP3).
> > > >
> > > > Signed-off-by: Huacai Chen 
> > > > Co-developed-by: Jiaxun Yang 
> > > > ---
> > > >  hw/mips/mips_int.c | 6 ++
> > > >  1 file changed, 2 insertions(+), 4 deletions(-)
> > > >
> > > > diff --git a/hw/mips/mips_int.c b/hw/mips/mips_int.c
> > > > index 796730b..5526219 100644
> > > > --- a/hw/mips/mips_int.c
> > > > +++ b/hw/mips/mips_int.c
> > > > @@ -48,16 +48,14 @@ static void cpu_mips_irq_request(void *opaque, int 
> > > > irq, int level)
> > > >  if (level) {
> > > >  env->CP0_Cause |= 1 << (irq + CP0Ca_IP);
> > > >
> > > > -if (kvm_enabled() && irq == 2) {
> > > > +if (kvm_enabled() && (irq == 2 || irq == 3))
> > >
> > > Shouldn't we check env->CP0_Config6 (or Config7) has the required
> > > feature first?
> > I'm sorry that I can't understand IRQ delivery has something to do
> > with Config6/Config7, to identify Loongson-3?
> >
>
> Obviously, yes.
>
> Thanks,
> Aleksandar
>
>
> > >
> > > >  kvm_mips_set_interrupt(cpu, irq, level);
> > > > -}
> > > >
> > > >  } else {
> > > >  env->CP0_Cause &= ~(1 << (irq + CP0Ca_IP));
> > > >
> > > > -if (kvm_enabled() && irq == 2) {
> > > > +if (kvm_enabled() && (irq == 2 || irq == 3))
> > > >  kvm_mips_set_interrupt(cpu, irq, level);
> > > > -}
> > > >  }
> > > >
> > > >  if (env->CP0_Cause & CP0Ca_IP_mask) {
> > > >
> >
> >
> >
> > --
> > Huacai Chen



Re: [PATCH for-5.1 4/7] target/mips: Add Loongson-3 CPU definition

2020-04-28 Thread Huacai Chen
Hi, Aleksandar,

I've tried translate.google.com, and documents are available here:
Loongson-3A R1 (Loongson-3A1000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A1000_p1.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A1000_processor_user_manual_P1.pdf
(Chinese Version)
User Manual Part 2:
http://ftp.godson.ac.cn/lemote/3A1000_p2.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A1000_processor_user_manual_P2.pdf
(Chinese Version)

Loongson-3A R2 (Loongson-3A2000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A2000_p1.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A2000_user1.pdf (Chinese Version)
User Manual Part 2:
http://ftp.godson.ac.cn/lemote/3A2000_p2.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A2000_user2.pdf (Chinese Version)

Loongson-3A R3 (Loongson-3A3000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A3000_p1.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A3000_3B3000usermanual1.pdf
(Chinese Version)
User Manual Part 2:
http://ftp.godson.ac.cn/lemote/3A3000_p2.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A3000_3B3000usermanual2.pdf
(Chinese Version)

Loongson-3A R4 (Loongson-3A4000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A4000_p1.pdf
http://ftp.godson.ac.cn/lemote/3A4000user.pdf (Chinese Version)
User Manual Part 2:
I'm sorry that it is unavailable now.

On Wed, Apr 29, 2020 at 2:37 AM Aleksandar Markovic
 wrote:
>
> Huacai,
>
> Can you please do machine translation of the document?
>
> It can be done via translate.google.com (it accepts pdf files, but
> does not have download feature, and workaround is to "print to pdf"...
>
> Thanks in advance!
> Aleksandar
>
> уто, 28. апр 2020. у 10:26 chen huacai  је написао/ла:
> >
> > Hi, Philippe,
> >
> > On Tue, Apr 28, 2020 at 2:34 PM Philippe Mathieu-Daudé  
> > wrote:
> > >
> > > Hi Huacai,
> > >
> > > On 4/27/20 11:33 AM, Huacai Chen wrote:
> > > > Loongson-3 CPU family include Loongson-3A R1/R2/R3/R4 and Loongson-3B
> > > > R1/R2. Loongson-3A R4 is the newest and its ISA is almost the superset
> > > > of all others. To reduce complexity, we just define a "Loongson-3A" CPU
> > > > which is corresponding to Loongson-3A R4. Loongson-3A has CONFIG6 and
> > > > CONFIG7, so add their bit-fields as well.
> > >
> > > Is there a public datasheet for R4? (If possible in English).
> > I'm sorry that we only have Chinese datasheet in www.loongson.cn.
> >
> > >
> > > >
> > > > Signed-off-by: Huacai Chen 
> > > > Co-developed-by: Jiaxun Yang 
> > > > ---
> > > >  target/mips/cpu.h| 28 ++
> > > >  target/mips/internal.h   |  2 ++
> > > >  target/mips/mips-defs.h  |  7 --
> > > >  target/mips/translate.c  |  2 ++
> > > >  target/mips/translate_init.inc.c | 51 
> > > > 
> > > >  5 files changed, 88 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/target/mips/cpu.h b/target/mips/cpu.h
> > > > index 94d01ea..0b3c987 100644
> > > > --- a/target/mips/cpu.h
> > > > +++ b/target/mips/cpu.h
> > > > @@ -940,7 +940,35 @@ struct CPUMIPSState {
> > > >  #define CP0C5_UFR  2
> > > >  #define CP0C5_NFExists 0
> > > >  int32_t CP0_Config6;
> > > > +int32_t CP0_Config6_rw_bitmask;
> > > > +#define CP0C6_BPPASS  31
> > > > +#define CP0C6_KPOS24
> > > > +#define CP0C6_KE  23
> > > > +#define CP0C6_VTLBONLY22
> > > > +#define CP0C6_LASX21
> > > > +#define CP0C6_SSEN20
> > > > +#define CP0C6_DISDRTIME   19
> > > > +#define CP0C6_PIXNUEN 18
> > > > +#define CP0C6_SCRAND  17
> > > > +#define CP0C6_LLEXCEN 16
> > > > +#define CP0C6_DISVC   15
> > > > +#define CP0C6_VCLRU   14
> > > > +#define CP0C6_DCLRU   13
> > > > +#define CP0C6_PIXUEN  12
> > > > +#define CP0C6_DISBLKLYEN  11
> > > > +#define CP0C6_UMEMUALEN   10
> > > > +#define CP0C6_SFBEN   8
> > > > +#define CP0C6_FLTINT  7
> > > > +#define CP0C6_VLTINT  6
> > > > +#define CP0C6_DISBTB  5
> > > > +#define CP0C6_STPREFCTL   2
> > > > +#define CP0C6_INSTPREF1
> > > > +#define CP0C6_DATAPREF0
> > > >  int32_t CP0_Config7;
> > 

Re: [PATCH for-5.1 4/7] target/mips: Add Loongson-3 CPU definition

2020-04-29 Thread Huacai Chen
Hi, Philippe,

The major differences of R3 and R4 are:
1, R4 has complete MIPS VZ ASE (while R3 is incomplete), so very
usable for KVM host;
2, R4 has MSA ASE while R3 hasn't;
3, R4 has cpucfg, rdcsr and wrcsr instructions (similar to cpuid,
rdmsr and wrmsr in X86).

On Wed, Apr 29, 2020 at 4:09 PM Philippe Mathieu-Daudé  wrote:
>
> On 4/29/20 5:51 AM, Huacai Chen wrote:
> > Hi, Aleksandar,
> >
> > I've tried translate.google.com, and documents are available here:
> > Loongson-3A R1 (Loongson-3A1000)
> > User Manual Part 1:
> > http://ftp.godson.ac.cn/lemote/3A1000_p1.pdf
> > http://ftp.godson.ac.cn/lemote/Loongson3A1000_processor_user_manual_P1.pdf
> > (Chinese Version)
> > User Manual Part 2:
> > http://ftp.godson.ac.cn/lemote/3A1000_p2.pdf
> > http://ftp.godson.ac.cn/lemote/Loongson3A1000_processor_user_manual_P2.pdf
> > (Chinese Version)
> >
> > Loongson-3A R2 (Loongson-3A2000)
> > User Manual Part 1:
> > http://ftp.godson.ac.cn/lemote/3A2000_p1.pdf
> > http://ftp.godson.ac.cn/lemote/Loongson3A2000_user1.pdf (Chinese Version)
> > User Manual Part 2:
> > http://ftp.godson.ac.cn/lemote/3A2000_p2.pdf
> > http://ftp.godson.ac.cn/lemote/Loongson3A2000_user2.pdf (Chinese Version)
> >
> > Loongson-3A R3 (Loongson-3A3000)
> > User Manual Part 1:
> > http://ftp.godson.ac.cn/lemote/3A3000_p1.pdf
> > http://ftp.godson.ac.cn/lemote/Loongson3A3000_3B3000usermanual1.pdf
> > (Chinese Version)
> > User Manual Part 2:
> > http://ftp.godson.ac.cn/lemote/3A3000_p2.pdf
> > http://ftp.godson.ac.cn/lemote/Loongson3A3000_3B3000usermanual2.pdf
> > (Chinese Version)
> >
> > Loongson-3A R4 (Loongson-3A4000)
> > User Manual Part 1:
> > http://ftp.godson.ac.cn/lemote/3A4000_p1.pdf
> > http://ftp.godson.ac.cn/lemote/3A4000user.pdf (Chinese Version)
> > User Manual Part 2:
> > I'm sorry that it is unavailable now.
>
> Thanks for the translations!
>
> Since we can only review Loongson-3A R3, are there specific features
> from R4 you need that are not available in R3?
>
> >
> > On Wed, Apr 29, 2020 at 2:37 AM Aleksandar Markovic
> >  wrote:
> >>
> >> Huacai,
> >>
> >> Can you please do machine translation of the document?
> >>
> >> It can be done via translate.google.com (it accepts pdf files, but
> >> does not have download feature, and workaround is to "print to pdf"...
> >>
> >> Thanks in advance!
> >> Aleksandar
> >>
> >> уто, 28. апр 2020. у 10:26 chen huacai  је 
> >> написао/ла:
> >>>
> >>> Hi, Philippe,
> >>>
> >>> On Tue, Apr 28, 2020 at 2:34 PM Philippe Mathieu-Daudé  
> >>> wrote:
> >>>>
> >>>> Hi Huacai,
> >>>>
> >>>> On 4/27/20 11:33 AM, Huacai Chen wrote:
> >>>>> Loongson-3 CPU family include Loongson-3A R1/R2/R3/R4 and Loongson-3B
> >>>>> R1/R2. Loongson-3A R4 is the newest and its ISA is almost the superset
> >>>>> of all others. To reduce complexity, we just define a "Loongson-3A" CPU
> >>>>> which is corresponding to Loongson-3A R4. Loongson-3A has CONFIG6 and
> >>>>> CONFIG7, so add their bit-fields as well.
> >>>>
> >>>> Is there a public datasheet for R4? (If possible in English).
> >>> I'm sorry that we only have Chinese datasheet in www.loongson.cn.
> >>>
> >>>>
> >>>>>
> >>>>> Signed-off-by: Huacai Chen 
> >>>>> Co-developed-by: Jiaxun Yang 
> >>>>> ---
> >>>>>   target/mips/cpu.h| 28 ++
> >>>>>   target/mips/internal.h   |  2 ++
> >>>>>   target/mips/mips-defs.h  |  7 --
> >>>>>   target/mips/translate.c  |  2 ++
> >>>>>   target/mips/translate_init.inc.c | 51 
> >>>>> 
> >>>>>   5 files changed, 88 insertions(+), 2 deletions(-)
> >>>>>
> >>>>> diff --git a/target/mips/cpu.h b/target/mips/cpu.h
> >>>>> index 94d01ea..0b3c987 100644
> >>>>> --- a/target/mips/cpu.h
> >>>>> +++ b/target/mips/cpu.h
> >>>>> @@ -940,7 +940,35 @@ struct CPUMIPSState {
> >>>>>   #define CP0C5_UFR  2
> >>>>>   #define CP0C5_NFExists 0
> >>>>>   int32_t CP0_Config6;

Re: [PATCH for-5.1 4/7] target/mips: Add Loongson-3 CPU definition

2020-04-29 Thread Huacai Chen
Hi, Philippe,

I think that this CPU definition is for Guest, not for Host (Maybe I'm wrong?).

On Wed, Apr 29, 2020 at 4:58 PM Philippe Mathieu-Daudé  wrote:
>
> On 4/29/20 10:27 AM, Huacai Chen wrote:
> > Hi, Philippe,
> >
> > The major differences of R3 and R4 are:
> > 1, R4 has complete MIPS VZ ASE (while R3 is incomplete), so very
> > usable for KVM host;
>
> So you need to set CP0C3_VZ.
If the definition is for Guest, I think CP0C3_VZ should not be set in
CP0_Config3, because only the Host can see VZ ASE.

>
> > 2, R4 has MSA ASE while R3 hasn't;
>
> So you need to set CP0C5_MSAEn.
I have already set CP0C5_MSAEn CP0_Config5_rw_bitmask, but I don't
think it should be set in CP0_Config5 because MSA is disabled by
default.

>
> > 3, R4 has cpucfg, rdcsr and wrcsr instructions (similar to cpuid,
> > rdmsr and wrmsr in X86).
>
> OK, these are not implemented.
>
> [...]
>
> >>>>>>> diff --git a/target/mips/translate_init.inc.c 
> >>>>>>> b/target/mips/translate_init.inc.c
> >>>>>>> index 6d145a9..a32412d 100644
> >>>>>>> --- a/target/mips/translate_init.inc.c
> >>>>>>> +++ b/target/mips/translate_init.inc.c
> >>>>>>> @@ -802,6 +802,57 @@ const mips_def_t mips_defs[] =
> >>>>>>>.mmu_type = MMU_TYPE_R4000,
> >>>>>>>},
> >>>>>>>{
> >>>>>>> +.name = "Loongson-3A",
> >>>>>>> +.CP0_PRid = 0x14C000,
> >>>>>>> +/* 64KB I-cache and d-cache. 4 way with 32 bit cache line 
> >>>>>>> size.  */
> >>>>>>> +.CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << 
> >>>>>>> CP0C0_AT) |
> >>>>>>> +   (MMU_TYPE_R4000 << CP0C0_MT),
> >>>>>>> +.CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << 
> >>>>>>> CP0C1_MMU) |
> >>>>>>> +   (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << 
> >>>>>>> CP0C1_IA) |
> >>>>>>> +   (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << 
> >>>>>>> CP0C1_DA) |
> >>>>>>> +   (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << 
> >>>>>>> CP0C1_EP),
> >>>>>>> +.CP0_Config2 = MIPS_CONFIG2,
> >>>>>>> +.CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << 
> >>>>>>> CP0C3_MSAP) |
> >>>>>>> +   (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << 
> >>>>>>> CP0C3_ULRI) |
> >>>>>>> +   (1 << CP0C3_RXI) | (1 << CP0C3_LPA) | (1 << 
> >>>>>>> CP0C3_VInt),
> >>>>>>> +.CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (2 << 
> >>>>>>> CP0C4_IE) |
> >>>>>>> +   (1 << CP0C4_AE) | (0x1c << CP0C4_KScrExist),
> >>>>>>> +.CP0_Config4_rw_bitmask = 0,
> >>>>>>> +.CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_NFExists) | (1 << 
> >>>>>>> 18),
> >>>>>>> +.CP0_Config5_rw_bitmask = (1 << CP0C5_K) | (1 << CP0C5_CV) |
> >>>>>>> +  (1 << CP0C5_MSAEn) | (1 << 
> >>>>>>> CP0C5_UFE) |
> >>>>>>> +  (1 << CP0C5_FRE) | (1 << 
> >>>>>>> CP0C5_SBRI),
> >>>>>>> +.CP0_Config6 = (1 << CP0C6_VCLRU) | (1 << CP0C6_DCLRU) | (1 
> >>>>>>> << CP0C6_SFBEN) |
> >>>>>>> +   (1 << CP0C6_FLTINT) | (1 << CP0C6_INSTPREF) | 
> >>>>>>> (1 << CP0C6_DATAPREF),
> >>>>>>> +.CP0_Config6_rw_bitmask = (1 << CP0C6_BPPASS) | (0x3f << 
> >>>>>>> CP0C6_KPOS) |
> >>>>>>> +  (1 << CP0C6_KE) | (1 << 
> >>>>>>> CP0C6_VTLBONLY) | (1 << CP0C6_LASX) |
> >&g

Re: [PATCH for-5.1 4/7] target/mips: Add Loongson-3 CPU definition

2020-04-29 Thread Huacai Chen
Hi, Philippe,

On Wed, Apr 29, 2020 at 5:30 PM Philippe Mathieu-Daudé  wrote:
>
> On 4/29/20 11:25 AM, Huacai Chen wrote:
> > Hi, Philippe,
> >
> > I think that this CPU definition is for Guest, not for Host (Maybe I'm 
> > wrong?).
>
> OK, it was not obvious to me (I haven't received the cover letter of
> this series).
> The code you modified is used by both host emulation and guest
> virtualization.
I'm very sorry that I hadn't send a cover letter...
Now I preparing the V2 series and I think put the cover letter of V2
here could make life easier...

Loongson-3 CPU family include Loongson-3A R1/R2/R3/R4 and Loongson-3B
R1/R2. Loongson-3A R1 is the oldest and its ISA is the smallest, while
Loongson-3A R4 is the newest and its ISA is almost the superset of all
others. To reduce complexity, in QEMU we just define two CPU types:

1, "Loongson-3A1000" CPU which is corresponding to Loongson-3A R1. It is
   suitable for TCG because Loongson-3A R1 has fewest ASE.
2, "Loongson-3A4000" CPU which is corresponding to Loongson-3A R4. It is
   suitable for KVM because Loongson-3A R4 has the VZ ASE.

Loongson-3 lacks English documents. I've tried to translated them with
translate.google.com, and the machine translated documents (together
with their original Chinese versions) are available here.

..

We are preparing to add QEMU's Loongson-3 support. MIPS VZ extension is
fully supported in Loongson-3A R4+, so we at first add QEMU/KVM support
in this series. And the next series will add QEMU/TCG support (it will
emulate Loongson-3A R1).

We already have a full functional Linux kernel (based on Linux-5.4.x LTS
but not upstream yet) here:

https://github.com/chenhuacai/linux

How to use QEMU/Loongson-3?
1, Download kernel source from the above URL;
2, Build a kernel with arch/mips/configs/loongson3_{def,hpc}config;
3, Boot the a Loongson-3A4000 host with this kernel;
4, Build QEMU-5.0.0 with this patchset;
5, modprobe kvm;
6, Use QEMU with TCG (available in future):
   qemu-system-mips64el -M loongson3,accel=tcg -cpu
Loongson-3A1000 -kernel  -append ...
   Use QEMU with KVM (available at present):
   qemu-system-mips64el -M loongson3,accel=kvm -cpu
Loongson-3A4000 -kernel  -append ...

   The "-cpu" parameter can be omitted here and QEMU will use the
correct type for TCG/KVM automatically.

>
> If you want to only add a guest cpu type, you should name it
> "Loongson-3A virtualized" and can restrict with:
>
>if (kvm_enabled()) {
>  add_guest_cpu();
>}
>
> But cleaner is to add the host cpu regardless, and in cpu_state_reset()
> restrict when virtualized:
>
>if (kvm_enabled()) {
>  /* disable host features on guest */
>  env->CP0_Config3 &= ~CP0C3_VZ;
>  ...
>}
>
> >
> > On Wed, Apr 29, 2020 at 4:58 PM Philippe Mathieu-Daudé  
> > wrote:
> >>
> >> On 4/29/20 10:27 AM, Huacai Chen wrote:
> >>> Hi, Philippe,
> >>>
> >>> The major differences of R3 and R4 are:
> >>> 1, R4 has complete MIPS VZ ASE (while R3 is incomplete), so very
> >>> usable for KVM host;
> >>
> >> So you need to set CP0C3_VZ.
> > If the definition is for Guest, I think CP0C3_VZ should not be set in
> > CP0_Config3, because only the Host can see VZ ASE.
> >
> >>
> >>> 2, R4 has MSA ASE while R3 hasn't;
> >>
> >> So you need to set CP0C5_MSAEn.
> > I have already set CP0C5_MSAEn CP0_Config5_rw_bitmask, but I don't
> > think it should be set in CP0_Config5 because MSA is disabled by
> > default.
> >
> >>
> >>> 3, R4 has cpucfg, rdcsr and wrcsr instructions (similar to cpuid,
> >>> rdmsr and wrmsr in X86).
> >>
> >> OK, these are not implemented.
>
> I was looking at TCG emulation, now I understand why you don't mind
> about them there.
Assume that you have read my cover letter now. So TCG only need to
consider Loongson-3A1000 and KVM only need to consider Loongson-3A4000
(in V2 I will define two types of CPU).

>
> >>
> >> [...]
> >>
> >>>>>>>>> diff --git a/target/mips/translate_init.inc.c 
> >>>>>>>>> b/target/mips/translate_init.inc.c
> >>>>>>>>> index 6d145a9..a32412d 100644
> >>>>>>>>> --- a/target/mips/translate_init.inc.c
> >>>>>>>>> +++ b/target/mips/translate_init.inc.c
> >>>>>>>>> @@ -802,6 +802,57 @@ const mips_def_t mips_defs[] =
> >>>>>>>>> .mmu_type = MMU_TYPE_R4000,
> >>>>>

Re: [PATCH for-5.1 3/7] hw/mips: Add CPU IRQ3 delivery for KVM

2020-04-29 Thread Huacai Chen
Hi, Philippe,

On Wed, Apr 29, 2020 at 5:18 PM Philippe Mathieu-Daudé  wrote:
>
> On 4/29/20 3:52 AM, Huacai Chen wrote:
> > Hi, Philippe and Aleksandar,
> >
> > I'm not refusing to change my patch, but I have two questions:
> > 1, Why we should identify Loongson-3 to deliver IP3? It seems that
> > deliver all IPs (IP2~IP7) unconditionally is harmless as well.
> > 2, How to identify Loongson-3 by Config6/Config7? Loongson-3 is not
> > the only processor which has Config6/Config7.
> Please don't top-post on technical lists, it makes the conversation
> harder to follow.
>
> This code is modelling the device, not KVM.
>
> Commit b1bd8b28cca is not very verbose. I wonder why not delivering all
> IRQs to kvm_mips_set_interrupt, that would make this patch simpler.
>
> I think the problem in QEMU MIPS IRQ delivery is one implementation is
> in cpu_mips_irq_request() while another one (vectored IRQ) in
> cpu_mips_hw_interrupts_pending (see 138afb024bb) and KVM is also in the
> middle.
I think the previous code only deliver IP2 is because KVM/MIPS only
use IP2 for external interrupts, but now I have changed KVM/MIPS as
well, please see:
https://patchwork.kernel.org/patch/11507591/

>
> And I see you selected CP0C3_VInt in the R4 definition... so what is
> delivered here?
CP0C3_VInt just indicates the capability, kernel of Loongson-3 doesn't use VINT.

>
> >
> > Huacai
> >
> > On Wed, Apr 29, 2020 at 2:58 AM Aleksandar Markovic
> >  wrote:
> >>
> >> уто, 28. апр 2020. у 10:21 chen huacai  је 
> >> написао/ла:
> >>>
> >>> Hi, Philippe,
> >>>
> >>> On Mon, Apr 27, 2020 at 5:57 PM Philippe Mathieu-Daudé  
> >>> wrote:
> >>>>
> >>>> On 4/27/20 11:33 AM, Huacai Chen wrote:
> >>>>> Currently, KVM/MIPS only deliver I/O interrupt via IP2, this patch add
> >>>>> IP2 delivery as well, because Loongson-3 based machine use both IRQ2
>
> "IP3 delivery as well"?
Sorry, this is my fault.

>
> >>>>> (CPU's IP2) and IRQ3 (CPU's IP3).
> >>>>>
> >>>>> Signed-off-by: Huacai Chen 
> >>>>> Co-developed-by: Jiaxun Yang 
> >>>>> ---
> >>>>>   hw/mips/mips_int.c | 6 ++
> >>>>>   1 file changed, 2 insertions(+), 4 deletions(-)
> >>>>>
> >>>>> diff --git a/hw/mips/mips_int.c b/hw/mips/mips_int.c
> >>>>> index 796730b..5526219 100644
> >>>>> --- a/hw/mips/mips_int.c
> >>>>> +++ b/hw/mips/mips_int.c
> >>>>> @@ -48,16 +48,14 @@ static void cpu_mips_irq_request(void *opaque, int 
> >>>>> irq, int level)
> >>>>>   if (level) {
> >>>>>   env->CP0_Cause |= 1 << (irq + CP0Ca_IP);
> >>>>>
> >>>>> -if (kvm_enabled() && irq == 2) {
> >>>>> +if (kvm_enabled() && (irq == 2 || irq == 3))
> >>>>
> >>>> Shouldn't we check env->CP0_Config6 (or Config7) has the required
> >>>> feature first?
> >>> I'm sorry that I can't understand IRQ delivery has something to do
> >>> with Config6/Config7, to identify Loongson-3?
> >>>
> >>
> >> Obviously, yes.
> >>
> >> Thanks,
> >> Aleksandar
> >>
> >>
> >>>>
> >>>>>   kvm_mips_set_interrupt(cpu, irq, level);
> >>>>> -}
> >>>>>
> >>>>>   } else {
> >>>>>   env->CP0_Cause &= ~(1 << (irq + CP0Ca_IP));
> >>>>>
> >>>>> -if (kvm_enabled() && irq == 2) {
> >>>>> +if (kvm_enabled() && (irq == 2 || irq == 3))
> >>>>>   kvm_mips_set_interrupt(cpu, irq, level);
> >>>>> -}
> >>>>>   }
> >>>>>
> >>>>>   if (env->CP0_Cause & CP0Ca_IP_mask) {
> >>>>>
> >>>
> >>>
> >>>
> >>> --
> >>> Huacai Chen
> >



[PATCH for-5.1 V2 0/7] mips: Add Loongson-3 machine support (with KVM)

2020-04-30 Thread Huacai Chen
Loongson-3 CPU family include Loongson-3A R1/R2/R3/R4 and Loongson-3B
R1/R2. Loongson-3A R1 is the oldest and its ISA is the smallest, while
Loongson-3A R4 is the newest and its ISA is almost the superset of all
others. To reduce complexity, in QEMU we just define two CPU types:

1, "Loongson-3A1000" CPU which is corresponding to Loongson-3A R1. It is
   suitable for TCG because Loongson-3A R1 has fewest ASE.
2, "Loongson-3A4000" CPU which is corresponding to Loongson-3A R4. It is
   suitable for KVM because Loongson-3A R4 has the VZ ASE.

Loongson-3 lacks English documents. I've tried to translated them with
translate.google.com, and the machine translated documents (together
with their original Chinese versions) are available here.

Loongson-3A R1 (Loongson-3A1000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A1000_p1.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A1000_processor_user_manual_P1.pdf 
(Chinese Version)
User Manual Part 2:
http://ftp.godson.ac.cn/lemote/3A1000_p2.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A1000_processor_user_manual_P2.pdf 
(Chinese Version)

Loongson-3A R2 (Loongson-3A2000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A2000_p1.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A2000_user1.pdf (Chinese Version)
User Manual Part 2:
http://ftp.godson.ac.cn/lemote/3A2000_p2.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A2000_user2.pdf (Chinese Version)

Loongson-3A R3 (Loongson-3A3000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A3000_p1.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A3000_3B3000usermanual1.pdf (Chinese 
Version)
User Manual Part 2:
http://ftp.godson.ac.cn/lemote/3A3000_p2.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A3000_3B3000usermanual2.pdf (Chinese 
Version)

Loongson-3A R4 (Loongson-3A4000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A4000_p1.pdf
http://ftp.godson.ac.cn/lemote/3A4000user.pdf (Chinese Version)
User Manual Part 2:
I'm sorry that it is unavailable now.

We are preparing to add QEMU's Loongson-3 support. MIPS VZ extension is
fully supported in Loongson-3A R4+, so we at first add QEMU/KVM support
in this series. And the next series will add QEMU/TCG support (it will
emulate Loongson-3A R1).

We already have a full functional Linux kernel (based on Linux-5.4.x LTS
but not upstream yet) here:

https://github.com/chenhuacai/linux

How to use QEMU/Loongson-3?
1, Download kernel source from the above URL;
2, Build a kernel with arch/mips/configs/loongson3_{def,hpc}config;
3, Boot a Loongson-3A4000 host with this kernel;
4, Build QEMU-5.0.0 with this patchset;
5, modprobe kvm;
6, Use QEMU with TCG (available in future):
   qemu-system-mips64el -M loongson3,accel=tcg -cpu Loongson-3A1000 -kernel 
 -append ... 
   Use QEMU with KVM (available at present): 
   qemu-system-mips64el -M loongson3,accel=kvm -cpu Loongson-3A4000 -kernel 
 -append ... 

   The "-cpu" parameter can be omitted here and QEMU will use the correct type 
for TCG/KVM automatically.

Huacai Chen(7):
 configure: Add KVM target support for MIPS64
 hw/mips: Implement the kvm_type() hook in MachineClass
 hw/mips: Add CPU IRQ3 delivery for KVM
 target/mips: Add Loongson-3 CPU definition
 target/mips: Add more CP0 register for save/restor
 hw/mips: Add Loongson-3 machine support (with KVM)
 MAINTAINERS: Add myself as Loongson-3 maintainer

Signed-off-by: Huacai Chen 
---
 MAINTAINERS  |   5 +
 configure|   2 +-
 default-configs/mips64el-softmmu.mak |   1 +
 hw/core/Makefile.objs|   2 +-
 hw/core/null-machine.c   |   4 +
 hw/mips/Kconfig  |  10 +
 hw/mips/Makefile.objs|   3 +-
 hw/mips/common.c |  29 ++
 hw/mips/mips_int.c   |   6 +-
 hw/mips/mips_loongson3.c | 886 +++
 include/hw/mips/mips.h   |   3 +
 target/mips/cpu.h|  28 ++
 target/mips/internal.h   |   2 +
 target/mips/kvm.c| 212 +
 target/mips/machine.c|   6 +-
 target/mips/mips-defs.h  |   7 +-
 target/mips/translate.c  |   2 +
 target/mips/translate_init.inc.c |  84 
 18 files changed, 1281 insertions(+), 11 deletions(-)
 create mode 100644 hw/mips/common.c
 create mode 100644 hw/mips/mips_loongson3.c
--
2.7.0



[PATCH for-5.1 V2 3/7] hw/mips: Add CPU IRQ3 delivery for KVM

2020-04-30 Thread Huacai Chen
Currently, KVM/MIPS only deliver I/O interrupt via IP2, this patch add
IP3 delivery as well, because Loongson-3 based machine use both IRQ2
(CPU's IP2) and IRQ3 (CPU's IP3).

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 hw/mips/mips_int.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/hw/mips/mips_int.c b/hw/mips/mips_int.c
index 796730b..5526219 100644
--- a/hw/mips/mips_int.c
+++ b/hw/mips/mips_int.c
@@ -48,16 +48,14 @@ static void cpu_mips_irq_request(void *opaque, int irq, int 
level)
 if (level) {
 env->CP0_Cause |= 1 << (irq + CP0Ca_IP);
 
-if (kvm_enabled() && irq == 2) {
+if (kvm_enabled() && (irq == 2 || irq == 3))
 kvm_mips_set_interrupt(cpu, irq, level);
-}
 
 } else {
 env->CP0_Cause &= ~(1 << (irq + CP0Ca_IP));
 
-if (kvm_enabled() && irq == 2) {
+if (kvm_enabled() && (irq == 2 || irq == 3))
 kvm_mips_set_interrupt(cpu, irq, level);
-}
 }
 
 if (env->CP0_Cause & CP0Ca_IP_mask) {
-- 
2.7.0




[PATCH for-5.1 V2 1/7] configure: Add KVM target support for MIPS64

2020-04-30 Thread Huacai Chen
Preparing for Loongson-3 virtualization, add KVM target support for
MIPS64 in configure script.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 configure | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure b/configure
index 23b5e93..7581e65 100755
--- a/configure
+++ b/configure
@@ -198,7 +198,7 @@ supported_kvm_target() {
 arm:arm | aarch64:aarch64 | \
 i386:i386 | i386:x86_64 | i386:x32 | \
 x86_64:i386 | x86_64:x86_64 | x86_64:x32 | \
-mips:mips | mipsel:mips | \
+mips:mips | mipsel:mips | mips64:mips | mips64el:mips | \
 ppc:ppc | ppc64:ppc | ppc:ppc64 | ppc64:ppc64 | ppc64:ppc64le | \
 s390x:s390x)
 return 0
-- 
2.7.0




[PATCH for-5.1 V2 4/7] target/mips: Add Loongson-3 CPU definition

2020-04-30 Thread Huacai Chen
Loongson-3 CPU family include Loongson-3A R1/R2/R3/R4 and Loongson-3B
R1/R2. Loongson-3A R1 is the oldest and its ISA is the smallest, while
Loongson-3A R4 is the newest and its ISA is almost the superset of all
others. To reduce complexity, we just define two CPU types:
1, "Loongson-3A1000" CPU which is corresponding to Loongson-3A R1. It is
   suitable for TCG because Loongson-3A R1 has fewest ASE.
2, "Loongson-3A4000" CPU which is corresponding to Loongson-3A R4. It is
   suitable for KVM because Loongson-3A R4 has the VZ ASE.

Loongson-3A has CONFIG6 and CONFIG7, so add their bit-fields as well.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 target/mips/cpu.h| 28 ++
 target/mips/internal.h   |  2 +
 target/mips/mips-defs.h  |  7 +++-
 target/mips/translate.c  |  2 +
 target/mips/translate_init.inc.c | 84 
 5 files changed, 121 insertions(+), 2 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 94d01ea..0b3c987 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -940,7 +940,35 @@ struct CPUMIPSState {
 #define CP0C5_UFR  2
 #define CP0C5_NFExists 0
 int32_t CP0_Config6;
+int32_t CP0_Config6_rw_bitmask;
+#define CP0C6_BPPASS  31
+#define CP0C6_KPOS24
+#define CP0C6_KE  23
+#define CP0C6_VTLBONLY22
+#define CP0C6_LASX21
+#define CP0C6_SSEN20
+#define CP0C6_DISDRTIME   19
+#define CP0C6_PIXNUEN 18
+#define CP0C6_SCRAND  17
+#define CP0C6_LLEXCEN 16
+#define CP0C6_DISVC   15
+#define CP0C6_VCLRU   14
+#define CP0C6_DCLRU   13
+#define CP0C6_PIXUEN  12
+#define CP0C6_DISBLKLYEN  11
+#define CP0C6_UMEMUALEN   10
+#define CP0C6_SFBEN   8
+#define CP0C6_FLTINT  7
+#define CP0C6_VLTINT  6
+#define CP0C6_DISBTB  5
+#define CP0C6_STPREFCTL   2
+#define CP0C6_INSTPREF1
+#define CP0C6_DATAPREF0
 int32_t CP0_Config7;
+int64_t CP0_Config7_rw_bitmask;
+#define CP0C7_NAPCGEN   2
+#define CP0C7_UNIMUEN   1
+#define CP0C7_VFPUCGEN  0
 uint64_t CP0_LLAddr;
 uint64_t CP0_MAAR[MIPS_MAAR_MAX];
 int32_t CP0_MAARI;
diff --git a/target/mips/internal.h b/target/mips/internal.h
index 1bf274b..7853cb1 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -36,7 +36,9 @@ struct mips_def_t {
 int32_t CP0_Config5;
 int32_t CP0_Config5_rw_bitmask;
 int32_t CP0_Config6;
+int32_t CP0_Config6_rw_bitmask;
 int32_t CP0_Config7;
+int32_t CP0_Config7_rw_bitmask;
 target_ulong CP0_LLAddr_rw_bitmask;
 int CP0_LLAddr_shift;
 int32_t SYNCI_Step;
diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h
index a831bb4..c2c96db 100644
--- a/target/mips/mips-defs.h
+++ b/target/mips/mips-defs.h
@@ -51,8 +51,9 @@
  */
 #define INSN_LOONGSON2E   0x0001ULL
 #define INSN_LOONGSON2F   0x0002ULL
-#define INSN_VR54XX   0x0004ULL
-#define INSN_R59000x0008ULL
+#define INSN_LOONGSON3A   0x0004ULL
+#define INSN_VR54XX   0x0008ULL
+#define INSN_R59000x0010ULL
 /*
  *   bits 56-63: vendor-specific ASEs
  */
@@ -94,6 +95,8 @@
 /* Wave Computing: "nanoMIPS" */
 #define CPU_NANOMIPS32  (CPU_MIPS32R6 | ISA_NANOMIPS32)
 
+#define CPU_LOONGSON3A  (CPU_MIPS64R2 | INSN_LOONGSON3A)
+
 /*
  * Strictly follow the architecture standard:
  * - Disallow "special" instruction handling for PMON/SPIM.
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 25b595a..2caf4cb 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -31206,7 +31206,9 @@ void cpu_state_reset(CPUMIPSState *env)
 env->CP0_Config5 = env->cpu_model->CP0_Config5;
 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
 env->CP0_Config6 = env->cpu_model->CP0_Config6;
+env->CP0_Config6_rw_bitmask = env->cpu_model->CP0_Config6_rw_bitmask;
 env->CP0_Config7 = env->cpu_model->CP0_Config7;
+env->CP0_Config7_rw_bitmask = env->cpu_model->CP0_Config7_rw_bitmask;
 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
  << env->cpu_model->CP0_LLAddr_shift;
 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
diff --git a/target/mips/translate_init.inc.c b/target/mips/translate_init.inc.c
index 6d145a9..21419c8 100644
--- a/target/mips/translate_init.inc.c
+++ b/target/mips/translate_init.inc.c
@@ -802,6 +802,90 @@ const mips_def_t mips_defs[] =
 .mmu_type = MMU_TYPE_R4000,
 },
 {
+.name = "Loongson-3A1000",
+.CP0_PRid = 0x6305,
+/* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. 

[PATCH for-5.1 V2 2/7] hw/mips: Implement the kvm_type() hook in MachineClass

2020-04-30 Thread Huacai Chen
MIPS has two types of KVM: TE & VZ, and TE is the default type. Now we
can't create a VZ guest in QEMU because it lacks the kvm_type() hook in
MachineClass. Besides, libvirt uses a null-machine to detect the kvm
capability, so by default it will return "KVM not supported" on a VZ
platform. Thus, null-machine also need the kvm_type() hook.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 hw/core/Makefile.objs  |  2 +-
 hw/core/null-machine.c |  4 
 hw/mips/Makefile.objs  |  2 +-
 hw/mips/common.c   | 29 +
 include/hw/mips/mips.h |  3 +++
 5 files changed, 38 insertions(+), 2 deletions(-)
 create mode 100644 hw/mips/common.c

diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index 6215e7c..7cfef1f 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -16,10 +16,10 @@ common-obj-$(CONFIG_SOFTMMU) += vm-change-state-handler.o
 common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
 common-obj-$(CONFIG_SOFTMMU) += sysbus.o
 common-obj-$(CONFIG_SOFTMMU) += machine.o
-common-obj-$(CONFIG_SOFTMMU) += null-machine.o
 common-obj-$(CONFIG_SOFTMMU) += loader.o
 common-obj-$(CONFIG_SOFTMMU) += machine-hmp-cmds.o
 common-obj-$(CONFIG_SOFTMMU) += numa.o
+obj-$(CONFIG_SOFTMMU) += null-machine.o
 obj-$(CONFIG_SOFTMMU) += machine-qmp-cmds.o
 
 common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c
index cb47d9d..94a36f9 100644
--- a/hw/core/null-machine.c
+++ b/hw/core/null-machine.c
@@ -17,6 +17,7 @@
 #include "sysemu/sysemu.h"
 #include "exec/address-spaces.h"
 #include "hw/core/cpu.h"
+#include "hw/mips/mips.h"
 
 static void machine_none_init(MachineState *mch)
 {
@@ -50,6 +51,9 @@ static void machine_none_machine_init(MachineClass *mc)
 mc->max_cpus = 1;
 mc->default_ram_size = 0;
 mc->default_ram_id = "ram";
+#ifdef TARGET_MIPS
+mc->kvm_type = mips_kvm_type;
+#endif
 }
 
 DEFINE_MACHINE("none", machine_none_machine_init)
diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs
index 525809a..2f7795b 100644
--- a/hw/mips/Makefile.objs
+++ b/hw/mips/Makefile.objs
@@ -1,4 +1,4 @@
-obj-y += addr.o mips_int.o
+obj-y += addr.o common.o mips_int.o
 obj-$(CONFIG_R4K) += mips_r4k.o
 obj-$(CONFIG_MALTA) += gt64xxx_pci.o mips_malta.o
 obj-$(CONFIG_MIPSSIM) += mips_mipssim.o
diff --git a/hw/mips/common.c b/hw/mips/common.c
new file mode 100644
index 000..eb0c649
--- /dev/null
+++ b/hw/mips/common.c
@@ -0,0 +1,29 @@
+/*
+ * Common MIPS routines
+ *
+ * Copyright (c) 2020 Huacai Chen (che...@lemote.com)
+ * This code is licensed under the GNU GPL v2.
+ */
+
+#include 
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/boards.h"
+#include "hw/mips/mips.h"
+#include "sysemu/kvm_int.h"
+
+int mips_kvm_type(MachineState *machine, const char *vm_type)
+{
+int r;
+KVMState *s = KVM_STATE(machine->accelerator);;
+
+r = kvm_check_extension(s, KVM_CAP_MIPS_VZ);
+if (r > 0)
+return KVM_VM_MIPS_VZ;
+
+r = kvm_check_extension(s, KVM_CAP_MIPS_TE);
+if (r > 0)
+return KVM_VM_MIPS_TE;
+
+return -1;
+}
diff --git a/include/hw/mips/mips.h b/include/hw/mips/mips.h
index 0af4c3d..2ac0580 100644
--- a/include/hw/mips/mips.h
+++ b/include/hw/mips/mips.h
@@ -20,4 +20,7 @@ void rc4030_dma_write(void *dma, uint8_t *buf, int len);
 
 DeviceState *rc4030_init(rc4030_dma **dmas, IOMMUMemoryRegion **dma_mr);
 
+/* common.c */
+int mips_kvm_type(MachineState *machine, const char *vm_type);
+
 #endif
-- 
2.7.0




[PATCH for-5.1 V2 7/7] MAINTAINERS: Add myself as Loongson-3 maintainer

2020-04-30 Thread Huacai Chen
Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 MAINTAINERS | 5 +
 1 file changed, 5 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index aa9a057..66c5a41 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1080,6 +1080,11 @@ F: hw/isa/vt82c686.c
 F: hw/pci-host/bonito.c
 F: include/hw/isa/vt82c686.h
 
+Loongson-3
+M: Huacai Chen 
+S: Maintained
+F: hw/mips/mips_loongson3.c
+
 Boston
 M: Paul Burton 
 R: Aleksandar Rikalo 
-- 
2.7.0




[PATCH for-5.1 V2 5/7] target/mips: Add more CP0 register for save/restore

2020-04-30 Thread Huacai Chen
Add more CP0 register for save/restore, including: EBase, XContext,
PageGrain, PWBase, PWSize, PWField, PWCtl, Config*, KScratch1~KScratch6.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 target/mips/kvm.c | 212 ++
 target/mips/machine.c |   6 +-
 2 files changed, 216 insertions(+), 2 deletions(-)

diff --git a/target/mips/kvm.c b/target/mips/kvm.c
index de3e26e..96cfa10 100644
--- a/target/mips/kvm.c
+++ b/target/mips/kvm.c
@@ -245,10 +245,16 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U64 | (8 * (_R) + (_S)))
 
 #define KVM_REG_MIPS_CP0_INDEX  MIPS_CP0_32(0, 0)
+#define KVM_REG_MIPS_CP0_RANDOM MIPS_CP0_32(1, 0)
 #define KVM_REG_MIPS_CP0_CONTEXTMIPS_CP0_64(4, 0)
 #define KVM_REG_MIPS_CP0_USERLOCAL  MIPS_CP0_64(4, 2)
 #define KVM_REG_MIPS_CP0_PAGEMASK   MIPS_CP0_32(5, 0)
+#define KVM_REG_MIPS_CP0_PAGEGRAIN  MIPS_CP0_32(5, 1)
+#define KVM_REG_MIPS_CP0_PWBASE MIPS_CP0_64(5, 5)
+#define KVM_REG_MIPS_CP0_PWFIELDMIPS_CP0_64(5, 6)
+#define KVM_REG_MIPS_CP0_PWSIZE MIPS_CP0_64(5, 7)
 #define KVM_REG_MIPS_CP0_WIRED  MIPS_CP0_32(6, 0)
+#define KVM_REG_MIPS_CP0_PWCTL  MIPS_CP0_32(6, 6)
 #define KVM_REG_MIPS_CP0_HWRENA MIPS_CP0_32(7, 0)
 #define KVM_REG_MIPS_CP0_BADVADDR   MIPS_CP0_64(8, 0)
 #define KVM_REG_MIPS_CP0_COUNT  MIPS_CP0_32(9, 0)
@@ -258,13 +264,22 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 #define KVM_REG_MIPS_CP0_CAUSE  MIPS_CP0_32(13, 0)
 #define KVM_REG_MIPS_CP0_EPCMIPS_CP0_64(14, 0)
 #define KVM_REG_MIPS_CP0_PRID   MIPS_CP0_32(15, 0)
+#define KVM_REG_MIPS_CP0_EBASE  MIPS_CP0_64(15, 1)
 #define KVM_REG_MIPS_CP0_CONFIG MIPS_CP0_32(16, 0)
 #define KVM_REG_MIPS_CP0_CONFIG1MIPS_CP0_32(16, 1)
 #define KVM_REG_MIPS_CP0_CONFIG2MIPS_CP0_32(16, 2)
 #define KVM_REG_MIPS_CP0_CONFIG3MIPS_CP0_32(16, 3)
 #define KVM_REG_MIPS_CP0_CONFIG4MIPS_CP0_32(16, 4)
 #define KVM_REG_MIPS_CP0_CONFIG5MIPS_CP0_32(16, 5)
+#define KVM_REG_MIPS_CP0_CONFIG6MIPS_CP0_32(16, 6)
+#define KVM_REG_MIPS_CP0_XCONTEXT   MIPS_CP0_64(20, 0)
 #define KVM_REG_MIPS_CP0_ERROREPC   MIPS_CP0_64(30, 0)
+#define KVM_REG_MIPS_CP0_KSCRATCH1  MIPS_CP0_64(31, 2)
+#define KVM_REG_MIPS_CP0_KSCRATCH2  MIPS_CP0_64(31, 3)
+#define KVM_REG_MIPS_CP0_KSCRATCH3  MIPS_CP0_64(31, 4)
+#define KVM_REG_MIPS_CP0_KSCRATCH4  MIPS_CP0_64(31, 5)
+#define KVM_REG_MIPS_CP0_KSCRATCH5  MIPS_CP0_64(31, 6)
+#define KVM_REG_MIPS_CP0_KSCRATCH6  MIPS_CP0_64(31, 7)
 
 static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
int32_t *addr)
@@ -394,6 +409,29 @@ static inline int kvm_mips_get_one_ureg64(CPUState *cs, 
uint64_t reg_id,
  (1U << CP0C5_UFE) | \
  (1U << CP0C5_FRE) | \
  (1U << CP0C5_UFR))
+#define KVM_REG_MIPS_CP0_CONFIG6_MASK   ((1U << CP0C6_BPPASS) | \
+ (0x3fU << CP0C6_KPOS) | \
+ (1U << CP0C6_KE) | \
+ (1U << CP0C6_VTLBONLY) | \
+ (1U << CP0C6_LASX) | \
+ (1U << CP0C6_SSEN) | \
+ (1U << CP0C6_DISDRTIME) | \
+ (1U << CP0C6_PIXNUEN) | \
+ (1U << CP0C6_SCRAND) | \
+ (1U << CP0C6_LLEXCEN) | \
+ (1U << CP0C6_DISVC) | \
+ (1U << CP0C6_VCLRU) | \
+ (1U << CP0C6_DCLRU) | \
+ (1U << CP0C6_PIXUEN) | \
+ (1U << CP0C6_DISBLKLYEN) | \
+ (1U << CP0C6_UMEMUALEN) | \
+ (1U << CP0C6_SFBEN) | \
+ (1U << CP0C6_FLTINT) | \
+ (1U << CP0C6_VLTINT) | \
+ (1U << CP0C6_DISBTB) | \
+ (3U << CP0C6_STPREFCTL) | \
+ (1U << CP0C6_INSTPREF) | \
+ (1U << CP0C6_DATAPREF))
 
 static inline int kvm_mips_change_one_reg(CPUState *cs, uint64_t reg_id,
   int32_t *addr, int32_t mask)
@@ -729,6 +767,11 

[PATCH for-5.1 V2 6/7] hw/mips: Add Loongson-3 machine support (with KVM)

2020-04-30 Thread Huacai Chen
Add Loongson-3 based machine support, it use i8259 as the interrupt
controler and use GPEX as the pci controller. Currently it can only
work with KVM, but we will add TCG support in future.

We already have a full functional Linux kernel (based on Linux-5.4.x LTS
but not upstream yet) here:

https://github.com/chenhuacai/linux

How to use QEMU/Loongson-3?
1, Download kernel source from the above URL;
2, Build a kernel with arch/mips/configs/loongson3_{def,hpc}config;
3, Boot the a Loongson-3A4000 host with this kernel;
4, Build QEMU-5.0.0 with this patchset;
5, modprobe kvm;
6, Use QEMU with TCG (available in future):
   qemu-system-mips64el -M loongson3,accel=tcg -cpu Loongson-3A1000 -kernel 
 -append ...
   Use QEMU with KVM (available at present):
   qemu-system-mips64el -M loongson3,accel=kvm -cpu Loongson-3A4000 -kernel 
 -append ...

   The "-cpu" parameter can be omitted here and QEMU will use the correct type 
for TCG/KVM automatically.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 default-configs/mips64el-softmmu.mak |   1 +
 hw/mips/Kconfig  |  10 +
 hw/mips/Makefile.objs|   1 +
 hw/mips/mips_loongson3.c | 886 +++
 4 files changed, 898 insertions(+)
 create mode 100644 hw/mips/mips_loongson3.c

diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index 8b0c9b1..fc798e4 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -3,6 +3,7 @@
 include mips-softmmu-common.mak
 CONFIG_IDE_VIA=y
 CONFIG_FULONG=y
+CONFIG_LOONGSON3=y
 CONFIG_ATI_VGA=y
 CONFIG_RTL8139_PCI=y
 CONFIG_JAZZ=y
diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index 2c2adbc..6f16b16 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -44,6 +44,16 @@ config JAZZ
 config FULONG
 bool
 
+config LOONGSON3
+bool
+select PCKBD
+select SERIAL
+select ISA_BUS
+select PCI_EXPRESS_GENERIC_BRIDGE
+select VIRTIO_VGA
+select QXL if SPICE
+select MSI_NONBROKEN
+
 config MIPS_CPS
 bool
 select PTIMER
diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs
index 2f7795b..f9bc8f5 100644
--- a/hw/mips/Makefile.objs
+++ b/hw/mips/Makefile.objs
@@ -4,5 +4,6 @@ obj-$(CONFIG_MALTA) += gt64xxx_pci.o mips_malta.o
 obj-$(CONFIG_MIPSSIM) += mips_mipssim.o
 obj-$(CONFIG_JAZZ) += mips_jazz.o
 obj-$(CONFIG_FULONG) += mips_fulong2e.o
+obj-$(CONFIG_LOONGSON3) += mips_loongson3.o
 obj-$(CONFIG_MIPS_CPS) += cps.o
 obj-$(CONFIG_MIPS_BOSTON) += boston.o
diff --git a/hw/mips/mips_loongson3.c b/hw/mips/mips_loongson3.c
new file mode 100644
index 000..e49ba63
--- /dev/null
+++ b/hw/mips/mips_loongson3.c
@@ -0,0 +1,886 @@
+/*
+ * Generic Loongson-3 Platform support
+ *
+ * Copyright (c) 2015-2020 Huacai Chen (che...@lemote.com)
+ * This code is licensed under the GNU GPL v2.
+ *
+ * Contributions are licensed under the terms of the GNU GPL,
+ * version 2 or (at your option) any later version.
+ */
+
+/*
+ * Generic PC Platform based on Loongson-3 CPU (MIPS64R2 with extensions,
+ * 800~2000MHz)
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "elf.h"
+#include "hw/boards.h"
+#include "hw/char/serial.h"
+#include "hw/mips/mips.h"
+#include "hw/mips/cpudevs.h"
+#include "hw/intc/i8259.h"
+#include "hw/loader.h"
+#include "hw/ide.h"
+#include "hw/isa/superio.h"
+#include "hw/pci/msi.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_host.h"
+#include "hw/pci-host/gpex.h"
+#include "hw/rtc/mc146818rtc.h"
+#include "net/net.h"
+#include "exec/address-spaces.h"
+#include "sysemu/kvm.h"
+#include "sysemu/qtest.h"
+#include "sysemu/reset.h"
+#include "sysemu/runstate.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+
+#define INITRD_OFFSET  0x0400
+#define BOOTPARAM_ADDR 0x8ff0
+#define BOOTPARAM_PHYADDR  0x0ff0
+#define CFG_ADDR   0x0f10
+#define FW_CONF_ADDR   0x0fff
+#define PM_MMIO_ADDR   0x1008
+#define PM_MMIO_SIZE   0x100
+#define PM_CNTL_MODE   0x10
+
+#define PHYS_TO_VIRT(x) ((x) | ~(target_ulong)0x7fff)
+
+/* Loongson-3 has a 2MB flash rom */
+#define BIOS_SIZE   (2 * MiB)
+#define LOONGSON_MAX_VCPUS  16
+
+#define LOONGSON3_BIOSNAME "bios_loongson3.bin"
+
+#define PCIE_IRQ_BASE 3
+
+#define VIRT_PCI_IO_BASE0x1800ul
+#define VIRT_PCI_IO_SIZE0x000cul
+#define VIRT_PCI_MEM_BASE   0x4000ul
+#define VIRT_PCI_MEM_SIZE   0x4000ul
+#define VIRT_PCI_ECAM_BASE  0x1a00ul
+#define VIRT_PCI_ECAM_SIZE  0x0200ul
+
+#define align

[PATCH V3 00/14] KVM: MIPS: Add Loongson-3 support (Host Side)

2020-05-03 Thread Huacai Chen
We are preparing to add KVM support for Loongson-3. VZ extension is
fully supported in Loongson-3A R4+, and we will not care about old CPUs
(at least now). We already have a full functional Linux kernel (based
on Linux-5.4.x LTS) and QEMU (based on 5.0.0-rc2) and their git
repositories are here:

QEMU: https://github.com/chenhuacai/qemu
Kernel: https://github.com/chenhuacai/linux

Of course these two repositories need to be rework and not suitable for
upstream (especially the commits need to be splitted). We show them here
is just to tell others what we have done, and how KVM/Loongson will look
like.

Our plan is make the KVM host side be upstream first, and after that,
we will make the KVM guest side and QEMU emulator be upstream.

V1 -> V2:
1, Remove "mips: define pud_index() regardless of page table folding"
   because it has been applied.
2, Make Loongson-specific code be guarded by CONFIG_CPU_LOONGSON64.

V2 -> V3:
1, Emulate a reduced feature list of CPUCFG.
2, Fix all possible checkpatch.pl errors and warnings.

Xing Li(2):
 KVM: MIPS: Define KVM_ENTRYHI_ASID to cpu_asid_mask(&boot_cpu_data)
 KVM: MIPS: Fix VPN2_MASK definition for variable cpu_vmbits

Huacai Chen(12):
 KVM: MIPS: Increase KVM_MAX_VCPUS and KVM_USER_MEM_SLOTS to 16
 KVM: MIPS: Add EVENTFD support which is needed by VHOST
 KVM: MIPS: Use lddir/ldpte instructions to lookup gpa_mm.pgd
 KVM: MIPS: Introduce and use cpu_guest_has_ldpte
 KVM: MIPS: Use root tlb to control guest's CCA for Loongson-3
 KVM: MIPS: Let indexed cacheops cause guest exit on Loongson-3
 KVM: MIPS: Add more types of virtual interrupts
 KVM: MIPS: Add Loongson-3 Virtual IPI interrupt support
 KVM: MIPS: Add CPUCFG emulation for Loongson-3
 KVM: MIPS: Add CONFIG6 and DIAG registers emulation
 KVM: MIPS: Add more MMIO load/store instructions emulation
 KVM: MIPS: Enable KVM support for Loongson-3

Signed-off-by: Huacai Chen 
---
 arch/mips/Kconfig|   1 +
 arch/mips/include/asm/cpu-features.h |   3 +
 arch/mips/include/asm/kvm_host.h |  52 +++-
 arch/mips/include/asm/mipsregs.h |   7 +
 arch/mips/include/uapi/asm/inst.h|  11 +
 arch/mips/kernel/cpu-probe.c |   2 +
 arch/mips/kvm/Kconfig|   1 +
 arch/mips/kvm/Makefile   |   5 +-
 arch/mips/kvm/emulate.c  | 503 ++-
 arch/mips/kvm/entry.c|  19 +-
 arch/mips/kvm/interrupt.c|  93 +--
 arch/mips/kvm/interrupt.h|  14 +-
 arch/mips/kvm/loongson_ipi.c | 214 +++
 arch/mips/kvm/mips.c |  49 +++-
 arch/mips/kvm/tlb.c  |  41 +++
 arch/mips/kvm/trap_emul.c|   3 +
 arch/mips/kvm/vz.c   | 235 +++-
 17 files changed, 1087 insertions(+), 166 deletions(-)
 create mode 100644 arch/mips/kvm/loongson_ipi.c
--
2.7.0



[PATCH V3 02/14] KVM: MIPS: Fix VPN2_MASK definition for variable cpu_vmbits

2020-05-03 Thread Huacai Chen
From: Xing Li 

If a CPU support more than 32bit vmbits (which is true for 64bit CPUs),
VPN2_MASK set to fixed 0xe000 will lead to a wrong EntryHi in some
functions such as _kvm_mips_host_tlb_inv().

The cpu_vmbits definition of 32bit CPU in cpu-features.h is 31, so we
still use the old definition.

Cc: sta...@vger.kernel.org
Signed-off-by: Xing Li 
[Huacai: Improve commit messages]
Signed-off-by: Huacai Chen 
---
 arch/mips/include/asm/kvm_host.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index a01cee9..caa2b936 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -274,7 +274,11 @@ enum emulation_result {
 #define MIPS3_PG_SHIFT 6
 #define MIPS3_PG_FRAME 0x3fc0
 
+#if defined(CONFIG_64BIT)
+#define VPN2_MASK  GENMASK(cpu_vmbits - 1, 13)
+#else
 #define VPN2_MASK  0xe000
+#endif
 #define KVM_ENTRYHI_ASID   cpu_asid_mask(&boot_cpu_data)
 #define TLB_IS_GLOBAL(x)   ((x).tlb_lo[0] & (x).tlb_lo[1] & ENTRYLO_G)
 #define TLB_VPN2(x)((x).tlb_hi & VPN2_MASK)
-- 
2.7.0




qemu-devel@nongnu.org

2020-05-03 Thread Huacai Chen
From: Xing Li 

The code in decode_config4() of arch/mips/kernel/cpu-probe.c

asid_mask = MIPS_ENTRYHI_ASID;
if (config4 & MIPS_CONF4_AE)
asid_mask |= MIPS_ENTRYHI_ASIDX;
set_cpu_asid_mask(c, asid_mask);

set asid_mask to cpuinfo->asid_mask.

So in order to support variable ASID_MASK, KVM_ENTRYHI_ASID should also
be changed to cpu_asid_mask(&boot_cpu_data).

Cc: sta...@vger.kernel.org
Signed-off-by: Xing Li 
[Huacai: Change current_cpu_data to boot_cpu_data for optimization]
Signed-off-by: Huacai Chen 
---
 arch/mips/include/asm/kvm_host.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 2c343c3..a01cee9 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -275,7 +275,7 @@ enum emulation_result {
 #define MIPS3_PG_FRAME 0x3fc0
 
 #define VPN2_MASK  0xe000
-#define KVM_ENTRYHI_ASID   MIPS_ENTRYHI_ASID
+#define KVM_ENTRYHI_ASID   cpu_asid_mask(&boot_cpu_data)
 #define TLB_IS_GLOBAL(x)   ((x).tlb_lo[0] & (x).tlb_lo[1] & ENTRYLO_G)
 #define TLB_VPN2(x)((x).tlb_hi & VPN2_MASK)
 #define TLB_ASID(x)((x).tlb_hi & KVM_ENTRYHI_ASID)
-- 
2.7.0




[PATCH V3 03/14] KVM: MIPS: Increase KVM_MAX_VCPUS and KVM_USER_MEM_SLOTS to 16

2020-05-03 Thread Huacai Chen
Loongson-3 based machines can have as many as 16 CPUs, and so does
memory slots, so increase KVM_MAX_VCPUS and KVM_USER_MEM_SLOTS to 16.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 arch/mips/include/asm/kvm_host.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index caa2b936..a7758c0 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -78,8 +78,8 @@
 #define KVM_REG_MIPS_CP0_KSCRATCH6 MIPS_CP0_64(31, 7)
 
 
-#define KVM_MAX_VCPUS  8
-#define KVM_USER_MEM_SLOTS 8
+#define KVM_MAX_VCPUS  16
+#define KVM_USER_MEM_SLOTS 16
 /* memory slots that does not exposed to userspace */
 #define KVM_PRIVATE_MEM_SLOTS  0
 
-- 
2.7.0




[PATCH V3 04/14] KVM: MIPS: Add EVENTFD support which is needed by VHOST

2020-05-03 Thread Huacai Chen
Add EVENTFD support for KVM/MIPS, which is needed by VHOST. Tested on
Loongson-3 platform.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 arch/mips/kvm/Kconfig | 1 +
 arch/mips/kvm/Makefile| 2 +-
 arch/mips/kvm/trap_emul.c | 3 +++
 arch/mips/kvm/vz.c| 3 +++
 4 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/mips/kvm/Kconfig b/arch/mips/kvm/Kconfig
index b91d145..d697752 100644
--- a/arch/mips/kvm/Kconfig
+++ b/arch/mips/kvm/Kconfig
@@ -22,6 +22,7 @@ config KVM
select EXPORT_UASM
select PREEMPT_NOTIFIERS
select KVM_GENERIC_DIRTYLOG_READ_PROTECT
+   select HAVE_KVM_EVENTFD
select HAVE_KVM_VCPU_ASYNC_IOCTL
select KVM_MMIO
select MMU_NOTIFIER
diff --git a/arch/mips/kvm/Makefile b/arch/mips/kvm/Makefile
index 01affc1..0a3cef6 100644
--- a/arch/mips/kvm/Makefile
+++ b/arch/mips/kvm/Makefile
@@ -2,7 +2,7 @@
 # Makefile for KVM support for MIPS
 #
 
-common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o)
+common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o 
eventfd.o)
 
 EXTRA_CFLAGS += -Ivirt/kvm -Iarch/mips/kvm
 
diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c
index 5a11e83..f464506b 100644
--- a/arch/mips/kvm/trap_emul.c
+++ b/arch/mips/kvm/trap_emul.c
@@ -529,6 +529,9 @@ static int kvm_trap_emul_check_extension(struct kvm *kvm, 
long ext)
case KVM_CAP_MIPS_TE:
r = 1;
break;
+   case KVM_CAP_IOEVENTFD:
+   r = 1;
+   break;
default:
r = 0;
break;
diff --git a/arch/mips/kvm/vz.c b/arch/mips/kvm/vz.c
index dde2088..17932ab 100644
--- a/arch/mips/kvm/vz.c
+++ b/arch/mips/kvm/vz.c
@@ -2927,6 +2927,9 @@ static int kvm_vz_check_extension(struct kvm *kvm, long 
ext)
r = 2;
break;
 #endif
+   case KVM_CAP_IOEVENTFD:
+   r = 1;
+   break;
default:
r = 0;
break;
-- 
2.7.0




[PATCH V3 05/14] KVM: MIPS: Use lddir/ldpte instructions to lookup gpa_mm.pgd

2020-05-03 Thread Huacai Chen
Loongson-3 can use lddir/ldpte instuctions to accelerate page table
walking, so use them to lookup gpa_mm.pgd.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 arch/mips/kvm/entry.c | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/mips/kvm/entry.c b/arch/mips/kvm/entry.c
index 16e1c93..fd71694 100644
--- a/arch/mips/kvm/entry.c
+++ b/arch/mips/kvm/entry.c
@@ -56,6 +56,7 @@
 #define C0_BADVADDR8, 0
 #define C0_BADINSTR8, 1
 #define C0_BADINSTRP   8, 2
+#define C0_PGD 9, 7
 #define C0_ENTRYHI 10, 0
 #define C0_GUESTCTL1   10, 4
 #define C0_STATUS  12, 0
@@ -307,7 +308,10 @@ static void *kvm_mips_build_enter_guest(void *addr)
 
 #ifdef CONFIG_KVM_MIPS_VZ
/* Save normal linux process pgd (VZ guarantees pgd_reg is set) */
-   UASM_i_MFC0(&p, K0, c0_kscratch(), pgd_reg);
+   if (cpu_has_ldpte)
+   UASM_i_MFC0(&p, K0, C0_PWBASE);
+   else
+   UASM_i_MFC0(&p, K0, c0_kscratch(), pgd_reg);
UASM_i_SW(&p, K0, offsetof(struct kvm_vcpu_arch, host_pgd), K1);
 
/*
@@ -469,8 +473,10 @@ void *kvm_mips_build_tlb_refill_exception(void *addr, void 
*handler)
u32 *p = addr;
struct uasm_label labels[2];
struct uasm_reloc relocs[2];
+#ifndef CONFIG_CPU_LOONGSON64
struct uasm_label *l = labels;
struct uasm_reloc *r = relocs;
+#endif
 
memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs));
@@ -490,6 +496,16 @@ void *kvm_mips_build_tlb_refill_exception(void *addr, void 
*handler)
 */
preempt_disable();
 
+#ifdef CONFIG_CPU_LOONGSON64
+   UASM_i_MFC0(&p, K1, C0_PGD);
+   uasm_i_lddir(&p, K0, K1, 3);  /* global page dir */
+#ifndef __PAGETABLE_PMD_FOLDED
+   uasm_i_lddir(&p, K1, K0, 1);  /* middle page dir */
+#endif
+   uasm_i_ldpte(&p, K1, 0);  /* even */
+   uasm_i_ldpte(&p, K1, 1);  /* odd */
+   uasm_i_tlbwr(&p);
+#else
/*
 * Now for the actual refill bit. A lot of this can be common with the
 * Linux TLB refill handler, however we don't need to handle so many
@@ -512,6 +528,7 @@ void *kvm_mips_build_tlb_refill_exception(void *addr, void 
*handler)
build_get_ptep(&p, K0, K1);
build_update_entries(&p, K0, K1);
build_tlb_write_entry(&p, &l, &r, tlb_random);
+#endif
 
preempt_enable();
 
-- 
2.7.0




[PATCH V3 06/14] KVM: MIPS: Introduce and use cpu_guest_has_ldpte

2020-05-03 Thread Huacai Chen
Loongson-3 has lddir/ldpte instructions and their related CP0 registers
are the same as HTW. So we introduce a cpu_guest_has_ldpte flag and use
it to indicate whether we need to save/restore HTW related CP0 registers
(PWBase, PWSize, PWField and PWCtl).

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 arch/mips/include/asm/cpu-features.h |  3 +++
 arch/mips/kernel/cpu-probe.c |  1 +
 arch/mips/kvm/vz.c   | 26 +-
 3 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/arch/mips/include/asm/cpu-features.h 
b/arch/mips/include/asm/cpu-features.h
index 400b123..e127495 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -659,6 +659,9 @@
 #ifndef cpu_guest_has_htw
 #define cpu_guest_has_htw  (cpu_data[0].guest.options & MIPS_CPU_HTW)
 #endif
+#ifndef cpu_guest_has_ldpte
+#define cpu_guest_has_ldpte(cpu_data[0].guest.options & MIPS_CPU_LDPTE)
+#endif
 #ifndef cpu_guest_has_mvh
 #define cpu_guest_has_mvh  (cpu_data[0].guest.options & MIPS_CPU_MVH)
 #endif
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index ca2e6f1..be1b556 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -2004,6 +2004,7 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips 
*c, unsigned int cpu)
 * register, we correct it here.
 */
c->options |= MIPS_CPU_FTLB | MIPS_CPU_TLBINV | MIPS_CPU_LDPTE;
+   c->guest.options |= MIPS_CPU_LDPTE;
c->writecombine = _CACHE_UNCACHED_ACCELERATED;
c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM |
MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2);
diff --git a/arch/mips/kvm/vz.c b/arch/mips/kvm/vz.c
index 17932ab..422cd06 100644
--- a/arch/mips/kvm/vz.c
+++ b/arch/mips/kvm/vz.c
@@ -1706,7 +1706,7 @@ static unsigned long kvm_vz_num_regs(struct kvm_vcpu 
*vcpu)
ret += ARRAY_SIZE(kvm_vz_get_one_regs_contextconfig);
if (cpu_guest_has_segments)
ret += ARRAY_SIZE(kvm_vz_get_one_regs_segments);
-   if (cpu_guest_has_htw)
+   if (cpu_guest_has_htw || cpu_guest_has_ldpte)
ret += ARRAY_SIZE(kvm_vz_get_one_regs_htw);
if (cpu_guest_has_maar && !cpu_guest_has_dyn_maar)
ret += 1 + ARRAY_SIZE(vcpu->arch.maar);
@@ -1755,7 +1755,7 @@ static int kvm_vz_copy_reg_indices(struct kvm_vcpu *vcpu, 
u64 __user *indices)
return -EFAULT;
indices += ARRAY_SIZE(kvm_vz_get_one_regs_segments);
}
-   if (cpu_guest_has_htw) {
+   if (cpu_guest_has_htw || cpu_guest_has_ldpte) {
if (copy_to_user(indices, kvm_vz_get_one_regs_htw,
 sizeof(kvm_vz_get_one_regs_htw)))
return -EFAULT;
@@ -1878,17 +1878,17 @@ static int kvm_vz_get_one_reg(struct kvm_vcpu *vcpu,
*v = read_gc0_segctl2();
break;
case KVM_REG_MIPS_CP0_PWBASE:
-   if (!cpu_guest_has_htw)
+   if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL;
*v = read_gc0_pwbase();
break;
case KVM_REG_MIPS_CP0_PWFIELD:
-   if (!cpu_guest_has_htw)
+   if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL;
*v = read_gc0_pwfield();
break;
case KVM_REG_MIPS_CP0_PWSIZE:
-   if (!cpu_guest_has_htw)
+   if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL;
*v = read_gc0_pwsize();
break;
@@ -1896,7 +1896,7 @@ static int kvm_vz_get_one_reg(struct kvm_vcpu *vcpu,
*v = (long)read_gc0_wired();
break;
case KVM_REG_MIPS_CP0_PWCTL:
-   if (!cpu_guest_has_htw)
+   if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL;
*v = read_gc0_pwctl();
break;
@@ -2101,17 +2101,17 @@ static int kvm_vz_set_one_reg(struct kvm_vcpu *vcpu,
write_gc0_segctl2(v);
break;
case KVM_REG_MIPS_CP0_PWBASE:
-   if (!cpu_guest_has_htw)
+   if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL;
write_gc0_pwbase(v);
break;
case KVM_REG_MIPS_CP0_PWFIELD:
-   if (!cpu_guest_has_htw)
+   if (!cpu_guest_has_htw && !cpu_guest_has_ldpte)
return -EINVAL;
write_gc0_pwfield(v);
break;
case KVM_REG_MIPS_CP0_PWSIZE:
-   if (!cpu_guest_has_htw)
+   if 

[PATCH V3 07/14] KVM: MIPS: Use root tlb to control guest's CCA for Loongson-3

2020-05-03 Thread Huacai Chen
KVM guest has two levels of address translation: guest tlb translates
GVA to GPA, and root tlb translates GPA to HPA. By default guest's CCA
is controlled by guest tlb, but Loongson-3 maintains all cache coherency
by hardware (including multi-core coherency and I/O DMA coherency) so it
prefers all guest mappings be cacheable mappings. Thus, we use root tlb
to control guest's CCA for Loongson-3.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 arch/mips/kvm/vz.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/mips/kvm/vz.c b/arch/mips/kvm/vz.c
index 422cd06..f9fbbc16 100644
--- a/arch/mips/kvm/vz.c
+++ b/arch/mips/kvm/vz.c
@@ -2871,6 +2871,12 @@ static int kvm_vz_hardware_enable(void)
if (cpu_has_guestctl2)
clear_c0_guestctl2(0x3f << 10);
 
+#ifdef CONFIG_CPU_LOONGSON64
+   /* Control guest CCA attribute */
+   if (cpu_has_csr())
+   csr_writel(csr_readl(0xffec) | 0x1, 0xffec);
+#endif
+
return 0;
 }
 
-- 
2.7.0




[PATCH V3 08/14] KVM: MIPS: Let indexed cacheops cause guest exit on Loongson-3

2020-05-03 Thread Huacai Chen
Loongson-3's indexed cache operations need a node-id in the address,
but in KVM guest the node-id may be incorrect. So, let indexed cache
operations cause guest exit on Loongson-3.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 arch/mips/kvm/vz.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/mips/kvm/vz.c b/arch/mips/kvm/vz.c
index f9fbbc16..ab320f0 100644
--- a/arch/mips/kvm/vz.c
+++ b/arch/mips/kvm/vz.c
@@ -2853,8 +2853,12 @@ static int kvm_vz_hardware_enable(void)
write_c0_guestctl0(MIPS_GCTL0_CP0 |
   (MIPS_GCTL0_AT_GUEST << MIPS_GCTL0_AT_SHIFT) |
   MIPS_GCTL0_CG | MIPS_GCTL0_CF);
-   if (cpu_has_guestctl0ext)
-   set_c0_guestctl0ext(MIPS_GCTL0EXT_CGI);
+   if (cpu_has_guestctl0ext) {
+   if (current_cpu_type() != CPU_LOONGSON64)
+   set_c0_guestctl0ext(MIPS_GCTL0EXT_CGI);
+   else
+   clear_c0_guestctl0ext(MIPS_GCTL0EXT_CGI);
+   }
 
if (cpu_has_guestid) {
write_c0_guestctl1(0);
-- 
2.7.0




[PATCH V3 10/14] KVM: MIPS: Add Loongson-3 Virtual IPI interrupt support

2020-05-03 Thread Huacai Chen
This patch add Loongson-3 Virtual IPI interrupt support in the kernel,
because emulate it in QEMU is too expensive for performance.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 arch/mips/include/asm/kvm_host.h |  32 ++
 arch/mips/kvm/Makefile   |   3 +
 arch/mips/kvm/emulate.c  |  23 -
 arch/mips/kvm/loongson_ipi.c | 214 +++
 arch/mips/kvm/mips.c |   6 ++
 5 files changed, 277 insertions(+), 1 deletion(-)
 create mode 100644 arch/mips/kvm/loongson_ipi.c

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index a7758c0..f165902 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -23,6 +23,8 @@
 #include 
 #include 
 
+#include 
+
 /* MIPS KVM register ids */
 #define MIPS_CP0_32(_R, _S)\
(KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U32 | (8 * (_R) + (_S)))
@@ -181,11 +183,39 @@ struct kvm_vcpu_stat {
 struct kvm_arch_memory_slot {
 };
 
+#ifdef CONFIG_CPU_LOONGSON64
+struct ipi_state {
+   uint32_t status;
+   uint32_t en;
+   uint32_t set;
+   uint32_t clear;
+   uint64_t buf[4];
+};
+
+struct loongson_kvm_ipi;
+
+struct ipi_io_device {
+   int node_id;
+   struct loongson_kvm_ipi *ipi;
+   struct kvm_io_device device;
+};
+
+struct loongson_kvm_ipi {
+   spinlock_t lock;
+   struct kvm *kvm;
+   struct ipi_state ipistate[16];
+   struct ipi_io_device dev_ipi[4];
+};
+#endif
+
 struct kvm_arch {
/* Guest physical mm */
struct mm_struct gpa_mm;
/* Mask of CPUs needing GPA ASID flush */
cpumask_t asid_flush_mask;
+#ifdef CONFIG_CPU_LOONGSON64
+   struct loongson_kvm_ipi ipi;
+#endif
 };
 
 #define N_MIPS_COPROC_REGS 32
@@ -1133,6 +1163,8 @@ extern int kvm_mips_trans_mtc0(union mips_instruction 
inst, u32 *opc,
 /* Misc */
 extern void kvm_mips_dump_stats(struct kvm_vcpu *vcpu);
 extern unsigned long kvm_mips_get_ramsize(struct kvm *kvm);
+extern int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
+struct kvm_mips_interrupt *irq);
 
 static inline void kvm_arch_hardware_unsetup(void) {}
 static inline void kvm_arch_sync_events(struct kvm *kvm) {}
diff --git a/arch/mips/kvm/Makefile b/arch/mips/kvm/Makefile
index 0a3cef6..506c4ac 100644
--- a/arch/mips/kvm/Makefile
+++ b/arch/mips/kvm/Makefile
@@ -13,6 +13,9 @@ kvm-objs := $(common-objs-y) mips.o emulate.o entry.o \
fpu.o
 kvm-objs += hypcall.o
 kvm-objs += mmu.o
+ifdef CONFIG_CPU_LOONGSON64
+kvm-objs += loongson_ipi.o
+endif
 
 ifdef CONFIG_KVM_MIPS_VZ
 kvm-objs   += vz.o
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index 754094b..3946499 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -1600,6 +1600,7 @@ enum emulation_result kvm_mips_emulate_store(union 
mips_instruction inst,
 struct kvm_run *run,
 struct kvm_vcpu *vcpu)
 {
+   int r;
enum emulation_result er;
u32 rt;
void *data = run->mmio.data;
@@ -1666,9 +1667,18 @@ enum emulation_result kvm_mips_emulate_store(union 
mips_instruction inst,
goto out_fail;
}
 
-   run->mmio.is_write = 1;
vcpu->mmio_needed = 1;
+   run->mmio.is_write = 1;
vcpu->mmio_is_write = 1;
+
+   r = kvm_io_bus_write(vcpu, KVM_MMIO_BUS,
+   run->mmio.phys_addr, run->mmio.len, data);
+
+   if (!r) {
+   vcpu->mmio_needed = 0;
+   return EMULATE_DONE;
+   }
+
return EMULATE_DO_MMIO;
 
 out_fail:
@@ -1681,6 +1691,7 @@ enum emulation_result kvm_mips_emulate_load(union 
mips_instruction inst,
u32 cause, struct kvm_run *run,
struct kvm_vcpu *vcpu)
 {
+   int r;
enum emulation_result er;
unsigned long curr_pc;
u32 op, rt;
@@ -1745,6 +1756,16 @@ enum emulation_result kvm_mips_emulate_load(union 
mips_instruction inst,
 
run->mmio.is_write = 0;
vcpu->mmio_is_write = 0;
+
+   r = kvm_io_bus_read(vcpu, KVM_MMIO_BUS,
+   run->mmio.phys_addr, run->mmio.len, run->mmio.data);
+
+   if (!r) {
+   kvm_mips_complete_mmio_load(vcpu, run);
+   vcpu->mmio_needed = 0;
+   return EMULATE_DONE;
+   }
+
return EMULATE_DO_MMIO;
 }
 
diff --git a/arch/mips/kvm/loongson_ipi.c b/arch/mips/kvm/loongson_ipi.c
new file mode 100644
index ..3681fc8
--- /dev/null
+++ b/arch/mips/kvm/loongson_ipi.c
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Loongson-3 Virtual IPI interrupt support.
+ *
+ * Copyright (C) 2019  Loongson Technologies, Inc.  All rights reserved.
+ *
+ * Authors: Chen Zhu 
+ * Authors:

[PATCH V3 09/14] KVM: MIPS: Add more types of virtual interrupts

2020-05-03 Thread Huacai Chen
In current implementation, MIPS KVM uses IP2, IP3, IP4 and IP7 for
external interrupt, two kinds of IPIs and timer interrupt respectively,
but Loongson-3 based machines prefer to use IP2, IP3, IP6 and IP7 for
two kinds of external interrupts, IPI and timer interrupt. So we define
two priority-irq mapping tables: kvm_loongson3_priority_to_irq[] for
Loongson-3, and kvm_default_priority_to_irq[] for others. The virtual
interrupt infrastructure is updated to deliver all types of interrupts
from IP2, IP3, IP4, IP6 and IP7.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 arch/mips/kvm/interrupt.c | 93 +++
 arch/mips/kvm/interrupt.h | 14 ---
 arch/mips/kvm/mips.c  | 40 ++--
 arch/mips/kvm/vz.c| 53 ---
 4 files changed, 67 insertions(+), 133 deletions(-)

diff --git a/arch/mips/kvm/interrupt.c b/arch/mips/kvm/interrupt.c
index 7257e8b6..d28c2c9c 100644
--- a/arch/mips/kvm/interrupt.c
+++ b/arch/mips/kvm/interrupt.c
@@ -61,27 +61,8 @@ void kvm_mips_queue_io_int_cb(struct kvm_vcpu *vcpu,
 * the EXC code will be set when we are actually
 * delivering the interrupt:
 */
-   switch (intr) {
-   case 2:
-   kvm_set_c0_guest_cause(vcpu->arch.cop0, (C_IRQ0));
-   /* Queue up an INT exception for the core */
-   kvm_mips_queue_irq(vcpu, MIPS_EXC_INT_IO);
-   break;
-
-   case 3:
-   kvm_set_c0_guest_cause(vcpu->arch.cop0, (C_IRQ1));
-   kvm_mips_queue_irq(vcpu, MIPS_EXC_INT_IPI_1);
-   break;
-
-   case 4:
-   kvm_set_c0_guest_cause(vcpu->arch.cop0, (C_IRQ2));
-   kvm_mips_queue_irq(vcpu, MIPS_EXC_INT_IPI_2);
-   break;
-
-   default:
-   break;
-   }
-
+   kvm_set_c0_guest_cause(vcpu->arch.cop0, 1 << (intr + 8));
+   kvm_mips_queue_irq(vcpu, kvm_irq_to_priority(intr));
 }
 
 void kvm_mips_dequeue_io_int_cb(struct kvm_vcpu *vcpu,
@@ -89,26 +70,8 @@ void kvm_mips_dequeue_io_int_cb(struct kvm_vcpu *vcpu,
 {
int intr = (int)irq->irq;
 
-   switch (intr) {
-   case -2:
-   kvm_clear_c0_guest_cause(vcpu->arch.cop0, (C_IRQ0));
-   kvm_mips_dequeue_irq(vcpu, MIPS_EXC_INT_IO);
-   break;
-
-   case -3:
-   kvm_clear_c0_guest_cause(vcpu->arch.cop0, (C_IRQ1));
-   kvm_mips_dequeue_irq(vcpu, MIPS_EXC_INT_IPI_1);
-   break;
-
-   case -4:
-   kvm_clear_c0_guest_cause(vcpu->arch.cop0, (C_IRQ2));
-   kvm_mips_dequeue_irq(vcpu, MIPS_EXC_INT_IPI_2);
-   break;
-
-   default:
-   break;
-   }
-
+   kvm_clear_c0_guest_cause(vcpu->arch.cop0, 1 << (-intr + 8));
+   kvm_mips_dequeue_irq(vcpu, kvm_irq_to_priority(-intr));
 }
 
 /* Deliver the interrupt of the corresponding priority, if possible. */
@@ -116,50 +79,20 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, 
unsigned int priority,
u32 cause)
 {
int allowed = 0;
-   u32 exccode;
+   u32 exccode, ie;
 
struct kvm_vcpu_arch *arch = &vcpu->arch;
struct mips_coproc *cop0 = vcpu->arch.cop0;
 
-   switch (priority) {
-   case MIPS_EXC_INT_TIMER:
-   if ((kvm_read_c0_guest_status(cop0) & ST0_IE)
-   && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
-   && (kvm_read_c0_guest_status(cop0) & IE_IRQ5)) {
-   allowed = 1;
-   exccode = EXCCODE_INT;
-   }
-   break;
-
-   case MIPS_EXC_INT_IO:
-   if ((kvm_read_c0_guest_status(cop0) & ST0_IE)
-   && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
-   && (kvm_read_c0_guest_status(cop0) & IE_IRQ0)) {
-   allowed = 1;
-   exccode = EXCCODE_INT;
-   }
-   break;
-
-   case MIPS_EXC_INT_IPI_1:
-   if ((kvm_read_c0_guest_status(cop0) & ST0_IE)
-   && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
-   && (kvm_read_c0_guest_status(cop0) & IE_IRQ1)) {
-   allowed = 1;
-   exccode = EXCCODE_INT;
-   }
-   break;
-
-   case MIPS_EXC_INT_IPI_2:
-   if ((kvm_read_c0_guest_status(cop0) & ST0_IE)
-   && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
-   && (kvm_read_c0_guest_status(cop0) & IE_IRQ2)) {
-   allowed = 1;
-   exccode = EXCCODE_INT;
-   }
-   break;
+   if (priority == MIPS_EXC_MAX)
+   

[PATCH V3 11/14] KVM: MIPS: Add CPUCFG emulation for Loongson-3

2020-05-03 Thread Huacai Chen
Loongson-3 overrides lwc2 instructions to implement CPUCFG and CSR
read/write functions. These instructions all cause guest exit so CSR
doesn't benifit KVM guest (and there are always legacy methods to
provide the same functions as CSR). So, we only emulate CPUCFG and let
it return a reduced feature list (which means the virtual CPU doesn't
have any other advanced features, including CSR) in KVM.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 arch/mips/include/asm/kvm_host.h  |  3 ++
 arch/mips/include/uapi/asm/inst.h | 11 ++
 arch/mips/kvm/mips.c  |  3 ++
 arch/mips/kvm/vz.c| 75 +++
 4 files changed, 92 insertions(+)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index f165902..3fd2f1c 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -173,6 +173,9 @@ struct kvm_vcpu_stat {
u64 vz_ghfc_exits;
u64 vz_gpa_exits;
u64 vz_resvd_exits;
+#ifdef CONFIG_CPU_LOONGSON64
+   u64 vz_cpucfg_exits;
+#endif
 #endif
u64 halt_successful_poll;
u64 halt_attempted_poll;
diff --git a/arch/mips/include/uapi/asm/inst.h 
b/arch/mips/include/uapi/asm/inst.h
index 98f97c8..43d1faa 100644
--- a/arch/mips/include/uapi/asm/inst.h
+++ b/arch/mips/include/uapi/asm/inst.h
@@ -1012,6 +1012,16 @@ struct loongson3_lsdc2_format {  /* Loongson-3 
overridden ldc2/sdc2 Load/Store fo
;))
 };
 
+struct loongson3_lscsr_format {/* Loongson-3 CPUCFG&CSR read/write 
format */
+   __BITFIELD_FIELD(unsigned int opcode : 6,
+   __BITFIELD_FIELD(unsigned int rs : 5,
+   __BITFIELD_FIELD(unsigned int fr : 5,
+   __BITFIELD_FIELD(unsigned int rd : 5,
+   __BITFIELD_FIELD(unsigned int fd : 5,
+   __BITFIELD_FIELD(unsigned int func : 6,
+   ;))
+};
+
 /*
  * MIPS16e instruction formats (16-bit length)
  */
@@ -1114,6 +1124,7 @@ union mips_instruction {
struct mm16_r5_format mm16_r5_format;
struct loongson3_lswc2_format loongson3_lswc2_format;
struct loongson3_lsdc2_format loongson3_lsdc2_format;
+   struct loongson3_lscsr_format loongson3_lscsr_format;
 };
 
 union mips16e_instruction {
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index ed989ef..9362769 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -68,6 +68,9 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
{ "vz_ghfc",  VCPU_STAT(vz_ghfc_exits),  KVM_STAT_VCPU },
{ "vz_gpa",   VCPU_STAT(vz_gpa_exits),   KVM_STAT_VCPU },
{ "vz_resvd", VCPU_STAT(vz_resvd_exits), KVM_STAT_VCPU },
+#ifdef CONFIG_CPU_LOONGSON64
+   { "vz_cpucfg",VCPU_STAT(vz_cpucfg_exits),KVM_STAT_VCPU },
+#endif
 #endif
{ "halt_successful_poll", VCPU_STAT(halt_successful_poll), 
KVM_STAT_VCPU },
{ "halt_attempted_poll", VCPU_STAT(halt_attempted_poll), KVM_STAT_VCPU 
},
diff --git a/arch/mips/kvm/vz.c b/arch/mips/kvm/vz.c
index 63d5b35..e5c751b 100644
--- a/arch/mips/kvm/vz.c
+++ b/arch/mips/kvm/vz.c
@@ -29,6 +29,7 @@
 #include 
 
 #include "interrupt.h"
+#include "loongson_regs.h"
 
 #include "trace.h"
 
@@ -1092,6 +1093,75 @@ static enum emulation_result kvm_vz_gpsi_cache(union 
mips_instruction inst,
return EMULATE_FAIL;
 }
 
+#ifdef CONFIG_CPU_LOONGSON64
+static enum emulation_result kvm_vz_gpsi_lwc2(union mips_instruction inst,
+ u32 *opc, u32 cause,
+ struct kvm_run *run,
+ struct kvm_vcpu *vcpu)
+{
+   unsigned int rs, rd;
+   unsigned int hostcfg;
+   unsigned long curr_pc;
+   enum emulation_result er = EMULATE_DONE;
+
+   /*
+* Update PC and hold onto current PC in case there is
+* an error and we want to rollback the PC
+*/
+   curr_pc = vcpu->arch.pc;
+   er = update_pc(vcpu, cause);
+   if (er == EMULATE_FAIL)
+   return er;
+
+   rs = inst.loongson3_lscsr_format.rs;
+   rd = inst.loongson3_lscsr_format.rd;
+   switch (inst.loongson3_lscsr_format.fr) {
+   case 0x8:  /* Read CPUCFG */
+   ++vcpu->stat.vz_cpucfg_exits;
+   hostcfg = read_cpucfg(vcpu->arch.gprs[rs]);
+
+   switch (vcpu->arch.gprs[rs]) {
+   case LOONGSON_CFG1:
+   hostcfg &= (LOONGSON_CFG1_FP | LOONGSON_CFG1_MMI |
+   LOONGSON_CFG1_MSA1 | LOONGSON_CFG1_MSA2 |
+   LOONGSON_CFG1_SFBP);
+   vcpu->arch.gprs[rd] = hostcfg;
+   break;
+   case LOONGSON_CFG2:
+   hostcfg &= (LOONGSON_CFG2_LEXT1 | LOONGSON_CFG2_LEXT2 |
+

[PATCH V3 12/14] KVM: MIPS: Add CONFIG6 and DIAG registers emulation

2020-05-03 Thread Huacai Chen
Loongson-3 has CONFIG6 and DIAG registers which need to be emulate.
CONFIG6 is mostly used to enable/disable FTLB and SFB, while DIAG is
mostly used to flush BTB, ITLB, DTLB, VTLB and FTLB.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 arch/mips/include/asm/kvm_host.h |  7 +
 arch/mips/include/asm/mipsregs.h |  7 +
 arch/mips/kvm/tlb.c  | 41 ++
 arch/mips/kvm/vz.c   | 62 +++-
 4 files changed, 116 insertions(+), 1 deletion(-)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 3fd2f1c..30b5e33 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -68,9 +68,11 @@
 #define KVM_REG_MIPS_CP0_CONFIG3   MIPS_CP0_32(16, 3)
 #define KVM_REG_MIPS_CP0_CONFIG4   MIPS_CP0_32(16, 4)
 #define KVM_REG_MIPS_CP0_CONFIG5   MIPS_CP0_32(16, 5)
+#define KVM_REG_MIPS_CP0_CONFIG6   MIPS_CP0_32(16, 6)
 #define KVM_REG_MIPS_CP0_CONFIG7   MIPS_CP0_32(16, 7)
 #define KVM_REG_MIPS_CP0_MAARI MIPS_CP0_64(17, 2)
 #define KVM_REG_MIPS_CP0_XCONTEXT  MIPS_CP0_64(20, 0)
+#define KVM_REG_MIPS_CP0_DIAG  MIPS_CP0_32(22, 0)
 #define KVM_REG_MIPS_CP0_ERROREPC  MIPS_CP0_64(30, 0)
 #define KVM_REG_MIPS_CP0_KSCRATCH1 MIPS_CP0_64(31, 2)
 #define KVM_REG_MIPS_CP0_KSCRATCH2 MIPS_CP0_64(31, 3)
@@ -256,6 +258,7 @@ struct mips_coproc {
 #define MIPS_CP0_WATCH_LO  18
 #define MIPS_CP0_WATCH_HI  19
 #define MIPS_CP0_TLB_XCONTEXT  20
+#define MIPS_CP0_DIAG  22
 #define MIPS_CP0_ECC   26
 #define MIPS_CP0_CACHE_ERR 27
 #define MIPS_CP0_TAG_LO28
@@ -927,6 +930,10 @@ void kvm_vz_save_guesttlb(struct kvm_mips_tlb *buf, 
unsigned int index,
  unsigned int count);
 void kvm_vz_load_guesttlb(const struct kvm_mips_tlb *buf, unsigned int index,
  unsigned int count);
+#ifdef CONFIG_CPU_LOONGSON64
+void kvm_loongson_clear_guest_vtlb(void);
+void kvm_loongson_clear_guest_ftlb(void);
+#endif
 #endif
 
 void kvm_mips_suspend_mm(int cpu);
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 796fe47..ce40fbf 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -674,6 +674,9 @@
 #define MIPS_CONF5_CV  (_ULCAST_(1) << 29)
 #define MIPS_CONF5_K   (_ULCAST_(1) << 30)
 
+#define MIPS_CONF6_INTIMER (_ULCAST_(1) << 6)
+#define MIPS_CONF6_EXTIMER (_ULCAST_(1) << 7)
+#define MIPS_CONF6_SFBEN   (_ULCAST_(1) << 8)
 #define MIPS_CONF6_SYND(_ULCAST_(1) << 13)
 /* proAptiv FTLB on/off bit */
 #define MIPS_CONF6_FTLBEN  (_ULCAST_(1) << 15)
@@ -993,6 +996,8 @@
 /* Disable Branch Return Cache */
 #define R10K_DIAG_D_BRC(_ULCAST_(1) << 22)
 
+/* Flush BTB */
+#define LOONGSON_DIAG_BTB  (_ULCAST_(1) << 1)
 /* Flush ITLB */
 #define LOONGSON_DIAG_ITLB (_ULCAST_(1) << 2)
 /* Flush DTLB */
@@ -2825,7 +2830,9 @@ __BUILD_SET_C0(status)
 __BUILD_SET_C0(cause)
 __BUILD_SET_C0(config)
 __BUILD_SET_C0(config5)
+__BUILD_SET_C0(config6)
 __BUILD_SET_C0(config7)
+__BUILD_SET_C0(diag)
 __BUILD_SET_C0(intcontrol)
 __BUILD_SET_C0(intctl)
 __BUILD_SET_C0(srsmap)
diff --git a/arch/mips/kvm/tlb.c b/arch/mips/kvm/tlb.c
index 7cd9216..1418715 100644
--- a/arch/mips/kvm/tlb.c
+++ b/arch/mips/kvm/tlb.c
@@ -20,6 +20,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -622,6 +623,46 @@ void kvm_vz_load_guesttlb(const struct kvm_mips_tlb *buf, 
unsigned int index,
 }
 EXPORT_SYMBOL_GPL(kvm_vz_load_guesttlb);
 
+#ifdef CONFIG_CPU_LOONGSON64
+void kvm_loongson_clear_guest_vtlb(void)
+{
+   int idx = read_gc0_index();
+
+   /* Set root GuestID for root probe and write of guest TLB entry */
+   set_root_gid_to_guest_gid();
+
+   write_gc0_index(0);
+   guest_tlbinvf();
+   write_gc0_index(idx);
+
+   clear_root_gid();
+   set_c0_diag(LOONGSON_DIAG_ITLB | LOONGSON_DIAG_DTLB);
+}
+EXPORT_SYMBOL_GPL(kvm_loongson_clear_guest_vtlb);
+
+void kvm_loongson_clear_guest_ftlb(void)
+{
+   int i;
+   int idx = read_gc0_index();
+
+   /* Set root GuestID for root probe and write of guest TLB entry */
+   set_root_gid_to_guest_gid();
+
+   for (i = current_cpu_data.tlbsizevtlb;
+i < (current_cpu_data.tlbsizevtlb +
+current_cpu_data.tlbsizeftlbsets);
+i++) {
+   write_gc0_index(i);
+   guest_tlbinvf();
+   }
+   write_gc0_index(idx);
+
+   clear_root_gid();
+   set_c0_diag(LOONGSON_DIAG_ITLB | LOONGSON_DIAG_DTLB);
+}
+EXPORT_SYMBOL_GPL(kvm_loongson_clear_guest_ftlb);
+#endif
+
 #endif
 
 /**
diff --git a/arch/mips/kvm/vz.c b/arch/mips/kvm/vz.c
index e5c751b..fc0f8d5 100644
--- a/arch/mips/kvm/vz.c
+++ b/arch/mips/kvm/vz.c
@@ -127,6 +127,11 @@ static inline 

[PATCH V3 14/14] KVM: MIPS: Enable KVM support for Loongson-3

2020-05-03 Thread Huacai Chen
This patch enable KVM support for Loongson-3 by selecting HAVE_KVM, but
only enable KVM/VZ on Loongson-3A R4+ (because VZ of early processors
are incomplete). Besides, Loongson-3 support SMP guests, so we clear the
linked load bit of LLAddr in kvm_vz_vcpu_load() if the guest has more
than one VCPUs.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 arch/mips/Kconfig| 1 +
 arch/mips/kernel/cpu-probe.c | 1 +
 arch/mips/kvm/vz.c   | 2 +-
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 9f15539..9c4bdac 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1470,6 +1470,7 @@ config CPU_LOONGSON64
select MIPS_L1_CACHE_SHIFT_6
select GPIOLIB
select SWIOTLB
+   select HAVE_KVM
help
The Loongson GSx64(GS264/GS464/GS464E/GS464V) series of 
processor
cores implements the MIPS64R2 instruction set with many 
extensions,
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index be1b556..4432442 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -2008,6 +2008,7 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips 
*c, unsigned int cpu)
c->writecombine = _CACHE_UNCACHED_ACCELERATED;
c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM |
MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2);
+   c->ases &= ~MIPS_ASE_VZ; /* VZ of Loongson-3A2000/3000 is 
incomplete */
break;
case PRID_IMP_LOONGSON_64G:
c->cputype = CPU_LOONGSON64;
diff --git a/arch/mips/kvm/vz.c b/arch/mips/kvm/vz.c
index fc0f8d5..5f877a9 100644
--- a/arch/mips/kvm/vz.c
+++ b/arch/mips/kvm/vz.c
@@ -2695,7 +2695,7 @@ static int kvm_vz_vcpu_load(struct kvm_vcpu *vcpu, int 
cpu)
 * prevents a SC on the next VCPU from succeeding by matching a LL on
 * the previous VCPU.
 */
-   if (cpu_guest_has_rw_llb)
+   if (vcpu->kvm->created_vcpus > 1)
write_gc0_lladdr(0);
 
return 0;
-- 
2.7.0




[PATCH V3 13/14] KVM: MIPS: Add more MMIO load/store instructions emulation

2020-05-03 Thread Huacai Chen
This patch add more MMIO load/store instructions emulation, which can
be observed in QXL and some other device drivers:

1, LWL, LWR, LDW, LDR, SWL, SWR, SDL and SDR for all MIPS;
2, GSLBX, GSLHX, GSLWX, GSLDX, GSSBX, GSSHX, GSSWX and GSSDX for
   Loongson-3.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 arch/mips/kvm/emulate.c | 480 +++-
 1 file changed, 470 insertions(+), 10 deletions(-)

diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index 3946499..71316fa 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -1604,6 +1604,7 @@ enum emulation_result kvm_mips_emulate_store(union 
mips_instruction inst,
enum emulation_result er;
u32 rt;
void *data = run->mmio.data;
+   unsigned int imme;
unsigned long curr_pc;
 
/*
@@ -1661,6 +1662,211 @@ enum emulation_result kvm_mips_emulate_store(union 
mips_instruction inst,
  vcpu->arch.gprs[rt], *(u8 *)data);
break;
 
+   case swl_op:
+   run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa(
+   vcpu->arch.host_cp0_badvaddr) & (~0x3);
+   run->mmio.len = 4;
+   imme = vcpu->arch.host_cp0_badvaddr & 0x3;
+   switch (imme) {
+   case 0:
+   *(u32 *)data = ((*(u32 *)data) & 0xff00) |
+   (vcpu->arch.gprs[rt] >> 24);
+   break;
+   case 1:
+   *(u32 *)data = ((*(u32 *)data) & 0x) |
+   (vcpu->arch.gprs[rt] >> 16);
+   break;
+   case 2:
+   *(u32 *)data = ((*(u32 *)data) & 0xff00) |
+   (vcpu->arch.gprs[rt] >> 8);
+   break;
+   case 3:
+   *(u32 *)data = vcpu->arch.gprs[rt];
+   break;
+   default:
+   break;
+   }
+
+   kvm_debug("[%#lx] OP_SWL: eaddr: %#lx, gpr: %#lx, data: %#x\n",
+ vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr,
+ vcpu->arch.gprs[rt], *(u32 *)data);
+   break;
+
+   case swr_op:
+   run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa(
+   vcpu->arch.host_cp0_badvaddr) & (~0x3);
+   run->mmio.len = 4;
+   imme = vcpu->arch.host_cp0_badvaddr & 0x3;
+   switch (imme) {
+   case 0:
+   *(u32 *)data = vcpu->arch.gprs[rt];
+   break;
+   case 1:
+   *(u32 *)data = ((*(u32 *)data) & 0xff) |
+   (vcpu->arch.gprs[rt] << 8);
+   break;
+   case 2:
+   *(u32 *)data = ((*(u32 *)data) & 0x) |
+   (vcpu->arch.gprs[rt] << 16);
+   break;
+   case 3:
+   *(u32 *)data = ((*(u32 *)data) & 0xff) |
+   (vcpu->arch.gprs[rt] << 24);
+   break;
+   default:
+   break;
+   }
+
+   kvm_debug("[%#lx] OP_SWR: eaddr: %#lx, gpr: %#lx, data: %#x\n",
+ vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr,
+ vcpu->arch.gprs[rt], *(u32 *)data);
+   break;
+
+   case sdl_op:
+   run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa(
+   vcpu->arch.host_cp0_badvaddr) & (~0x7);
+
+   run->mmio.len = 8;
+   imme = vcpu->arch.host_cp0_badvaddr & 0x7;
+   switch (imme) {
+   case 0:
+   *(u64 *)data = ((*(u64 *)data) & 0xff00) |
+   ((vcpu->arch.gprs[rt] >> 56) & 0xff);
+   break;
+   case 1:
+   *(u64 *)data = ((*(u64 *)data) & 0x) |
+   ((vcpu->arch.gprs[rt] >> 48) & 0x);
+   break;
+   case 2:
+   *(u64 *)data = ((*(u64 *)data) & 0xff00) |
+   ((vcpu->arch.gprs[rt] >> 40) & 
0xff);
+   break;
+   case 3:
+   *(u64 *)data = ((*(u64 *)data) & 0x) |
+ 

[PATCH for-5.1 V3 0/7] mips: Add Loongson-3 machine support (with KVM)

2020-05-03 Thread Huacai Chen
Loongson-3 CPU family include Loongson-3A R1/R2/R3/R4 and Loongson-3B
R1/R2. Loongson-3A R1 is the oldest and its ISA is the smallest, while
Loongson-3A R4 is the newest and its ISA is almost the superset of all
others. To reduce complexity, in QEMU we just define two CPU types:

1, "Loongson-3A1000" CPU which is corresponding to Loongson-3A R1. It is
   suitable for TCG because Loongson-3A R1 has fewest ASE.
2, "Loongson-3A4000" CPU which is corresponding to Loongson-3A R4. It is
   suitable for KVM because Loongson-3A R4 has the VZ ASE.

Loongson-3 lacks English documents. I've tried to translated them with
translate.google.com, and the machine translated documents (together
with their original Chinese versions) are available here.

Loongson-3A R1 (Loongson-3A1000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A1000_p1.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A1000_processor_user_manual_P1.pdf 
(Chinese Version)
User Manual Part 2:
http://ftp.godson.ac.cn/lemote/3A1000_p2.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A1000_processor_user_manual_P2.pdf 
(Chinese Version)

Loongson-3A R2 (Loongson-3A2000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A2000_p1.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A2000_user1.pdf (Chinese Version)
User Manual Part 2:
http://ftp.godson.ac.cn/lemote/3A2000_p2.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A2000_user2.pdf (Chinese Version)

Loongson-3A R3 (Loongson-3A3000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A3000_p1.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A3000_3B3000usermanual1.pdf (Chinese 
Version)
User Manual Part 2:
http://ftp.godson.ac.cn/lemote/3A3000_p2.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A3000_3B3000usermanual2.pdf (Chinese 
Version)

Loongson-3A R4 (Loongson-3A4000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A4000_p1.pdf
http://ftp.godson.ac.cn/lemote/3A4000user.pdf (Chinese Version)
User Manual Part 2:
I'm sorry that it is unavailable now.

We are preparing to add QEMU's Loongson-3 support. MIPS VZ extension is
fully supported in Loongson-3A R4+, so we at first add QEMU/KVM support
in this series. And the next series will add QEMU/TCG support (it will
emulate Loongson-3A R1).

We already have a full functional Linux kernel (based on Linux-5.4.x LTS
but not upstream yet) here:

https://github.com/chenhuacai/linux

How to use QEMU/Loongson-3?
1, Download kernel source from the above URL;
2, Build a kernel with arch/mips/configs/loongson3_{def,hpc}config;
3, Boot a Loongson-3A4000 host with this kernel;
4, Build QEMU-5.0.0 with this patchset;
5, modprobe kvm;
6, Use QEMU with TCG (available in future):
   qemu-system-mips64el -M loongson3,accel=tcg -cpu Loongson-3A1000 -kernel 
 -append ... 
   Use QEMU with KVM (available at present): 
   qemu-system-mips64el -M loongson3,accel=kvm -cpu Loongson-3A4000 -kernel 
 -append ... 

   The "-cpu" parameter can be omitted here and QEMU will use the correct type 
for TCG/KVM automatically.

V1 -> V2:
1, Add a cover letter;
2, Improve CPU definitions;
3, Remove LS7A-related things (Use GPEX instead);
4, Add a description of how to run QEMU/Loongson-3.

V2 -> V3:
1, Fix all possible checkpatch.pl errors and warnings.

Huacai Chen(7):
 configure: Add KVM target support for MIPS64
 hw/mips: Implement the kvm_type() hook in MachineClass
 hw/mips: Add CPU IRQ3 delivery for KVM
 target/mips: Add Loongson-3 CPU definition
 target/mips: Add more CP0 register for save/restor
 hw/mips: Add Loongson-3 machine support (with KVM)
 MAINTAINERS: Add myself as Loongson-3 maintainer

Signed-off-by: Huacai Chen 
---
 MAINTAINERS  |   5 +
 configure|   2 +-
 default-configs/mips64el-softmmu.mak |   1 +
 hw/core/Makefile.objs|   2 +-
 hw/core/null-machine.c   |   4 +
 hw/mips/Kconfig  |  10 +
 hw/mips/Makefile.objs|   3 +-
 hw/mips/common.c |  31 ++
 hw/mips/mips_int.c   |   4 +-
 hw/mips/mips_loongson3.c | 901 +++
 include/hw/mips/mips.h   |   3 +
 target/mips/cpu.h|  28 ++
 target/mips/internal.h   |   2 +
 target/mips/kvm.c| 212 +
 target/mips/machine.c|   6 +-
 target/mips/mips-defs.h  |   7 +-
 target/mips/translate.c  |   2 +
 target/mips/translate_init.inc.c |  86 
 18 files changed, 1300 insertions(+), 9 deletions(-)
 create mode 100644 hw/mips/common.c
 create mode 100644 hw/mips/mips_loongson3.c
--
2.7.0



[PATCH for-5.1 V3 1/7] configure: Add KVM target support for MIPS64

2020-05-03 Thread Huacai Chen
Preparing for Loongson-3 virtualization, add KVM target support for
MIPS64 in configure script.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 configure | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure b/configure
index 23b5e93..7581e65 100755
--- a/configure
+++ b/configure
@@ -198,7 +198,7 @@ supported_kvm_target() {
 arm:arm | aarch64:aarch64 | \
 i386:i386 | i386:x86_64 | i386:x32 | \
 x86_64:i386 | x86_64:x86_64 | x86_64:x32 | \
-mips:mips | mipsel:mips | \
+mips:mips | mipsel:mips | mips64:mips | mips64el:mips | \
 ppc:ppc | ppc64:ppc | ppc:ppc64 | ppc64:ppc64 | ppc64:ppc64le | \
 s390x:s390x)
 return 0
-- 
2.7.0




[PATCH for-5.1 V3 2/7] hw/mips: Implement the kvm_type() hook in MachineClass

2020-05-03 Thread Huacai Chen
MIPS has two types of KVM: TE & VZ, and TE is the default type. Now we
can't create a VZ guest in QEMU because it lacks the kvm_type() hook in
MachineClass. Besides, libvirt uses a null-machine to detect the kvm
capability, so by default it will return "KVM not supported" on a VZ
platform. Thus, null-machine also need the kvm_type() hook.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 hw/core/Makefile.objs  |  2 +-
 hw/core/null-machine.c |  4 
 hw/mips/Makefile.objs  |  2 +-
 hw/mips/common.c   | 31 +++
 include/hw/mips/mips.h |  3 +++
 5 files changed, 40 insertions(+), 2 deletions(-)
 create mode 100644 hw/mips/common.c

diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index 1d540ed..b5672f4 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -17,11 +17,11 @@ common-obj-$(CONFIG_SOFTMMU) += vm-change-state-handler.o
 common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
 common-obj-$(CONFIG_SOFTMMU) += sysbus.o
 common-obj-$(CONFIG_SOFTMMU) += machine.o
-common-obj-$(CONFIG_SOFTMMU) += null-machine.o
 common-obj-$(CONFIG_SOFTMMU) += loader.o
 common-obj-$(CONFIG_SOFTMMU) += machine-hmp-cmds.o
 common-obj-$(CONFIG_SOFTMMU) += numa.o
 common-obj-$(CONFIG_SOFTMMU) += clock-vmstate.o
+obj-$(CONFIG_SOFTMMU) += null-machine.o
 obj-$(CONFIG_SOFTMMU) += machine-qmp-cmds.o
 
 common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c
index cb47d9d..94a36f9 100644
--- a/hw/core/null-machine.c
+++ b/hw/core/null-machine.c
@@ -17,6 +17,7 @@
 #include "sysemu/sysemu.h"
 #include "exec/address-spaces.h"
 #include "hw/core/cpu.h"
+#include "hw/mips/mips.h"
 
 static void machine_none_init(MachineState *mch)
 {
@@ -50,6 +51,9 @@ static void machine_none_machine_init(MachineClass *mc)
 mc->max_cpus = 1;
 mc->default_ram_size = 0;
 mc->default_ram_id = "ram";
+#ifdef TARGET_MIPS
+mc->kvm_type = mips_kvm_type;
+#endif
 }
 
 DEFINE_MACHINE("none", machine_none_machine_init)
diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs
index 525809a..2f7795b 100644
--- a/hw/mips/Makefile.objs
+++ b/hw/mips/Makefile.objs
@@ -1,4 +1,4 @@
-obj-y += addr.o mips_int.o
+obj-y += addr.o common.o mips_int.o
 obj-$(CONFIG_R4K) += mips_r4k.o
 obj-$(CONFIG_MALTA) += gt64xxx_pci.o mips_malta.o
 obj-$(CONFIG_MIPSSIM) += mips_mipssim.o
diff --git a/hw/mips/common.c b/hw/mips/common.c
new file mode 100644
index 000..0e33bd0
--- /dev/null
+++ b/hw/mips/common.c
@@ -0,0 +1,31 @@
+/*
+ * Common MIPS routines
+ *
+ * Copyright (c) 2020 Huacai Chen (che...@lemote.com)
+ * This code is licensed under the GNU GPL v2.
+ */
+
+#include 
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/boards.h"
+#include "hw/mips/mips.h"
+#include "sysemu/kvm_int.h"
+
+int mips_kvm_type(MachineState *machine, const char *vm_type)
+{
+int r;
+KVMState *s = KVM_STATE(machine->accelerator);
+
+r = kvm_check_extension(s, KVM_CAP_MIPS_VZ);
+if (r > 0) {
+return KVM_VM_MIPS_VZ;
+}
+
+r = kvm_check_extension(s, KVM_CAP_MIPS_TE);
+if (r > 0) {
+return KVM_VM_MIPS_TE;
+}
+
+return -1;
+}
diff --git a/include/hw/mips/mips.h b/include/hw/mips/mips.h
index 0af4c3d..2ac0580 100644
--- a/include/hw/mips/mips.h
+++ b/include/hw/mips/mips.h
@@ -20,4 +20,7 @@ void rc4030_dma_write(void *dma, uint8_t *buf, int len);
 
 DeviceState *rc4030_init(rc4030_dma **dmas, IOMMUMemoryRegion **dma_mr);
 
+/* common.c */
+int mips_kvm_type(MachineState *machine, const char *vm_type);
+
 #endif
-- 
2.7.0




[PATCH for-5.1 V3 3/7] hw/mips: Add CPU IRQ3 delivery for KVM

2020-05-03 Thread Huacai Chen
Currently, KVM/MIPS only deliver I/O interrupt via IP2, this patch add
IP3 delivery as well, because Loongson-3 based machine use both IRQ2
(CPU's IP2) and IRQ3 (CPU's IP3).

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 hw/mips/mips_int.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/mips/mips_int.c b/hw/mips/mips_int.c
index 796730b..982ce34 100644
--- a/hw/mips/mips_int.c
+++ b/hw/mips/mips_int.c
@@ -48,14 +48,14 @@ static void cpu_mips_irq_request(void *opaque, int irq, int 
level)
 if (level) {
 env->CP0_Cause |= 1 << (irq + CP0Ca_IP);
 
-if (kvm_enabled() && irq == 2) {
+if (kvm_enabled() && (irq == 2 || irq == 3)) {
 kvm_mips_set_interrupt(cpu, irq, level);
 }
 
 } else {
 env->CP0_Cause &= ~(1 << (irq + CP0Ca_IP));
 
-if (kvm_enabled() && irq == 2) {
+if (kvm_enabled() && (irq == 2 || irq == 3)) {
 kvm_mips_set_interrupt(cpu, irq, level);
 }
 }
-- 
2.7.0




[PATCH for-5.1 V3 6/7] hw/mips: Add Loongson-3 machine support (with KVM)

2020-05-03 Thread Huacai Chen
Add Loongson-3 based machine support, it use i8259 as the interrupt
controler and use GPEX as the pci controller. Currently it can only
work with KVM, but we will add TCG support in future.

We already have a full functional Linux kernel (based on Linux-5.4.x LTS
but not upstream yet) here:

https://github.com/chenhuacai/linux

How to use QEMU/Loongson-3?
1, Download kernel source from the above URL;
2, Build a kernel with arch/mips/configs/loongson3_{def,hpc}config;
3, Boot the a Loongson-3A4000 host with this kernel;
4, Build QEMU-5.0.0 with this patchset;
5, modprobe kvm;
6, Use QEMU with TCG (available in future):
   qemu-system-mips64el -M loongson3,accel=tcg -cpu Loongson-3A1000 -kernel 
 -append ...
   Use QEMU with KVM (available at present):
   qemu-system-mips64el -M loongson3,accel=kvm -cpu Loongson-3A4000 -kernel 
 -append ...

   The "-cpu" parameter can be omitted here and QEMU will use the correct type 
for TCG/KVM automatically.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 default-configs/mips64el-softmmu.mak |   1 +
 hw/mips/Kconfig  |  10 +
 hw/mips/Makefile.objs|   1 +
 hw/mips/mips_loongson3.c | 901 +++
 4 files changed, 913 insertions(+)
 create mode 100644 hw/mips/mips_loongson3.c

diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index 8b0c9b1..fc798e4 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -3,6 +3,7 @@
 include mips-softmmu-common.mak
 CONFIG_IDE_VIA=y
 CONFIG_FULONG=y
+CONFIG_LOONGSON3=y
 CONFIG_ATI_VGA=y
 CONFIG_RTL8139_PCI=y
 CONFIG_JAZZ=y
diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index 2c2adbc..6f16b16 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -44,6 +44,16 @@ config JAZZ
 config FULONG
 bool
 
+config LOONGSON3
+bool
+select PCKBD
+select SERIAL
+select ISA_BUS
+select PCI_EXPRESS_GENERIC_BRIDGE
+select VIRTIO_VGA
+select QXL if SPICE
+select MSI_NONBROKEN
+
 config MIPS_CPS
 bool
 select PTIMER
diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs
index 2f7795b..f9bc8f5 100644
--- a/hw/mips/Makefile.objs
+++ b/hw/mips/Makefile.objs
@@ -4,5 +4,6 @@ obj-$(CONFIG_MALTA) += gt64xxx_pci.o mips_malta.o
 obj-$(CONFIG_MIPSSIM) += mips_mipssim.o
 obj-$(CONFIG_JAZZ) += mips_jazz.o
 obj-$(CONFIG_FULONG) += mips_fulong2e.o
+obj-$(CONFIG_LOONGSON3) += mips_loongson3.o
 obj-$(CONFIG_MIPS_CPS) += cps.o
 obj-$(CONFIG_MIPS_BOSTON) += boston.o
diff --git a/hw/mips/mips_loongson3.c b/hw/mips/mips_loongson3.c
new file mode 100644
index 000..3294a67
--- /dev/null
+++ b/hw/mips/mips_loongson3.c
@@ -0,0 +1,901 @@
+/*
+ * Generic Loongson-3 Platform support
+ *
+ * Copyright (c) 2015-2020 Huacai Chen (che...@lemote.com)
+ * This code is licensed under the GNU GPL v2.
+ *
+ * Contributions are licensed under the terms of the GNU GPL,
+ * version 2 or (at your option) any later version.
+ */
+
+/*
+ * Generic PC Platform based on Loongson-3 CPU (MIPS64R2 with extensions,
+ * 800~2000MHz)
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "elf.h"
+#include "hw/boards.h"
+#include "hw/char/serial.h"
+#include "hw/mips/mips.h"
+#include "hw/mips/cpudevs.h"
+#include "hw/intc/i8259.h"
+#include "hw/loader.h"
+#include "hw/ide.h"
+#include "hw/isa/superio.h"
+#include "hw/pci/msi.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_host.h"
+#include "hw/pci-host/gpex.h"
+#include "hw/rtc/mc146818rtc.h"
+#include "net/net.h"
+#include "exec/address-spaces.h"
+#include "sysemu/kvm.h"
+#include "sysemu/qtest.h"
+#include "sysemu/reset.h"
+#include "sysemu/runstate.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+
+#define INITRD_OFFSET 0x0400
+#define BOOTPARAM_ADDR0x8ff0
+#define BOOTPARAM_PHYADDR 0x0ff0
+#define CFG_ADDR  0x0f10
+#define FW_CONF_ADDR  0x0fff
+#define PM_MMIO_ADDR  0x1008
+#define PM_MMIO_SIZE  0x100
+#define PM_CNTL_MODE  0x10
+
+#define PHYS_TO_VIRT(x) ((x) | ~(target_ulong)0x7fff)
+
+/* Loongson-3 has a 2MB flash rom */
+#define BIOS_SIZE   (2 * MiB)
+#define LOONGSON_MAX_VCPUS  16
+
+#define LOONGSON3_BIOSNAME "bios_loongson3.bin"
+
+#define PCIE_IRQ_BASE   3
+
+#define VIRT_PCI_IO_BASE0x1800ul
+#define VIRT_PCI_IO_SIZE0x000cul
+#define VIRT_PCI_MEM_BASE   0x4000ul
+#define VIRT_PCI_MEM_SIZE   0x4000ul
+#define VIRT_PCI_ECAM_BASE  0x1a00ul
+#define VIRT_PCI_ECAM_SIZE  0x0200ul
+
+#define align

[PATCH for-5.1 V3 4/7] target/mips: Add Loongson-3 CPU definition

2020-05-03 Thread Huacai Chen
Loongson-3 CPU family include Loongson-3A R1/R2/R3/R4 and Loongson-3B
R1/R2. Loongson-3A R1 is the oldest and its ISA is the smallest, while
Loongson-3A R4 is the newest and its ISA is almost the superset of all
others. To reduce complexity, we just define two CPU types:
1, "Loongson-3A1000" CPU which is corresponding to Loongson-3A R1. It is
   suitable for TCG because Loongson-3A R1 has fewest ASE.
2, "Loongson-3A4000" CPU which is corresponding to Loongson-3A R4. It is
   suitable for KVM because Loongson-3A R4 has the VZ ASE.

Loongson-3A has CONFIG6 and CONFIG7, so add their bit-fields as well.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 target/mips/cpu.h| 28 +
 target/mips/internal.h   |  2 +
 target/mips/mips-defs.h  |  7 +++-
 target/mips/translate.c  |  2 +
 target/mips/translate_init.inc.c | 86 
 5 files changed, 123 insertions(+), 2 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 94d01ea..0b3c987 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -940,7 +940,35 @@ struct CPUMIPSState {
 #define CP0C5_UFR  2
 #define CP0C5_NFExists 0
 int32_t CP0_Config6;
+int32_t CP0_Config6_rw_bitmask;
+#define CP0C6_BPPASS  31
+#define CP0C6_KPOS24
+#define CP0C6_KE  23
+#define CP0C6_VTLBONLY22
+#define CP0C6_LASX21
+#define CP0C6_SSEN20
+#define CP0C6_DISDRTIME   19
+#define CP0C6_PIXNUEN 18
+#define CP0C6_SCRAND  17
+#define CP0C6_LLEXCEN 16
+#define CP0C6_DISVC   15
+#define CP0C6_VCLRU   14
+#define CP0C6_DCLRU   13
+#define CP0C6_PIXUEN  12
+#define CP0C6_DISBLKLYEN  11
+#define CP0C6_UMEMUALEN   10
+#define CP0C6_SFBEN   8
+#define CP0C6_FLTINT  7
+#define CP0C6_VLTINT  6
+#define CP0C6_DISBTB  5
+#define CP0C6_STPREFCTL   2
+#define CP0C6_INSTPREF1
+#define CP0C6_DATAPREF0
 int32_t CP0_Config7;
+int64_t CP0_Config7_rw_bitmask;
+#define CP0C7_NAPCGEN   2
+#define CP0C7_UNIMUEN   1
+#define CP0C7_VFPUCGEN  0
 uint64_t CP0_LLAddr;
 uint64_t CP0_MAAR[MIPS_MAAR_MAX];
 int32_t CP0_MAARI;
diff --git a/target/mips/internal.h b/target/mips/internal.h
index 1bf274b..7853cb1 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -36,7 +36,9 @@ struct mips_def_t {
 int32_t CP0_Config5;
 int32_t CP0_Config5_rw_bitmask;
 int32_t CP0_Config6;
+int32_t CP0_Config6_rw_bitmask;
 int32_t CP0_Config7;
+int32_t CP0_Config7_rw_bitmask;
 target_ulong CP0_LLAddr_rw_bitmask;
 int CP0_LLAddr_shift;
 int32_t SYNCI_Step;
diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h
index a831bb4..c2c96db 100644
--- a/target/mips/mips-defs.h
+++ b/target/mips/mips-defs.h
@@ -51,8 +51,9 @@
  */
 #define INSN_LOONGSON2E   0x0001ULL
 #define INSN_LOONGSON2F   0x0002ULL
-#define INSN_VR54XX   0x0004ULL
-#define INSN_R59000x0008ULL
+#define INSN_LOONGSON3A   0x0004ULL
+#define INSN_VR54XX   0x0008ULL
+#define INSN_R59000x0010ULL
 /*
  *   bits 56-63: vendor-specific ASEs
  */
@@ -94,6 +95,8 @@
 /* Wave Computing: "nanoMIPS" */
 #define CPU_NANOMIPS32  (CPU_MIPS32R6 | ISA_NANOMIPS32)
 
+#define CPU_LOONGSON3A  (CPU_MIPS64R2 | INSN_LOONGSON3A)
+
 /*
  * Strictly follow the architecture standard:
  * - Disallow "special" instruction handling for PMON/SPIM.
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 25b595a..2caf4cb 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -31206,7 +31206,9 @@ void cpu_state_reset(CPUMIPSState *env)
 env->CP0_Config5 = env->cpu_model->CP0_Config5;
 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
 env->CP0_Config6 = env->cpu_model->CP0_Config6;
+env->CP0_Config6_rw_bitmask = env->cpu_model->CP0_Config6_rw_bitmask;
 env->CP0_Config7 = env->cpu_model->CP0_Config7;
+env->CP0_Config7_rw_bitmask = env->cpu_model->CP0_Config7_rw_bitmask;
 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
  << env->cpu_model->CP0_LLAddr_shift;
 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
diff --git a/target/mips/translate_init.inc.c b/target/mips/translate_init.inc.c
index 6d145a9..a31f229 100644
--- a/target/mips/translate_init.inc.c
+++ b/target/mips/translate_init.inc.c
@@ -802,6 +802,92 @@ const mips_def_t mips_defs[] =
 .mmu_type = MMU_TYPE_R4000,
 },
 {
+.name = "Loongson-3A1000",
+.CP0_PRid = 0x6305,
+/* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. 

[PATCH for-5.1 V3 7/7] MAINTAINERS: Add myself as Loongson-3 maintainer

2020-05-03 Thread Huacai Chen
Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 MAINTAINERS | 5 +
 1 file changed, 5 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index fc3d1b0..8d5cfec 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1084,6 +1084,11 @@ F: hw/isa/vt82c686.c
 F: hw/pci-host/bonito.c
 F: include/hw/isa/vt82c686.h
 
+Loongson-3
+M: Huacai Chen 
+S: Maintained
+F: hw/mips/mips_loongson3.c
+
 Boston
 M: Paul Burton 
 R: Aleksandar Rikalo 
-- 
2.7.0




[PATCH for-5.1 V3 5/7] target/mips: Add more CP0 register for save/restore

2020-05-03 Thread Huacai Chen
Add more CP0 register for save/restore, including: EBase, XContext,
PageGrain, PWBase, PWSize, PWField, PWCtl, Config*, KScratch1~KScratch6.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 target/mips/kvm.c | 212 ++
 target/mips/machine.c |   6 +-
 2 files changed, 216 insertions(+), 2 deletions(-)

diff --git a/target/mips/kvm.c b/target/mips/kvm.c
index de3e26e..96cfa10 100644
--- a/target/mips/kvm.c
+++ b/target/mips/kvm.c
@@ -245,10 +245,16 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U64 | (8 * (_R) + (_S)))
 
 #define KVM_REG_MIPS_CP0_INDEX  MIPS_CP0_32(0, 0)
+#define KVM_REG_MIPS_CP0_RANDOM MIPS_CP0_32(1, 0)
 #define KVM_REG_MIPS_CP0_CONTEXTMIPS_CP0_64(4, 0)
 #define KVM_REG_MIPS_CP0_USERLOCAL  MIPS_CP0_64(4, 2)
 #define KVM_REG_MIPS_CP0_PAGEMASK   MIPS_CP0_32(5, 0)
+#define KVM_REG_MIPS_CP0_PAGEGRAIN  MIPS_CP0_32(5, 1)
+#define KVM_REG_MIPS_CP0_PWBASE MIPS_CP0_64(5, 5)
+#define KVM_REG_MIPS_CP0_PWFIELDMIPS_CP0_64(5, 6)
+#define KVM_REG_MIPS_CP0_PWSIZE MIPS_CP0_64(5, 7)
 #define KVM_REG_MIPS_CP0_WIRED  MIPS_CP0_32(6, 0)
+#define KVM_REG_MIPS_CP0_PWCTL  MIPS_CP0_32(6, 6)
 #define KVM_REG_MIPS_CP0_HWRENA MIPS_CP0_32(7, 0)
 #define KVM_REG_MIPS_CP0_BADVADDR   MIPS_CP0_64(8, 0)
 #define KVM_REG_MIPS_CP0_COUNT  MIPS_CP0_32(9, 0)
@@ -258,13 +264,22 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 #define KVM_REG_MIPS_CP0_CAUSE  MIPS_CP0_32(13, 0)
 #define KVM_REG_MIPS_CP0_EPCMIPS_CP0_64(14, 0)
 #define KVM_REG_MIPS_CP0_PRID   MIPS_CP0_32(15, 0)
+#define KVM_REG_MIPS_CP0_EBASE  MIPS_CP0_64(15, 1)
 #define KVM_REG_MIPS_CP0_CONFIG MIPS_CP0_32(16, 0)
 #define KVM_REG_MIPS_CP0_CONFIG1MIPS_CP0_32(16, 1)
 #define KVM_REG_MIPS_CP0_CONFIG2MIPS_CP0_32(16, 2)
 #define KVM_REG_MIPS_CP0_CONFIG3MIPS_CP0_32(16, 3)
 #define KVM_REG_MIPS_CP0_CONFIG4MIPS_CP0_32(16, 4)
 #define KVM_REG_MIPS_CP0_CONFIG5MIPS_CP0_32(16, 5)
+#define KVM_REG_MIPS_CP0_CONFIG6MIPS_CP0_32(16, 6)
+#define KVM_REG_MIPS_CP0_XCONTEXT   MIPS_CP0_64(20, 0)
 #define KVM_REG_MIPS_CP0_ERROREPC   MIPS_CP0_64(30, 0)
+#define KVM_REG_MIPS_CP0_KSCRATCH1  MIPS_CP0_64(31, 2)
+#define KVM_REG_MIPS_CP0_KSCRATCH2  MIPS_CP0_64(31, 3)
+#define KVM_REG_MIPS_CP0_KSCRATCH3  MIPS_CP0_64(31, 4)
+#define KVM_REG_MIPS_CP0_KSCRATCH4  MIPS_CP0_64(31, 5)
+#define KVM_REG_MIPS_CP0_KSCRATCH5  MIPS_CP0_64(31, 6)
+#define KVM_REG_MIPS_CP0_KSCRATCH6  MIPS_CP0_64(31, 7)
 
 static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
int32_t *addr)
@@ -394,6 +409,29 @@ static inline int kvm_mips_get_one_ureg64(CPUState *cs, 
uint64_t reg_id,
  (1U << CP0C5_UFE) | \
  (1U << CP0C5_FRE) | \
  (1U << CP0C5_UFR))
+#define KVM_REG_MIPS_CP0_CONFIG6_MASK   ((1U << CP0C6_BPPASS) | \
+ (0x3fU << CP0C6_KPOS) | \
+ (1U << CP0C6_KE) | \
+ (1U << CP0C6_VTLBONLY) | \
+ (1U << CP0C6_LASX) | \
+ (1U << CP0C6_SSEN) | \
+ (1U << CP0C6_DISDRTIME) | \
+ (1U << CP0C6_PIXNUEN) | \
+ (1U << CP0C6_SCRAND) | \
+ (1U << CP0C6_LLEXCEN) | \
+ (1U << CP0C6_DISVC) | \
+ (1U << CP0C6_VCLRU) | \
+ (1U << CP0C6_DCLRU) | \
+ (1U << CP0C6_PIXUEN) | \
+ (1U << CP0C6_DISBLKLYEN) | \
+ (1U << CP0C6_UMEMUALEN) | \
+ (1U << CP0C6_SFBEN) | \
+ (1U << CP0C6_FLTINT) | \
+ (1U << CP0C6_VLTINT) | \
+ (1U << CP0C6_DISBTB) | \
+ (3U << CP0C6_STPREFCTL) | \
+ (1U << CP0C6_INSTPREF) | \
+ (1U << CP0C6_DATAPREF))
 
 static inline int kvm_mips_change_one_reg(CPUState *cs, uint64_t reg_id,
   int32_t *addr, int32_t mask)
@@ -729,6 +767,11 

[PATCH for-5.1 V5 3/4] hw/mips: Add Loongson-3 machine support (with KVM)

2020-06-23 Thread Huacai Chen
Add Loongson-3 based machine support, it use i8259 as the interrupt
controler and use GPEX as the pci controller. Currently it can only
work with KVM, but we will add TCG support in future.

As the machine model is not based on any exiting physical hardware, the
name of the machine is "loongson3-virt". It may be superseded in future
by a real machine model. If this happens, then a regular deprecation
procedure shall occur for "loongson3-virt" machine.

We already have a full functional Linux kernel (based on Linux-5.4.x LTS
but not upstream yet) here:

https://github.com/chenhuacai/linux

How to use QEMU/Loongson-3?
1, Download kernel source from the above URL;
2, Build a kernel with arch/mips/configs/loongson3_{def,hpc}config;
3, Boot the a Loongson-3A4000 host with this kernel;
4, Build QEMU-master with this patchset;
5, modprobe kvm;
6, Use QEMU with TCG (available in future):
   qemu-system-mips64el -M loongson3-virt,accel=tcg -cpu Loongson-3A1000 
-kernel  -append ...
   Use QEMU with KVM (available at present):
   qemu-system-mips64el -M loongson3-virt,accel=kvm -cpu Loongson-3A4000 
-kernel  -append ...

   The "-cpu" parameter is optional here and QEMU will use the correct type for 
TCG/KVM automatically.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 default-configs/mips64el-softmmu.mak |   1 +
 hw/mips/Kconfig  |  11 +
 hw/mips/Makefile.objs|   1 +
 hw/mips/loongson3_virt.c | 969 +++
 4 files changed, 982 insertions(+)
 create mode 100644 hw/mips/loongson3_virt.c

diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index 9f8a3ef..26c660a 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -3,6 +3,7 @@
 include mips-softmmu-common.mak
 CONFIG_IDE_VIA=y
 CONFIG_FULOONG=y
+CONFIG_LOONGSON3V=y
 CONFIG_ATI_VGA=y
 CONFIG_RTL8139_PCI=y
 CONFIG_JAZZ=y
diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index 67d39c5..cc5609b 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -45,6 +45,17 @@ config FULOONG
 bool
 select PCI_BONITO
 
+config LOONGSON3V
+bool
+select PCKBD
+select SERIAL
+select GOLDFISH_RTC
+select LOONGSON_LIOINTC
+select PCI_EXPRESS_GENERIC_BRIDGE
+select VIRTIO_VGA
+select QXL if SPICE
+select MSI_NONBROKEN
+
 config MIPS_CPS
 bool
 select PTIMER
diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs
index 739e2b7..0993852 100644
--- a/hw/mips/Makefile.objs
+++ b/hw/mips/Makefile.objs
@@ -4,5 +4,6 @@ obj-$(CONFIG_MALTA) += gt64xxx_pci.o malta.o
 obj-$(CONFIG_MIPSSIM) += mipssim.o
 obj-$(CONFIG_JAZZ) += jazz.o
 obj-$(CONFIG_FULOONG) += fuloong2e.o
+obj-$(CONFIG_LOONGSON3V) += loongson3_virt.o
 obj-$(CONFIG_MIPS_CPS) += cps.o
 obj-$(CONFIG_MIPS_BOSTON) += boston.o
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
new file mode 100644
index 000..5907772
--- /dev/null
+++ b/hw/mips/loongson3_virt.c
@@ -0,0 +1,969 @@
+/*
+ * Generic Loongson-3 Platform support
+ *
+ * Copyright (c) 2016-2020 Huacai Chen (che...@lemote.com)
+ * This code is licensed under the GNU GPL v2.
+ *
+ * Contributions are licensed under the terms of the GNU GPL,
+ * version 2 or (at your option) any later version.
+ */
+
+/*
+ * Generic virtualized PC Platform based on Loongson-3 CPU (MIPS64R2 with
+ * extensions, 800~2000MHz)
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "elf.h"
+#include "kvm_mips.h"
+#include "hw/boards.h"
+#include "hw/char/serial.h"
+#include "hw/mips/mips.h"
+#include "hw/mips/cpudevs.h"
+#include "hw/misc/empty_slot.h"
+#include "hw/intc/i8259.h"
+#include "hw/loader.h"
+#include "hw/isa/superio.h"
+#include "hw/pci/msi.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_host.h"
+#include "hw/pci-host/gpex.h"
+#include "hw/rtc/mc146818rtc.h"
+#include "hw/usb.h"
+#include "net/net.h"
+#include "exec/address-spaces.h"
+#include "sysemu/kvm.h"
+#include "sysemu/qtest.h"
+#include "sysemu/reset.h"
+#include "sysemu/runstate.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+
+#define PM_CNTL_MODE  0x10
+
+/* Overall MMIO & Memory layout */
+enum {
+VIRT_LOWMEM,
+VIRT_PM,
+VIRT_FW_CFG,
+VIRT_RTC,
+VIRT_PCIE_PIO,
+VIRT_PCIE_ECAM,
+VIRT_BIOS_ROM,
+VIRT_UART,
+VIRT_LIOINTC,
+VIRT_PCIE_MMIO,
+VIRT_HIGHMEM
+};
+
+/* Low MEM layout for QEMU kernel loader */
+enum {
+LOADER_KERNEL,
+LOADER_INITRD,
+LOADER_CMDLINE
+};
+
+/* BIOS ROM layout for QEMU kernel loader */
+enum {

[PATCH for-5.1 V5 1/4] hw/mips: Implement the kvm_type() hook in MachineClass

2020-06-23 Thread Huacai Chen
MIPS has two types of KVM: TE & VZ, and TE is the default type. Now we
can't create a VZ guest in QEMU because it lacks the kvm_type() hook in
MachineClass. This patch add the the kvm_type() hook to support both of
the two types.

Reviewed-by: Aleksandar Markovic 
Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 target/mips/kvm.c  | 20 
 target/mips/kvm_mips.h | 11 +++
 2 files changed, 31 insertions(+)

diff --git a/target/mips/kvm.c b/target/mips/kvm.c
index 96cfa10..373f582 100644
--- a/target/mips/kvm.c
+++ b/target/mips/kvm.c
@@ -21,10 +21,12 @@
 #include "qemu/main-loop.h"
 #include "qemu/timer.h"
 #include "sysemu/kvm.h"
+#include "sysemu/kvm_int.h"
 #include "sysemu/runstate.h"
 #include "sysemu/cpus.h"
 #include "kvm_mips.h"
 #include "exec/memattrs.h"
+#include "hw/boards.h"
 
 #define DEBUG_KVM 0
 
@@ -1270,3 +1272,21 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
 {
 abort();
 }
+
+int mips_kvm_type(MachineState *machine, const char *vm_type)
+{
+int r;
+KVMState *s = KVM_STATE(machine->accelerator);
+
+r = kvm_check_extension(s, KVM_CAP_MIPS_VZ);
+if (r > 0) {
+return KVM_VM_MIPS_VZ;
+}
+
+r = kvm_check_extension(s, KVM_CAP_MIPS_TE);
+if (r > 0) {
+return KVM_VM_MIPS_TE;
+}
+
+return -1;
+}
diff --git a/target/mips/kvm_mips.h b/target/mips/kvm_mips.h
index 1e40147..171d53d 100644
--- a/target/mips/kvm_mips.h
+++ b/target/mips/kvm_mips.h
@@ -12,6 +12,8 @@
 #ifndef KVM_MIPS_H
 #define KVM_MIPS_H
 
+#include "cpu.h"
+
 /**
  * kvm_mips_reset_vcpu:
  * @cpu: MIPSCPU
@@ -23,4 +25,13 @@ void kvm_mips_reset_vcpu(MIPSCPU *cpu);
 int kvm_mips_set_interrupt(MIPSCPU *cpu, int irq, int level);
 int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level);
 
+#ifdef CONFIG_KVM
+int mips_kvm_type(MachineState *machine, const char *vm_type);
+#else
+static inline int mips_kvm_type(MachineState *machine, const char *vm_type)
+{
+return 0;
+}
+#endif
+
 #endif /* KVM_MIPS_H */
-- 
2.7.0




[PATCH for-5.1 V5 2/4] hw/intc: Add Loongson liointc support

2020-06-23 Thread Huacai Chen
Loongson-3 has an integrated liointc (Local I/O interrupt controller).
It is similar to goldfish interrupt controller, but more powerful (e.g.,
it can route external interrupt to multi-cores).

Signed-off-by: Huacai Chen 
Signed-off-by: Jiaxun Yang 
---
 hw/intc/Kconfig|   3 +
 hw/intc/Makefile.objs  |   1 +
 hw/intc/loongson_liointc.c | 246 +
 3 files changed, 250 insertions(+)
 create mode 100644 hw/intc/loongson_liointc.c

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index a189d6f..264d82d 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -61,3 +61,6 @@ config S390_FLIC_KVM
 
 config OMPIC
 bool
+
+config LOONGSON_LIOINTC
+bool
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index a61e672..9a26fbe 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -50,3 +50,4 @@ obj-$(CONFIG_MIPS_CPS) += mips_gic.o
 obj-$(CONFIG_NIOS2) += nios2_iic.o
 obj-$(CONFIG_OMPIC) += ompic.o
 obj-$(CONFIG_IBEX) += ibex_plic.o
+obj-$(CONFIG_LOONGSON_LIOINTC) += loongson_liointc.o
diff --git a/hw/intc/loongson_liointc.c b/hw/intc/loongson_liointc.c
new file mode 100644
index 000..d4c1b48
--- /dev/null
+++ b/hw/intc/loongson_liointc.c
@@ -0,0 +1,246 @@
+/*
+ * QEMU Loongson Local I/O interrupt controler.
+ *
+ * Copyright (c) 2020 Jiaxun Yang 
+ *
+ * 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 "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "qemu/module.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+
+#define D(x)
+
+#define NUM_IRQS32
+
+#define NUM_CORES   4
+#define NUM_IPS 4
+#define NUM_PARENTS (NUM_CORES * NUM_IPS)
+#define PARENT_COREx_IPy(x, y)(NUM_IPS * x + y)
+
+#define R_MAPPER_START0x0
+#define R_MAPPER_END  0x20
+#define R_ISR   R_MAPPER_END
+#define R_IEN   0x24
+#define R_IEN_SET   0x28
+#define R_IEN_CLR   0x2c
+#define R_PERCORE_ISR(x) (0x40 + 0x8 * x)
+#define R_END   0x64
+
+#define TYPE_LOONGSON_LIOINTC "loongson.liointc"
+#define LOONGSON_LIOINTC(obj) OBJECT_CHECK(struct loongson_liointc, (obj), 
TYPE_LOONGSON_LIOINTC)
+
+struct loongson_liointc
+{
+SysBusDevice parent_obj;
+
+MemoryRegion mmio;
+qemu_irq parent_irq[NUM_PARENTS];
+
+uint8_t mapper[NUM_IRQS]; /* 0:3 for core, 4:7 for IP */
+uint32_t isr;
+uint32_t ien;
+uint32_t per_core_isr[NUM_CORES];
+
+/* state of the interrupt input pins */
+uint32_t pin_state;
+bool parent_state[NUM_PARENTS];
+};
+
+static void update_irq(struct loongson_liointc *p)
+{
+uint32_t irq, core, ip;
+uint32_t per_ip_isr[NUM_IPS] = {0};
+
+/* level triggered interrupt */
+p->isr = p->pin_state;
+
+/* Clear disabled IRQs */
+p->isr &= p->ien;
+
+/* Clear per_core_isr */
+for (core = 0; core < NUM_CORES; core++) {
+p->per_core_isr[core] = 0;
+}
+
+/* Update per_core_isr and per_ip_isr */
+for (irq = 0; irq < NUM_IRQS; irq++) {
+if (!(p->isr & (1 << irq))) {
+continue;
+}
+
+for (core = 0; core < NUM_CORES; core++) {
+if ((p->mapper[irq] & (1 << core))) {
+p->per_core_isr[core] |= (1 << irq);
+}
+}
+
+for (ip = 0; ip < NUM_IPS; ip++) {
+if ((p->mapper[irq] & (1 << (ip + 4 {
+per_ip_isr[ip] |= (1 << irq);
+}
+}
+}
+
+/* Emit IRQ to parent! */
+for (core = 0; core < NUM_CORES; core++) {
+for (ip = 0; ip < NUM_IPS; ip++) {
+int parent = PARENT_COREx_IPy(core, ip);
+   if (p->parent_state[parent] !=
+(!!p->per_core_isr[core] && !!per_ip_isr[ip])) {
+p->parent_state[parent] = !p->pare

[PATCH for-5.1 V5 0/4] mips: Add Loongson-3 machine support (with KVM)

2020-06-23 Thread Huacai Chen
Loongson-3 CPU family include Loongson-3A R1/R2/R3/R4 and Loongson-3B
R1/R2. Loongson-3A R1 is the oldest and its ISA is the smallest, while
Loongson-3A R4 is the newest and its ISA is almost the superset of all
others. To reduce complexity, in QEMU we just define two CPU types:

1, "Loongson-3A1000" CPU which is corresponding to Loongson-3A R1. It is
   suitable for TCG because Loongson-3A R1 has fewest ASE.
2, "Loongson-3A4000" CPU which is corresponding to Loongson-3A R4. It is
   suitable for KVM because Loongson-3A R4 has the VZ ASE.

Loongson-3 lacks English documents. I've tried to translated them with
translate.google.com, and the machine translated documents (together
with their original Chinese versions) are available here.

Loongson-3A R1 (Loongson-3A1000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A1000_p1.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A1000_processor_user_manual_P1.pdf 
(Chinese Version)
User Manual Part 2:
http://ftp.godson.ac.cn/lemote/3A1000_p2.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A1000_processor_user_manual_P2.pdf 
(Chinese Version)

Loongson-3A R2 (Loongson-3A2000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A2000_p1.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A2000_user1.pdf (Chinese Version)
User Manual Part 2:
http://ftp.godson.ac.cn/lemote/3A2000_p2.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A2000_user2.pdf (Chinese Version)

Loongson-3A R3 (Loongson-3A3000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A3000_p1.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A3000_3B3000usermanual1.pdf (Chinese 
Version)
User Manual Part 2:
http://ftp.godson.ac.cn/lemote/3A3000_p2.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A3000_3B3000usermanual2.pdf (Chinese 
Version)

Loongson-3A R4 (Loongson-3A4000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A4000_p1.pdf
http://ftp.godson.ac.cn/lemote/3A4000user.pdf (Chinese Version)
User Manual Part 2:
I'm sorry that it is unavailable now.

We are preparing to add QEMU's Loongson-3 support. MIPS VZ extension is
fully supported in Loongson-3A R4+, so we at first add QEMU/KVM support
in this series. And the next series will add QEMU/TCG support (it will
emulate Loongson-3A R1).

We already have a full functional Linux kernel (based on Linux-5.4.x LTS
but not upstream yet) here:

https://github.com/chenhuacai/linux

How to use QEMU/Loongson-3?
1, Download kernel source from the above URL;
2, Build a kernel with arch/mips/configs/loongson3_{def,hpc}config;
3, Boot a Loongson-3A4000 host with this kernel;
4, Build QEMU-5.0.0 with this patchset;
5, modprobe kvm;
6, Use QEMU with TCG (available in future):
   qemu-system-mips64el -M loongson3-virt,accel=tcg -cpu Loongson-3A1000 
-kernel  -append ...
   Use QEMU with KVM (available at present):
   qemu-system-mips64el -M loongson3-virt,accel=kvm -cpu Loongson-3A4000 
-kernel  -append ...

   The "-cpu" parameter is optional here and QEMU will use the correct type for 
TCG/KVM automatically.

V1 -> V2:
1, Add a cover letter;
2, Improve CPU definitions;
3, Remove LS7A-related things (Use GPEX instead);
4, Add a description of how to run QEMU/Loongson-3.

V2 -> V3:
1, Fix all possible checkpatch.pl errors and warnings.

V3 -> V4:
1, Sync code with upstream;
2, Remove merged patches;
3, Fix build failure without CONFIG_KVM;
4, Add Reviewed-by: Aleksandar Markovic .

V4 -> V5:
1, Improve coding style;
2, Remove merged patches;
3, Rename machine name from "loongson3" to "loongson3-virt";
4, Rework the "loongson3-virt" machine to drop any ISA things;
5, Rework "hw/mips: Implement the kvm_type() hook in MachineClass";
6, Add Jiaxun Yang as a reviewer of Loongson-3.

Huacai Chen(4):
 hw/mips: Implement the kvm_type() hook in MachineClass
 hw/intc: Add Loongson liointc support
 hw/mips: Add Loongson-3 machine support (with KVM)
 MAINTAINERS: Add Loongson-3 maintainer and reviewer

Signed-off-by: Huacai Chen 
---
 MAINTAINERS  |   6 +
 default-configs/mips64el-softmmu.mak |   1 +
 hw/intc/Kconfig  |   3 +
 hw/intc/Makefile.objs|   1 +
 hw/intc/loongson_liointc.c   | 246 +
 hw/mips/Kconfig  |  11 +
 hw/mips/Makefile.objs|   1 +
 hw/mips/loongson3_virt.c | 969 +++
 target/mips/kvm.c|  20 +
 target/mips/kvm_mips.h   |  11 +
 10 files changed, 1269 insertions(+)
 create mode 100644 hw/intc/loongson_liointc.c
 create mode 100644 hw/mips/loongson3_virt.c
--
2.7.0



[PATCH for-5.1 V5 4/4] MAINTAINERS: Add Loongson-3 maintainer and reviewer

2020-06-23 Thread Huacai Chen
Add myself as a maintainer of Loongson-3 virtual platform, and also add
Jiaxun Yang as a reviewer.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 MAINTAINERS | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index f0cb1fd..293188e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1095,6 +1095,12 @@ F: hw/isa/vt82c686.c
 F: hw/pci-host/bonito.c
 F: include/hw/isa/vt82c686.h
 
+Loongson-3 Virtual Platform
+M: Huacai Chen 
+R: Jiaxun Yang 
+S: Maintained
+F: hw/mips/loongson3_virt.c
+
 Boston
 M: Paul Burton 
 R: Aleksandar Rikalo 
-- 
2.7.0




Re: [PATCH for-5.1 V5 0/4] mips: Add Loongson-3 machine support (with KVM)

2020-06-23 Thread Huacai Chen
Hi, Aleksandar,

On Tue, Jun 23, 2020 at 9:58 PM Aleksandar Markovic
 wrote:
>
>
>
> уторак, 23. јун 2020.,  је написао/ла:
>>
>> Patchew URL: 
>> https://patchew.org/QEMU/1592914438-30317-1-git-send-email-che...@lemote.com/
>>
>>
>>
>> Hi,
>>
>> This series seems to have some coding style problems. See output below for
>> more information:
>>
>
> Hi, Huacai.
>
> Please fix all checkpatch warnings in the next version (except thise that 
> complain about the need for updating MAONTAINERS)
>
> Also, you dont need " for-5.1" in subject prefixes.
>
> Please fix these and other small things that I commented about, and send v6 
> soon (tomorrow, if possible?), so that we remove these small obstacles and 
> focus on the core functionality of tge series.
>
> Thanks, Aleksandar
>
>
>
>
>>
>> Subject: [PATCH for-5.1 V5 0/4] mips: Add Loongson-3 machine support (with 
>> KVM)
>> Type: series
>> Message-id: 1592914438-30317-1-git-send-email-che...@lemote.com
>>
>> === TEST SCRIPT BEGIN ===
>> #!/bin/bash
>> git rev-parse base > /dev/null || exit 0
>> git config --local diff.renamelimit 0
>> git config --local diff.renames True
>> git config --local diff.algorithm histogram
>> ./scripts/checkpatch.pl --mailback base..
>> === TEST SCRIPT END ===
>>
>> From https://github.com/patchew-project/qemu
>>  * [new tag] 
>> patchew/1592914438-30317-1-git-send-email-che...@lemote.com -> 
>> patchew/1592914438-30317-1-git-send-email-che...@lemote.com
>> Switched to a new branch 'test'
>> 63e13a2 MAINTAINERS: Add Loongson-3 maintainer and reviewer
>> 727fa14 hw/mips: Add Loongson-3 machine support (with KVM)
>> 5fd21a0 hw/intc: Add Loongson liointc support
>> 6996d49 hw/mips: Implement the kvm_type() hook in MachineClass
>>
>> === OUTPUT BEGIN ===
>> 1/4 Checking commit 6996d492ec71 (hw/mips: Implement the kvm_type() hook in 
>> MachineClass)
>> 2/4 Checking commit 5fd21a0bcd83 (hw/intc: Add Loongson liointc support)
>> WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
>> #36:
>> new file mode 100644
>>
>> ERROR: line over 90 characters
>> #90: FILE: hw/intc/loongson_liointc.c:50:
>> +#define LOONGSON_LIOINTC(obj) OBJECT_CHECK(struct loongson_liointc, (obj), 
>> TYPE_LOONGSON_LIOINTC)
>>
>> ERROR: open brace '{' following struct go on the same line
>> #93: FILE: hw/intc/loongson_liointc.c:53:
>> +struct loongson_liointc
>> +{
>>
>> ERROR: code indent should never use tabs
>> #148: FILE: hw/intc/loongson_liointc.c:108:
>> +^Iif (p->parent_state[parent] !=$
>>
>> total: 3 errors, 1 warnings, 256 lines checked
>>
>> Patch 2/4 has style problems, please review.  If any of these errors
>> are false positives report them to the maintainer, see
>> CHECKPATCH in MAINTAINERS.
>>
>> 3/4 Checking commit 727fa142abed (hw/mips: Add Loongson-3 machine support 
>> (with KVM))
>> WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
>> #84:
>> new file mode 100644
>>
>> WARNING: line over 80 characters
>> #404: FILE: hw/mips/loongson3_virt.c:316:
>> +static void loongson3_pm_write(void *opaque, hwaddr addr, uint64_t val, 
>> unsigned size)
>>
>> WARNING: line over 80 characters
>> #704: FILE: hw/mips/loongson3_virt.c:616:
>> +fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, 
>> (uint16_t)current_machine->smp.max_cpus);
>>
>> WARNING: line over 80 characters
>> #840: FILE: hw/mips/loongson3_virt.c:752:
>> +static inline void loongson3_virt_devices_init(MachineState *machine, 
>> DeviceState *pic)
>>
>> WARNING: line over 80 characters
>> #871: FILE: hw/mips/loongson3_virt.c:783:
>> + get_system_io(), 0, 
>> virt_memmap[VIRT_PCIE_PIO].size);
>>
>> WARNING: line over 80 characters
>> #977: FILE: hw/mips/loongson3_virt.c:889:
>> +/* Allocate RAM/BIOS, 0x~0x1000 is alias of 
>> 0x8000~0x9000 */
>>
>> total: 0 errors, 6 warnings, 999 lines checked
>>
>> Patch 3/4 has style problems, please review.  If any of these errors
>> are false positives report them to the maintainer, see
>> CHECKPATCH in MAINTAINERS.
>> 4/4 Checking commit 63e13a297290 (MAINTAINERS: Add Loongson-3 maintainer and 
>> reviewer)
>> === OUTPUT END ===
>>
>> Test command exited with code: 1
>>
>>
>> The full log is available at
>> http://patchew.org/logs/1592914438-30317-1-git-send-email-che...@lemote.com/testing.checkpatch/?type=message.
OK, all errors will be fixed.

>> ---
>> Email generated automatically by Patchew [https://patchew.org/].
>> Please send your feedback to patchew-de...@redhat.com



Re: [PATCH for-5.1 V5 4/4] MAINTAINERS: Add Loongson-3 maintainer and reviewer

2020-06-23 Thread Huacai Chen
Hi, Aleksandar,

On Tue, Jun 23, 2020 at 9:50 PM Aleksandar Markovic
 wrote:
>
>
>
> уторак, 23. јун 2020., Huacai Chen  је написао/ла:
>>
>> Add myself as a maintainer of Loongson-3 virtual platform, and also add
>> Jiaxun Yang as a reviewer.
>>
>> Signed-off-by: Huacai Chen 
>> Co-developed-by: Jiaxun Yang 
>> ---
>>  MAINTAINERS | 6 ++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index f0cb1fd..293188e 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -1095,6 +1095,12 @@ F: hw/isa/vt82c686.c
>>  F: hw/pci-host/bonito.c
>>  F: include/hw/isa/vt82c686.h
>>
>> +Loongson-3 Virtual Platform
>> +M: Huacai Chen 
>> +R: Jiaxun Yang 
>> +S: Maintained
>> +F: hw/mips/loongson3_virt.c
>
>
>  hw/intc/loongson_liointc.c is missing.
Thanks, this will be added.

>
>>
>> +
>>  Boston
>>  M: Paul Burton 
>>  R: Aleksandar Rikalo 
>> --
>> 2.7.0
>>



Re: [PATCH for-5.1 V5 3/4] hw/mips: Add Loongson-3 machine support (with KVM)

2020-06-23 Thread Huacai Chen
Hi, Aleksandar,

On Tue, Jun 23, 2020 at 10:04 PM Aleksandar Markovic
 wrote:
>
>
>
> уторак, 23. јун 2020., Huacai Chen  је написао/ла:
>>
>> Add Loongson-3 based machine support, it use i8259 as the interrupt
>> controler and use GPEX as the pci controller. Currently it can only
>> work with KVM, but we will add TCG support in future.
>>
>> As the machine model is not based on any exiting physical hardware, the
>> name of the machine is "loongson3-virt". It may be superseded in future
>> by a real machine model. If this happens, then a regular deprecation
>> procedure shall occur for "loongson3-virt" machine.
>>
>> We already have a full functional Linux kernel (based on Linux-5.4.x LTS
>> but not upstream yet) here:
>>
>> https://github.com/chenhuacai/linux
>>
>> How to use QEMU/Loongson-3?
>> 1, Download kernel source from the above URL;
>> 2, Build a kernel with arch/mips/configs/loongson3_{def,hpc}config;
>> 3, Boot the a Loongson-3A4000 host with this kernel;
>> 4, Build QEMU-master with this patchset;
>> 5, modprobe kvm;
>> 6, Use QEMU with TCG (available in future):
>>qemu-system-mips64el -M loongson3-virt,accel=tcg -cpu Loongson-3A1000 
>> -kernel  -append ...
>>Use QEMU with KVM (available at present):
>>qemu-system-mips64el -M loongson3-virt,accel=kvm -cpu Loongson-3A4000 
>> -kernel  -append ...
>>
>>The "-cpu" parameter is optional here and QEMU will use the correct type 
>> for TCG/KVM automatically.
>>
>> Signed-off-by: Huacai Chen 
>> Co-developed-by: Jiaxun Yang 
>> ---
>>  default-configs/mips64el-softmmu.mak |   1 +
>>  hw/mips/Kconfig  |  11 +
>>  hw/mips/Makefile.objs|   1 +
>>  hw/mips/loongson3_virt.c | 969 
>> +++
>>  4 files changed, 982 insertions(+)
>>  create mode 100644 hw/mips/loongson3_virt.c
>>
>> diff --git a/default-configs/mips64el-softmmu.mak 
>> b/default-configs/mips64el-softmmu.mak
>> index 9f8a3ef..26c660a 100644
>> --- a/default-configs/mips64el-softmmu.mak
>> +++ b/default-configs/mips64el-softmmu.mak
>> @@ -3,6 +3,7 @@
>>  include mips-softmmu-common.mak
>>  CONFIG_IDE_VIA=y
>>  CONFIG_FULOONG=y
>> +CONFIG_LOONGSON3V=y
>>  CONFIG_ATI_VGA=y
>>  CONFIG_RTL8139_PCI=y
>>  CONFIG_JAZZ=y
>> diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
>> index 67d39c5..cc5609b 100644
>> --- a/hw/mips/Kconfig
>> +++ b/hw/mips/Kconfig
>> @@ -45,6 +45,17 @@ config FULOONG
>>  bool
>>  select PCI_BONITO
>>
>> +config LOONGSON3V
>> +bool
>> +select PCKBD
>> +select SERIAL
>> +select GOLDFISH_RTC
>> +select LOONGSON_LIOINTC
>> +select PCI_EXPRESS_GENERIC_BRIDGE
>> +select VIRTIO_VGA
>> +select QXL if SPICE
>> +select MSI_NONBROKEN
>> +
>>  config MIPS_CPS
>>  bool
>>  select PTIMER
>> diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs
>> index 739e2b7..0993852 100644
>> --- a/hw/mips/Makefile.objs
>> +++ b/hw/mips/Makefile.objs
>> @@ -4,5 +4,6 @@ obj-$(CONFIG_MALTA) += gt64xxx_pci.o malta.o
>>  obj-$(CONFIG_MIPSSIM) += mipssim.o
>>  obj-$(CONFIG_JAZZ) += jazz.o
>>  obj-$(CONFIG_FULOONG) += fuloong2e.o
>> +obj-$(CONFIG_LOONGSON3V) += loongson3_virt.o
>>  obj-$(CONFIG_MIPS_CPS) += cps.o
>>  obj-$(CONFIG_MIPS_BOSTON) += boston.o
>> diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
>> new file mode 100644
>> index 000..5907772
>> --- /dev/null
>> +++ b/hw/mips/loongson3_virt.c
>> @@ -0,0 +1,969 @@
>> +/*
>> + * Generic Loongson-3 Platform support
>> + *
>> + * Copyright (c) 2016-2020 Huacai Chen (che...@lemote.com)
>> + * This code is licensed under the GNU GPL v2.
>> + *
>> + * Contributions are licensed under the terms of the GNU GPL,
>> + * version 2 or (at your option) any later version.
>> + */
>
>
> Again, wrong license preamble.
>
> You already agreed with the text tgat I sent in some of uor conversations, 
> why did you revert to this version?
All mistakes will be fixed, thanks.

>
> Yours,
> Aleksandar
>
>
>>
>> +
>> +/*
>> + * Generic virtualized PC Platform based on Loongson-3 CPU (MIPS64R2 with
>> + * extensions, 800~2000MHz)
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "qemu-common.h"
>> +#include "qemu/units.h"
>

[PATCH V6 1/4] hw/mips: Implement the kvm_type() hook in MachineClass

2020-06-24 Thread Huacai Chen
MIPS has two types of KVM: TE & VZ, and TE is the default type. Now we
can't create a VZ guest in QEMU because it lacks the kvm_type() hook in
MachineClass. This patch add the the kvm_type() hook to support both of
the two types.

Reviewed-by: Aleksandar Markovic 
Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 target/mips/kvm.c  | 20 
 target/mips/kvm_mips.h | 11 +++
 2 files changed, 31 insertions(+)

diff --git a/target/mips/kvm.c b/target/mips/kvm.c
index 96cfa10..373f582 100644
--- a/target/mips/kvm.c
+++ b/target/mips/kvm.c
@@ -21,10 +21,12 @@
 #include "qemu/main-loop.h"
 #include "qemu/timer.h"
 #include "sysemu/kvm.h"
+#include "sysemu/kvm_int.h"
 #include "sysemu/runstate.h"
 #include "sysemu/cpus.h"
 #include "kvm_mips.h"
 #include "exec/memattrs.h"
+#include "hw/boards.h"
 
 #define DEBUG_KVM 0
 
@@ -1270,3 +1272,21 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
 {
 abort();
 }
+
+int mips_kvm_type(MachineState *machine, const char *vm_type)
+{
+int r;
+KVMState *s = KVM_STATE(machine->accelerator);
+
+r = kvm_check_extension(s, KVM_CAP_MIPS_VZ);
+if (r > 0) {
+return KVM_VM_MIPS_VZ;
+}
+
+r = kvm_check_extension(s, KVM_CAP_MIPS_TE);
+if (r > 0) {
+return KVM_VM_MIPS_TE;
+}
+
+return -1;
+}
diff --git a/target/mips/kvm_mips.h b/target/mips/kvm_mips.h
index 1e40147..171d53d 100644
--- a/target/mips/kvm_mips.h
+++ b/target/mips/kvm_mips.h
@@ -12,6 +12,8 @@
 #ifndef KVM_MIPS_H
 #define KVM_MIPS_H
 
+#include "cpu.h"
+
 /**
  * kvm_mips_reset_vcpu:
  * @cpu: MIPSCPU
@@ -23,4 +25,13 @@ void kvm_mips_reset_vcpu(MIPSCPU *cpu);
 int kvm_mips_set_interrupt(MIPSCPU *cpu, int irq, int level);
 int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level);
 
+#ifdef CONFIG_KVM
+int mips_kvm_type(MachineState *machine, const char *vm_type);
+#else
+static inline int mips_kvm_type(MachineState *machine, const char *vm_type)
+{
+return 0;
+}
+#endif
+
 #endif /* KVM_MIPS_H */
-- 
2.7.0




[PATCH V6 0/4] mips: Add Loongson-3 machine support (with KVM)

2020-06-24 Thread Huacai Chen
Loongson-3 CPU family include Loongson-3A R1/R2/R3/R4 and Loongson-3B
R1/R2. Loongson-3A R1 is the oldest and its ISA is the smallest, while
Loongson-3A R4 is the newest and its ISA is almost the superset of all
others. To reduce complexity, in QEMU we just define two CPU types:

1, "Loongson-3A1000" CPU which is corresponding to Loongson-3A R1. It is
   suitable for TCG because Loongson-3A R1 has fewest ASE.
2, "Loongson-3A4000" CPU which is corresponding to Loongson-3A R4. It is
   suitable for KVM because Loongson-3A R4 has the VZ ASE.

Loongson-3 lacks English documents. I've tried to translated them with
translate.google.com, and the machine translated documents (together
with their original Chinese versions) are available here.

Loongson-3A R1 (Loongson-3A1000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A1000_p1.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A1000_processor_user_manual_P1.pdf 
(Chinese Version)
User Manual Part 2:
http://ftp.godson.ac.cn/lemote/3A1000_p2.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A1000_processor_user_manual_P2.pdf 
(Chinese Version)

Loongson-3A R2 (Loongson-3A2000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A2000_p1.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A2000_user1.pdf (Chinese Version)
User Manual Part 2:
http://ftp.godson.ac.cn/lemote/3A2000_p2.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A2000_user2.pdf (Chinese Version)

Loongson-3A R3 (Loongson-3A3000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A3000_p1.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A3000_3B3000usermanual1.pdf (Chinese 
Version)
User Manual Part 2:
http://ftp.godson.ac.cn/lemote/3A3000_p2.pdf
http://ftp.godson.ac.cn/lemote/Loongson3A3000_3B3000usermanual2.pdf (Chinese 
Version)

Loongson-3A R4 (Loongson-3A4000)
User Manual Part 1:
http://ftp.godson.ac.cn/lemote/3A4000_p1.pdf
http://ftp.godson.ac.cn/lemote/3A4000user.pdf (Chinese Version)
User Manual Part 2:
I'm sorry that it is unavailable now.

We are preparing to add QEMU's Loongson-3 support. MIPS VZ extension is
fully supported in Loongson-3A R4+, so we at first add QEMU/KVM support
in this series. And the next series will add QEMU/TCG support (it will
emulate Loongson-3A R1).

We already have a full functional Linux kernel (based on Linux-5.4.x LTS
but not upstream yet) here:

https://github.com/chenhuacai/linux

How to use QEMU/Loongson-3?
1, Download kernel source from the above URL;
2, Build a kernel with arch/mips/configs/loongson3_{def,hpc}config;
3, Boot a Loongson-3A4000 host with this kernel;
4, Build QEMU-5.0.0 with this patchset;
5, modprobe kvm;
6, Use QEMU with TCG (available in future):
   qemu-system-mips64el -M loongson3-virt,accel=tcg -cpu Loongson-3A1000 
-kernel  -append ...
   Use QEMU with KVM (available at present):
   qemu-system-mips64el -M loongson3-virt,accel=kvm -cpu Loongson-3A4000 
-kernel  -append ...

   The "-cpu" parameter is optional here and QEMU will use the correct type for 
TCG/KVM automatically.

V1 -> V2:
1, Add a cover letter;
2, Improve CPU definitions;
3, Remove LS7A-related things (Use GPEX instead);
4, Add a description of how to run QEMU/Loongson-3.

V2 -> V3:
1, Fix all possible checkpatch.pl errors and warnings.

V3 -> V4:
1, Sync code with upstream;
2, Remove merged patches;
3, Fix build failure without CONFIG_KVM;
4, Add Reviewed-by: Aleksandar Markovic .

V4 -> V5:
1, Improve coding style;
2, Remove merged patches;
3, Rename machine name from "loongson3" to "loongson3-virt";
4, Rework the "loongson3-virt" machine to drop any ISA things;
5, Rework "hw/mips: Implement the kvm_type() hook in MachineClass";
6, Add Jiaxun Yang as a reviewer of Loongson-3.

V5 -> V6:
1, Fix license preamble;
2, Improve commit messages;
3, Add hw/intc/loongson_liointc.c to MAINTAINERS;
4, Fix all possible checkpatch.pl errors and warnings.

Huacai Chen(4):
 hw/mips: Implement the kvm_type() hook in MachineClass
 hw/intc: Add Loongson liointc support
 hw/mips: Add Loongson-3 machine support (with KVM)
 MAINTAINERS: Add Loongson-3 maintainer and reviewer

Signed-off-by: Huacai Chen 
---
 MAINTAINERS  |   7 +
 default-configs/mips64el-softmmu.mak |   1 +
 hw/intc/Kconfig  |   3 +
 hw/intc/Makefile.objs|   1 +
 hw/intc/loongson_liointc.c   | 241 +
 hw/mips/Kconfig  |  11 +
 hw/mips/Makefile.objs|   1 +
 hw/mips/loongson3_virt.c | 978 +++
 target/mips/kvm.c|  20 +
 target/mips/kvm_mips.h   |  11 +
 10 files changed, 1274 insertions(+)
 create mode 100644 hw/intc/loongson_liointc.c
 create mode 100644 hw/mips/loongson3_virt.c
--
2.7.0



[PATCH V6 3/4] hw/mips: Add Loongson-3 machine support (with KVM)

2020-06-24 Thread Huacai Chen
Add Loongson-3 based machine support, it use liointc as the interrupt
controler and use GPEX as the pci controller. Currently it can only work
with KVM, but we will add TCG support in future.

As the machine model is not based on any exiting physical hardware, the
name of the machine is "loongson3-virt". It may be superseded in future
by a real machine model. If this happens, then a regular deprecation
procedure shall occur for "loongson3-virt" machine.

We now already have a full functional Linux kernel (based on Linux-5.4.x
LTS, the kvm host side has been upstream in Linux-5.8, but the kvm guest
side has not been upstream yet) here:

https://github.com/chenhuacai/linux

How to use QEMU/Loongson-3?
1, Download kernel source from the above URL;
2, Build a kernel with arch/mips/configs/loongson3_{def,hpc}config;
3, Boot the a Loongson-3A4000 host with this kernel;
4, Build QEMU-master with this patchset;
5, modprobe kvm;
6, Use QEMU with TCG (available in future):
   qemu-system-mips64el -M loongson3-virt,accel=tcg -cpu Loongson-3A1000 
-kernel  -append ...
   Use QEMU with KVM (available at present):
   qemu-system-mips64el -M loongson3-virt,accel=kvm -cpu Loongson-3A4000 
-kernel  -append ...

   The "-cpu" parameter is optional here and QEMU will use the correct type for 
TCG/KVM automatically.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 default-configs/mips64el-softmmu.mak |   1 +
 hw/mips/Kconfig  |  11 +
 hw/mips/Makefile.objs|   1 +
 hw/mips/loongson3_virt.c | 978 +++
 4 files changed, 991 insertions(+)
 create mode 100644 hw/mips/loongson3_virt.c

diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index 9f8a3ef..26c660a 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -3,6 +3,7 @@
 include mips-softmmu-common.mak
 CONFIG_IDE_VIA=y
 CONFIG_FULOONG=y
+CONFIG_LOONGSON3V=y
 CONFIG_ATI_VGA=y
 CONFIG_RTL8139_PCI=y
 CONFIG_JAZZ=y
diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index 67d39c5..cc5609b 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -45,6 +45,17 @@ config FULOONG
 bool
 select PCI_BONITO
 
+config LOONGSON3V
+bool
+select PCKBD
+select SERIAL
+select GOLDFISH_RTC
+select LOONGSON_LIOINTC
+select PCI_EXPRESS_GENERIC_BRIDGE
+select VIRTIO_VGA
+select QXL if SPICE
+select MSI_NONBROKEN
+
 config MIPS_CPS
 bool
 select PTIMER
diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs
index 739e2b7..0993852 100644
--- a/hw/mips/Makefile.objs
+++ b/hw/mips/Makefile.objs
@@ -4,5 +4,6 @@ obj-$(CONFIG_MALTA) += gt64xxx_pci.o malta.o
 obj-$(CONFIG_MIPSSIM) += mipssim.o
 obj-$(CONFIG_JAZZ) += jazz.o
 obj-$(CONFIG_FULOONG) += fuloong2e.o
+obj-$(CONFIG_LOONGSON3V) += loongson3_virt.o
 obj-$(CONFIG_MIPS_CPS) += cps.o
 obj-$(CONFIG_MIPS_BOSTON) += boston.o
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
new file mode 100644
index 000..e0e1939
--- /dev/null
+++ b/hw/mips/loongson3_virt.c
@@ -0,0 +1,978 @@
+/*
+ * Generic Loongson-3 Platform support
+ *
+ * Copyright (c) 2016-2020 Huacai Chen (che...@lemote.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Generic virtualized PC Platform based on Loongson-3 CPU (MIPS64R2 with
+ * extensions, 800~2000MHz)
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "elf.h"
+#include "kvm_mips.h"
+#include "hw/boards.h"
+#include "hw/char/serial.h"
+#include "hw/mips/mips.h"
+#include "hw/mips/cpudevs.h"
+#include "hw/misc/empty_slot.h"
+#include "hw/intc/i8259.h"
+#include "hw/loader.h"
+#include "hw/isa/superio.h"
+#include "hw/pci/msi.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_host.h"
+#include "hw/pci-host/gpex.h"
+#include "hw/rtc/mc146818rtc.h"
+#include "hw/usb.h"
+#include "net/net.h"
+#include "exec/address-spaces.h"
+#include "sysemu/kvm.h"
+#include "sysemu/qtest.h"
+#include "sysemu/reset.h&quo

[PATCH V6 4/4] MAINTAINERS: Add Loongson-3 maintainer and reviewer

2020-06-24 Thread Huacai Chen
Add myself as a maintainer of Loongson-3 virtual platform, and also add
Jiaxun Yang as a reviewer.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 51a4570..0226a74 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1095,6 +1095,13 @@ F: hw/isa/vt82c686.c
 F: hw/pci-host/bonito.c
 F: include/hw/isa/vt82c686.h
 
+Loongson-3 Virtual Platform
+M: Huacai Chen 
+R: Jiaxun Yang 
+S: Maintained
+F: hw/mips/loongson3_virt.c
+F: hw/intc/loongson_liointc.c
+
 Boston
 M: Paul Burton 
 R: Aleksandar Rikalo 
-- 
2.7.0




[PATCH V6 2/4] hw/intc: Add Loongson liointc support

2020-06-24 Thread Huacai Chen
Loongson-3 has an integrated liointc (Local I/O interrupt controller).
It is similar to goldfish interrupt controller, but more powerful (e.g.,
it can route external interrupt to multi-cores).

Documents about Loongson-3's liointc:
1, https://wiki.godson.ac.cn/ip_block:liointc;
2, The "I/O中断" section of Loongson-3's user mannual, part 1.

Signed-off-by: Huacai Chen 
Signed-off-by: Jiaxun Yang 
---
 hw/intc/Kconfig|   3 +
 hw/intc/Makefile.objs  |   1 +
 hw/intc/loongson_liointc.c | 241 +
 3 files changed, 245 insertions(+)
 create mode 100644 hw/intc/loongson_liointc.c

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index f562342..2ae1e89 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -64,3 +64,6 @@ config OMPIC
 
 config RX_ICU
 bool
+
+config LOONGSON_LIOINTC
+bool
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index a420263..3ac2b40 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -51,3 +51,4 @@ obj-$(CONFIG_MIPS_CPS) += mips_gic.o
 obj-$(CONFIG_NIOS2) += nios2_iic.o
 obj-$(CONFIG_OMPIC) += ompic.o
 obj-$(CONFIG_IBEX) += ibex_plic.o
+obj-$(CONFIG_LOONGSON_LIOINTC) += loongson_liointc.o
diff --git a/hw/intc/loongson_liointc.c b/hw/intc/loongson_liointc.c
new file mode 100644
index 000..e39e39e
--- /dev/null
+++ b/hw/intc/loongson_liointc.c
@@ -0,0 +1,241 @@
+/*
+ * QEMU Loongson Local I/O interrupt controler.
+ *
+ * Copyright (c) 2020 Jiaxun Yang 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "qemu/module.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+
+#define D(x)
+
+#define NUM_IRQS32
+
+#define NUM_CORES   4
+#define NUM_IPS 4
+#define NUM_PARENTS (NUM_CORES * NUM_IPS)
+#define PARENT_COREx_IPy(x, y)(NUM_IPS * x + y)
+
+#define R_MAPPER_START0x0
+#define R_MAPPER_END  0x20
+#define R_ISR   R_MAPPER_END
+#define R_IEN   0x24
+#define R_IEN_SET   0x28
+#define R_IEN_CLR   0x2c
+#define R_PERCORE_ISR(x) (0x40 + 0x8 * x)
+#define R_END   0x64
+
+#define TYPE_LOONGSON_LIOINTC "loongson.liointc"
+#define LOONGSON_LIOINTC(obj) \
+OBJECT_CHECK(struct loongson_liointc, (obj), TYPE_LOONGSON_LIOINTC)
+
+struct loongson_liointc {
+SysBusDevice parent_obj;
+
+MemoryRegion mmio;
+qemu_irq parent_irq[NUM_PARENTS];
+
+uint8_t mapper[NUM_IRQS]; /* 0:3 for core, 4:7 for IP */
+uint32_t isr;
+uint32_t ien;
+uint32_t per_core_isr[NUM_CORES];
+
+/* state of the interrupt input pins */
+uint32_t pin_state;
+bool parent_state[NUM_PARENTS];
+};
+
+static void update_irq(struct loongson_liointc *p)
+{
+uint32_t irq, core, ip;
+uint32_t per_ip_isr[NUM_IPS] = {0};
+
+/* level triggered interrupt */
+p->isr = p->pin_state;
+
+/* Clear disabled IRQs */
+p->isr &= p->ien;
+
+/* Clear per_core_isr */
+for (core = 0; core < NUM_CORES; core++) {
+p->per_core_isr[core] = 0;
+}
+
+/* Update per_core_isr and per_ip_isr */
+for (irq = 0; irq < NUM_IRQS; irq++) {
+if (!(p->isr & (1 << irq))) {
+continue;
+}
+
+for (core = 0; core < NUM_CORES; core++) {
+if ((p->mapper[irq] & (1 << core))) {
+p->per_core_isr[core] |= (1 << irq);
+}
+}
+
+for (ip = 0; ip < NUM_IPS; ip++) {
+if ((p->mapper[irq] & (1 << (ip + 4 {
+per_ip_isr[ip] |= (1 << irq);
+}
+}
+}
+
+/* Emit IRQ to parent! */
+for (core = 0; core < NUM_CORES; core++) {
+for (ip = 0; ip < NUM_IPS; ip++) {
+int parent = PARENT_COREx_IPy(core, ip);
+if (p->parent_state[parent] !=
+(!!p->per_core_isr[core] && !!per_ip_isr[ip])) {
+p->parent_state[parent] = !p->parent_state[parent];
+qemu_set_irq(p->parent_irq[parent], p->parent_state[parent]);
+}
+}
+}
+}
+
+static uint64_t
+liointc_read(void *opaque, hwaddr addr, unsigned int size)
+{
+struct loongson_liointc *p = opaque;
+uin

  1   2   3   4   >