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