From patchwork Tue Jul 12 11:14:52 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leon Alrae X-Patchwork-Id: 9225121 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DD8BB60868 for ; Tue, 12 Jul 2016 11:25:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CDF5D27CCB for ; Tue, 12 Jul 2016 11:25:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C14A827F46; Tue, 12 Jul 2016 11:25:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2201527CCB for ; Tue, 12 Jul 2016 11:25:13 +0000 (UTC) Received: from localhost ([::1]:39068 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bMvoO-0007bQ-89 for patchwork-qemu-devel@patchwork.kernel.org; Tue, 12 Jul 2016 07:25:12 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47951) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bMvfO-0005xh-OF for qemu-devel@nongnu.org; Tue, 12 Jul 2016 07:15:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bMvfJ-00023B-Ex for qemu-devel@nongnu.org; Tue, 12 Jul 2016 07:15:53 -0400 Received: from mailapp01.imgtec.com ([195.59.15.196]:39970) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bMvfJ-000235-6P for qemu-devel@nongnu.org; Tue, 12 Jul 2016 07:15:49 -0400 Received: from hhmail02.hh.imgtec.org (unknown [10.100.10.20]) by Forcepoint Email with ESMTPS id 596A0B548B9C3 for ; Tue, 12 Jul 2016 12:15:34 +0100 (IST) Received: from hhmipssw204.hh.imgtec.org (10.100.21.121) by hhmail02.hh.imgtec.org (10.100.10.20) with Microsoft SMTP Server (TLS) id 14.3.294.0; Tue, 12 Jul 2016 12:15:37 +0100 From: Leon Alrae To: Date: Tue, 12 Jul 2016 12:14:52 +0100 Message-ID: <1468322097-2315-7-git-send-email-leon.alrae@imgtec.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1468322097-2315-1-git-send-email-leon.alrae@imgtec.com> References: <1468322097-2315-1-git-send-email-leon.alrae@imgtec.com> MIME-Version: 1.0 X-Originating-IP: [10.100.21.121] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.59.15.196 Subject: [Qemu-devel] [PULL 06/11] hw/mips_cmgcr: implement RESET_BASE register in CM GCR X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Implement RESET_BASE register which is local to each VP and a write to it changes VP's reset exception base. Also, add OTHER register to allow a software running on one VP to access other VP's local registers. Guest can use this mechanism to specify custom address from which a VP will start execution. Signed-off-by: Leon Alrae --- hw/misc/mips_cmgcr.c | 54 +++++++++++++++++++++++++++++++++++++++++++- include/hw/misc/mips_cmgcr.h | 18 +++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/hw/misc/mips_cmgcr.c b/hw/misc/mips_cmgcr.c index e6cf17d..b3ba166 100644 --- a/hw/misc/mips_cmgcr.c +++ b/hw/misc/mips_cmgcr.c @@ -59,6 +59,8 @@ static inline void update_gic_base(MIPSGCRState *gcr, uint64_t val) static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size) { MIPSGCRState *gcr = (MIPSGCRState *) opaque; + MIPSGCRVPState *current_vps = &gcr->vps[current_cpu->cpu_index]; + MIPSGCRVPState *other_vps = &gcr->vps[current_vps->other]; switch (addr) { /* Global Control Block Register */ @@ -85,8 +87,14 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size) case MIPS_COCB_OFS + GCR_CL_CONFIG_OFS: /* Set PVP to # of VPs - 1 */ return gcr->num_vps - 1; + case MIPS_CLCB_OFS + GCR_CL_RESETBASE_OFS: + return current_vps->reset_base; + case MIPS_COCB_OFS + GCR_CL_RESETBASE_OFS: + return other_vps->reset_base; case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS: - return 0; + return current_vps->other; + case MIPS_COCB_OFS + GCR_CL_OTHER_OFS: + return other_vps->other; default: qemu_log_mask(LOG_UNIMP, "Read %d bytes at GCR offset 0x%" HWADDR_PRIx "\n", size, addr); @@ -95,10 +103,18 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size) return 0; } +static inline target_ulong get_exception_base(MIPSGCRVPState *vps) +{ + /* TODO: BEV_BASE and SELECT_BEV */ + return (int32_t)(vps->reset_base & GCR_CL_RESET_BASE_RESETBASE_MSK); +} + /* Write GCR registers */ static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) { MIPSGCRState *gcr = (MIPSGCRState *)opaque; + MIPSGCRVPState *current_vps = &gcr->vps[current_cpu->cpu_index]; + MIPSGCRVPState *other_vps = &gcr->vps[current_vps->other]; switch (addr) { case GCR_GIC_BASE_OFS: @@ -107,6 +123,26 @@ static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) case GCR_CPC_BASE_OFS: update_cpc_base(gcr, data); break; + case MIPS_CLCB_OFS + GCR_CL_RESETBASE_OFS: + current_vps->reset_base = data & GCR_CL_RESET_BASE_MSK; + cpu_set_exception_base(current_cpu->cpu_index, + get_exception_base(current_vps)); + break; + case MIPS_COCB_OFS + GCR_CL_RESETBASE_OFS: + other_vps->reset_base = data & GCR_CL_RESET_BASE_MSK; + cpu_set_exception_base(current_vps->other, + get_exception_base(other_vps)); + break; + case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS: + if ((data & GCR_CL_OTHER_MSK) < gcr->num_vps) { + current_vps->other = data & GCR_CL_OTHER_MSK; + } + break; + case MIPS_COCB_OFS + GCR_CL_OTHER_OFS: + if ((data & GCR_CL_OTHER_MSK) < gcr->num_vps) { + other_vps->other = data & GCR_CL_OTHER_MSK; + } + break; default: qemu_log_mask(LOG_UNIMP, "Write %d bytes at GCR offset 0x%" HWADDR_PRIx " 0x%" PRIx64 "\n", size, addr, data); @@ -148,9 +184,16 @@ static void mips_gcr_init(Object *obj) static void mips_gcr_reset(DeviceState *dev) { MIPSGCRState *s = MIPS_GCR(dev); + int i; update_gic_base(s, 0); update_cpc_base(s, 0); + + for (i = 0; i < s->num_vps; i++) { + s->vps[i].other = 0; + s->vps[i].reset_base = 0xBFC00000 & GCR_CL_RESET_BASE_MSK; + cpu_set_exception_base(i, get_exception_base(&s->vps[i])); + } } static const VMStateDescription vmstate_mips_gcr = { @@ -170,12 +213,21 @@ static Property mips_gcr_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static void mips_gcr_realize(DeviceState *dev, Error **errp) +{ + MIPSGCRState *s = MIPS_GCR(dev); + + /* Create local set of registers for each VP */ + s->vps = g_new(MIPSGCRVPState, s->num_vps); +} + static void mips_gcr_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->props = mips_gcr_properties; dc->vmsd = &vmstate_mips_gcr; dc->reset = mips_gcr_reset; + dc->realize = mips_gcr_realize; } static const TypeInfo mips_gcr_info = { diff --git a/include/hw/misc/mips_cmgcr.h b/include/hw/misc/mips_cmgcr.h index 5b90e94..690e1d6 100644 --- a/include/hw/misc/mips_cmgcr.h +++ b/include/hw/misc/mips_cmgcr.h @@ -35,6 +35,7 @@ /* Core Local and Core Other Block Register Map */ #define GCR_CL_CONFIG_OFS 0x0010 #define GCR_CL_OTHER_OFS 0x0018 +#define GCR_CL_RESETBASE_OFS 0x0020 /* GCR_L2_CONFIG register fields */ #define GCR_L2_CONFIG_BYPASS_SHF 20 @@ -50,6 +51,20 @@ #define GCR_CPC_BASE_CPCBASE_MSK 0xFFFFFFFF8000ULL #define GCR_CPC_BASE_MSK (GCR_CPC_BASE_CPCEN_MSK | GCR_CPC_BASE_CPCBASE_MSK) +/* GCR_CL_OTHER_OFS register fields */ +#define GCR_CL_OTHER_VPOTHER_MSK 0x7 +#define GCR_CL_OTHER_MSK GCR_CL_OTHER_VPOTHER_MSK + +/* GCR_CL_RESETBASE_OFS register fields */ +#define GCR_CL_RESET_BASE_RESETBASE_MSK 0xFFFFF000U +#define GCR_CL_RESET_BASE_MSK GCR_CL_RESET_BASE_RESETBASE_MSK + +typedef struct MIPSGCRVPState MIPSGCRVPState; +struct MIPSGCRVPState { + uint32_t other; + uint64_t reset_base; +}; + typedef struct MIPSGCRState MIPSGCRState; struct MIPSGCRState { SysBusDevice parent_obj; @@ -63,6 +78,9 @@ struct MIPSGCRState { uint64_t cpc_base; uint64_t gic_base; + + /* VP Local/Other Registers */ + MIPSGCRVPState *vps; }; #endif /* _MIPS_GCR_H */