From nobody Sat Apr 27 00:45:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of _spf.google.com designates 209.85.221.49 as permitted sender) client-ip=209.85.221.49; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wr1-f49.google.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.49 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com; dmarc=fail(p=none dis=none) header.from=amsat.org ARC-Seal: i=1; a=rsa-sha256; t=1618763560; cv=none; d=zohomail.com; s=zohoarc; b=nMYxCkFvep2kxS04xqai05z0B3AWfNHjNqbc4f6u3Bh4/I4Meiv/5zYfPB+ycLMksBehLKBDKb6cxFfLQf5VIe3ysgsN/bzC31A1sUbhsvtD3nBAVSp92VpWll/YQmmIXbTlT5NaL0ogvdq4mgcVRn03yK93neFOrYUfk+Wl49I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1618763560; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Sender:Subject:To; bh=NIsi822bMMuzY0ClUxKqT1adRaz2kyzQG16pu95t3kA=; b=M+HRNHFJLcNTiNa+Et8xwlOcgSi2tvsmPiczdphPC1j6njKmdUCGZBnMICUcnq+ucces+Vq1bzHFnBAAOyIitMP0se1hduPlueJNYZmJXlHzkj7mGqrawtZbE+r6icqF0PlMGMPiRb21zGqF+SAnE6ZTglVMV2aJzCeR1touM8M= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of _spf.google.com designates 209.85.221.49 as permitted sender) smtp.mailfrom=philippe.mathieu.daude@gmail.com; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.49]) by mx.zohomail.com with SMTPS id 1618763560750351.2492438318254; Sun, 18 Apr 2021 09:32:40 -0700 (PDT) Received: by mail-wr1-f49.google.com with SMTP id x7so31476869wrw.10 for ; Sun, 18 Apr 2021 09:32:40 -0700 (PDT) Return-Path: Return-Path: Received: from localhost.localdomain (39.red-81-40-121.staticip.rima-tde.net. [81.40.121.39]) by smtp.gmail.com with ESMTPSA id a15sm18725962wrr.53.2021.04.18.09.32.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Apr 2021 09:32:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=NIsi822bMMuzY0ClUxKqT1adRaz2kyzQG16pu95t3kA=; b=jtyKz53sYt2daZGsRObr/z7s3XBmdGnTze3IEbNxkrVHSyIYl4nQTbvAeL0GKhFJGA 8fefuQArtjeioASs6Iq2ecJfOlPu3zU5z539A4jxC3jnCCF4pjTJsPgwdj0QJnQKEwUC y8URH6XHui/1tqL/cvtQf/MJQMkraIcjglIWG+vs+SUl1PkaTSrKLTw2epuUNB1dv49V tu/kVhjzw7wMBU7wToJkUruPPI7fz0ZHZZTKwM9MFbAMHTu6BdiUFH/r5lI4FbOnz0OZ /JAUbfbyfM1xYikcikwOn9kjJVeBIvLE6Nx0r2EuyUkrZK8JhWVhQp8hVIA9mXvisfKK 8zfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=NIsi822bMMuzY0ClUxKqT1adRaz2kyzQG16pu95t3kA=; b=brt/ZiVqO4dTehLHHugrnv4MUgAB3JaRdtDETo5ZLluKfTqPgnByoylF31pzJbypxz PmjrS6qqZHVPoU8YphqZ4zTxiYj68Qp+uJUs1wVDP4G4oawnmBgzCedt525jBTQmj1/c cmirOUxvqIvgjlpyqGn+4eQo+emnYPDmM4gci9NXs1PQ8wsMKM93R0YngA68woyoFXos wmyK4gpwwjE3c9FywVPhd6rnGD5muSqUxWvDPstNXvf//YOPWL7b218rr8zT1ijPilO2 Gd8QXz1d/nno5xdwXJ9dHBmsWLzEi4BB5va0b8W9l/P7IZsaKTuY0mJROJqFKTmcAZZr txbQ== X-Gm-Message-State: AOAM53243CW7oBzPjiqHOt7uZHjEoJQjcuFF713kqZo95Eot1/hGaFn9 yMszENmleJqkiuD3mCibVTU= X-Google-Smtp-Source: ABdhPJw0ZCMs4/o6Iv0385Kjd4XROUDvEd/xzWrpMyk3bArjyz6Z1Sj0JLb3cVd1tgxT/ggdvst7xA== X-Received: by 2002:adf:e747:: with SMTP id c7mr9805374wrn.220.1618763558825; Sun, 18 Apr 2021 09:32:38 -0700 (PDT) Sender: =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Huacai Chen , Aleksandar Rikalo , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Jiaxun Yang , Richard Henderson , Aurelien Jarno Subject: [PATCH 13/26] target/mips: Move code related to physical addressing to sysemu/phys.c Date: Sun, 18 Apr 2021 18:31:21 +0200 Message-Id: <20210418163134.1133100-14-f4bug@amsat.org> X-Mailer: git-send-email 2.26.3 In-Reply-To: <20210418163134.1133100-1-f4bug@amsat.org> References: <20210418163134.1133100-1-f4bug@amsat.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) Declare get_physical_address() with local scope and move it along with mips_cpu_get_phys_page_debug() to sysemu/phys.c new file. Signed-off-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Richard Henderson --- target/mips/internal.h | 25 +++- target/mips/sysemu/physaddr.c | 257 +++++++++++++++++++++++++++++++++ target/mips/tlb_helper.c | 254 -------------------------------- target/mips/sysemu/meson.build | 1 + 4 files changed, 282 insertions(+), 255 deletions(-) create mode 100644 target/mips/sysemu/physaddr.c diff --git a/target/mips/internal.h b/target/mips/internal.h index 294560c9d2f..51a45bd397a 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -81,15 +81,38 @@ extern const struct mips_def_t mips_defs[]; extern const int mips_defs_number; =20 bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req); -hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); int mips_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int mips_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void mips_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr); =20 +#define USEG_LIMIT ((target_ulong)(int32_t)0x7FFFFFFFUL) +#define KSEG0_BASE ((target_ulong)(int32_t)0x80000000UL) +#define KSEG1_BASE ((target_ulong)(int32_t)0xA0000000UL) +#define KSEG2_BASE ((target_ulong)(int32_t)0xC0000000UL) +#define KSEG3_BASE ((target_ulong)(int32_t)0xE0000000UL) + +#define KVM_KSEG0_BASE ((target_ulong)(int32_t)0x40000000UL) +#define KVM_KSEG2_BASE ((target_ulong)(int32_t)0x60000000UL) + #if !defined(CONFIG_USER_ONLY) =20 +enum { + TLBRET_XI =3D -6, + TLBRET_RI =3D -5, + TLBRET_DIRTY =3D -4, + TLBRET_INVALID =3D -3, + TLBRET_NOMATCH =3D -2, + TLBRET_BADADDR =3D -1, + TLBRET_MATCH =3D 0 +}; + +int get_physical_address(CPUMIPSState *env, hwaddr *physical, + int *prot, target_ulong real_address, + MMUAccessType access_type, int mmu_idx); +hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); + typedef struct r4k_tlb_t r4k_tlb_t; struct r4k_tlb_t { target_ulong VPN; diff --git a/target/mips/sysemu/physaddr.c b/target/mips/sysemu/physaddr.c new file mode 100644 index 00000000000..1918633aa1c --- /dev/null +++ b/target/mips/sysemu/physaddr.c @@ -0,0 +1,257 @@ +/* + * MIPS TLB (Translation lookaside buffer) helpers. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/exec-all.h" +#include "../internal.h" + +static int is_seg_am_mapped(unsigned int am, bool eu, int mmu_idx) +{ + /* + * Interpret access control mode and mmu_idx. + * AdE? TLB? + * AM K S U E K S U E + * UK 0 0 1 1 0 0 - - 0 + * MK 1 0 1 1 0 1 - - !eu + * MSK 2 0 0 1 0 1 1 - !eu + * MUSK 3 0 0 0 0 1 1 1 !eu + * MUSUK 4 0 0 0 0 0 1 1 0 + * USK 5 0 0 1 0 0 0 - 0 + * - 6 - - - - - - - - + * UUSK 7 0 0 0 0 0 0 0 0 + */ + int32_t adetlb_mask; + + switch (mmu_idx) { + case 3: /* ERL */ + /* If EU is set, always unmapped */ + if (eu) { + return 0; + } + /* fall through */ + case MIPS_HFLAG_KM: + /* Never AdE, TLB mapped if AM=3D{1,2,3} */ + adetlb_mask =3D 0x70000000; + goto check_tlb; + + case MIPS_HFLAG_SM: + /* AdE if AM=3D{0,1}, TLB mapped if AM=3D{2,3,4} */ + adetlb_mask =3D 0xc0380000; + goto check_ade; + + case MIPS_HFLAG_UM: + /* AdE if AM=3D{0,1,2,5}, TLB mapped if AM=3D{3,4} */ + adetlb_mask =3D 0xe4180000; + /* fall through */ + check_ade: + /* does this AM cause AdE in current execution mode */ + if ((adetlb_mask << am) < 0) { + return TLBRET_BADADDR; + } + adetlb_mask <<=3D 8; + /* fall through */ + check_tlb: + /* is this AM mapped in current execution mode */ + return ((adetlb_mask << am) < 0); + default: + assert(0); + return TLBRET_BADADDR; + }; +} + +static int get_seg_physical_address(CPUMIPSState *env, hwaddr *physical, + int *prot, target_ulong real_address, + MMUAccessType access_type, int mmu_idx, + unsigned int am, bool eu, + target_ulong segmask, + hwaddr physical_base) +{ + int mapped =3D is_seg_am_mapped(am, eu, mmu_idx); + + if (mapped < 0) { + /* is_seg_am_mapped can report TLBRET_BADADDR */ + return mapped; + } else if (mapped) { + /* The segment is TLB mapped */ + return env->tlb->map_address(env, physical, prot, real_address, + access_type); + } else { + /* The segment is unmapped */ + *physical =3D physical_base | (real_address & segmask); + *prot =3D PAGE_READ | PAGE_WRITE | PAGE_EXEC; + return TLBRET_MATCH; + } +} + +static int get_segctl_physical_address(CPUMIPSState *env, hwaddr *physical, + int *prot, target_ulong real_addres= s, + MMUAccessType access_type, int mmu_= idx, + uint16_t segctl, target_ulong segma= sk) +{ + unsigned int am =3D (segctl & CP0SC_AM_MASK) >> CP0SC_AM; + bool eu =3D (segctl >> CP0SC_EU) & 1; + hwaddr pa =3D ((hwaddr)segctl & CP0SC_PA_MASK) << 20; + + return get_seg_physical_address(env, physical, prot, real_address, + access_type, mmu_idx, am, eu, segmask, + pa & ~(hwaddr)segmask); +} + +int get_physical_address(CPUMIPSState *env, hwaddr *physical, + int *prot, target_ulong real_address, + MMUAccessType access_type, int mmu_idx) +{ + /* User mode can only access useg/xuseg */ +#if defined(TARGET_MIPS64) + int user_mode =3D mmu_idx =3D=3D MIPS_HFLAG_UM; + int supervisor_mode =3D mmu_idx =3D=3D MIPS_HFLAG_SM; + int kernel_mode =3D !user_mode && !supervisor_mode; + int UX =3D (env->CP0_Status & (1 << CP0St_UX)) !=3D 0; + int SX =3D (env->CP0_Status & (1 << CP0St_SX)) !=3D 0; + int KX =3D (env->CP0_Status & (1 << CP0St_KX)) !=3D 0; +#endif + int ret =3D TLBRET_MATCH; + /* effective address (modified for KVM T&E kernel segments) */ + target_ulong address =3D real_address; + + if (mips_um_ksegs_enabled()) { + /* KVM T&E adds guest kernel segments in useg */ + if (real_address >=3D KVM_KSEG0_BASE) { + if (real_address < KVM_KSEG2_BASE) { + /* kseg0 */ + address +=3D KSEG0_BASE - KVM_KSEG0_BASE; + } else if (real_address <=3D USEG_LIMIT) { + /* kseg2/3 */ + address +=3D KSEG2_BASE - KVM_KSEG2_BASE; + } + } + } + + if (address <=3D USEG_LIMIT) { + /* useg */ + uint16_t segctl; + + if (address >=3D 0x40000000UL) { + segctl =3D env->CP0_SegCtl2; + } else { + segctl =3D env->CP0_SegCtl2 >> 16; + } + ret =3D get_segctl_physical_address(env, physical, prot, + real_address, access_type, + mmu_idx, segctl, 0x3FFFFFFF); +#if defined(TARGET_MIPS64) + } else if (address < 0x4000000000000000ULL) { + /* xuseg */ + if (UX && address <=3D (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) { + ret =3D env->tlb->map_address(env, physical, prot, + real_address, access_type); + } else { + ret =3D TLBRET_BADADDR; + } + } else if (address < 0x8000000000000000ULL) { + /* xsseg */ + if ((supervisor_mode || kernel_mode) && + SX && address <=3D (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) { + ret =3D env->tlb->map_address(env, physical, prot, + real_address, access_type); + } else { + ret =3D TLBRET_BADADDR; + } + } else if (address < 0xC000000000000000ULL) { + /* xkphys */ + if ((address & 0x07FFFFFFFFFFFFFFULL) <=3D env->PAMask) { + /* KX/SX/UX bit to check for each xkphys EVA access mode */ + static const uint8_t am_ksux[8] =3D { + [CP0SC_AM_UK] =3D (1u << CP0St_KX), + [CP0SC_AM_MK] =3D (1u << CP0St_KX), + [CP0SC_AM_MSK] =3D (1u << CP0St_SX), + [CP0SC_AM_MUSK] =3D (1u << CP0St_UX), + [CP0SC_AM_MUSUK] =3D (1u << CP0St_UX), + [CP0SC_AM_USK] =3D (1u << CP0St_SX), + [6] =3D (1u << CP0St_KX), + [CP0SC_AM_UUSK] =3D (1u << CP0St_UX), + }; + unsigned int am =3D CP0SC_AM_UK; + unsigned int xr =3D (env->CP0_SegCtl2 & CP0SC2_XR_MASK) >> CP0= SC2_XR; + + if (xr & (1 << ((address >> 59) & 0x7))) { + am =3D (env->CP0_SegCtl1 & CP0SC1_XAM_MASK) >> CP0SC1_XAM; + } + /* Does CP0_Status.KX/SX/UX permit the access mode (am) */ + if (env->CP0_Status & am_ksux[am]) { + ret =3D get_seg_physical_address(env, physical, prot, + real_address, access_type, + mmu_idx, am, false, env->PA= Mask, + 0); + } else { + ret =3D TLBRET_BADADDR; + } + } else { + ret =3D TLBRET_BADADDR; + } + } else if (address < 0xFFFFFFFF80000000ULL) { + /* xkseg */ + if (kernel_mode && KX && + address <=3D (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) { + ret =3D env->tlb->map_address(env, physical, prot, + real_address, access_type); + } else { + ret =3D TLBRET_BADADDR; + } +#endif + } else if (address < KSEG1_BASE) { + /* kseg0 */ + ret =3D get_segctl_physical_address(env, physical, prot, real_addr= ess, + access_type, mmu_idx, + env->CP0_SegCtl1 >> 16, 0x1FFFFF= FF); + } else if (address < KSEG2_BASE) { + /* kseg1 */ + ret =3D get_segctl_physical_address(env, physical, prot, real_addr= ess, + access_type, mmu_idx, + env->CP0_SegCtl1, 0x1FFFFFFF); + } else if (address < KSEG3_BASE) { + /* sseg (kseg2) */ + ret =3D get_segctl_physical_address(env, physical, prot, real_addr= ess, + access_type, mmu_idx, + env->CP0_SegCtl0 >> 16, 0x1FFFFF= FF); + } else { + /* + * kseg3 + * XXX: debug segment is not emulated + */ + ret =3D get_segctl_physical_address(env, physical, prot, real_addr= ess, + access_type, mmu_idx, + env->CP0_SegCtl0, 0x1FFFFFFF); + } + return ret; +} + +hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) +{ + MIPSCPU *cpu =3D MIPS_CPU(cs); + CPUMIPSState *env =3D &cpu->env; + hwaddr phys_addr; + int prot; + + if (get_physical_address(env, &phys_addr, &prot, addr, MMU_DATA_LOAD, + cpu_mmu_index(env, false)) !=3D 0) { + return -1; + } + return phys_addr; +} diff --git a/target/mips/tlb_helper.c b/target/mips/tlb_helper.c index bb4b503ff72..2304fff4c42 100644 --- a/target/mips/tlb_helper.c +++ b/target/mips/tlb_helper.c @@ -25,16 +25,6 @@ #include "exec/log.h" #include "hw/mips/cpudevs.h" =20 -enum { - TLBRET_XI =3D -6, - TLBRET_RI =3D -5, - TLBRET_DIRTY =3D -4, - TLBRET_INVALID =3D -3, - TLBRET_NOMATCH =3D -2, - TLBRET_BADADDR =3D -1, - TLBRET_MATCH =3D 0 -}; - #if !defined(CONFIG_USER_ONLY) =20 /* no MMU emulation */ @@ -166,236 +156,6 @@ void mmu_init(CPUMIPSState *env, const mips_def_t *de= f) } } =20 -static int is_seg_am_mapped(unsigned int am, bool eu, int mmu_idx) -{ - /* - * Interpret access control mode and mmu_idx. - * AdE? TLB? - * AM K S U E K S U E - * UK 0 0 1 1 0 0 - - 0 - * MK 1 0 1 1 0 1 - - !eu - * MSK 2 0 0 1 0 1 1 - !eu - * MUSK 3 0 0 0 0 1 1 1 !eu - * MUSUK 4 0 0 0 0 0 1 1 0 - * USK 5 0 0 1 0 0 0 - 0 - * - 6 - - - - - - - - - * UUSK 7 0 0 0 0 0 0 0 0 - */ - int32_t adetlb_mask; - - switch (mmu_idx) { - case 3: /* ERL */ - /* If EU is set, always unmapped */ - if (eu) { - return 0; - } - /* fall through */ - case MIPS_HFLAG_KM: - /* Never AdE, TLB mapped if AM=3D{1,2,3} */ - adetlb_mask =3D 0x70000000; - goto check_tlb; - - case MIPS_HFLAG_SM: - /* AdE if AM=3D{0,1}, TLB mapped if AM=3D{2,3,4} */ - adetlb_mask =3D 0xc0380000; - goto check_ade; - - case MIPS_HFLAG_UM: - /* AdE if AM=3D{0,1,2,5}, TLB mapped if AM=3D{3,4} */ - adetlb_mask =3D 0xe4180000; - /* fall through */ - check_ade: - /* does this AM cause AdE in current execution mode */ - if ((adetlb_mask << am) < 0) { - return TLBRET_BADADDR; - } - adetlb_mask <<=3D 8; - /* fall through */ - check_tlb: - /* is this AM mapped in current execution mode */ - return ((adetlb_mask << am) < 0); - default: - assert(0); - return TLBRET_BADADDR; - }; -} - -static int get_seg_physical_address(CPUMIPSState *env, hwaddr *physical, - int *prot, target_ulong real_address, - MMUAccessType access_type, int mmu_idx, - unsigned int am, bool eu, - target_ulong segmask, - hwaddr physical_base) -{ - int mapped =3D is_seg_am_mapped(am, eu, mmu_idx); - - if (mapped < 0) { - /* is_seg_am_mapped can report TLBRET_BADADDR */ - return mapped; - } else if (mapped) { - /* The segment is TLB mapped */ - return env->tlb->map_address(env, physical, prot, real_address, - access_type); - } else { - /* The segment is unmapped */ - *physical =3D physical_base | (real_address & segmask); - *prot =3D PAGE_READ | PAGE_WRITE | PAGE_EXEC; - return TLBRET_MATCH; - } -} - -static int get_segctl_physical_address(CPUMIPSState *env, hwaddr *physical, - int *prot, target_ulong real_addres= s, - MMUAccessType access_type, int mmu_= idx, - uint16_t segctl, target_ulong segma= sk) -{ - unsigned int am =3D (segctl & CP0SC_AM_MASK) >> CP0SC_AM; - bool eu =3D (segctl >> CP0SC_EU) & 1; - hwaddr pa =3D ((hwaddr)segctl & CP0SC_PA_MASK) << 20; - - return get_seg_physical_address(env, physical, prot, real_address, - access_type, mmu_idx, am, eu, segmask, - pa & ~(hwaddr)segmask); -} - -static int get_physical_address(CPUMIPSState *env, hwaddr *physical, - int *prot, target_ulong real_address, - MMUAccessType access_type, int mmu_idx) -{ - /* User mode can only access useg/xuseg */ -#if defined(TARGET_MIPS64) - int user_mode =3D mmu_idx =3D=3D MIPS_HFLAG_UM; - int supervisor_mode =3D mmu_idx =3D=3D MIPS_HFLAG_SM; - int kernel_mode =3D !user_mode && !supervisor_mode; - int UX =3D (env->CP0_Status & (1 << CP0St_UX)) !=3D 0; - int SX =3D (env->CP0_Status & (1 << CP0St_SX)) !=3D 0; - int KX =3D (env->CP0_Status & (1 << CP0St_KX)) !=3D 0; -#endif - int ret =3D TLBRET_MATCH; - /* effective address (modified for KVM T&E kernel segments) */ - target_ulong address =3D real_address; - -#define USEG_LIMIT ((target_ulong)(int32_t)0x7FFFFFFFUL) -#define KSEG0_BASE ((target_ulong)(int32_t)0x80000000UL) -#define KSEG1_BASE ((target_ulong)(int32_t)0xA0000000UL) -#define KSEG2_BASE ((target_ulong)(int32_t)0xC0000000UL) -#define KSEG3_BASE ((target_ulong)(int32_t)0xE0000000UL) - -#define KVM_KSEG0_BASE ((target_ulong)(int32_t)0x40000000UL) -#define KVM_KSEG2_BASE ((target_ulong)(int32_t)0x60000000UL) - - if (mips_um_ksegs_enabled()) { - /* KVM T&E adds guest kernel segments in useg */ - if (real_address >=3D KVM_KSEG0_BASE) { - if (real_address < KVM_KSEG2_BASE) { - /* kseg0 */ - address +=3D KSEG0_BASE - KVM_KSEG0_BASE; - } else if (real_address <=3D USEG_LIMIT) { - /* kseg2/3 */ - address +=3D KSEG2_BASE - KVM_KSEG2_BASE; - } - } - } - - if (address <=3D USEG_LIMIT) { - /* useg */ - uint16_t segctl; - - if (address >=3D 0x40000000UL) { - segctl =3D env->CP0_SegCtl2; - } else { - segctl =3D env->CP0_SegCtl2 >> 16; - } - ret =3D get_segctl_physical_address(env, physical, prot, - real_address, access_type, - mmu_idx, segctl, 0x3FFFFFFF); -#if defined(TARGET_MIPS64) - } else if (address < 0x4000000000000000ULL) { - /* xuseg */ - if (UX && address <=3D (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) { - ret =3D env->tlb->map_address(env, physical, prot, - real_address, access_type); - } else { - ret =3D TLBRET_BADADDR; - } - } else if (address < 0x8000000000000000ULL) { - /* xsseg */ - if ((supervisor_mode || kernel_mode) && - SX && address <=3D (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) { - ret =3D env->tlb->map_address(env, physical, prot, - real_address, access_type); - } else { - ret =3D TLBRET_BADADDR; - } - } else if (address < 0xC000000000000000ULL) { - /* xkphys */ - if ((address & 0x07FFFFFFFFFFFFFFULL) <=3D env->PAMask) { - /* KX/SX/UX bit to check for each xkphys EVA access mode */ - static const uint8_t am_ksux[8] =3D { - [CP0SC_AM_UK] =3D (1u << CP0St_KX), - [CP0SC_AM_MK] =3D (1u << CP0St_KX), - [CP0SC_AM_MSK] =3D (1u << CP0St_SX), - [CP0SC_AM_MUSK] =3D (1u << CP0St_UX), - [CP0SC_AM_MUSUK] =3D (1u << CP0St_UX), - [CP0SC_AM_USK] =3D (1u << CP0St_SX), - [6] =3D (1u << CP0St_KX), - [CP0SC_AM_UUSK] =3D (1u << CP0St_UX), - }; - unsigned int am =3D CP0SC_AM_UK; - unsigned int xr =3D (env->CP0_SegCtl2 & CP0SC2_XR_MASK) >> CP0= SC2_XR; - - if (xr & (1 << ((address >> 59) & 0x7))) { - am =3D (env->CP0_SegCtl1 & CP0SC1_XAM_MASK) >> CP0SC1_XAM; - } - /* Does CP0_Status.KX/SX/UX permit the access mode (am) */ - if (env->CP0_Status & am_ksux[am]) { - ret =3D get_seg_physical_address(env, physical, prot, - real_address, access_type, - mmu_idx, am, false, env->PA= Mask, - 0); - } else { - ret =3D TLBRET_BADADDR; - } - } else { - ret =3D TLBRET_BADADDR; - } - } else if (address < 0xFFFFFFFF80000000ULL) { - /* xkseg */ - if (kernel_mode && KX && - address <=3D (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) { - ret =3D env->tlb->map_address(env, physical, prot, - real_address, access_type); - } else { - ret =3D TLBRET_BADADDR; - } -#endif - } else if (address < KSEG1_BASE) { - /* kseg0 */ - ret =3D get_segctl_physical_address(env, physical, prot, real_addr= ess, - access_type, mmu_idx, - env->CP0_SegCtl1 >> 16, 0x1FFFFF= FF); - } else if (address < KSEG2_BASE) { - /* kseg1 */ - ret =3D get_segctl_physical_address(env, physical, prot, real_addr= ess, - access_type, mmu_idx, - env->CP0_SegCtl1, 0x1FFFFFFF); - } else if (address < KSEG3_BASE) { - /* sseg (kseg2) */ - ret =3D get_segctl_physical_address(env, physical, prot, real_addr= ess, - access_type, mmu_idx, - env->CP0_SegCtl0 >> 16, 0x1FFFFF= FF); - } else { - /* - * kseg3 - * XXX: debug segment is not emulated - */ - ret =3D get_segctl_physical_address(env, physical, prot, real_addr= ess, - access_type, mmu_idx, - env->CP0_SegCtl0, 0x1FFFFFFF); - } - return ret; -} - void cpu_mips_tlb_flush(CPUMIPSState *env) { /* Flush qemu's TLB and discard all shadowed entries. */ @@ -482,20 +242,6 @@ static void raise_mmu_exception(CPUMIPSState *env, tar= get_ulong address, env->error_code =3D error_code; } =20 -hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) -{ - MIPSCPU *cpu =3D MIPS_CPU(cs); - CPUMIPSState *env =3D &cpu->env; - hwaddr phys_addr; - int prot; - - if (get_physical_address(env, &phys_addr, &prot, addr, MMU_DATA_LOAD, - cpu_mmu_index(env, false)) !=3D 0) { - return -1; - } - return phys_addr; -} - #if !defined(TARGET_MIPS64) =20 /* diff --git a/target/mips/sysemu/meson.build b/target/mips/sysemu/meson.build index f2a1ff46081..925ceeaa449 100644 --- a/target/mips/sysemu/meson.build +++ b/target/mips/sysemu/meson.build @@ -2,4 +2,5 @@ 'addr.c', 'cp0_timer.c', 'machine.c', + 'physaddr.c', )) --=20 2.26.3