svn commit: r348886 - in head/sys/riscv: include riscv
Ian Lepore
ian at freebsd.org
Tue Jun 11 01:12:38 UTC 2019
On Tue, 2019-06-11 at 00:55 +0000, Mitchell Horne wrote:
> Author: mhorne
> Date: Tue Jun 11 00:55:54 2019
> New Revision: 348886
> URL: https://svnweb.freebsd.org/changeset/base/348886
>
> Log:
> RISC-V: expose extension bits in AT_HWCAP
>
> AT_HWCAP is a field in the elf auxiliary vector meant to describe
> cpu-specific hardware features. For RISC-V we want to use this to
> indicate the presence of any standard extensions supported by the
> CPU.
> This allows userland applications to query the system for supported
> extensions using elf_aux_info(3).
>
> Support for an extension is indicated by the presence of its
> corresponding bit in AT_HWCAP -- e.g. systems supporting the 'c'
> extension (compressed instructions) will have the second bit set.
>
> Extensions advertised through AT_HWCAP are only those that are
> supported
> by all harts in the system.
>
A word of advice from the arm world (a don't make the mistakes we did
kind of thing): If linux has already defined AT_HWCAP values for
riscv, life may be better in the long run if our values match theirs as
much as possible. It will especially help with ports.
-- Ian
> Reviewed by: jhb, markj
> Approved by: markj (mentor)
> MFC after: 2 weeks
> Differential Revision: https://reviews.freebsd.org/D20493
>
> Modified:
> head/sys/riscv/include/elf.h
> head/sys/riscv/include/md_var.h
> head/sys/riscv/riscv/elf_machdep.c
> head/sys/riscv/riscv/identcpu.c
>
> Modified: head/sys/riscv/include/elf.h
> =====================================================================
> =========
> --- head/sys/riscv/include/elf.h Mon Jun 10 23:25:40 2019 (r348
> 885)
> +++ head/sys/riscv/include/elf.h Tue Jun 11 00:55:54 2019 (r348
> 886)
> @@ -74,4 +74,15 @@ __ElfType(Auxinfo);
> /* TODO: set correct value */
> #define ET_DYN_LOAD_ADDR 0x100000
>
> +/* Flags passed in AT_HWCAP */
> +#define HWCAP_ISA_BIT(c) (1 << ((c) - 'A'))
> +#define HWCAP_ISA_I HWCAP_ISA_BIT('I')
> +#define HWCAP_ISA_M HWCAP_ISA_BIT('M')
> +#define HWCAP_ISA_A HWCAP_ISA_BIT('A')
> +#define HWCAP_ISA_F HWCAP_ISA_BIT('F')
> +#define HWCAP_ISA_D HWCAP_ISA_BIT('D')
> +#define HWCAP_ISA_C HWCAP_ISA_BIT('C')
> +#define HWCAP_ISA_G \
> + (HWCAP_ISA_I | HWCAP_ISA_M | HWCAP_ISA_A | HWCAP_ISA_F |
> HWCAP_ISA_D)
> +
> #endif /* !_MACHINE_ELF_H_ */
>
> Modified: head/sys/riscv/include/md_var.h
> =====================================================================
> =========
> --- head/sys/riscv/include/md_var.h Mon Jun 10 23:25:40 2019 (r348
> 885)
> +++ head/sys/riscv/include/md_var.h Tue Jun 11 00:55:54 2019 (r348
> 886)
> @@ -38,6 +38,7 @@ extern char sigcode[];
> extern int szsigcode;
> extern uint64_t *vm_page_dump;
> extern int vm_page_dump_size;
> +extern u_long elf_hwcap;
>
> struct dumperinfo;
>
>
> Modified: head/sys/riscv/riscv/elf_machdep.c
> =====================================================================
> =========
> --- head/sys/riscv/riscv/elf_machdep.c Mon Jun 10 23:25:40
> 2019 (r348885)
> +++ head/sys/riscv/riscv/elf_machdep.c Tue Jun 11 00:55:54
> 2019 (r348886)
> @@ -58,6 +58,8 @@ __FBSDID("$FreeBSD$");
> #include <machine/elf.h>
> #include <machine/md_var.h>
>
> +u_long elf_hwcap;
> +
> struct sysentvec elf64_freebsd_sysvec = {
> .sv_size = SYS_MAXSYSCALL,
> .sv_table = sysent,
> @@ -90,6 +92,7 @@ struct sysentvec elf64_freebsd_sysvec = {
> .sv_schedtail = NULL,
> .sv_thread_detach = NULL,
> .sv_trap = NULL,
> + .sv_hwcap = &elf_hwcap,
> };
> INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec);
>
>
> Modified: head/sys/riscv/riscv/identcpu.c
> =====================================================================
> =========
> --- head/sys/riscv/riscv/identcpu.c Mon Jun 10 23:25:40 2019 (r348
> 885)
> +++ head/sys/riscv/riscv/identcpu.c Tue Jun 11 00:55:54 2019 (r348
> 886)
> @@ -32,18 +32,28 @@
> * SUCH DAMAGE.
> */
>
> +#include "opt_platform.h"
> +
> #include <sys/cdefs.h>
> __FBSDID("$FreeBSD$");
>
> #include <sys/param.h>
> +#include <sys/systm.h>
> +#include <sys/kernel.h>
> #include <sys/pcpu.h>
> #include <sys/sysctl.h>
> -#include <sys/systm.h>
>
> #include <machine/cpu.h>
> #include <machine/cpufunc.h>
> +#include <machine/elf.h>
> +#include <machine/md_var.h>
> #include <machine/trap.h>
>
> +#ifdef FDT
> +#include <dev/fdt/fdt_common.h>
> +#include <dev/ofw/openfirm.h>
> +#endif
> +
> char machine[] = "riscv";
>
> SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0,
> @@ -87,6 +97,84 @@ const struct cpu_implementers cpu_implementers[] =
> {
> { CPU_IMPL_UCB_ROCKET, "UC Berkeley Rocket" },
> CPU_IMPLEMENTER_NONE,
> };
> +
> +#ifdef FDT
> +/*
> + * The ISA string is made up of a small prefix (e.g. rv64) and up to
> 26 letters
> + * indicating the presence of the 26 possible standard extensions.
> Therefore 32
> + * characters will be sufficient.
> + */
> +#define ISA_NAME_MAXLEN 32
> +#define ISA_PREFIX ("rv"
> __XSTRING(__riscv_xlen))
> +#define ISA_PREFIX_LEN (sizeof(ISA_PREFIX) - 1)
> +
> +static void
> +fill_elf_hwcap(void *dummy __unused)
> +{
> + u_long caps[256] = {0};
> + char isa[ISA_NAME_MAXLEN];
> + u_long hwcap;
> + phandle_t node;
> + ssize_t len;
> + int i;
> +
> + caps['i'] = caps['I'] = HWCAP_ISA_I;
> + caps['m'] = caps['M'] = HWCAP_ISA_M;
> + caps['a'] = caps['A'] = HWCAP_ISA_A;
> +#ifdef FPE
> + caps['f'] = caps['F'] = HWCAP_ISA_F;
> + caps['d'] = caps['D'] = HWCAP_ISA_D;
> +#endif
> + caps['c'] = caps['C'] = HWCAP_ISA_C;
> +
> + node = OF_finddevice("/cpus");
> + if (node == -1) {
> + if (bootverbose)
> + printf("fill_elf_hwcap: Can't find cpus
> node\n");
> + return;
> + }
> +
> + /*
> + * Iterate through the CPUs and examine their ISA string. While
> we
> + * could assign elf_hwcap to be whatever the boot CPU supports,
> to
> + * handle the (unusual) case of running a system with
> hetergeneous
> + * ISAs, keep only the extension bits that are common to all
> harts.
> + */
> + for (node = OF_child(node); node > 0; node = OF_peer(node)) {
> + if (!fdt_is_compatible_strict(node, "riscv")) {
> + if (bootverbose)
> + printf("fill_elf_hwcap: Can't find
> cpu\n");
> + return;
> + }
> +
> + len = OF_getprop(node, "riscv,isa", isa, sizeof(isa));
> + KASSERT(len <= ISA_NAME_MAXLEN, ("ISA string
> truncated"));
> + if (len == -1) {
> + if (bootverbose)
> + printf("fill_elf_hwcap: "
> + "Can't find riscv,isa property\n");
> + return;
> + } else if (strncmp(isa, ISA_PREFIX, ISA_PREFIX_LEN) !=
> 0) {
> + if (bootverbose)
> + printf("fill_elf_hwcap: "
> + "Unsupported ISA string: %s\n",
> isa);
> + return;
> + }
> +
> + hwcap = 0;
> + for (i = ISA_PREFIX_LEN; i < len; i++)
> + hwcap |= caps[(unsigned char)isa[i]];
> +
> + if (elf_hwcap != 0)
> + elf_hwcap &= hwcap;
> + else
> + elf_hwcap = hwcap;
> +
> + }
> +}
> +
> +SYSINIT(identcpu, SI_SUB_CPU, SI_ORDER_ANY, fill_elf_hwcap, NULL);
> +#endif
>
> void
> identify_cpu(void)
>
More information about the svn-src-all
mailing list