Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/aarch64/aarch64 MODULAR support



details:   https://anonhg.NetBSD.org/src/rev/66c7199994f4
branches:  trunk
changeset: 363910:66c7199994f4
user:      ryo <ryo%NetBSD.org@localhost>
date:      Wed Aug 15 11:10:45 2018 +0000

description:
MODULAR support

diffstat:

 sys/arch/aarch64/aarch64/aarch64_machdep.c |   55 ++++-
 sys/arch/aarch64/aarch64/kobj_machdep.c    |  364 +++++++++++++++++++++++++++++
 2 files changed, 416 insertions(+), 3 deletions(-)

diffs (truncated from 502 to 300 lines):

diff -r b4082cebd584 -r 66c7199994f4 sys/arch/aarch64/aarch64/aarch64_machdep.c
--- a/sys/arch/aarch64/aarch64/aarch64_machdep.c        Wed Aug 15 11:08:18 2018 +0000
+++ b/sys/arch/aarch64/aarch64/aarch64_machdep.c        Wed Aug 15 11:10:45 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: aarch64_machdep.c,v 1.8 2018/08/05 06:48:50 skrll Exp $ */
+/* $NetBSD: aarch64_machdep.c,v 1.9 2018/08/15 11:10:45 ryo Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,16 +30,18 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: aarch64_machdep.c,v 1.8 2018/08/05 06:48:50 skrll Exp $");
+__KERNEL_RCSID(1, "$NetBSD: aarch64_machdep.c,v 1.9 2018/08/15 11:10:45 ryo Exp $");
 
 #include "opt_arm_debug.h"
 #include "opt_ddb.h"
 #include "opt_kernhist.h"
+#include "opt_modular.h"
 
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/bus.h>
 #include <sys/kauth.h>
+#include <sys/module.h>
 #include <sys/msgbuf.h>
 #include <sys/sysctl.h>
 
@@ -87,6 +89,11 @@
 
 struct vm_map *phys_map;
 
+#ifdef MODULAR
+vaddr_t module_start, module_end;
+static struct vm_map module_map_store;
+#endif
+
 /* XXX */
 vaddr_t physical_start;
 vaddr_t physical_end;
@@ -158,6 +165,7 @@
        psize_t memsize_total;
        vaddr_t kernstart, kernend;
        vaddr_t kernstart_l2, kernend_l2;       /* L2 table 2MB aligned */
+       vaddr_t kernelvmstart;
        int i;
 
        aarch64_getcacheinfo();
@@ -168,6 +176,25 @@
        kernend = round_page((vaddr_t)_end);
        kernstart_l2 = kernstart & -L2_SIZE;            /* trunk L2_SIZE(2M) */
        kernend_l2 = (kernend + L2_SIZE - 1) & -L2_SIZE;/* round L2_SIZE(2M) */
+       kernelvmstart = kernend_l2;
+
+#ifdef MODULAR
+       /*
+        * aarch64 compiler (gcc & llvm) uses R_AARCH_CALL26/R_AARCH_JUMP26
+        * for function calling/jumping.
+        * (at this time, both compilers doesn't support -mlong-calls)
+        * therefore kernel modules should be loaded within maximum 26bit word,
+        * or +-128MB from kernel.
+        */
+#define MODULE_RESERVED_MAX    (1024 * 1024 * 128)
+#define MODULE_RESERVED_SIZE   (1024 * 1024 * 32)      /* good enough? */
+       module_start = kernelvmstart;
+       module_end = kernend_l2 + MODULE_RESERVED_SIZE;
+       if (module_end >= kernstart_l2 + MODULE_RESERVED_MAX)
+               module_end = kernstart_l2 + MODULE_RESERVED_MAX;
+       KASSERT(module_end > kernend_l2);
+       kernelvmstart = module_end;
+#endif /* MODULAR */
 
        paddr_t kernstart_phys = KERN_VTOPHYS(kernstart);
        paddr_t kernend_phys = KERN_VTOPHYS(kernend);
