Browse Source

Various bits of aarch64 code to support ARM64.

Implement (or copy from another architecture) most of the
bits required for building libraries and applications for
aarch64.  The system more or less builds now.

I'm sure there are some bugs in this code: see, for example,
libc/aarch64/main9.S: this is the "get to build" stage.  The
next stage is "make work."

Signed-off-by: Dan Cross <cross@gajendra.net>
Dan Cross 7 years ago
parent
commit
40e0434b70

+ 17 - 0
sys/src/cmd/gdbserver/aarch64.S

@@ -0,0 +1,17 @@
+/*
+ * This file is part of the UCB release of Plan 9. It is subject to the license
+ * terms in the LICENSE file found in the top-level directory of this
+ * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
+ * part of the UCB release of Plan 9, including this file, may be copied,
+ * modified, propagated, or distributed except according to the terms contained
+ * in the LICENSE file.
+ */
+
+.text
+
+.global breakpoint
+breakpoint:
+.long	0xdeadbeef
+
+.global ebreakpoint
+ebreakpoint:

+ 133 - 0
sys/src/cmd/gdbserver/regsaarch64.c

@@ -0,0 +1,133 @@
+/*
+ * Kernel Debug Core
+ *
+ * Maintainer: Jason Wessel <jason.wessel@windriver.com>
+ *
+ * Copyright (C) 2000-2001 VERITAS Software Corporation.
+ * Copyright (C) 2002-2004 Timesys Corporation
+ * Copyright (C) 2003-2004 Amit S. Kale <amitkale@linsyssoft.com>
+ * Copyright (C) 2004 Pavel Machek <pavel@ucw.cz>
+ * Copyright (C) 2004-2006 Tom Rini <trini@kernel.crashing.org>
+ * Copyright (C) 2004-2006 LinSysSoft Technologies Pvt. Ltd.
+ * Copyright (C) 2005-2009 Wind River Systems, Inc.
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ * Copyright (C) 2008 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *
+ * Contributors at various stages not listed above:
+ *  Jason Wessel ( jason.wessel@windriver.com )
+ *  George Anzinger <george@mvista.com>
+ *  Anurekh Saxena (anurekh.saxena@timesys.com)
+ *  Lake Stevens Instrument Division (Glenn Engel)
+ *  Jim Kingdon, Cygnus Support.
+ *
+ * Original KGDB stub: David Grothe <dave@gcom.com>,
+ * Tigran Aivazian <tigran@sco.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <u.h>
+#include <libc.h>
+#include <ureg.h>
+#include <ctype.h>
+
+#include "debug_core.h"
+#include "gdb.h"
+
+/* all because gdb has stupid register layouts. Too bad. */
+
+static char *
+gdb_hex_reg_helper(uintptr_t *gdb_regs, int regnum, char *out)
+{
+	int offset = 0;
+
+	if (regnum <= GDB_PC)
+		return mem2hex((void *)&gdb_regs[offset], out, sizeof(uintptr_t));
+	if (regnum == GDB_PS)
+		return mem2hex((void *)&gdb_regs[offset], out, sizeof(uint32_t));
+	memset(out, 0, sizeof(uint32_t));
+	return nil;
+}
+
+/* Handle the 'p' individual regster get */
+void
+gdb_cmd_reg_get(struct state *ks)
+{
+	unsigned long regnum;
+	char *ptr = (char *)&remcom_in_buffer[1];
+
+	hex2long(&ptr, &regnum);
+	syslog(0, "gdbserver", "Get reg %p: ", regnum);
+	if (regnum >= DBG_MAX_REG_NUM) {
+		syslog(0, "gdbserver", "fails\n");
+		error_packet(remcom_out_buffer, Einval);
+		return;
+	}
+	syslog(0, "gdbserver", "returns :%s:\n", ptr);
+	gdb_hex_reg_helper(ks->gdbregs, regnum, (char *)ptr);
+}
+
+/* Handle the 'P' individual regster set */
+void
+gdb_cmd_reg_set(struct state *ks)
+{
+	fprint(2, "%s: NOET YET\n", __func__);
+#if 0 // not yet.
+	unsigned long regnum;
+	char *ptr = &remcom_in_buffer[1];
+	int i = 0;
+
+	hex2long(&ptr, &regnum);
+	if (*ptr++ != '=' ||
+		!dbg_get_reg(regnum, gdb_regs, ks->linux_regs)) {
+		error_packet(remcom_out_buffer, -EINVAL);
+		return;
+	}
+	memset(gdb_regs, 0, sizeof(gdb_regs));
+	while (i < sizeof(gdb_regs) * 2)
+		if (hex_to_bin(ptr[i]) >= 0)
+			i++;
+		else
+			break;
+	i = i / 2;
+	hex2mem(ptr, (char *)gdb_regs, i);
+	dbg_set_reg(regnum, gdb_regs, ks->linux_regs);
+#endif
+	strcpy((char *)remcom_out_buffer, "OK");
+}
+
+void arch_set_pc(uintptr_t *regs, unsigned long pc)
+{
+	// not yet.
+}
+
+char *
+gpr(struct state *ks, int pid)
+{
+	if (ks->gdbregs == nil)
+		ks->gdbregs = malloc(NUMREGBYTES);
+
+	if (pid <= 0) {
+		syslog(0, "gdbserver", "%s: FUCK. pid <= 0", __func__);
+		pid = 1;
+	}
+	char *cp = ks->gdbregs;
+	char *regname = smprint("/proc/%d/gdbregs", pid);
+	int fd = open(regname, 0);
+	if (fd < 0) {
+		syslog(0, "gdbserver", "open(%s, 0): %r\n", regname);
+		return errstring(Enoent);
+	}
+
+	if (pread(fd, cp, NUMREGBYTES, 0) < NUMREGBYTES){
+		close(fd);
+		return errstring(Eio);
+	}
+	close(fd);
+
+	return nil;
+
+}
+

