From nobody Sat Apr 27 22:08:07 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1592995516; cv=none; d=zohomail.com; s=zohoarc; b=mjm6S3fcBNe7Ofl8WE8gP3fRCRd7yOBx3uz/bfaN9CHZCCaAJNQCEhlD3fJx9MTtfB9wSy5Rwp+lisPiLFKqthMN0c2ffZNLiNyWNvgokios9VWIffDdd8fQ/bZ7wb8qp/ELKDRnD3nTBJD18gO0eIUHcDEUA71AIAay4v6+CK8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1592995516; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=6zv4LKrUNZWMbaVi6BSvUFBtq8jf6g3exSrZ11NT8kw=; b=XPbR6ca2nsTeOB+DpDAcxCSqBqnz5YImqFY5yfk7Tla+TmlE0YGOPWeh3HSAxpfEy7xO817Pe/wJVjvihdkiAz+aA80MjMNEF6E1fIIqZkRFa4WQ+nDBqN5LfUXrnBw6VSJfmGeJc99y4xm8qp1idyWrgT4Hsrxx5HxZPttLpsc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1592995516624868.6172403870655; Wed, 24 Jun 2020 03:45:16 -0700 (PDT) Received: from localhost ([::1]:59288 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jo2u3-00010n-Bd for importer@patchew.org; Wed, 24 Jun 2020 06:45:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54086) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jo2t6-000087-B4 for qemu-devel@nongnu.org; Wed, 24 Jun 2020 06:44:16 -0400 Received: from mail-pl1-x644.google.com ([2607:f8b0:4864:20::644]:44031) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jo2t4-0007FC-OW for qemu-devel@nongnu.org; Wed, 24 Jun 2020 06:44:16 -0400 Received: by mail-pl1-x644.google.com with SMTP id x8so12064plm.10 for ; Wed, 24 Jun 2020 03:44:14 -0700 (PDT) Received: from software.domain.org (28.144.92.34.bc.googleusercontent.com. [34.92.144.28]) by smtp.gmail.com with ESMTPSA id q6sm19772395pff.163.2020.06.24.03.44.11 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 24 Jun 2020 03:44:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=6zv4LKrUNZWMbaVi6BSvUFBtq8jf6g3exSrZ11NT8kw=; b=lyKehYlC3nPymjcC/Esz1X+YtU7MT/JufUjitssMiVduviY8jZbfDI+sRx6gtJ7KSX yrDditTiuWrOYvUzcBs4Gb7XtTnSvE01HsmmoGrqLbmijQJ2a8wGrmpNbZQS0bS/F7Sg hRk7u1dBAK8CqbbHy4zC7dCjmtvaPCijtgLoauCOV/rVrk7Ev/aIvNLiKPkEgJCRfHwu p63Hf8KXx3GnSsrVlfbhNQfkw7MCd6Gil3tfU4AgY0CLICAwZg0+4z/74/3gIDOUUue8 +QkBpRRMo2b4GagY8Jf65W+7/cKAAXeE1U+2FPX2Ixwzf1Pizt454lAMtL7gzyPQpjBI sR6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=6zv4LKrUNZWMbaVi6BSvUFBtq8jf6g3exSrZ11NT8kw=; b=N7JwE3KyF4ftqAjD+22s9phJGFPwqELcj0+TRyEn+kBxClciSv2/t27aG7k3RlHyEd I9aWPdq4hQU6ggXeTv51Jmt3Vy/eERYQdoiFN+lxCEOMmbLRj8EBdkEKyagTlh0ZztHx i3S1XFl1dam1nr1da9yPXn5ho1KObbtNtn7r2qFlWmxnn2ABDb+U2AXd0LUbG+2P2ax0 9OhFcDSJpC0UoX8tEwvFySrrfzwDnqDU5A+K0Q5k9nUrGzKYgkAQB96Ro40p34dWJ7iD syxokkE7KAvIEK9/7Kf3TS9IROg9PyPI8eHH1GdX3lkdccHPNajE2zpy812Mkhht1UOr CZ3g== X-Gm-Message-State: AOAM532/gzM/Xe0XgDnvd56AdeWtWcqx11KH/f0Y7YjcC5lbzCDNAVr6 YUp25E9yEgDuLUCGgEL+wJc= X-Google-Smtp-Source: ABdhPJyJHkKpPekpV9mYL1k+ulMTYvopXSV+KbczZ4AcluCRmfjWWCE8BPr/oR/6o+jSAGtPVj818w== X-Received: by 2002:a17:90a:950e:: with SMTP id t14mr25492150pjo.99.1592995453438; Wed, 24 Jun 2020 03:44:13 -0700 (PDT) From: Huacai Chen X-Google-Original-From: Huacai Chen To: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Aleksandar Markovic Subject: [PATCH V6 1/4] hw/mips: Implement the kvm_type() hook in MachineClass Date: Wed, 24 Jun 2020 18:45:28 +0800 Message-Id: <1592995531-32600-2-git-send-email-chenhc@lemote.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1592995531-32600-1-git-send-email-chenhc@lemote.com> References: <1592995531-32600-1-git-send-email-chenhc@lemote.com> Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::644; envelope-from=zltjiangshi@gmail.com; helo=mail-pl1-x644.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Huacai Chen , Huacai Chen , Aleksandar Rikalo , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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" =20 #define DEBUG_KVM 0 =20 @@ -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 =3D KVM_STATE(machine->accelerator); + + r =3D kvm_check_extension(s, KVM_CAP_MIPS_VZ); + if (r > 0) { + return KVM_VM_MIPS_VZ; + } + + r =3D 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 =20 +#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); =20 +#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 */ --=20 2.7.0 From nobody Sat Apr 27 22:08:07 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1592995735; cv=none; d=zohomail.com; s=zohoarc; b=niZl+/T4CSf6uCRAAMPsiDBdfjQqVbHsRyW+a28Z3PUjMP/Ktbwk/H2O3+EbQzBa3YlANfuY1ABgtz5qrKGqw2SXWhMPZav7m/MjpCOriacOAWpY96AL2Ih4f8upzi0lzS2/plA+tLHKnedbQA83lPie1cJ2V2keQDgDuuMt5dI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1592995735; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=NPuODA5fSgxiIW6iJpbMrQsxewuE64kAisz5nousKIc=; b=BjpEip0fDFfQdaJhcuVfD34OZcUTHSsz3Y4lc4TecI2D6LFObHdmE09Nz7riPl9SMTdNRMdQnihuiw8Lrm/NvqbqKPz0NeZH1IsJyrDHRG9xBtTfwHi3m0k7Pvk3YjRCRU99I/SK9H7kzbXbGzyzf2YFqmiu0Zb7alTS6zerx2Q= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1592995734868767.8604818215753; Wed, 24 Jun 2020 03:48:54 -0700 (PDT) Received: from localhost ([::1]:41712 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jo2xZ-0005qQ-IQ for importer@patchew.org; Wed, 24 Jun 2020 06:48:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54292) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jo2ti-0000rY-69 for qemu-devel@nongnu.org; Wed, 24 Jun 2020 06:44:54 -0400 Received: from mail-pl1-x641.google.com ([2607:f8b0:4864:20::641]:37348) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jo2tf-0007Xo-Fd for qemu-devel@nongnu.org; Wed, 24 Jun 2020 06:44:53 -0400 Received: by mail-pl1-x641.google.com with SMTP id y18so915718plr.4 for ; Wed, 24 Jun 2020 03:44:51 -0700 (PDT) Received: from software.domain.org (28.144.92.34.bc.googleusercontent.com. [34.92.144.28]) by smtp.gmail.com with ESMTPSA id q6sm19772395pff.163.2020.06.24.03.44.47 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 24 Jun 2020 03:44:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=NPuODA5fSgxiIW6iJpbMrQsxewuE64kAisz5nousKIc=; b=Yyn9Vb3b+0PjHu5yINKohpnEbpTJ2F/L7p7R+/KmuvOlDsgRcfYtVUsTMMlSjkeJZg sF8I0AqoQgE9bzqWXCc24Zsmj6Z4CdD5O7zNhRQPZWqUvWLVYFqHP9OJfeb6LZxtEvga IQUddHhwgMBMtSwWTyO5lUe8Oim6/+qu01WsaSbgbiF681+5yCVlam7SCTA4GZvZAnzJ YWAX3ZwgytOaQ4NsQG+xawKSyo7fVu6L0qpXeok8TqcxZdwmhcOblpCKklyuROcx2YOu O/t2Nxmdw7JfhS9Z6nlNSNHT3U0pm7/OnBEiFGNH6U6V6iSWG9t0sKuciv7cC67bvnB7 JbXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=NPuODA5fSgxiIW6iJpbMrQsxewuE64kAisz5nousKIc=; b=VxsClCdUYfC81jDU6S2ga2IW0izXslYDi2s/ZecTUrMn3Pw8eg+jnthcnDP0RdWRDz NykqARMAOTCbbCofPhq+VW3oZOCEZg7ZXPZ8XO8dt/sCkmzooFb7i2+jsJzx2UpoGj6P q1kdUIWzTMQ0/gD0K1oGsGevJFtnRXAB9Ji6eJx/2R7I4U0PqSqILeeWtR8VB2EfI6wE TYyX+5tyY2itGLCn+oY69jbj/BfAcTIX2/uNkce/yd9zVV0KGFVvgpCZvUHF1KKAV7TD VwSsip+KKk3jv7FX1Qz1bHMnDlUBfKgT0jdIaD2nxJcT5rqaedPAfPWZ0rRdSm2RX1KH XHEg== X-Gm-Message-State: AOAM5313K37N0vY/jglcYjVep2OEzAPC+2/aYt7Qv0nTzGH+Cqv68SEB sVZGupMOaINOB7LY4la5HjA= X-Google-Smtp-Source: ABdhPJzo39JdJnOZ14BsOK8ZlLEnjCgFrRCNVef8TXkxs3ntn4PxkV35jXQE+45BXtGAx0qL82Yr8A== X-Received: by 2002:a17:90a:fe0c:: with SMTP id ck12mr28981708pjb.209.1592995490127; Wed, 24 Jun 2020 03:44:50 -0700 (PDT) From: Huacai Chen X-Google-Original-From: Huacai Chen To: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Aleksandar Markovic Subject: [PATCH V6 2/4] hw/intc: Add Loongson liointc support Date: Wed, 24 Jun 2020 18:45:29 +0800 Message-Id: <1592995531-32600-3-git-send-email-chenhc@lemote.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1592995531-32600-1-git-send-email-chenhc@lemote.com> References: <1592995531-32600-1-git-send-email-chenhc@lemote.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::641; envelope-from=zltjiangshi@gmail.com; helo=mail-pl1-x641.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Aleksandar Rikalo , Huacai Chen , qemu-devel@nongnu.org, Jiaxun Yang , Huacai Chen , Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) 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=E4=B8=AD=E6=96=AD" section of Loongson-3's user mannual, part 1. Signed-off-by: Huacai Chen Signed-off-by: Jiaxun Yang Reviewed-by: Aleksandar Markovic --- 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 =20 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) +=3D mips_gic.o obj-$(CONFIG_NIOS2) +=3D nios2_iic.o obj-$(CONFIG_OMPIC) +=3D ompic.o obj-$(CONFIG_IBEX) +=3D ibex_plic.o +obj-$(CONFIG_LOONGSON_LIOINTC) +=3D loongson_liointc.o diff --git a/hw/intc/loongson_liointc.c b/hw/intc/loongson_liointc.c new file mode 100644 index 0000000..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 . + */ + +#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_IRQS 32 + +#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_START 0x0 +#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] =3D {0}; + + /* level triggered interrupt */ + p->isr =3D p->pin_state; + + /* Clear disabled IRQs */ + p->isr &=3D p->ien; + + /* Clear per_core_isr */ + for (core =3D 0; core < NUM_CORES; core++) { + p->per_core_isr[core] =3D 0; + } + + /* Update per_core_isr and per_ip_isr */ + for (irq =3D 0; irq < NUM_IRQS; irq++) { + if (!(p->isr & (1 << irq))) { + continue; + } + + for (core =3D 0; core < NUM_CORES; core++) { + if ((p->mapper[irq] & (1 << core))) { + p->per_core_isr[core] |=3D (1 << irq); + } + } + + for (ip =3D 0; ip < NUM_IPS; ip++) { + if ((p->mapper[irq] & (1 << (ip + 4)))) { + per_ip_isr[ip] |=3D (1 << irq); + } + } + } + + /* Emit IRQ to parent! */ + for (core =3D 0; core < NUM_CORES; core++) { + for (ip =3D 0; ip < NUM_IPS; ip++) { + int parent =3D PARENT_COREx_IPy(core, ip); + if (p->parent_state[parent] !=3D + (!!p->per_core_isr[core] && !!per_ip_isr[ip])) { + p->parent_state[parent] =3D !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 =3D opaque; + uint32_t r =3D 0; + + /* Mapper is 1 byte */ + if (size =3D=3D 1 && addr < R_MAPPER_END) { + r =3D p->mapper[addr]; + goto out; + } + + /* Rest is 4 byte */ + if (size !=3D 4 || (addr % 4)) { + goto out; + } + + if (addr >=3D R_PERCORE_ISR(0) && + addr < R_PERCORE_ISR(NUM_CORES)) { + int core =3D (addr - R_PERCORE_ISR(0)) / 4; + r =3D p->per_core_isr[core]; + goto out; + } + + switch (addr) { + case R_ISR: + r =3D p->isr; + break; + case R_IEN: + r =3D p->ien; + break; + default: + break; + } + +out: + D(qemu_log("%s: size=3D%d addr=3D%lx val=3D%x\n", __func__, size, addr= , r)); + return r; +} + +static void +liointc_write(void *opaque, hwaddr addr, + uint64_t val64, unsigned int size) +{ + struct loongson_liointc *p =3D opaque; + uint32_t value =3D val64; + + D(qemu_log("%s: size=3D%d, addr=3D%lx val=3D%x\n", __func__, size, add= r, value)); + + /* Mapper is 1 byte */ + if (size =3D=3D 1 && addr < R_MAPPER_END) { + p->mapper[addr] =3D value; + goto out; + } + + /* Rest is 4 byte */ + if (size !=3D 4 || (addr % 4)) { + goto out; + } + + if (addr >=3D R_PERCORE_ISR(0) && + addr < R_PERCORE_ISR(NUM_CORES)) { + int core =3D (addr - R_PERCORE_ISR(0)) / 4; + p->per_core_isr[core] =3D value; + goto out; + } + + switch (addr) { + case R_IEN_SET: + p->ien |=3D value; + break; + case R_IEN_CLR: + p->ien &=3D ~value; + break; + default: + break; + } + +out: + update_irq(p); +} + +static const MemoryRegionOps pic_ops =3D { + .read =3D liointc_read, + .write =3D liointc_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, + .valid =3D { + .min_access_size =3D 1, + .max_access_size =3D 4 + } +}; + +static void irq_handler(void *opaque, int irq, int level) +{ + struct loongson_liointc *p =3D opaque; + + p->pin_state &=3D ~(1 << irq); + p->pin_state |=3D level << irq; + update_irq(p); +} + +static void loongson_liointc_init(Object *obj) +{ + struct loongson_liointc *p =3D LOONGSON_LIOINTC(obj); + int i; + + qdev_init_gpio_in(DEVICE(obj), irq_handler, 32); + + for (i =3D 0; i < NUM_PARENTS; i++) { + sysbus_init_irq(SYS_BUS_DEVICE(obj), &p->parent_irq[i]); + } + + memory_region_init_io(&p->mmio, obj, &pic_ops, p, + "loongson.liointc", R_END); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &p->mmio); +} + +static const TypeInfo loongson_liointc_info =3D { + .name =3D TYPE_LOONGSON_LIOINTC, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(struct loongson_liointc), + .instance_init =3D loongson_liointc_init, +}; + +static void loongson_liointc_register_types(void) +{ + type_register_static(&loongson_liointc_info); +} + +type_init(loongson_liointc_register_types) --=20 2.7.0 From nobody Sat Apr 27 22:08:07 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1592995599; cv=none; d=zohomail.com; s=zohoarc; b=TnEEvSUUUvUpubHG5Yf2Gz+ATu+/OdboaroW+viusZjduMQVzu6G91X8rSu2gUcF8L/Q7WOolzCUX7VrXxnJ5zXRETgf5bwDVEgLLbtI4qNyGiAOK1h+qKWMJ1e9WhCUaWVilaqrdZh5fdVaCPFLTZ/c4rUXpPulCybtEPmKc8U= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1592995599; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=BluAEgEuqz6avrnmxEuNnax5MrFGbbHsVIrcYuGcM6E=; b=AxEzSnDj/h1M2I+h2Ha8D1Ai9IldgXEe9uopNdxlOJdeJb7k3V/lGBcEieKiVAghNp7oMccxngNpgQaqR9nEYyuRPT2/2DY661yLzoU3d5dZjv8scJxy546HKKtNUE+wMEezH/en3fhLhr0j12WsqfQHRexNj9gUSa489tzv11Q= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1592995599596451.2991100278408; Wed, 24 Jun 2020 03:46:39 -0700 (PDT) Received: from localhost ([::1]:35094 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jo2vO-00034B-4e for importer@patchew.org; Wed, 24 Jun 2020 06:46:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54484) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jo2uA-0001av-8J for qemu-devel@nongnu.org; Wed, 24 Jun 2020 06:45:22 -0400 Received: from mail-pf1-x42e.google.com ([2607:f8b0:4864:20::42e]:36395) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jo2u6-0007kp-HU for qemu-devel@nongnu.org; Wed, 24 Jun 2020 06:45:21 -0400 Received: by mail-pf1-x42e.google.com with SMTP id 207so815719pfu.3 for ; Wed, 24 Jun 2020 03:45:18 -0700 (PDT) Received: from software.domain.org (28.144.92.34.bc.googleusercontent.com. [34.92.144.28]) by smtp.gmail.com with ESMTPSA id q6sm19772395pff.163.2020.06.24.03.45.13 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 24 Jun 2020 03:45:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=BluAEgEuqz6avrnmxEuNnax5MrFGbbHsVIrcYuGcM6E=; b=djQdzAlzy72u/HHas4Ma1hJwzYA/aZg3wr+AuIIM8zmMrPjpJxXqO1ki/Gjixyyucc IK2hASudv0t+5rlFZYAs130iYZsd8sv0Aw4t//Nl4RXsNAXsbCuKr14CV9MDCTRuzJER YRkuxYA4RnPcT4ywDCvagftq4nA6TjyzCWQIbtNkNQMoR4okJNor/LITzNvGXHlzmV2o OvMs3cjmJvzz+13ePe36VgzTJL8EdO0N+JLjgHTGeC+ho5XXV/Yd1eQayImbfInaVNz7 H2JKbieP5n+EglxoPxaCq5HK+QDpn+ZOoCV8nE29NPJWfv9ZLSagX7gQAe3QyX0AA8fa 5Mdw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=BluAEgEuqz6avrnmxEuNnax5MrFGbbHsVIrcYuGcM6E=; b=gTda/7JwdnsWuKMHA5ThhDyQO+XoKHWnLAOj59hPgUw46S4qhjt1PecEwaYBCxkNOv T/ExIMPOK1SotN0XQkTlo2eTTFjAZlECgSkRBpEkU+pIpHxSr/Mvt1PyWRbMXwmDeVQq 1kFaNPFSsoC9y59n3qRSBIxCE0uK3r8ZlWGTEun4pB/6WP5mOxEKGzhNBhN7X5a0IyAo 8zFtFpbhgSG16n55eSfMuXNzTlKNNOOrHd7ydclpLcTlylSDYHrQt/HwoKo6AyQDd+RB 8xSJ2Qe2BcCiwtxHzNje+UU7/ASAhsGAqWisRKphEfqi4RRQLymM54RMUXs6/LWPkmsa 53gg== X-Gm-Message-State: AOAM532sHYWWkijTlapSOtZ++eLXldOk7qy6j2hbZE6SIpRkt5Crs0bH V3yC7SKZwS97gg/udjDvJZU= X-Google-Smtp-Source: ABdhPJwEbDBplpY7zI5GCzwlz8mfg89io9Rqbyqr79JYfezxwXX7TfLfg87DAevCkGRJxUwEMIt80A== X-Received: by 2002:a63:e550:: with SMTP id z16mr20466902pgj.92.1592995516446; Wed, 24 Jun 2020 03:45:16 -0700 (PDT) From: Huacai Chen X-Google-Original-From: Huacai Chen To: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Aleksandar Markovic Subject: [PATCH V6 3/4] hw/mips: Add Loongson-3 machine support (with KVM) Date: Wed, 24 Jun 2020 18:45:30 +0800 Message-Id: <1592995531-32600-4-git-send-email-chenhc@lemote.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1592995531-32600-1-git-send-email-chenhc@lemote.com> References: <1592995531-32600-1-git-send-email-chenhc@lemote.com> Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::42e; envelope-from=zltjiangshi@gmail.com; helo=mail-pf1-x42e.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Huacai Chen , Huacai Chen , Aleksandar Rikalo , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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=3Dtcg -cpu Loongson-3A1= 000 -kernel -append ... Use QEMU with KVM (available at present): qemu-system-mips64el -M loongson3-virt,accel=3Dkvm -cpu Loongson-3A4= 000 -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/mips64e= l-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=3Dy CONFIG_FULOONG=3Dy +CONFIG_LOONGSON3V=3Dy CONFIG_ATI_VGA=3Dy CONFIG_RTL8139_PCI=3Dy CONFIG_JAZZ=3Dy 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 =20 +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) +=3D gt64xxx_pci.o malta.o obj-$(CONFIG_MIPSSIM) +=3D mipssim.o obj-$(CONFIG_JAZZ) +=3D jazz.o obj-$(CONFIG_FULOONG) +=3D fuloong2e.o +obj-$(CONFIG_LOONGSON3V) +=3D loongson3_virt.o obj-$(CONFIG_MIPS_CPS) +=3D cps.o obj-$(CONFIG_MIPS_BOSTON) +=3D boston.o diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c new file mode 100644 index 0000000..e0e1939 --- /dev/null +++ b/hw/mips/loongson3_virt.c @@ -0,0 +1,978 @@ +/* + * Generic Loongson-3 Platform support + * + * Copyright (c) 2016-2020 Huacai Chen (chenhc@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 . + */ + +/* + * 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 { + LOADER_BOOTROM, + LOADER_PARAM, +}; + +struct MemmapEntry { + hwaddr base; + hwaddr size; +}; + +/* Data for BIOS to identify machine */ +#define FW_CFG_MACHINE_VERSION (FW_CFG_ARCH_LOCAL + 0) +#define FW_CFG_CPU_FREQ (FW_CFG_ARCH_LOCAL + 1) + +/* + * LEFI (a UEFI-like interface for BIOS-Kernel boot parameters) data struc= trues + * defined at arch/mips/include/asm/mach-loongson64/boot_param.h in Linux = kernel + */ +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 si= ze */ + } map[128]; +} __attribute__((packed)); + +enum loongson_cpu_type { + Legacy_2E =3D 0x0, + Legacy_2F =3D 0x1, + Legacy_3A =3D 0x2, + Legacy_3B =3D 0x3, + Legacy_1A =3D 0x4, + Legacy_1B =3D 0x5, + Legacy_2G =3D 0x6, + Legacy_2H =3D 0x7, + Loongson_1A =3D 0x100, + Loongson_1B =3D 0x101, + Loongson_2E =3D 0x200, + Loongson_2F =3D 0x201, + Loongson_2G =3D 0x202, + Loongson_2H =3D 0x203, + Loongson_3A =3D 0x300, + Loongson_3B =3D 0x301 +}; + +/* + * Capability and feature descriptor structure for MIPS CPU + */ +struct efi_cpuinfo_loongson { + uint16_t vers; /* version of efi_cpuinfo_loongson */ + uint32_t processor_id; /* PRID, e.g. 6305, 6306 */ + uint32_t cputype; /* Loongson_3A/3B, etc. */ + uint32_t total_node; /* num of total numa nodes */ + uint16_t cpu_startup_core_id; /* Boot core id */ + uint16_t reserved_cores_mask; + uint32_t cpu_clock_freq; /* cpu_clock */ + uint32_t nr_cpus; + char cpuname[64]; +} __attribute__((packed)); + +#define MAX_UARTS 64 +struct uart_device { + uint32_t iotype; + uint32_t uartclk; + uint32_t int_offset; + uint64_t uart_base; +} __attribute__((packed)); + +#define MAX_SENSORS 64 +#define SENSOR_TEMPER 0x00000001 +#define SENSOR_VOLTAGE 0x00000002 +#define SENSOR_FAN 0x00000004 +struct sensor_device { + char name[32]; /* a formal name */ + char label[64]; /* a flexible description */ + uint32_t type; /* SENSOR_* */ + uint32_t id; /* instance id of a sensor-class */ + uint32_t fan_policy; /* step speed or constant speed */ + uint32_t fan_percent;/* only for constant speed policy */ + uint64_t base_addr; /* base address of device registers */ +} __attribute__((packed)); + +struct system_loongson { + uint16_t vers; /* version of system_loongson */ + uint32_t ccnuma_smp; /* 0: no numa; 1: has numa */ + uint32_t sing_double_channel;/* 1: single; 2: double */ + uint32_t nr_uarts; + struct uart_device uarts[MAX_UARTS]; + uint32_t nr_sensors; + struct sensor_device sensors[MAX_SENSORS]; + char has_ec; + char ec_name[32]; + uint64_t ec_base_addr; + char has_tcm; + char tcm_name[32]; + uint64_t tcm_base_addr; + uint64_t workarounds; + uint64_t of_dtb_addr; /* NULL if not support */ +} __attribute__((packed)); + +struct irq_source_routing_table { + uint16_t vers; + uint16_t size; + uint16_t rtr_bus; + uint16_t rtr_devfn; + uint32_t vendor; + uint32_t device; + uint32_t PIC_type; /* conform use HT or PCI to route to CPU-= PIC */ + uint64_t ht_int_bit; /* 3A: 1<<24; 3B: 1<<16 */ + uint64_t ht_enable; /* irqs used in this PIC */ + uint32_t node_id; /* node id: 0x0-0; 0x1-1; 0x10-2; 0x11-3 = */ + uint64_t pci_mem_start_addr; + uint64_t pci_mem_end_addr; + uint64_t pci_io_start_addr; + uint64_t pci_io_end_addr; + uint64_t pci_config_addr; + uint16_t dma_mask_bits; + uint16_t dma_noncoherent; +} __attribute__((packed)); + +struct interface_info { + uint16_t vers; /* version of the specificition */ + uint16_t size; + uint8_t flag; + char description[64]; +} __attribute__((packed)); + +#define MAX_RESOURCE_NUMBER 128 +struct resource_loongson { + uint64_t start; /* resource start address */ + uint64_t end; /* resource end address */ + char name[64]; + uint32_t flags; +}; + +struct archdev_data {}; /* arch specific additions */ + +struct board_devices { + char name[64]; /* hold the device name */ + uint32_t num_resources; /* number of device_resource */ + /* for each device's resource */ + struct resource_loongson resource[MAX_RESOURCE_NUMBER]; + /* arch specific additions */ + struct archdev_data archdata; +}; + +struct loongson_special_attribute { + uint16_t vers; /* version of this special */ + char special_name[64]; /* special_atribute_name */ + uint32_t loongson_special_type; /* type of special device */ + /* for each device's resource */ + struct resource_loongson resource[MAX_RESOURCE_NUMBER]; +}; + +struct loongson_params { + uint64_t memory_offset; /* efi_memory_map_loongson struct offset = */ + uint64_t cpu_offset; /* efi_cpuinfo_loongson struct offset */ + uint64_t system_offset; /* system_loongson struct offset */ + uint64_t irq_offset; /* irq_source_routing_table struct offset= */ + uint64_t interface_offset; /* interface_info struct offset */ + uint64_t special_offset; /* loongson_special_attribute struct offs= et */ + uint64_t boarddev_table_offset; /* board_devices offset */ +}; + +struct smbios_tables { + uint16_t vers; /* version of smbios */ + uint64_t vga_bios; /* vga_bios address */ + struct loongson_params lp; +}; + +struct efi_reset_system_t { + uint64_t ResetCold; + uint64_t ResetWarm; + uint64_t ResetType; + uint64_t Shutdown; + uint64_t DoSuspend; /* NULL if not support */ +}; + +struct efi_loongson { + uint64_t mps; /* MPS table */ + uint64_t acpi; /* ACPI table (IA64 ext 0.71) */ + uint64_t acpi20; /* ACPI table (ACPI 2.0) */ + struct smbios_tables smbios; /* SM BIOS table */ + uint64_t sal_systab; /* SAL system table */ + uint64_t boot_info; /* boot info table */ +}; + +struct boot_params { + struct efi_loongson efi; + struct efi_reset_system_t reset_system; +}; + +#define LOONGSON_MAX_VCPUS 16 + +#define LOONGSON3_BIOSNAME "bios_loongson3.bin" + +#define UART_IRQ 0 +#define RTC_IRQ 1 +#define PCIE_IRQ_BASE 2 + +#define align(x) (((x) + 63) & ~63) + +static const struct MemmapEntry virt_memmap[] =3D { + [VIRT_LOWMEM] =3D { 0x00000000, 0x10000000 }, + [VIRT_PM] =3D { 0x10080000, 0x100 }, + [VIRT_FW_CFG] =3D { 0x10080100, 0x100 }, + [VIRT_RTC] =3D { 0x10081000, 0x1000 }, + [VIRT_PCIE_PIO] =3D { 0x18000000, 0xc0000 }, + [VIRT_PCIE_ECAM] =3D { 0x1a000000, 0x2000000 }, + [VIRT_BIOS_ROM] =3D { 0x1fc00000, 0x200000 }, + [VIRT_UART] =3D { 0x1fe001e0, 0x8 }, + [VIRT_LIOINTC] =3D { 0x3ff01400, 0x64 }, + [VIRT_PCIE_MMIO] =3D { 0x40000000, 0x40000000 }, + [VIRT_HIGHMEM] =3D { 0x80000000, 0x0 }, /* Variable */ +}; + +static const struct MemmapEntry loader_memmap[] =3D { + [LOADER_KERNEL] =3D { 0x00000000, 0x4000000 }, + [LOADER_INITRD] =3D { 0x04000000, 0x0 }, /* Variable */ + [LOADER_CMDLINE] =3D { 0x0ff00000, 0x100000 }, +}; + +static const struct MemmapEntry loader_rommap[] =3D { + [LOADER_BOOTROM] =3D { 0x1fc00000, 0x1000 }, + [LOADER_PARAM] =3D { 0x1fc01000, 0x10000 }, +}; + +static struct _loaderparams { + uint64_t ram_size; + const char *kernel_cmdline; + const char *kernel_filename; + const char *initrd_filename; + uint64_t kernel_entry; + uint64_t a0, a1, a2; +} loaderparams; + +static uint64_t loongson3_pm_read(void *opaque, hwaddr addr, unsigned size) +{ + return 0; +} + +static void loongson3_pm_write(void *opaque, hwaddr addr, uint64_t val, un= signed size) +{ + if (addr !=3D PM_CNTL_MODE) { + return; + } + + switch (val) { + case 0x00: + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); + return; + case 0xff: + qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); + return; + default: + return; + } +} + +static const MemoryRegionOps loongson3_pm_ops =3D { + .read =3D loongson3_pm_read, + .write =3D loongson3_pm_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, +}; + +static struct efi_memory_map_loongson *init_memory_map(void *g_map) +{ + struct efi_memory_map_loongson *emap =3D g_map; + + emap->nr_map =3D 2; + emap->mem_freq =3D 300000000; + + emap->map[0].node_id =3D 0; + emap->map[0].mem_type =3D 1; + emap->map[0].mem_start =3D 0x0; + emap->map[0].mem_size =3D (loaderparams.ram_size > 0x10000000 + ? 256 : (loaderparams.ram_size >> 20)) - 16; + + emap->map[1].node_id =3D 0; + emap->map[1].mem_type =3D 2; + emap->map[1].mem_start =3D 0x90000000; + emap->map[1].mem_size =3D (loaderparams.ram_size > 0x10000000 + ? (loaderparams.ram_size >> 20) - 256 : 0); + + return emap; +} + +#define BUFLEN 1024 + +static uint32_t get_cpu_freq(void) +{ + int fd =3D 0, freq =3D 0; + char buf[BUFLEN], *buf_p; + + fd =3D open("/proc/cpuinfo", O_RDONLY); + if (fd =3D=3D -1) { + fprintf(stderr, "Failed to open /proc/cpuinfo!\n"); + return 0; + } + + if (read(fd, buf, BUFLEN) < 0) { + close(fd); + fprintf(stderr, "Failed to read /proc/cpuinfo!\n"); + return 0; + } + close(fd); + + buf_p =3D strstr(buf, "model name"); + while (*buf_p !=3D '@') { + buf_p++; + } + + buf_p +=3D 2; + memcpy(buf, buf_p, 12); + buf_p =3D buf; + while ((*buf_p >=3D '0') && (*buf_p <=3D '9')) { + buf_p++; + } + *buf_p =3D '\0'; + + freq =3D atoi(buf); + + return freq * 1000 * 1000; +} + +static struct efi_cpuinfo_loongson *init_cpu_info(void *g_cpuinfo_loongson) +{ + struct efi_cpuinfo_loongson *c =3D g_cpuinfo_loongson; + + c->cputype =3D Loongson_3A; + c->processor_id =3D MIPS_CPU(first_cpu)->env.CP0_PRid; + c->cpu_clock_freq =3D get_cpu_freq(); + if (!c->cpu_clock_freq) { + c->cpu_clock_freq =3D 500000000; + } + + c->cpu_startup_core_id =3D 0; + c->nr_cpus =3D current_machine->smp.cpus; + c->total_node =3D (current_machine->smp.cpus + 3) / 4; + + return c; +} + +static struct system_loongson *init_system_loongson(void *g_system) +{ + struct system_loongson *s =3D g_system; + + s->ccnuma_smp =3D 0; + s->sing_double_channel =3D 1; + s->nr_uarts =3D 1; + s->uarts[0].iotype =3D 2; + s->uarts[0].int_offset =3D 2; + s->uarts[0].uartclk =3D 25000000; /* Random value */ + s->uarts[0].uart_base =3D virt_memmap[VIRT_UART].base; + + return s; +} + +static struct irq_source_routing_table *init_irq_source(void *g_irq_source) +{ + struct irq_source_routing_table *irq_info =3D g_irq_source; + + irq_info->node_id =3D 0; + irq_info->PIC_type =3D 0; + irq_info->dma_mask_bits =3D 64; + irq_info->pci_mem_start_addr =3D virt_memmap[VIRT_PCIE_MMIO].base; + irq_info->pci_mem_end_addr =3D virt_memmap[VIRT_PCIE_MMIO].base + + virt_memmap[VIRT_PCIE_MMIO].size - 1; + irq_info->pci_io_start_addr =3D virt_memmap[VIRT_PCIE_PIO].base; + + return irq_info; +} + +static struct interface_info *init_interface_info(void *g_interface) +{ + struct interface_info *interface =3D g_interface; + + interface->vers =3D 0x01; + strcpy(interface->description, "UEFI_Version_v1.0"); + + return interface; +} + +static struct board_devices *board_devices_info(void *g_board) +{ + struct board_devices *bd =3D g_board; + + strcpy(bd->name, "Loongson-3A-VIRT-1w-V1.00-demo"); + + return bd; +} + +static struct loongson_special_attribute *init_special_info(void *g_specia= l) +{ + struct loongson_special_attribute *special =3D g_special; + + strcpy(special->special_name, "2016-08-01"); + + return special; +} + +static void init_loongson_params(struct loongson_params *lp, void *p) +{ + lp->memory_offset =3D (unsigned long long)init_memory_map(p) + - (unsigned long long)lp; + p +=3D align(sizeof(struct efi_memory_map_loongson)); + + lp->cpu_offset =3D (unsigned long long)init_cpu_info(p) + - (unsigned long long)lp; + p +=3D align(sizeof(struct efi_cpuinfo_loongson)); + + lp->system_offset =3D (unsigned long long)init_system_loongson(p) + - (unsigned long long)lp; + p +=3D align(sizeof(struct system_loongson)); + + lp->irq_offset =3D (unsigned long long)init_irq_source(p) + - (unsigned long long)lp; + p +=3D align(sizeof(struct irq_source_routing_table)); + + lp->interface_offset =3D (unsigned long long)init_interface_info(p) + - (unsigned long long)lp; + p +=3D align(sizeof(struct interface_info)); + + lp->boarddev_table_offset =3D (unsigned long long)board_devices_info(p) + - (unsigned long long)lp; + p +=3D align(sizeof(struct board_devices)); + + lp->special_offset =3D (unsigned long long)init_special_info(p) + - (unsigned long long)lp; + p +=3D align(sizeof(struct loongson_special_attribute)); +} + +static void init_reset_system(struct efi_reset_system_t *reset) +{ + reset->Shutdown =3D 0xffffffffbfc000a8; + reset->ResetCold =3D 0xffffffffbfc00080; + reset->ResetWarm =3D 0xffffffffbfc00080; +} + +static void init_boot_param(void) +{ + void *p; + struct boot_params *bp; + + p =3D g_malloc0(loader_rommap[LOADER_PARAM].size); + bp =3D p; + + bp->efi.smbios.vers =3D 1; + init_reset_system(&(bp->reset_system)); + p +=3D align(sizeof(struct boot_params)); + init_loongson_params(&(bp->efi.smbios.lp), p); + + rom_add_blob_fixed("params_rom", bp, + loader_rommap[LOADER_PARAM].size, + loader_rommap[LOADER_PARAM].base); + + g_free(bp); + + loaderparams.a2 =3D cpu_mips_phys_to_kseg0(NULL, + loader_rommap[LOADER_PARAM].b= ase); +} + +static void init_boot_rom(void) +{ + const unsigned int boot_code[] =3D { + 0x40086000, /* mfc0 t0, CP0_STATUS = */ + 0x240900E4, /* li t1, 0xe4 #set kx, sx, ux, erl = */ + 0x01094025, /* or t0, t0, t1 = */ + 0x3C090040, /* lui t1, 0x40 #set bev = */ + 0x01094025, /* or t0, t0, t1 = */ + 0x40886000, /* mtc0 t0, CP0_STATUS = */ + 0x00000000, + 0x40806800, /* mtc0 zero, CP0_CAUSE = */ + 0x00000000, + 0x400A7801, /* mfc0 t2, $15, 1 = */ + 0x314A00FF, /* andi t2, 0x0ff = */ + 0x3C089000, /* dli t0, 0x900000003ff01000 = */ + 0x00084438, + 0x35083FF0, + 0x00084438, + 0x35081000, + 0x314B0003, /* andi t3, t2, 0x3 #local cpuid = */ + 0x000B5A00, /* sll t3, 8 = */ + 0x010B4025, /* or t0, t0, t3 = */ + 0x314C000C, /* andi t4, t2, 0xc #node id = */ + 0x000C62BC, /* dsll t4, 42 = */ + 0x010C4025, /* or t0, t0, t4 = */ + /* WaitForInit: = */ + 0xDD020020, /* ld v0, FN_OFF(t0) #FN_OFF 0x020 = */ + 0x1040FFFE, /* beqz v0, WaitForInit = */ + 0x00000000, /* nop = */ + 0xDD1D0028, /* ld sp, SP_OFF(t0) #FN_OFF 0x028 = */ + 0xDD1C0030, /* ld gp, GP_OFF(t0) #FN_OFF 0x030 = */ + 0xDD050038, /* ld a1, A1_OFF(t0) #FN_OFF 0x038 = */ + 0x00400008, /* jr v0 #byebye = */ + 0x00000000, /* nop = */ + 0x1000FFFF, /* 1: b 1b = */ + 0x00000000, /* nop = */ + + /* Reset = */ + 0x3C0C9000, /* dli t0, 0x9000000010080010 = */ + 0x358C0000, + 0x000C6438, + 0x358C1008, + 0x000C6438, + 0x358C0010, + 0x240D0000, /* li t1, 0x00 = */ + 0xA18D0000, /* sb t1, (t0) = */ + 0x1000FFFF, /* 1: b 1b = */ + 0x00000000, /* nop = */ + + /* Shutdown = */ + 0x3C0C9000, /* dli t0, 0x9000000010080010 = */ + 0x358C0000, + 0x000C6438, + 0x358C1008, + 0x000C6438, + 0x358C0010, + 0x240D00FF, /* li t1, 0xff = */ + 0xA18D0000, /* sb t1, (t0) = */ + 0x1000FFFF, /* 1: b 1b = */ + 0x00000000 /* nop = */ + }; + + rom_add_blob_fixed("boot_rom", boot_code, sizeof(boot_code), + loader_rommap[LOADER_BOOTROM].base); +} + +static void fw_cfg_boot_set(void *opaque, const char *boot_device, + Error **errp) +{ + fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]); +} + +static void fw_conf_init(unsigned long ram_size) +{ + FWCfgState *fw_cfg; + hwaddr cfg_addr =3D virt_memmap[VIRT_FW_CFG].base; + + fw_cfg =3D fw_cfg_init_mem_wide(cfg_addr, cfg_addr + 8, 8, 0, NULL); + fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)current_machine->smp.= cpus); + fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)current_machine->smp= .max_cpus); + fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); + fw_cfg_add_i32(fw_cfg, FW_CFG_MACHINE_VERSION, 1); + fw_cfg_add_i32(fw_cfg, FW_CFG_CPU_FREQ, get_cpu_freq()); + qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); +} + +static int set_prom_cmdline(ram_addr_t initrd_offset, long initrd_size) +{ + hwaddr cmdline_vaddr; + char memenv[32]; + char highmemenv[32]; + void *cmdline_buf; + unsigned int *parg_env; + int ret =3D 0; + + /* Allocate cmdline_buf for command line. */ + cmdline_buf =3D g_malloc0(loader_memmap[LOADER_CMDLINE].size); + cmdline_vaddr =3D cpu_mips_phys_to_kseg0(NULL, + loader_memmap[LOADER_CMDLINE].b= ase); + + /* + * Layout of cmdline_buf looks like this: + * argv[0], argv[1], 0, env[0], env[1], ... env[i], 0, + * argv[0]'s data, argv[1]'s data, env[0]'data, ..., env[i]'s data, 0 + */ + parg_env =3D (void *)cmdline_buf; + + ret =3D (3 + 1) * 4; + *parg_env++ =3D cmdline_vaddr + ret; + ret +=3D (1 + snprintf(cmdline_buf + ret, 256 - ret, "g")); + + /* argv1 */ + *parg_env++ =3D cmdline_vaddr + ret; + if (initrd_size > 0) + ret +=3D (1 + snprintf(cmdline_buf + ret, 256 - ret, + "rd_start=3D0x" TARGET_FMT_lx " rd_size=3D%li %s", + cpu_mips_phys_to_kseg0(NULL, initrd_offset), + initrd_size, loaderparams.kernel_cmdline)); + else + ret +=3D (1 + snprintf(cmdline_buf + ret, 256 - ret, "%s", + loaderparams.kernel_cmdline)); + + /* argv2 */ + *parg_env++ =3D cmdline_vaddr + 4 * ret; + + /* env */ + sprintf(memenv, "%ld", loaderparams.ram_size > 0x10000000 + ? 256 : (loaderparams.ram_size >> 20)); + sprintf(highmemenv, "%ld", loaderparams.ram_size > 0x10000000 + ? (loaderparams.ram_size >> 20) - 256 : 0); + + rom_add_blob_fixed("cmdline", cmdline_buf, + loader_memmap[LOADER_CMDLINE].size, + loader_memmap[LOADER_CMDLINE].base); + + g_free(cmdline_buf); + + loaderparams.a0 =3D 2; + loaderparams.a1 =3D cmdline_vaddr; + + return 0; +} + +static uint64_t load_kernel(CPUMIPSState *env) +{ + long kernel_size; + ram_addr_t initrd_offset; + uint64_t kernel_entry, kernel_low, kernel_high, initrd_size; + + kernel_size =3D load_elf(loaderparams.kernel_filename, NULL, + cpu_mips_kseg0_to_phys, NULL, + (uint64_t *)&kernel_entry, + (uint64_t *)&kernel_low, (uint64_t *)&kernel_hi= gh, + NULL, 0, EM_MIPS, 1, 0); + if (kernel_size < 0) { + error_report("could not load kernel '%s': %s", + loaderparams.kernel_filename, + load_elf_strerror(kernel_size)); + exit(1); + } + + /* load initrd */ + initrd_size =3D 0; + initrd_offset =3D 0; + if (loaderparams.initrd_filename) { + initrd_size =3D get_image_size(loaderparams.initrd_filename); + if (initrd_size > 0) { + initrd_offset =3D (kernel_high + ~INITRD_PAGE_MASK) & + INITRD_PAGE_MASK; + initrd_offset =3D MAX(initrd_offset, + loader_memmap[LOADER_INITRD].base); + + if (initrd_offset + initrd_size > ram_size) { + error_report("memory too small for initial ram disk '%s'", + loaderparams.initrd_filename); + exit(1); + } + + initrd_size =3D load_image_targphys(loaderparams.initrd_filena= me, + initrd_offset, + ram_size - initrd_offset); + } + + if (initrd_size =3D=3D (target_ulong) -1) { + error_report("could not load initial ram disk '%s'", + loaderparams.initrd_filename); + exit(1); + } + } + + /* Setup prom cmdline. */ + set_prom_cmdline(initrd_offset, initrd_size); + + return kernel_entry; +} + +static void main_cpu_reset(void *opaque) +{ + MIPSCPU *cpu =3D opaque; + CPUMIPSState *env =3D &cpu->env; + + cpu_reset(CPU(cpu)); + + /* Loongson-3 reset stuff */ + if (loaderparams.kernel_filename) { + if (cpu =3D=3D MIPS_CPU(first_cpu)) { + env->active_tc.gpr[4] =3D loaderparams.a0; + env->active_tc.gpr[5] =3D loaderparams.a1; + env->active_tc.gpr[6] =3D loaderparams.a2; + env->active_tc.PC =3D loaderparams.kernel_entry; + } + env->CP0_Status &=3D ~((1 << CP0St_BEV) | (1 << CP0St_ERL)); + } +} + +static inline void loongson3_virt_devices_init(MachineState *machine, Devi= ceState *pic) +{ + int i; + qemu_irq irq; + PCIBus *pci_bus; + DeviceState *dev; + MemoryRegion *pio_alias; + MemoryRegion *mmio_alias, *mmio_reg; + MemoryRegion *ecam_alias, *ecam_reg; + + dev =3D qdev_new(TYPE_GPEX_HOST); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + pci_bus =3D PCI_HOST_BRIDGE(dev)->bus; + + ecam_alias =3D g_new0(MemoryRegion, 1); + ecam_reg =3D sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); + memory_region_init_alias(ecam_alias, OBJECT(dev), "pcie-ecam", + ecam_reg, 0, virt_memmap[VIRT_PCIE_ECAM].size= ); + memory_region_add_subregion(get_system_memory(), + virt_memmap[VIRT_PCIE_ECAM].base, ecam_ali= as); + + mmio_alias =3D g_new0(MemoryRegion, 1); + mmio_reg =3D sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1); + memory_region_init_alias(mmio_alias, OBJECT(dev), "pcie-mmio", + mmio_reg, virt_memmap[VIRT_PCIE_MMIO].base, + virt_memmap[VIRT_PCIE_MMIO].size); + memory_region_add_subregion(get_system_memory(), + virt_memmap[VIRT_PCIE_MMIO].base, mmio_ali= as); + + pio_alias =3D g_new0(MemoryRegion, 1); + memory_region_init_alias(pio_alias, OBJECT(dev), "pcie-pio", + get_system_io(), 0, virt_memmap[VIRT_PCIE_PIO= ].size); + memory_region_add_subregion(get_system_memory(), + virt_memmap[VIRT_PCIE_PIO].base, pio_alias= ); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, virt_memmap[VIRT_PCIE_PIO].bas= e); + + for (i =3D 0; i < GPEX_NUM_IRQS; i++) { + irq =3D qdev_get_gpio_in(pic, PCIE_IRQ_BASE + i); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, irq); + gpex_set_irq_num(GPEX_HOST(dev), i, PCIE_IRQ_BASE + i); + } + + pci_vga_init(pci_bus); + + if (defaults_enabled()) { + pci_create_simple(pci_bus, -1, "pci-ohci"); + usb_create_simple(usb_bus_find(-1), "usb-kbd"); + usb_create_simple(usb_bus_find(-1), "usb-tablet"); + } + + for (i =3D 0; i < nb_nics; i++) { + NICInfo *nd =3D &nd_table[i]; + + if (!nd->model) { + nd->model =3D g_strdup("virtio"); + } + + pci_nic_init_nofail(nd, pci_bus, nd->model, NULL); + } +} + +static void mips_loongson3_virt_init(MachineState *machine) +{ + int i; + long bios_size; + MIPSCPU *cpu; + CPUMIPSState *env; + DeviceState *liointc; + char *filename; + const char *kernel_cmdline =3D machine->kernel_cmdline; + const char *kernel_filename =3D machine->kernel_filename; + const char *initrd_filename =3D machine->initrd_filename; + ram_addr_t ram_size =3D machine->ram_size; + MemoryRegion *address_space_mem =3D get_system_memory(); + MemoryRegion *ram =3D g_new(MemoryRegion, 1); + MemoryRegion *bios =3D g_new(MemoryRegion, 1); + MemoryRegion *iomem =3D g_new(MemoryRegion, 1); + + /* TODO: TCG will support all CPU types */ + if (!kvm_enabled()) { + if (!machine->cpu_type) { + machine->cpu_type =3D MIPS_CPU_TYPE_NAME("Loongson-3A1000"); + } + if (!strstr(machine->cpu_type, "Loongson-3A1000")) { + error_report("Loongson-3/TCG need cpu type Loongson-3A1000"); + exit(1); + } + } else { + if (!machine->cpu_type) { + machine->cpu_type =3D MIPS_CPU_TYPE_NAME("Loongson-3A4000"); + } + if (!strstr(machine->cpu_type, "Loongson-3A4000")) { + error_report("Loongson-3/KVM need cpu type Loongson-3A4000"); + exit(1); + } + } + + if (ram_size < 512 * 0x100000) { + error_report("Loongson-3 need at least 512MB memory"); + exit(1); + } + + /* + * The whole MMIO range among configure registers doesn't generate + * exception when accessing invalid memory. Create an empty slot to + * emulate this feature. + */ + empty_slot_init("fallback", 0, 0x80000000); + + liointc =3D qdev_new("loongson.liointc"); + sysbus_realize_and_unref(SYS_BUS_DEVICE(liointc), &error_fatal); + + sysbus_mmio_map(SYS_BUS_DEVICE(liointc), 0, virt_memmap[VIRT_LIOINTC].= base); + + for (i =3D 0; i < machine->smp.cpus; i++) { + int ip; + + /* init CPUs */ + cpu =3D MIPS_CPU(cpu_create(machine->cpu_type)); + + /* Init internal devices */ + cpu_mips_irq_init_cpu(cpu); + cpu_mips_clock_init(cpu); + qemu_register_reset(main_cpu_reset, cpu); + + if (i >=3D 4) { + continue; /* Only node-0 can be connected to LIOINTC */ + } + + for (ip =3D 0; ip < 4 ; ip++) { + int pin =3D i * 4 + ip; + sysbus_connect_irq(SYS_BUS_DEVICE(liointc), + pin, cpu->env.irq[ip + 2]); + } + } + env =3D &MIPS_CPU(first_cpu)->env; + + /* Allocate RAM/BIOS, 0x00000000~0x10000000 is alias of 0x80000000~0x9= 0000000 */ + memory_region_init_rom(bios, NULL, "loongson3.bios", + virt_memmap[VIRT_BIOS_ROM].size, &error_fatal); + memory_region_init_alias(ram, NULL, "loongson3.lowmem", + machine->ram, 0, virt_memmap[VIRT_LOWMEM].size); + memory_region_init_io(iomem, NULL, &loongson3_pm_ops, + NULL, "loongson3_pm", virt_memmap[VIRT_PM].size= ); + + memory_region_add_subregion(address_space_mem, + virt_memmap[VIRT_LOWMEM].base, ram); + memory_region_add_subregion(address_space_mem, + virt_memmap[VIRT_BIOS_ROM].base, bios); + memory_region_add_subregion(address_space_mem, + virt_memmap[VIRT_HIGHMEM].base, machine->ram); + memory_region_add_subregion(address_space_mem, + virt_memmap[VIRT_PM].base, iomem); + + /* + * We do not support flash operation, just loading bios.bin as raw BIO= S. + * Please use -L to set the BIOS path and -bios to set bios name. + */ + + if (kernel_filename) { + loaderparams.ram_size =3D ram_size; + loaderparams.kernel_filename =3D kernel_filename; + loaderparams.kernel_cmdline =3D kernel_cmdline; + loaderparams.initrd_filename =3D initrd_filename; + loaderparams.kernel_entry =3D load_kernel(env); + + init_boot_rom(); + init_boot_param(); + } else { + if (bios_name =3D=3D NULL) { + bios_name =3D LOONGSON3_BIOSNAME; + } + filename =3D qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); + if (filename) { + bios_size =3D load_image_targphys(filename, + virt_memmap[VIRT_BIOS_ROM].bas= e, + virt_memmap[VIRT_BIOS_ROM].siz= e); + g_free(filename); + } else { + bios_size =3D -1; + } + + if ((bios_size < 0 || bios_size > virt_memmap[VIRT_BIOS_ROM].size)= && + !kernel_filename && !qtest_enabled()) { + error_report("Could not load MIPS bios '%s'", bios_name); + exit(1); + } + + fw_conf_init(ram_size); + } + + msi_nonbroken =3D true; + loongson3_virt_devices_init(machine, liointc); + + sysbus_create_simple("goldfish_rtc", virt_memmap[VIRT_RTC].base, + qdev_get_gpio_in(liointc, RTC_IRQ)); + + if (serial_hd(0)) { + serial_mm_init(address_space_mem, virt_memmap[VIRT_UART].base, 0, + qdev_get_gpio_in(liointc, UART_IRQ), 115200, + serial_hd(0), DEVICE_NATIVE_ENDIAN); + } +} + +static void mips_loongson3_virt_machine_init(MachineClass *mc) +{ + mc->desc =3D "Loongson-3 Virtualization Platform"; + mc->init =3D mips_loongson3_virt_init; + mc->block_default_type =3D IF_IDE; + mc->max_cpus =3D LOONGSON_MAX_VCPUS; + mc->default_ram_id =3D "loongson3.highram"; + /* 1500MB is the requirement of distros for Loongson-3 */ + mc->default_ram_size =3D 1500 * MiB; + mc->kvm_type =3D mips_kvm_type; + mc->minimum_page_bits =3D 14; +} + +DEFINE_MACHINE("loongson3-virt", mips_loongson3_virt_machine_init) --=20 2.7.0 From nobody Sat Apr 27 22:08:07 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1592995617; cv=none; d=zohomail.com; s=zohoarc; b=Ym4Zw+3CViyUqHjmqzKpkcmWqGGzeVPVoT+daGvFmWttUbltOHRyG8ig/MrVpCd9glra9/GniboPLxqleraJhger8Ypq7BS9c/zCDoWuVaIMNfCT2Xq3d8qsoKb/ZPj1soQJjRdHbJBlUH/PG5LE5kzNowWdxO16q6wh15yYqIg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1592995617; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=dYpAwmxzkvZdFtH5PUKaA7YkdGli1btcQ6lQGV7cfYc=; b=dVkfYYAt2QCwqZrMHylk8R6o68Ec5NQ7cjHBXl1eJsg4iREwjALRxsmWZ9DZRBSQpaiqvZ0cfVLKbgYmZ2SNuxkZSlA2be4WDgSxaqMMQaRcHMTa/iU7t4FrS6Fpu84BQS+723+Oa4DFmJipk6i9JVDAm47eyfZrSHVtN73ZBt8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1592995617768789.4308373004209; Wed, 24 Jun 2020 03:46:57 -0700 (PDT) Received: from localhost ([::1]:36538 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jo2vg-0003ei-Ja for importer@patchew.org; Wed, 24 Jun 2020 06:46:56 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54572) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jo2uX-000272-Fv for qemu-devel@nongnu.org; Wed, 24 Jun 2020 06:45:45 -0400 Received: from mail-pf1-x444.google.com ([2607:f8b0:4864:20::444]:45448) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jo2uV-000828-Ns for qemu-devel@nongnu.org; Wed, 24 Jun 2020 06:45:45 -0400 Received: by mail-pf1-x444.google.com with SMTP id a127so981720pfa.12 for ; Wed, 24 Jun 2020 03:45:43 -0700 (PDT) Received: from software.domain.org (28.144.92.34.bc.googleusercontent.com. [34.92.144.28]) by smtp.gmail.com with ESMTPSA id q6sm19772395pff.163.2020.06.24.03.45.39 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 24 Jun 2020 03:45:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=dYpAwmxzkvZdFtH5PUKaA7YkdGli1btcQ6lQGV7cfYc=; b=WIGa3aOOZiLkHusDt2uNN/83Uw5DP8nrotPeAIxvUUL4XTzFtURyzb3wQc8ss59kFZ oVdCLr8/Ut72AU9h7uutAznTDOjkfxLTDCD2urt2z/RVGAskTa8CNS6eNwJjPwUHwcSH YDX4zcQ4anEK2CDIPcYemrzYdgd+4zbVeFEZszT9gSi1wEodrnPYsXCBOYCm41wz5t6b rIGgo6ojWk2r5Jh+tPiEkew0e0e2DpK39T9FHalpU4eDxIDRtSd4cijxPvBrsVIIjM6u qS8DaN/U5fYlStApGJARZl2fwDJJDllxzaL02Q5LFrTyMNOvb1tBgHnfhvWZgBhlQtNY mtiw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=dYpAwmxzkvZdFtH5PUKaA7YkdGli1btcQ6lQGV7cfYc=; b=P8b/rdKQq/PXGMOUt1Pj05W0791FZjcjagqWX8uyS00Os3CVjEUejTd/9MLzjaP8wZ /Qoxj+7ef/4vTSOftVcxP45L/JQCzyi7H0ldo6fIHJt4Vct/38ngAOn6Z696uDDD57lj WUleTFp2LVktlX+4f5Ck0ouCG1nj4/WQHeyk/vUjV/xJcM0zj/tlw36Xup2pbMW5X/5w 9yhrhawBbf0o8AlncW3JI3O4S4rMHtPkXPmiCHXtFd1ZMlx0EMOJRMHn+j5jJvF8CHZy GQGM/w59bTAG35F4lmuXwHQSnile8qi78O9UC1DGXkE0ggJYqFnDsV8cvEqdGHW8d9Ch ad0A== X-Gm-Message-State: AOAM533nfP+3bT0QcnHQvBvMpK8QwsJ4CqcR/GYk8FnaMZzi5M7vSGcg NSTB7nFBivr66I6tKEEQOyE= X-Google-Smtp-Source: ABdhPJyJ5X4MWdwZotpWV7yRIyNXrXDsdgSg4l5pbZXm3y6d3QuiRmRx7rHSbS0ShHiiqjfnkDehzw== X-Received: by 2002:aa7:96d7:: with SMTP id h23mr30170934pfq.320.1592995542010; Wed, 24 Jun 2020 03:45:42 -0700 (PDT) From: Huacai Chen X-Google-Original-From: Huacai Chen To: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Aleksandar Markovic Subject: [PATCH V6 4/4] MAINTAINERS: Add Loongson-3 maintainer and reviewer Date: Wed, 24 Jun 2020 18:45:31 +0800 Message-Id: <1592995531-32600-5-git-send-email-chenhc@lemote.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1592995531-32600-1-git-send-email-chenhc@lemote.com> References: <1592995531-32600-1-git-send-email-chenhc@lemote.com> Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::444; envelope-from=zltjiangshi@gmail.com; helo=mail-pf1-x444.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Huacai Chen , Huacai Chen , Aleksandar Rikalo , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Aleksandar Markovic --- 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 =20 +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 --=20 2.7.0