Home | History | Annotate | Line # | Download | only in hpcarm
      1 /*	$NetBSD: hpc_machdep.c,v 1.106 2019/07/16 14:41:49 skrll Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1994-1998 Mark Brinicombe.
      5  * Copyright (c) 1994 Brini.
      6  * All rights reserved.
      7  *
      8  * This code is derived from software written for Brini by Mark Brinicombe
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *      This product includes software developed by Brini.
     21  * 4. The name of the company nor the name of the author may be used to
     22  *    endorse or promote products derived from this software without specific
     23  *    prior written permission.
     24  *
     25  * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
     26  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     27  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     28  * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
     29  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     30  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     31  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     35  * SUCH DAMAGE.
     36  */
     37 
     38 /*
     39  * Machine dependent functions for kernel setup.
     40  */
     41 
     42 #include <sys/cdefs.h>
     43 __KERNEL_RCSID(0, "$NetBSD: hpc_machdep.c,v 1.106 2019/07/16 14:41:49 skrll Exp $");
     44 
     45 #include "opt_cputypes.h"
     46 #include "opt_kloader.h"
     47 #ifndef KLOADER_KERNEL_PATH
     48 #define KLOADER_KERNEL_PATH	"/netbsd"
     49 #endif
     50 
     51 #include <sys/param.h>
     52 #include <sys/kernel.h>
     53 #include <sys/boot_flag.h>
     54 #include <sys/mount.h>
     55 #include <sys/pmf.h>
     56 #include <sys/reboot.h>
     57 #include <sys/cpu.h>
     58 
     59 #include <uvm/uvm.h>
     60 
     61 #include <arm/locore.h>
     62 
     63 #include <machine/bootconfig.h>
     64 #include <machine/bootinfo.h>
     65 #include <machine/platid.h>
     66 #include <machine/pmap.h>
     67 #ifdef KLOADER
     68 #include <machine/kloader.h>
     69 #endif
     70 
     71 #include <dev/cons.h>
     72 #include <dev/hpc/apm/apmvar.h>
     73 
     74 BootConfig bootconfig;		/* Boot config storage */
     75 #ifdef KLOADER
     76 struct kloader_bootinfo kbootinfo;
     77 static char kernel_path[] = KLOADER_KERNEL_PATH;
     78 #endif
     79 struct bootinfo *bootinfo, bootinfo_storage;
     80 char booted_kernel_storage[80];
     81 extern char *booted_kernel;
     82 
     83 paddr_t physical_start;
     84 paddr_t physical_freestart;
     85 paddr_t physical_freeend;
     86 paddr_t physical_end;
     87 
     88 #ifndef PMAP_STATIC_L1S
     89 int max_processes = 64;			/* Default number */
     90 #endif /* !PMAP_STATIC_L1S */
     91 
     92 char *boot_args = NULL;
     93 char boot_file[16];
     94 
     95 paddr_t msgbufphys;
     96 
     97 /* Prototypes */
     98 void dumpsys(void);
     99 
    100 /* Mode dependent sleep function holder */
    101 void (*__sleep_func)(void *);
    102 void *__sleep_ctx;
    103 
    104 void (*__cpu_reset)(void) __dead = cpu_reset;
    105 
    106 vaddr_t initarm(int, char **, struct bootinfo *);
    107 #if defined(CPU_SA1100) || defined(CPU_SA1110)
    108 vaddr_t init_sa11x0(int, char **, struct bootinfo *);
    109 #endif
    110 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270)
    111 vaddr_t init_pxa2x0(int, char **, struct bootinfo *);
    112 #endif
    113 
    114 #ifdef BOOT_DUMP
    115 void	dumppages(char *, int);
    116 #endif
    117 
    118 /*
    119  * Reboots the system.
    120  *
    121  * Deal with any syncing, unmounting, dumping and shutdown hooks,
    122  * then reset the CPU.
    123  */
    124 void
    125 cpu_reboot(int howto, char *bootstr)
    126 {
    127 
    128 	/*
    129 	 * If we are still cold then hit the air brakes
    130 	 * and crash to earth fast.
    131 	 */
    132 	if (cold) {
    133 		doshutdownhooks();
    134 		pmf_system_shutdown(boothowto);
    135 		printf("Halted while still in the ICE age.\n");
    136 		printf("The operating system has halted.\n");
    137 		printf("Please press any key to reboot.\n\n");
    138 		cngetc();
    139 		printf("rebooting...\n");
    140 		__cpu_reset();
    141 		/* NOTREACHED */
    142 	}
    143 
    144 	/* Reset the sleep function. */
    145 	__sleep_func = NULL;
    146 	__sleep_ctx = NULL;
    147 
    148 	/* Disable console buffering. */
    149 	cnpollc(1);
    150 
    151 #ifdef KLOADER
    152 	if ((howto & RB_HALT) == 0) {
    153 		if (howto & RB_STRING) {
    154 			kloader_reboot_setup(bootstr);
    155 		} else {
    156 			kloader_reboot_setup(kernel_path);
    157 		}
    158 	}
    159 #endif
    160 
    161 	/*
    162 	 * If RB_NOSYNC was not specified sync the discs.
    163 	 * Note: Unless cold is set to 1 here, syslogd will die during
    164 	 * the unmount.  It looks like syslogd is getting woken up only
    165 	 * to find that it cannot page part of the binary in as the
    166 	 * file system has been unmounted.
    167 	 */
    168 	if (!(howto & RB_NOSYNC))
    169 		bootsync();
    170 
    171 	/* Say NO to interrupts. */
    172 	(void)splhigh();
    173 
    174 	/* Do a dump if requested. */
    175 	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
    176 		dumpsys();
    177 
    178 	/* Run any shutdown hooks. */
    179 	doshutdownhooks();
    180 
    181 	pmf_system_shutdown(boothowto);
    182 
    183 	/* Make sure IRQs are disabled. */
    184 	IRQdisable;
    185 
    186 	if (howto & RB_HALT) {
    187 		printf("The operating system has halted.\n");
    188 		printf("Please press any key to reboot.\n\n");
    189 		cngetc();
    190 #ifdef KLOADER
    191 	} else {
    192 		kloader_reboot();
    193 		/* NOTREACHED */
    194 #endif
    195 	}
    196 
    197 	printf("rebooting...\n");
    198 	__cpu_reset();
    199 	/* NOTREACHED */
    200 }
    201 
    202 void
    203 machine_sleep(void)
    204 {
    205 
    206 	if (__sleep_func != NULL)
    207 		__sleep_func(__sleep_ctx);
    208 }
    209 
    210 void
    211 machine_standby(void)
    212 {
    213 }
    214 
    215 /*
    216  * Initial entry point on startup. This gets called before main() is
    217  * entered.
    218  * It should be responsible for setting up everything that must be
    219  * in place when main is called.
    220  * This includes:
    221  *   Taking a copy of the boot configuration structure.
    222  */
    223 vaddr_t
    224 initarm(int argc, char **argv, struct bootinfo *bi)
    225 {
    226 
    227 	__sleep_func = NULL;
    228 	__sleep_ctx = NULL;
    229 
    230 	/* parse kernel args */
    231 	booted_kernel = booted_kernel_storage;
    232 	boothowto = 0;
    233 	boot_file[0] = '\0';
    234 	if (argc > 0 && argv != NULL) {
    235 		strncpy(booted_kernel_storage, argv[0],
    236 		    sizeof(booted_kernel_storage));
    237 		for (int i = 1; i < argc; i++) {
    238 			char *cp = argv[i];
    239 
    240 			switch (*cp) {
    241 			case 'b':
    242 				/* boot device: -b=sd0 etc. */
    243 				cp = cp + 2;
    244 				if (strcmp(cp, MOUNT_NFS) == 0)
    245 					rootfstype = MOUNT_NFS;
    246 				else
    247 					strncpy(boot_file, cp,
    248 					    sizeof(boot_file));
    249 				break;
    250 
    251 			default:
    252 				BOOT_FLAG(*cp, boothowto);
    253 				break;
    254 			}
    255 		}
    256 	}
    257 
    258 	/* copy bootinfo into known kernel space */
    259 	if (bi != NULL)
    260 		bootinfo_storage = *bi;
    261 	bootinfo = &bootinfo_storage;
    262 
    263 #ifdef BOOTINFO_FB_WIDTH
    264 	bootinfo->fb_line_bytes = BOOTINFO_FB_LINE_BYTES;
    265 	bootinfo->fb_width = BOOTINFO_FB_WIDTH;
    266 	bootinfo->fb_height = BOOTINFO_FB_HEIGHT;
    267 	bootinfo->fb_type = BOOTINFO_FB_TYPE;
    268 #endif
    269 
    270 	if (bootinfo->magic == BOOTINFO_MAGIC) {
    271 		platid.dw.dw0 = bootinfo->platid_cpu;
    272 		platid.dw.dw1 = bootinfo->platid_machine;
    273 
    274 #ifndef RTC_OFFSET
    275 		/*
    276 		 * rtc_offset from bootinfo.timezone set by hpcboot.exe
    277 		 */
    278 		if (rtc_offset == 0 &&
    279 		    (bootinfo->timezone > (-12 * 60) &&
    280 		     bootinfo->timezone <= (12 * 60)))
    281 			rtc_offset = bootinfo->timezone;
    282 #endif
    283 	}
    284 
    285 #ifdef KLOADER
    286 	/* copy boot parameter for kloader */
    287 	kloader_bootinfo_set(&kbootinfo, argc, argv, bi, false);
    288 #endif
    289 
    290 	/*
    291 	 * Heads up ... Setup the CPU / MMU / TLB functions.
    292 	 */
    293 	set_cpufuncs();
    294 	IRQdisable;
    295 
    296 #if defined(CPU_SA1100) || defined(CPU_SA1110)
    297 	return init_sa11x0(argc, argv, bi);
    298 #elif defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270)
    299 	return init_pxa2x0(argc, argv, bi);
    300 #else
    301 #error	No CPU support
    302 #endif
    303 }
    304 
    305 #ifdef BOOT_DUMP
    306 void
    307 dumppages(char *start, int nbytes)
    308 {
    309 	char *p = start;
    310 	char *p1;
    311 	int i;
    312 
    313 	for (i = nbytes; i > 0; i -= 16, p += 16) {
    314 		for (p1 = p + 15; p != p1; p1--) {
    315 			if (*p1)
    316 				break;
    317 		}
    318 		if (!*p1)
    319 			continue;
    320 		printf("%08x %02x %02x %02x %02x %02x %02x %02x %02x"
    321 		    " %02x %02x %02x %02x %02x %02x %02x %02x\n",
    322 		    (unsigned int)p,
    323 		    p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
    324 		    p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
    325 	}
    326 }
    327 #endif
    328