+ 25 - 0
sys/src/libc/aarch64/ainc.S

@@ -0,0 +1,25 @@
+// This file is part of the Harvey operating system.  It is subject to the
+// license terms of the GNU GPL v2 in LICENSE.gpl found in the top-level
+// directory of this distribution and at http://www.gnu.org/licenses/gpl-2.0.txt
+//
+// No part of Harvey operating system, including this file, may be copied,
+// modified, propagated, or distributed except according to the terms
+// contained in the LICENSE.gpl file.
+
+.text
+
+.globl ainc
+ainc:	LDXR	x1, [x0]
+	ADD	x1, x1, #1
+	STLXR	w1, x1, [x0]
+	CBNZ	w1, ainc
+	DMB	ISH
+	RET
+
+.globl adec
+adec:	LDXR	x1, [x0]
+	SUB	x1, x1, #1
+	STLXR	w1, x1, [x0]
+	CBNZ	w1, adec
+	DMB	ISH
+	RET

+ 18 - 0
sys/src/libc/aarch64/argv0.c

@@ -0,0 +1,18 @@
+/*
+ * This file is part of the Harvey operating system.  It is subject to the
+ * license terms of the GNU GPL v2 in LICENSE.gpl found in the top-level
+ * directory of this distribution and at http://www.gnu.org/licenses/gpl-2.0.txt
+ *
+ * No part of Harvey operating system, including this file, may be copied,
+ * modified, propagated, or distributed except according to the terms
+ * contained in the LICENSE.gpl file.
+ */
+
+#include <u.h>
+#include <libc.h>
+
+void (*_abort)(void);
+char *argv0;
+char *_tos;
+char *_privates;
+char *_nprivates;

+ 9 - 0
sys/src/libc/aarch64/build.json

@@ -1,6 +1,15 @@
 {
     "archfiles": {
         "SourceFiles": [
+            "$ARCH/ainc.S",
+            "$ARCH/argv0.c",
+            "$ARCH/getcallerpc.S",
+            "$ARCH/getcallstack.S",
+            "$ARCH/main9.S",
+            "$ARCH/notejmp.c",
+            "$ARCH/setjmp.c",
+            "$ARCH/sqrt.c",
+            "$ARCH/tas.S"
         ]
     }
 }

+ 15 - 0
sys/src/libc/aarch64/getcallerpc.S

@@ -0,0 +1,15 @@
+// This file is part of the Harvey operating system.  It is subject to the
+// license terms of the GNU GPL v2 in LICENSE.gpl found in the top-level
+// directory of this distribution and at http://www.gnu.org/licenses/gpl-2.0.txt
+//
+// No part of Harvey operating system, including this file, may be copied,
+// modified, propagated, or distributed except according to the terms
+// contained in the LICENSE.gpl file.
+
+.text
+
+.globl getcallerpc
+getcallerpc:
+	ADD	x1, sp, #16
+	STR	x1, [x0]
+	RET

+ 16 - 0
sys/src/libc/aarch64/getcallstack.S