@@ -188,6 +215,10 @@
            "kernel_start          = 0x%016lx\n"
            "kernel_end            = 0x%016lx\n"
            "kernel_end_l2         = 0x%016lx\n"
+#ifdef MODULAR
+           "module_start          = 0x%016lx\n"
+           "module_end            = 0x%016lx\n"
+#endif
            "(kernel va area)\n"
            "(devmap va area)\n"
            "VM_MAX_KERNEL_ADDRESS = 0x%016lx\n"
@@ -202,6 +233,10 @@
            kernstart,
            kernend,
            kernend_l2,
+#ifdef MODULAR
+           module_start,
+           module_end,
+#endif
            VM_MAX_KERNEL_ADDRESS);
 
        /*
@@ -273,7 +308,7 @@
         * kernel image is mapped on L2 table (2MB*n) by locore.S
         * virtual space start from 2MB aligned kernend
         */
-       pmap_bootstrap(kernend_l2, VM_MAX_KERNEL_ADDRESS);
+       pmap_bootstrap(kernelvmstart, VM_MAX_KERNEL_ADDRESS);
 
        /*
         * setup lwp0
@@ -428,6 +463,14 @@
        cpu_reset_address0 = NULL;
 }
 
+#ifdef MODULAR
+/* Push any modules loaded by the boot loader */
+void
+module_init_md(void)
+{
+}
+#endif /* MODULAR */
+
 bool
 mm_md_direct_mapped_phys(paddr_t pa, vaddr_t *vap)
 {
@@ -465,6 +508,12 @@
        phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
           VM_PHYS_SIZE, 0, FALSE, NULL);
 
+#ifdef MODULAR
+       uvm_map_setup(&module_map_store, module_start, module_end, 0);
+       module_map_store.pmap = pmap_kernel();
+       module_map = &module_map_store;
+#endif
+
        /* Hello! */
        banner();
 }
