#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <machine/cpu.h>
#include <machine/pmon.h>
int pmon_argc;
int32_t *pmon_argv;
int32_t *pmon_envp;
vaddr_t pmon_envbase;
int pmon_envtype;
void
pmon_init(int32_t argc, int32_t argv, int32_t envp, int32_t callvec,
uint32_t prid)
{
pmon_callvec = callvec;
pmon_argc = argc;
pmon_argv = (int32_t *)(vaddr_t)argv;
pmon_envp = (int32_t *)(vaddr_t)envp;
switch (prid & 0xff) {
case 0x02:
case 0x03:
pmon_envtype = PMON_ENVTYPE_ENVP;
pmon_envbase = CKSEG1_BASE;
break;
default:
{
struct pmon_env *env = (struct pmon_env *)pmon_envp;
if (env->efi.bios.version < 0x2000 &&
env->efi.bios.vga_bios >= CKSEG0_BASE &&
env->efi.bios.vga_bios < CKSEG0_BASE + CKSEG_SIZE) {
pmon_envtype = PMON_ENVTYPE_EFI;
} else {
pmon_envtype = PMON_ENVTYPE_ENVP;
pmon_envbase = CKSEG0_BASE;
}
}
break;
}
if (pmon_envtype == PMON_ENVTYPE_ENVP) {
pmon_envbase = (uint64_t)*pmon_envp < CKSEG1_BASE ?
CKSEG0_BASE : CKSEG1_BASE;
}
}
const char *
pmon_getarg(const int argno)
{
if (argno < 0 || argno >= pmon_argc)
return NULL;
return (const char *)(vaddr_t)pmon_argv[argno];
}
int
pmon_getenvtype()
{
return pmon_envtype;
}
const char *
pmon_getenv(const char *var)
{
int32_t *envptr = pmon_envp;
const char *envstr;
size_t varlen;
if (envptr == NULL || pmon_envtype != PMON_ENVTYPE_ENVP)
return NULL;
varlen = strlen(var);
while (*envptr != 0) {
envstr = (const char *)(vaddr_t)*envptr;
if ((vaddr_t)envstr - pmon_envbase >= CKSEG_SIZE) {
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
*envptr = 0;
break;
}
if (strncmp(envstr, var, varlen) == 0 &&
envstr[varlen] == '=')
return envstr + varlen + 1;
envptr++;
}
return NULL;
}
const struct pmon_env_reset *
pmon_get_env_reset(void)
{
struct pmon_env *env = (struct pmon_env *)pmon_envp;
if (pmon_envtype != PMON_ENVTYPE_EFI)
return NULL;
return &env->reset;
}
const struct pmon_env_smbios *
pmon_get_env_smbios(void)
{
struct pmon_env *env = (struct pmon_env *)pmon_envp;
if (pmon_envtype != PMON_ENVTYPE_EFI)
return NULL;
return &env->efi.bios;
}
const struct pmon_env_mem *
pmon_get_env_mem(void)
{
struct pmon_env *env = (struct pmon_env *)pmon_envp;
uint64_t va = (uint64_t)&env->efi.bios.ptrs;
if (pmon_envtype != PMON_ENVTYPE_EFI)
return NULL;
return (const struct pmon_env_mem *)
(va + env->efi.bios.ptrs.offs_mem);
}
const struct pmon_env_cpu *
pmon_get_env_cpu(void)
{
struct pmon_env *env = (struct pmon_env *)pmon_envp;
uint64_t va = (uint64_t)&env->efi.bios.ptrs;
if (pmon_envtype != PMON_ENVTYPE_EFI)
return NULL;
return (const struct pmon_env_cpu *)
(va + env->efi.bios.ptrs.offs_cpu);
}
const struct pmon_env_sys *
pmon_get_env_sys(void)
{
struct pmon_env *env = (struct pmon_env *)pmon_envp;
uint64_t va = (uint64_t)&env->efi.bios.ptrs;
if (pmon_envtype != PMON_ENVTYPE_EFI)
return NULL;
return (const struct pmon_env_sys *)
(va + env->efi.bios.ptrs.offs_sys);
}
const struct pmon_env_irq *
pmon_get_env_irq(void)
{
struct pmon_env *env = (struct pmon_env *)pmon_envp;
uint64_t va = (uint64_t)&env->efi.bios.ptrs;
if (pmon_envtype != PMON_ENVTYPE_EFI)
return NULL;
return (const struct pmon_env_irq *)
(va + env->efi.bios.ptrs.offs_irq);
}
const struct pmon_env_iface *
pmon_get_env_iface(void)
{
struct pmon_env *env = (struct pmon_env *)pmon_envp;
uint64_t va = (uint64_t)&env->efi.bios.ptrs;
if (pmon_envtype != PMON_ENVTYPE_EFI)
return NULL;
return (const struct pmon_env_iface *)
(va + env->efi.bios.ptrs.offs_iface);
}
const struct pmon_env_special *
pmon_get_env_special(void)
{
struct pmon_env *env = (struct pmon_env *)pmon_envp;
uint64_t va = (uint64_t)&env->efi.bios.ptrs;
if (pmon_envtype != PMON_ENVTYPE_EFI)
return NULL;
return (const struct pmon_env_special *)
(va + env->efi.bios.ptrs.offs_special);
}
const struct pmon_env_device *
pmon_get_env_device(void)
{
struct pmon_env *env = (struct pmon_env *)pmon_envp;
uint64_t va = (uint64_t)&env->efi.bios.ptrs;
if (pmon_envtype != PMON_ENVTYPE_EFI)
return NULL;
return (const struct pmon_env_device *)
(va + env->efi.bios.ptrs.offs_device);
}