#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: hpc_machdep.c,v 1.107 2025/12/22 07:45:47 skrll Exp $");
#include "opt_cputypes.h"
#include "opt_kloader.h"
#ifndef KLOADER_KERNEL_PATH
#define KLOADER_KERNEL_PATH "/netbsd"
#endif
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/boot_flag.h>
#include <sys/mount.h>
#include <sys/pmf.h>
#include <sys/reboot.h>
#include <sys/cpu.h>
#include <uvm/uvm.h>
#include <arm/locore.h>
#include <machine/bootconfig.h>
#include <machine/bootinfo.h>
#include <machine/platid.h>
#include <machine/pmap.h>
#ifdef KLOADER
#include <machine/kloader.h>
#endif
#include <dev/cons.h>
#include <dev/hpc/apm/apmvar.h>
BootConfig bootconfig;
#ifdef KLOADER
struct kloader_bootinfo kbootinfo;
static char kernel_path[] = KLOADER_KERNEL_PATH;
#endif
struct bootinfo *bootinfo, bootinfo_storage;
char booted_kernel_storage[80];
extern char *booted_kernel;
paddr_t physical_start;
paddr_t physical_freestart;
paddr_t physical_freeend;
paddr_t physical_end;
#ifndef PMAP_STATIC_L1S
int max_processes = 64;
#endif
char *boot_args = NULL;
char boot_file[16];
paddr_t msgbufphys;
void dumpsys(void);
void (*__sleep_func)(void *);
void *__sleep_ctx;
void (*__cpu_reset)(void) __dead = cpu_reset;
vaddr_t initarm(int, char **, struct bootinfo *);
#if defined(CPU_SA1100) || defined(CPU_SA1110)
vaddr_t init_sa11x0(int, char **, struct bootinfo *);
#endif
#if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270)
vaddr_t init_pxa2x0(int, char **, struct bootinfo *);
#endif
#ifdef BOOT_DUMP
void dumppages(char *, int);
#endif
void
cpu_reboot(int howto, char *bootstr)
{
if (cold) {
doshutdownhooks();
pmf_system_shutdown(boothowto);
printf("Halted while still in the ICE age.\n");
printf("The operating system has halted.\n");
printf("Please press any key to reboot.\n\n");
cngetc();
printf("rebooting...\n");
__cpu_reset();
}
__sleep_func = NULL;
__sleep_ctx = NULL;
cnpollc(true);
#ifdef KLOADER
if ((howto & RB_HALT) == 0) {
if (howto & RB_STRING) {
kloader_reboot_setup(bootstr);
} else {
kloader_reboot_setup(kernel_path);
}
}
#endif
if (!(howto & RB_NOSYNC))
bootsync();
(void)splhigh();
if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
dumpsys();
doshutdownhooks();
pmf_system_shutdown(boothowto);
IRQdisable;
if (howto & RB_HALT) {
printf("The operating system has halted.\n");
printf("Please press any key to reboot.\n\n");
cngetc();
#ifdef KLOADER
} else {
kloader_reboot();
#endif
}
printf("rebooting...\n");
__cpu_reset();
}
void
machine_sleep(void)
{
if (__sleep_func != NULL)
__sleep_func(__sleep_ctx);
}
void
machine_standby(void)
{
}
vaddr_t
initarm(int argc, char **argv, struct bootinfo *bi)
{
__sleep_func = NULL;
__sleep_ctx = NULL;
booted_kernel = booted_kernel_storage;
boothowto = 0;
boot_file[0] = '\0';
if (argc > 0 && argv != NULL) {
strncpy(booted_kernel_storage, argv[0],
sizeof(booted_kernel_storage));
for (int i = 1; i < argc; i++) {
char *cp = argv[i];
switch (*cp) {
case 'b':
cp = cp + 2;
if (strcmp(cp, MOUNT_NFS) == 0)
rootfstype = MOUNT_NFS;
else
strncpy(boot_file, cp,
sizeof(boot_file));
break;
default:
BOOT_FLAG(*cp, boothowto);
break;
}
}
}
if (bi != NULL)
bootinfo_storage = *bi;
bootinfo = &bootinfo_storage;
#ifdef BOOTINFO_FB_WIDTH
bootinfo->fb_line_bytes = BOOTINFO_FB_LINE_BYTES;
bootinfo->fb_width = BOOTINFO_FB_WIDTH;
bootinfo->fb_height = BOOTINFO_FB_HEIGHT;
bootinfo->fb_type = BOOTINFO_FB_TYPE;
#endif
if (bootinfo->magic == BOOTINFO_MAGIC) {
platid.dw.dw0 = bootinfo->platid_cpu;
platid.dw.dw1 = bootinfo->platid_machine;
#ifndef RTC_OFFSET
if (rtc_offset == 0 &&
(bootinfo->timezone > (-12 * 60) &&
bootinfo->timezone <= (12 * 60)))
rtc_offset = bootinfo->timezone;
#endif
}
#ifdef KLOADER
kloader_bootinfo_set(&kbootinfo, argc, argv, bi, false);
#endif
set_cpufuncs();
IRQdisable;
#if defined(CPU_SA1100) || defined(CPU_SA1110)
return init_sa11x0(argc, argv, bi);
#elif defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270)
return init_pxa2x0(argc, argv, bi);
#else
#error No CPU support
#endif
}
#ifdef BOOT_DUMP
void
dumppages(char *start, int nbytes)
{
char *p = start;
char *p1;
int i;
for (i = nbytes; i > 0; i -= 16, p += 16) {
for (p1 = p + 15; p != p1; p1--) {
if (*p1)
break;
}
if (!*p1)
continue;
printf("%08x %02x %02x %02x %02x %02x %02x %02x %02x"
" %02x %02x %02x %02x %02x %02x %02x %02x\n",
(unsigned int)p,
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
}
}
#endif