1 1.1 bouyer /* $OpenBSD: pmon.c,v 1.4 2010/02/16 21:29:54 miod Exp $ */ 2 1.1 bouyer 3 1.1 bouyer /* 4 1.1 bouyer * Copyright (c) 2009 Miodrag Vallat. 5 1.1 bouyer * 6 1.1 bouyer * Permission to use, copy, modify, and distribute this software for any 7 1.1 bouyer * purpose with or without fee is hereby granted, provided that the above 8 1.1 bouyer * copyright notice and this permission notice appear in all copies. 9 1.1 bouyer * 10 1.1 bouyer * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 1.1 bouyer * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 1.1 bouyer * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 1.1 bouyer * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 1.1 bouyer * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 1.1 bouyer * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 1.1 bouyer * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 1.1 bouyer */ 18 1.1 bouyer 19 1.1 bouyer #include <sys/param.h> 20 1.1 bouyer #include <sys/systm.h> 21 1.2 matt #include <sys/cpu.h> 22 1.1 bouyer #include <sys/proc.h> 23 1.1 bouyer 24 1.2 matt #include <mips/cpuregs.h> 25 1.1 bouyer #include <mips/pmon/pmon.h> 26 1.1 bouyer 27 1.1 bouyer int pmon_argc; 28 1.1 bouyer int32_t *pmon_argv; 29 1.1 bouyer int32_t *pmon_envp; 30 1.1 bouyer 31 1.1 bouyer void 32 1.1 bouyer pmon_init(int32_t argc, int32_t argv, int32_t envp, int32_t callvec) 33 1.1 bouyer { 34 1.1 bouyer pmon_callvec = callvec; 35 1.1 bouyer 36 1.1 bouyer pmon_argc = argc; 37 1.1 bouyer /* sign extend pointers */ 38 1.1 bouyer pmon_argv = (int32_t *)(vaddr_t)argv; 39 1.1 bouyer pmon_envp = (int32_t *)(vaddr_t)envp; 40 1.1 bouyer } 41 1.1 bouyer 42 1.1 bouyer const char * 43 1.1 bouyer pmon_getarg(const int argno) 44 1.1 bouyer { 45 1.1 bouyer if (argno < 0 || argno >= pmon_argc) 46 1.1 bouyer return NULL; 47 1.1 bouyer 48 1.1 bouyer return (const char *)(vaddr_t)pmon_argv[argno]; 49 1.1 bouyer } 50 1.1 bouyer 51 1.1 bouyer const char * 52 1.1 bouyer pmon_getenv(const char *var) 53 1.1 bouyer { 54 1.1 bouyer int32_t *envptr = pmon_envp; 55 1.1 bouyer const char *envstr; 56 1.1 bouyer size_t varlen; 57 1.1 bouyer 58 1.1 bouyer if (envptr == NULL) 59 1.1 bouyer return NULL; 60 1.1 bouyer 61 1.1 bouyer varlen = strlen(var); 62 1.1 bouyer while (*envptr != 0) { 63 1.1 bouyer envstr = (const char *)(vaddr_t)*envptr; 64 1.1 bouyer /* 65 1.1 bouyer * There is a PMON2000 bug, at least on Lemote Yeeloong, 66 1.1 bouyer * which causes it to override part of the environment 67 1.1 bouyer * pointers array with the environment data itself. 68 1.1 bouyer * 69 1.1 bouyer * This only happens on cold boot, and if the BSD kernel 70 1.1 bouyer * is loaded without symbols (i.e. no option -k passed 71 1.1 bouyer * to the boot command). 72 1.1 bouyer * 73 1.1 bouyer * Until a suitable workaround is found or the bug is 74 1.1 bouyer * fixed, ignore broken environment information and 75 1.1 bouyer * tell the user (in case this prevents us from finding 76 1.1 bouyer * important information). 77 1.1 bouyer */ 78 1.1 bouyer if ((vaddr_t)envstr < (vaddr_t)MIPS_KSEG1_START || 79 1.1 bouyer (vaddr_t)envstr >= (vaddr_t)MIPS_KSEG2_START) { 80 1.1 bouyer printf("WARNING! CORRUPTED ENVIRONMENT!\n"); 81 1.1 bouyer printf("Unable to search for %s.\n", var); 82 1.1 bouyer #ifdef _STANDALONE 83 1.1 bouyer printf("If boot fails, power-cycle the machine.\n"); 84 1.1 bouyer #else 85 1.1 bouyer printf("If the kernel fails to identify the system" 86 1.1 bouyer " type, please boot it again with `-k' option.\n"); 87 1.1 bouyer #endif 88 1.1 bouyer 89 1.1 bouyer /* terminate environment for further calls */ 90 1.1 bouyer *envptr = 0; 91 1.1 bouyer break; 92 1.1 bouyer } 93 1.1 bouyer if (strncmp(envstr, var, varlen) == 0 && 94 1.1 bouyer envstr[varlen] == '=') 95 1.1 bouyer return envstr + varlen + 1; 96 1.1 bouyer envptr++; 97 1.1 bouyer } 98 1.1 bouyer 99 1.1 bouyer return NULL; 100 1.1 bouyer } 101