@@ -0,0 +1,16 @@
+// This file is part of the Harvey operating system.  It is subject to the
+// license terms of the GNU GPL v2 in LICENSE.gpl found in the top-level
+// directory of this distribution and at http://www.gnu.org/licenses/gpl-2.0.txt
+//
+// No part of Harvey operating system, including this file, may be copied,
+// modified, propagated, or distributed except according to the terms
+// contained in the LICENSE.gpl file.
+
+.text
+
+.globl getcallstack
+getcallstack:
+	ADD	x1, sp, #16
+	STR	x1, [x0]
+	STR	XZR, [x0, #8]
+	RET

+ 13 - 0
sys/src/libc/aarch64/main9.S

@@ -0,0 +1,13 @@
+// This file is part of the Harvey operating system.  It is subject to the
+// license terms of the GNU GPL v2 in LICENSE.gpl found in the top-level
+// directory of this distribution and at http://www.gnu.org/licenses/gpl-2.0.txt
+//
+// No part of Harvey operating system, including this file, may be copied,
+// modified, propagated, or distributed except according to the terms
+// contained in the LICENSE.gpl file.
+
+.text
+
+.globl _main
+_main:
+	RET

+ 22 - 0
sys/src/libc/aarch64/notejmp.c

@@ -0,0 +1,22 @@
+/*
+ * This file is part of the Harvey operating system.  It is subject to the
+ * license terms of the GNU GPL v2 in LICENSE.gpl found in the top-level
+ * directory of this distribution and at http://www.gnu.org/licenses/gpl-2.0.txt
+ *
+ * No part of Harvey operating system, including this file, may be copied,
+ * modified, propagated, or distributed except according to the terms
+ * contained in the LICENSE.gpl file.
+ */
+
+#include <u.h>
+#include <libc.h>
+#include <ureg.h>
+
+void
+notejmp(void *vr, jmp_buf j, int ret)
+{
+	// TODO(cross): Write this.
+	(void)vr;
+	(void)j;
+	(void)ret;
+}

+ 24 - 0
sys/src/libc/aarch64/setjmp.c

@@ -0,0 +1,24 @@
+/*
+ * This file is part of the Harvey operating system.  It is subject to the
+ * license terms of the GNU GPL v2 in LICENSE.gpl found in the top-level
+ * directory of this distribution and at http://www.gnu.org/licenses/gpl-2.0.txt
+ *
+ * No part of Harvey operating system, including this file, may be copied,
+ * modified, propagated, or distributed except according to the terms
+ * contained in the LICENSE.gpl file.
+ */
+
+#include <u.h>
+#include <libc.h>
+
+int
+setjmp(jmp_buf buf)
+{
+	return __builtin_setjmp(buf);
+}
+
+void
+longjmp(jmp_buf buf, int n)
+{
+	return __builtin_longjmp(buf, 1);
+}

+ 16 - 0
sys/src/libc/aarch64/sqrt.c

@@ -0,0 +1,16 @@
+// from vesa karvonen
+double sqrt (double y) {
+	double x, z, tempf;
+	unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
+
+	tempf = y;
+	*tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */
+	x =  tempf;
+	z =  y*0.5;                        /* hoist out the "/2"    */
+	x = (1.5*x) - (x*x)*(x*z);         /* iteration formula     */
+	x = (1.5*x) - (x*x)*(x*z);
+	x = (1.5*x) - (x*x)*(x*z);
+	x = (1.5*x) - (x*x)*(x*z);
+	x = (1.5*x) - (x*x)*(x*z);
+	return x*y;
+}

+ 20 - 0
sys/src/libc/aarch64/tas.S

@@ -0,0 +1,20 @@
+// This file is part of the Harvey operating system.  It is subject to the
+// license terms of the GNU GPL v2 in LICENSE.gpl found in the top-level
+// directory of this distribution and at http://www.gnu.org/licenses/gpl-2.0.txt
+//
+// No part of Harvey operating system, including this file, may be copied,
+// modified, propagated, or distributed except according to the terms
+// contained in the LICENSE.gpl file.
+
+.text
+
+.globl _tas
+_tas:
+	MOVK	w1, #0xdead
+	MOVZ	w1, #0xbeef
+	LDXR	x2, [x0]
+	CBNZ	x2, 1f
+	STLXR	w1, x1, [x0]
+	DMB	ISH
+1:	MOV	x1, x2
+	RET

+ 37 - 1
sys/src/libthread/aarch64.c

@@ -1 +1,37 @@
-//
+/*
+ * This file is part of the UCB release of Plan 9. It is subject to the license
+ * terms in the LICENSE file found in the top-level directory of this
+ * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
+ * part of the UCB release of Plan 9, including this file, may be copied,
+ * modified, propagated, or distributed except according to the terms contained
+ * in the LICENSE file.
+ */
+
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include "threadimpl.h"
+
+/* first argument goes in a register; simplest just to ignore it */
+static void
+launcheraarch64(int unused, void (*f)(void *arg), void *arg)
+{
+	(void)unused;
+	(*f)(arg);
+	threadexits(nil);
+}
+
+void
+_threadinitstack(Thread *t, void (*f)(void*), void *arg)
+{
+	uint64_t *tos;
+
+	tos = (uint64_t*)&t->stk[t->stksize&~0x0F];
+	*--tos = (uint64_t)arg;
+	*--tos = (uint64_t)f;
+	*--tos = 0;	/* first arg to launcheraarch64 */
+	*--tos = 0;	/* place to store return PC */
+
+	t->sched[JMPBUFPC] = (uint64_t)launcheraarch64+JMPBUFDPC;
+	t->sched[JMPBUFSP] = (uint64_t)tos;
+}