Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch Add pmon (firmware used by loongson2-based systems ...
details: https://anonhg.NetBSD.org/src/rev/d8122672b6a2
branches: trunk
changeset: 768777:d8122672b6a2
user: bouyer <bouyer%NetBSD.org@localhost>
date: Sat Aug 27 13:34:29 2011 +0000
description:
Add pmon (firmware used by loongson2-based systems and maybe others) support,
from OpenBSD.
This includes code to call back pmon routines from a 64bit kernel,
as well code to read pmon arguments and variables.
diffstat:
sys/arch/evbmips/conf/files.evbmips | 7 ++-
sys/arch/mips/pmon/pmon.c | 99 +++++++++++++++++++++++++++++++++++
sys/arch/mips/pmon/pmon.h | 52 ++++++++++++++++++
sys/arch/mips/pmon/pmon32.S | 100 ++++++++++++++++++++++++++++++++++++
4 files changed, 257 insertions(+), 1 deletions(-)
diffs (282 lines):
diff -r 3b95769172e6 -r d8122672b6a2 sys/arch/evbmips/conf/files.evbmips
--- a/sys/arch/evbmips/conf/files.evbmips Sat Aug 27 13:28:37 2011 +0000
+++ b/sys/arch/evbmips/conf/files.evbmips Sat Aug 27 13:34:29 2011 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.evbmips,v 1.6 2007/03/20 08:52:01 dyoung Exp $
+# $NetBSD: files.evbmips,v 1.7 2011/08/27 13:34:29 bouyer Exp $
# maxpartitions must be the first item in files.${ARCH}
maxpartitions 16
@@ -20,4 +20,9 @@
# Console glue.
file dev/cons.c
+# PMON suport
+defflag PMON
+file arch/mips/pmon/pmon.c pmon
+file arch/mips/pmon/pmon32.S pmon
+
include "arch/evbmips/conf/majors.evbmips"
diff -r 3b95769172e6 -r d8122672b6a2 sys/arch/mips/pmon/pmon.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/mips/pmon/pmon.c Sat Aug 27 13:34:29 2011 +0000
@@ -0,0 +1,99 @@
+/* $OpenBSD: pmon.c,v 1.4 2010/02/16 21:29:54 miod Exp $ */
+
+/*
+ * Copyright (c) 2009 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+
+#include <machine/cpu.h>
+#include <mips/pmon/pmon.h>
+
+int pmon_argc;
+int32_t *pmon_argv;
+int32_t *pmon_envp;
+
+void
+pmon_init(int32_t argc, int32_t argv, int32_t envp, int32_t callvec)
+{
+ pmon_callvec = callvec;
+
+ pmon_argc = argc;
+ /* sign extend pointers */
+ pmon_argv = (int32_t *)(vaddr_t)argv;
+ pmon_envp = (int32_t *)(vaddr_t)envp;
+}
+
+const char *
+pmon_getarg(const int argno)
+{
+ if (argno < 0 || argno >= pmon_argc)
+ return NULL;
+
+ return (const char *)(vaddr_t)pmon_argv[argno];
+}
+
+const char *
+pmon_getenv(const char *var)
+{
+ int32_t *envptr = pmon_envp;
+ const char *envstr;
+ size_t varlen;
+
+ if (envptr == NULL)
+ return NULL;
+
+ varlen = strlen(var);
+ while (*envptr != 0) {
+ envstr = (const char *)(vaddr_t)*envptr;
+ /*
+ * There is a PMON2000 bug, at least on Lemote Yeeloong,
+ * which causes it to override part of the environment
+ * pointers array with the environment data itself.
+ *
+ * This only happens on cold boot, and if the BSD kernel
+ * is loaded without symbols (i.e. no option -k passed
+ * to the boot command).
+ *
+ * Until a suitable workaround is found or the bug is
+ * fixed, ignore broken environment information and
+ * tell the user (in case this prevents us from finding
+ * important information).
+ */
+ if ((vaddr_t)envstr < (vaddr_t)MIPS_KSEG1_START ||
+ (vaddr_t)envstr >= (vaddr_t)MIPS_KSEG2_START) {
+ printf("WARNING! CORRUPTED ENVIRONMENT!\n");
+ printf("Unable to search for %s.\n", var);
+#ifdef _STANDALONE
+ printf("If boot fails, power-cycle the machine.\n");
+#else
+ printf("If the kernel fails to identify the system"
+ " type, please boot it again with `-k' option.\n");
+#endif
+
+ /* terminate environment for further calls */
+ *envptr = 0;
+ break;
+ }
+ if (strncmp(envstr, var, varlen) == 0 &&
+ envstr[varlen] == '=')
+ return envstr + varlen + 1;
+ envptr++;
+ }
+
+ return NULL;
+}
diff -r 3b95769172e6 -r d8122672b6a2 sys/arch/mips/pmon/pmon.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/mips/pmon/pmon.h Sat Aug 27 13:34:29 2011 +0000
@@ -0,0 +1,52 @@
+/* $OpenBSD: pmon.h,v 1.2 2010/02/14 22:39:33 miod Exp $ */
+
+/*
+ * Copyright (c) 2009 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _MACHINE_PMON_H_
+#define _MACHINE_PMON_H_
+
+#if defined(_KERNEL) || defined(_STANDALONE)
+
+/*
+ * PMON2000 callvec definitions
+ */
+
+/* 32-bit compatible types */
+typedef uint32_t pmon_size_t;
+typedef int32_t pmon_ssize_t;
+typedef int64_t pmon_off_t;
+
+int pmon_open(const char *, int, ...);
+int pmon_close(int);
+int pmon_read(int, void *, pmon_size_t);
+pmon_ssize_t pmon_write(int, const void *, pmon_size_t);
+pmon_off_t pmon_lseek(int, pmon_off_t, int);
+int pmon_printf(const char *, ...);
+void pmon_cacheflush(void);
+char * pmon_gets(char *);
+
+#define PMON_MAXLN 256 /* internal gets() size limit */
+
+extern int32_t pmon_callvec;
+
+const char *pmon_getarg(const int);
+const char *pmon_getenv(const char *);
+void pmon_init(int32_t, int32_t, int32_t, int32_t);
+
+#endif /* _KERNEL || _STANDALONE */
+
+#endif /* _MACHINE_PMON_H_ */
diff -r 3b95769172e6 -r d8122672b6a2 sys/arch/mips/pmon/pmon32.S
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/mips/pmon/pmon32.S Sat Aug 27 13:34:29 2011 +0000
@@ -0,0 +1,100 @@
+/* $NetBSD: pmon32.S,v 1.1 2011/08/27 13:34:29 bouyer Exp $ */
+/* OpenBSD: pmon32.S,v 1.4 2010/02/18 18:53:33 miod Exp */
+
+/*
+ * Copyright (c) 2009 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Wrapper routines to invoke PMON2000 functions from 64-bit code.
+ *
+ * PMON is compiled as 64 bit code, using the gcc o64 ABI (similar to the o32
+ * ABI, but using 64 bit registers).
+ *
+ * As a result, only up to four arguments to functions will be passed through
+ * registers. It's up to the caller to never invoke pmon_printf() with more
+ * than four arguments; other functions are not affected.
+ */
+
+#include <machine/param.h>
+#include <machine/asm.h>
+
+#ifndef _STANDALONE
+#include "assym.h"
+#endif
+
+ .set mips3
+
+ .data
+ .globl pmon_callvec
+pmon_callvec:
+ .word 0
+
+ .text
+#define PMON_CALLFRAME_SIZ (CALLFRAME_SIZ)
+/*
+ * Note that we need to provide a PMON_CALLFRAME_SIZ untouched area above sp,
+ * or we'll risk our stack being corrupted upon return.
+ */
+
+#define FRAMESZ(sz) (((sz) + ALSK) & ~ALSK)
+
+#define PMON_WRAP(name, index) \
+ NNON_LEAF(name, FRAMESZ(PMON_CALLFRAME_SIZ + 11 * SZREG), ra); \
+ PTR_SUBU sp, sp, FRAMESZ(PMON_CALLFRAME_SIZ + 11 * SZREG); \
+ REG_S ra, (10 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ .mask 0xc0ff0000, (CALLFRAME_RA - FRAMESZ(PMON_CALLFRAME_SIZ + 10 * SZREG)); \
+ REG_S s0, (0 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_S s1, (1 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_S s2, (2 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_S s3, (3 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_S s4, (4 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_S s5, (5 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_S s6, (6 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_S s7, (7 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_S s8, (8 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_S t8, (9 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ lw t0, pmon_callvec; \
+ lw t0, (index) * 4 (t0); \
+ jalr t0; \
+ nop; \
+ REG_L t8, (9 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_L s8, (8 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_L s7, (7 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_L s6, (6 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_L s5, (5 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_L s4, (4 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_L s3, (3 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_L s2, (2 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_L s1, (1 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_L s0, (0 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ REG_L ra, (10 * SZREG + PMON_CALLFRAME_SIZ)(sp); \
+ PTR_ADDU sp, sp, FRAMESZ(PMON_CALLFRAME_SIZ + 11 * SZREG); \
+ jr ra; \
+ nop; \
+ END(name)
+
+PMON_WRAP(pmon_printf, 5)
+PMON_WRAP(pmon_gets, 7)
+#ifdef _STANDALONE
+PMON_WRAP(pmon_open, 0)
+PMON_WRAP(pmon_close, 1)
+PMON_WRAP(pmon_read, 2)
+PMON_WRAP(pmon_lseek, 4)
+PMON_WRAP(pmon_cacheflush, 6)
+#endif
+#if 0 /* unused */
+PMON_WRAP(pmon_write, 3)
+#endif
Home |
Main Index |
Thread Index |
Old Index