From nobody Fri Nov 10 16:06:08 2023 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4SRkFr5Ndhz4ywlF; Fri, 10 Nov 2023 16:06:08 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4SRkFr4Smnz3NMb; Fri, 10 Nov 2023 16:06:08 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1699632368; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=fY5r7L2DOQ4iKlYbwGwRBSZ0wja6ksozcL4xWq8w5VU=; b=j51UPVvkbaxElErsf5DybjrzklcEK8GBeMgKhC9JIdhsvCOag9EqfG39y97Rb7LPvME4TG znkYkkg40mXYg74wwNJkbobYFcEQiMPwltUBYaSI+sGEaMU2DmXMghGg7/22ZwwwxOu/B6 UOZYeL9ce2SYaZ8rH/Q1SNRDqVGHEcrHOdP95EFpJSRlRObD2tMD8bEayGP1gIy1P5Xwjv apUPM7v10So2HB4SDxYtQk75bTLkAtPf7JVOjGYu1brl5p3HAxtCIx6nxQYx2+ghvIOEVC KytdGgqfqkG+JbQg7M4ErOUmPCib4bicBJHBdYg87Bi99qdFtnL3S9mULC06Ng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1699632368; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=fY5r7L2DOQ4iKlYbwGwRBSZ0wja6ksozcL4xWq8w5VU=; b=pMdG2XsAjdUwfq5/GT2wZR+8cuJUt1uowBJk0r7YmNWa9nG3ok8drxB4lekORq3+wh43/m 4clp4luysFL3yeuf25XNupNAzp73UakVii+zYgpmP6ZL/uNKC2jZgXrDeUBeO/Kl3uLxzD wFyaJiclYj4Ry2hpMst5/GiSfS/5nmzM1J213aE7HJsJZaa/r9/cXZMClzhdVZmohOG0KD MnZmf5h72xez6OaeKNDac2DAeSPJ6Qgu1PYXWS/UyPr3bpD2McTcbqGFLih53AcDrIC4Bq lxu4Tnuk1qQAyaqI8ijBMLDp6lMcpvDM0APTa2zjC3JaXaH+EWxVo/vt+fP9LA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1699632368; a=rsa-sha256; cv=none; b=tmhQd8v0RzakwmDg7ztf3LFHgkaf1HTmlP3h5xISN+yzScbKXuvFdkmoXq53fRXL3gHpVZ lKblamt2Dfhjjgr44YMdwqdlQx8/Rbo4wRMwr9FV6MPjJymUWF/BXP3eLx7oFjL/RUfgnq wms7t948DTbcDZwHo664ZkvSEkUYzKT2VbGfcm5ffsArIXNTPTv60N4vgoOgeCJ8vh6GKZ 6nGyA0MQE4mPhr2fIWwKVUAhCtODkqjFJFtOvbQx+1+crCV8hETJAiS0aaLgfHt4vy0N2U SmGU7uDsJ3nfyEruYk+KXhtcpc+lZTy1LO7bqu8gdxn8DUnoV4c2GGHgw0ntsg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4SRkFr3RHCz14Xh; Fri, 10 Nov 2023 16:06:08 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 3AAG68LS018201; Fri, 10 Nov 2023 16:06:08 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 3AAG68d5018198; Fri, 10 Nov 2023 16:06:08 GMT (envelope-from git) Date: Fri, 10 Nov 2023 16:06:08 GMT Message-Id: <202311101606.3AAG68d5018198@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Andrew Turner Subject: git: e6dbc99d47dd - main - arm64: Create a Linux view of the ID registers List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: andrew X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: e6dbc99d47ddb254d75822817592bb82b5ce4d97 Auto-Submitted: auto-generated The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=e6dbc99d47ddb254d75822817592bb82b5ce4d97 commit e6dbc99d47ddb254d75822817592bb82b5ce4d97 Author: Andrew Turner AuthorDate: 2023-10-25 12:34:38 +0000 Commit: Andrew Turner CommitDate: 2023-11-10 16:01:13 +0000 arm64: Create a Linux view of the ID registers When adding support for new hardware extensions we may not want to enable support for the FreeBSD and Linux ABIs at the same time. To support this split the Linux ID register and hwcaps so they can be configured separately. Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D42372 --- sys/arm64/arm64/elf_machdep.c | 3 ++ sys/arm64/arm64/identcpu.c | 86 +++++++++++++++++++++++++++++++----------- sys/arm64/include/md_var.h | 2 + sys/arm64/linux/linux_sysvec.c | 4 +- 4 files changed, 70 insertions(+), 25 deletions(-) diff --git a/sys/arm64/arm64/elf_machdep.c b/sys/arm64/arm64/elf_machdep.c index dd053d4d7847..66377464111f 100644 --- a/sys/arm64/arm64/elf_machdep.c +++ b/sys/arm64/arm64/elf_machdep.c @@ -56,6 +56,9 @@ u_long __read_frequently elf_hwcap; u_long __read_frequently elf_hwcap2; +/* TODO: Move to a better location */ +u_long __read_frequently linux_elf_hwcap; +u_long __read_frequently linux_elf_hwcap2; struct arm64_addr_mask elf64_addr_mask; diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c index d699e409bc8a..ac44b87ffcbd 100644 --- a/sys/arm64/arm64/identcpu.c +++ b/sys/arm64/arm64/identcpu.c @@ -33,10 +33,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include @@ -162,6 +164,7 @@ static struct cpu_desc cpu_desc0; static struct cpu_desc *cpu_desc; static struct cpu_desc kern_cpu_desc; static struct cpu_desc user_cpu_desc; +static struct cpu_desc l_user_cpu_desc; static struct cpu_desc * get_cpu_desc(u_int cpu) @@ -275,10 +278,12 @@ const struct cpu_implementers cpu_implementers[] = { }; #define MRS_TYPE_MASK 0xf +#define MRS_TYPE_FBSD_SHIFT 0 +#define MRS_TYPE_LNX_SHIFT 8 #define MRS_INVALID 0 #define MRS_EXACT 1 #define MRS_EXACT_VAL(x) (MRS_EXACT | ((x) << 4)) -#define MRS_EXACT_FIELD(x) ((x) >> 4) +#define MRS_EXACT_FIELD(x) (((x) >> 4) & 0xf) #define MRS_LOWER 2 struct mrs_field_value { @@ -341,17 +346,23 @@ struct mrs_field { u_int shift; }; -#define MRS_FIELD_HWCAP(_register, _name, _sign, _type, _values, _hwcap) \ +#define MRS_FIELD_HWCAP_SPLIT(_register, _name, _sign, _fbsd_type, \ + _lnx_type, _values, _hwcap) \ { \ .name = #_name, \ .sign = (_sign), \ - .type = (_type), \ + .type = ((_fbsd_type) << MRS_TYPE_FBSD_SHIFT) | \ + ((_lnx_type) << MRS_TYPE_LNX_SHIFT), \ .shift = _register ## _ ## _name ## _SHIFT, \ .mask = _register ## _ ## _name ## _MASK, \ .values = (_values), \ .hwcaps = (_hwcap), \ } +#define MRS_FIELD_HWCAP(_register, _name, _sign, _type, _values, _hwcap) \ + MRS_FIELD_HWCAP_SPLIT(_register, _name, _sign, _type, _type, \ + _values, _hwcap) + #define MRS_FIELD(_register, _name, _sign, _type, _values) \ MRS_FIELD_HWCAP(_register, _name, _sign, _type, _values, NULL) @@ -1911,7 +1922,10 @@ user_mrs_handler(vm_offset_t va, uint32_t insn, struct trapframe *frame, for (i = 0; i < nitems(user_regs); i++) { if (user_regs[i].CRm == CRm && user_regs[i].Op2 == Op2) { - value = CPU_DESC_FIELD(user_cpu_desc, i); + if (SV_CURPROC_ABI() == SV_ABI_FREEBSD) + value = CPU_DESC_FIELD(user_cpu_desc, i); + else + value = CPU_DESC_FIELD(l_user_cpu_desc, i); break; } } @@ -2064,12 +2078,32 @@ get_kernel_reg_masked(u_int reg, uint64_t *valp, uint64_t mask) return (false); } +static uint64_t +update_special_reg_field(uint64_t user_reg, u_int type, uint64_t value, + u_int shift, bool sign) +{ + switch (type & MRS_TYPE_MASK) { + case MRS_EXACT: + user_reg &= ~(0xful << shift); + user_reg |= (uint64_t)MRS_EXACT_FIELD(type) << shift; + break; + case MRS_LOWER: + user_reg = update_lower_register(user_reg, value, shift, 4, + sign); + break; + default: + panic("Invalid field type: %d", type); + } + + return (user_reg); +} + void update_special_regs(u_int cpu) { struct cpu_desc *desc; const struct mrs_field *fields; - uint64_t user_reg, kern_reg, value; + uint64_t l_user_reg, user_reg, kern_reg, value; int i, j; if (cpu == 0) { @@ -2080,6 +2114,8 @@ update_special_regs(u_int cpu) ID_AA64PFR0_FP_NONE | ID_AA64PFR0_EL1_64 | ID_AA64PFR0_EL0_64; user_cpu_desc.id_aa64dfr0 = ID_AA64DFR0_DebugVer_8; + /* Create the Linux user visible cpu description */ + memcpy(&l_user_cpu_desc, &user_cpu_desc, sizeof(user_cpu_desc)); } desc = get_cpu_desc(cpu); @@ -2088,33 +2124,33 @@ update_special_regs(u_int cpu) if (cpu == 0) { kern_reg = value; user_reg = value; + l_user_reg = value; } else { kern_reg = CPU_DESC_FIELD(kern_cpu_desc, i); user_reg = CPU_DESC_FIELD(user_cpu_desc, i); + l_user_reg = CPU_DESC_FIELD(l_user_cpu_desc, i); } fields = user_regs[i].fields; for (j = 0; fields[j].type != 0; j++) { - switch (fields[j].type & MRS_TYPE_MASK) { - case MRS_EXACT: - user_reg &= ~(0xful << fields[j].shift); - user_reg |= - (uint64_t)MRS_EXACT_FIELD(fields[j].type) << - fields[j].shift; - break; - case MRS_LOWER: - user_reg = update_lower_register(user_reg, - value, fields[j].shift, 4, fields[j].sign); - break; - default: - panic("Invalid field type: %d", fields[j].type); - } + /* Update the FreeBSD userspace ID register view */ + user_reg = update_special_reg_field(user_reg, + fields[j].type >> MRS_TYPE_FBSD_SHIFT, value, + fields[j].shift, fields[j].sign); + + /* Update the Linux userspace ID register view */ + l_user_reg = update_special_reg_field(l_user_reg, + fields[j].type >> MRS_TYPE_LNX_SHIFT, value, + fields[j].shift, fields[j].sign); + + /* Update the kernel ID register view */ kern_reg = update_lower_register(kern_reg, value, fields[j].shift, 4, fields[j].sign); } CPU_DESC_FIELD(kern_cpu_desc, i) = kern_reg; CPU_DESC_FIELD(user_cpu_desc, i) = user_reg; + CPU_DESC_FIELD(l_user_cpu_desc, i) = l_user_reg; } } @@ -2148,7 +2184,8 @@ int64_t idcache_line_size; /* The minimum cache line size */ * Find the values to export to userspace as AT_HWCAP and AT_HWCAP2. */ static void -parse_cpu_features(bool is64bit, u_long *hwcap, u_long *hwcap2) +parse_cpu_features(bool is64bit, struct cpu_desc *cpu_desc, u_long *hwcap, + u_long *hwcap2) { const struct mrs_field_hwcap *hwcaps; const struct mrs_field *fields; @@ -2160,7 +2197,7 @@ parse_cpu_features(bool is64bit, u_long *hwcap, u_long *hwcap2) if (user_regs[i].is64bit != is64bit) continue; - reg = CPU_DESC_FIELD(user_cpu_desc, i); + reg = CPU_DESC_FIELD(*cpu_desc, i); fields = user_regs[i].fields; for (j = 0; fields[j].type != 0; j++) { hwcaps = fields[j].hwcaps; @@ -2216,13 +2253,16 @@ identify_cpu_sysinit(void *dummy __unused) } /* Find the values to export to userspace as AT_HWCAP and AT_HWCAP2 */ - parse_cpu_features(true, &elf_hwcap, &elf_hwcap2); + parse_cpu_features(true, &user_cpu_desc, &elf_hwcap, &elf_hwcap2); + parse_cpu_features(true, &l_user_cpu_desc, &linux_elf_hwcap, + &linux_elf_hwcap2); #ifdef COMPAT_FREEBSD32 - parse_cpu_features(false, &elf32_hwcap, &elf32_hwcap2); + parse_cpu_features(false, &user_cpu_desc, &elf32_hwcap, &elf32_hwcap2); #endif /* We export the CPUID registers */ elf_hwcap |= HWCAP_CPUID; + linux_elf_hwcap |= HWCAP_CPUID; #ifdef COMPAT_FREEBSD32 /* Set the default caps and any that need to check multiple fields */ diff --git a/sys/arm64/include/md_var.h b/sys/arm64/include/md_var.h index e0f707f3d881..f9aaaeba7306 100644 --- a/sys/arm64/include/md_var.h +++ b/sys/arm64/include/md_var.h @@ -37,6 +37,8 @@ extern char sigcode[]; extern int szsigcode; extern u_long elf_hwcap; extern u_long elf_hwcap2; +extern u_long linux_elf_hwcap; +extern u_long linux_elf_hwcap2; #ifdef COMPAT_FREEBSD32 extern u_long elf32_hwcap; extern u_long elf32_hwcap2; diff --git a/sys/arm64/linux/linux_sysvec.c b/sys/arm64/linux/linux_sysvec.c index 4b5544841313..185c4f3044b1 100644 --- a/sys/arm64/linux/linux_sysvec.c +++ b/sys/arm64/linux/linux_sysvec.c @@ -456,8 +456,8 @@ struct sysentvec elf_linux_sysvec = { .sv_schedtail = linux_schedtail, .sv_thread_detach = linux_thread_detach, .sv_trap = NULL, - .sv_hwcap = &elf_hwcap, - .sv_hwcap2 = &elf_hwcap2, + .sv_hwcap = &linux_elf_hwcap, + .sv_hwcap2 = &linux_elf_hwcap2, .sv_onexec = linux_on_exec_vmspace, .sv_onexit = linux_on_exit, .sv_ontdexit = linux_thread_dtor,