xref: /openbsd/sys/arch/loongson/stand/boot/exec.c (revision 898184e3)
1 /*	$OpenBSD: exec.c,v 1.2 2010/04/03 19:13:27 miod 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 #include <machine/cpu.h>
26 
27 typedef void (*program)(int32_t, int32_t, int32_t *, int32_t, uint64_t *);
28 
29 #define	PTR_TO_CKSEG1(ptr)	(int32_t)(CKSEG1_BASE | (uint64_t)(ptr))
30 
31 void
32 run_loadfile(u_long *marks, int howto)
33 {
34 	int32_t newargc;
35 	int32_t *newargv;
36 	char kernelflags[8];
37 	char *c;
38 	const char *arg;
39 
40 	/*
41 	 * Build a new commandline:
42 	 * boot <device kernel is loaded from> -<kernel options>
43 	 */
44 
45 	newargc = howto == 0 ? 2 : 3;
46 	newargv = alloc(newargc * sizeof(int32_t));
47 	if (newargv == NULL)
48 		panic("out of memory");
49 
50 	arg = "boot";	/* kernel needs this. */
51 	newargv[0] = PTR_TO_CKSEG1(arg);
52 	newargv[1] = PTR_TO_CKSEG1(&pmon_bootdev);
53 	if (howto != 0) {
54 		c = kernelflags;
55 		*c++ = '-';
56 		if (howto & RB_ASKNAME)
57 			*c++ = 'a';
58 		if (howto & RB_CONFIG)
59 			*c++ = 'c';
60 		if (howto & RB_KDB)
61 			*c++ = 'd';
62 		if (howto & RB_SINGLE)
63 			*c++ = 's';
64 		*c = '\0';
65 		newargv[2] = PTR_TO_CKSEG1(&kernelflags);
66 	}
67 
68 	pmon_cacheflush();
69 
70 	(*(program)(marks[MARK_ENTRY]))(newargc, PTR_TO_CKSEG1(newargv),
71 	    pmon_envp, pmon_callvec,
72 	    (uint64_t *)PHYS_TO_CKSEG0(marks[MARK_END]));
73 
74 	rd_invalidate();
75 	_rtt();
76 }
77