diff -r b4082cebd584 -r 66c7199994f4 sys/arch/aarch64/aarch64/kobj_machdep.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/aarch64/aarch64/kobj_machdep.c   Wed Aug 15 11:10:45 2018 +0000
@@ -0,0 +1,364 @@
+/*     $NetBSD: kobj_machdep.c,v 1.1 2018/08/15 11:10:45 ryo Exp $     */
+
+/*
+ * Copyright (c) 2018 Ryo Shimizu <ryo%nerv.org@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.1 2018/08/15 11:10:45 ryo Exp $");
+
+#define ELFSIZE                ARCH_ELFSIZE
+
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/kobj.h>
+#include <sys/exec.h>
+#include <sys/exec_elf.h>
+#include <sys/errno.h>
+#include <sys/queue.h>
+#include <sys/tree.h>
+
+#include <aarch64/cpufunc.h>
+
+/* #define KOBJ_MACHDEP_DEBUG */
+
+#ifdef KOBJ_MACHDEP_DEBUG
+#ifdef DDB
+#include <aarch64/db_machdep.h>        /* for strdisasm() */
+#endif
+
+struct rtypeinfo {
+       Elf_Word rtype;
+       const char *name;
+};
+
+static const struct rtypeinfo rtypetbl[] = {
+       { R_AARCH64_ABS64,              "R_AARCH64_ABS64"               },
+       { R_AARCH64_ADD_ABS_LO12_NC,    "R_AARCH64_ADD_ABS_LO12_NC"     },
+       { R_AARCH_LDST64_ABS_LO12_NC,   "R_AARCH64_LDST64_ABS_LO12_NC"  },
+       { R_AARCH_LDST32_ABS_LO12_NC,   "R_AARCH64_LDST32_ABS_LO12_NC"  },
+       { R_AARCH_LDST16_ABS_LO12_NC,   "R_AARCH64_LDST16_ABS_LO12_NC"  },
+       { R_AARCH64_LDST8_ABS_LO12_NC,  "R_AARCH64_LDST8_ABS_LO12_NC"   },
+       { R_AARCH64_ADR_PREL_PG_HI21_NC, "R_AARCH64_ADR_PREL_PG_HI21_NC"},
+       { R_AARCH64_ADR_PREL_PG_HI21,   "R_AARCH64_ADR_PREL_PG_HI21"    },
+       { R_AARCH_JUMP26,               "R_AARCH64_JUMP26"              },
+       { R_AARCH_CALL26,               "R_AARCH64_CALL26"              },
+       { R_AARCH64_PREL32,             "R_AARCH64_PREL32"              },
+       { R_AARCH64_PREL16,             "R_AARCH64_PREL16"              }
+};
+
+static const char *
+strrtype(Elf_Word rtype)
+{
+       int i;
+       static char buf[64];
+
+       for (i = 0; i < __arraycount(rtypetbl); i++) {
+               if (rtypetbl[i].rtype == rtype)
+                       return rtypetbl[i].name;
+       }
+       snprintf(buf, sizeof(buf), "RELOCATION-TYPE-%d", rtype);
+       return buf;
+}
+#endif /* KOBJ_MACHDEP_DEBUG */
+
+static inline bool
+checkalign(Elf_Addr addr, int alignbyte, void *where, Elf64_Addr off)
+{
+       if ((addr & (alignbyte - 1)) != 0) {
+               printf("kobj_reloc: Relocation 0x%jx unaligned at %p"
+                   " (base+0x%jx). must be aligned %d\n",
+                   (uintptr_t)addr, where, off, alignbyte);
+               return true;
+       }
+       return false;
+}
+
+static inline bool
+checkoverflow(Elf_Addr addr, int bitwidth, Elf_Addr targetaddr,
+    const char *bitscale, void *where, Elf64_Addr off)
+{
+       const Elf_Addr mask = ~__BITS(bitwidth - 1, 0);
+
+       if (((addr & mask) != 0) && ((addr & mask) != mask)) {
+               printf("kobj_reloc: Relocation 0x%jx too far from %p"
+                   " (base+0x%jx) for %dbit%s\n",
+                   (uintptr_t)targetaddr, where, off, bitwidth, bitscale);
+               return true;
+       }
+       return false;
+}
+
+#define WIDTHMASK(w)   (0xffffffffffffffffUL >> (64 - (w)))
+
+int
+kobj_reloc(kobj_t ko, uintptr_t relocbase, const void *data,
+    bool isrela, bool local)
+{
+       Elf_Addr saddr, addend, raddr, val;
+       Elf64_Addr off, *where;
+       Elf32_Addr *where32;
+       uint16_t *where16;
+       Elf_Word rtype, symidx;
+       const Elf_Rela *rela;
+       int error;
+       uint32_t *insn, immhi, immlo, shift;
+       bool nc = false;
+#ifdef KOBJ_MACHDEP_DEBUG
+#ifdef DDB
+       char disasmbuf[256];
+#endif
+       Elf_Addr old;
+#endif /* KOBJ_MACHDEP_DEBUG */
+
+
+#ifdef KOBJ_MACHDEP_DEBUG
+       printf("%s:%d: ko=%p, relocbase=0x%jx, data=%p"
+           ", isrela=%d, local=%d\n", __func__, __LINE__,
+           ko, relocbase, data, isrela, local);
+#endif /* KOBJ_MACHDEP_DEBUG */
+
+       if (!isrela) {
+               printf("kobj_reloc: REL relocations not supported");
+               error = 1;
+               goto done;
+       }
+
+       rela = (const Elf_Rela *)data;
+       addend = rela->r_addend;
+       rtype = ELF_R_TYPE(rela->r_info);
+       symidx = ELF_R_SYM(rela->r_info);
+       off = rela->r_offset;
+       where = (Elf_Addr *)(relocbase + off);
+
+       /* pointer to 32bit, 16bit, and instruction */
+       where32 = (void *)where;
+       where16 = (void *)where;
+       insn = (uint32_t *)where;
+
+       /* no need to lookup any symbols */



Home | Main Index | Thread Index | Old Index