xref: /openbsd/sys/arch/loongson/stand/boot/exec.c (revision cecf84d4)
1 /*	$OpenBSD: exec.c,v 1.3 2014/11/18 20:51:01 krw Exp $	*/
2 
3 /*
4  * Copyright (c) 2010 Miodrag Vallat.
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/param.h>
20 #include <sys/reboot.h>
21 #include <machine/cpu.h>
22 #include <machine/pmon.h>
23 #include "libsa.h"
24 #include <lib/libsa/loadfile.h>
25 
26 typedef void (*program)(int32_t, int32_t, int32_t *, int32_t, uint64_t *);
27 
28 #define	PTR_TO_CKSEG1(ptr)	(int32_t)(CKSEG1_BASE | (uint64_t)(ptr))
29 
30 void
31 run_loadfile(u_long *marks, int howto)
32 {
33 	int32_t newargc;
34 	int32_t *newargv;
35 	char kernelflags[8];
36 	char *c;
37 	const char *arg;
38 
39 	/*
40 	 * Build a new commandline:
41 	 * boot <device kernel is loaded from> -<kernel options>
42 	 */
43 
44 	newargc = howto == 0 ? 2 : 3;
45 	newargv = alloc(newargc * sizeof(int32_t));
46 	if (newargv == NULL)
47 		panic("out of memory");
48 
49 	arg = "boot";	/* kernel needs this. */
50 	newargv[0] = PTR_TO_CKSEG1(arg);
51 	newargv[1] = PTR_TO_CKSEG1(&pmon_bootdev);
52 	if (howto != 0) {
53 		c = kernelflags;
54 		*c++ = '-';
55 		if (howto & RB_ASKNAME)
56 			*c++ = 'a';
57 		if (howto & RB_CONFIG)
58 			*c++ = 'c';
59 		if (howto & RB_KDB)
60 			*c++ = 'd';
61 		if (howto & RB_SINGLE)
62 			*c++ = 's';
63 		*c = '\0';
64 		newargv[2] = PTR_TO_CKSEG1(&kernelflags);
65 	}
66 
67 	pmon_cacheflush();
68 
69 	(*(program)(marks[MARK_ENTRY]))(newargc, PTR_TO_CKSEG1(newargv),
70 	    pmon_envp, pmon_callvec,
71 	    (uint64_t *)PHYS_TO_CKSEG0(marks[MARK_END]));
72 
73 	rd_invalidate();
74 	_rtt();
75 }
76