6 #include "libopenbios/bindings.h"
7 #include "arch/common/nvram.h"
8 #include "drivers/drivers.h"
9 #include "libc/diskio.h"
10 #include "libc/vsprintf.h"
11 #include "libopenbios/ofmem.h"
12 #include "libopenbios/sys_info.h"
17 uint32_t kernel_image;
19 uint32_t qemu_cmdline;
20 uint32_t cmdline_size;
24 static struct linux_mlist_v0 *totphyslist, *availlist, *prommaplist;
26 static void setup_romvec(void)
28 /* SPARC32 is slightly unusual in that before invoking any loaders, a romvec array
29 needs to be set up to pass certain parameters using a C struct. Hence this function
30 extracts the relevant boot information and places it in obp_arg. */
32 int intprop, proplen, target, device, i;
33 unsigned int *intprop_ptr;
35 char *prop, *id, *name;
36 static char bootpathbuf[128], bootargsbuf[128], buf[128];
37 struct linux_mlist_v0 **pp;
39 /* Get the stdin and stdout paths */
40 chosen = find_dev("/chosen");
41 intprop = get_int_property(chosen, "stdin", &proplen);
43 fword("get-instance-path");
44 ((struct linux_romvec *)romvec)->pv_stdin = pop_fstr_copy();
46 intprop = get_int_property(chosen, "stdout", &proplen);
48 fword("get-instance-path");
49 ((struct linux_romvec *)romvec)->pv_stdout = pop_fstr_copy();
51 /* Get the name of the selected boot device, along with the device and unit number */
52 prop = get_property(chosen, "bootpath", &proplen);
53 strncpy(bootpathbuf, prop, proplen);
54 prop = get_property(chosen, "bootargs", &proplen);
55 strncpy(bootargsbuf, prop, proplen);
57 /* Set bootpath pointer used in romvec table to the bootpath */
58 push_str(bootpathbuf);
59 fword("pathres-resolve-aliases");
60 bootpath = pop_fstr_copy();
61 printk("bootpath: %s\n", bootpath);
63 /* Now do some work to get hold of the target, partition etc. */
64 push_str(bootpathbuf);
66 feval("ihandle>boot-device-handle drop to my-self");
68 fword("get-my-property");
70 name = pop_fstr_copy();
72 if (!strncmp(name, "sd", 2)) {
75 Old-style SunOS disk paths are given in the form:
80 c = controller (Nth controller in system, usually 0)
81 t = target (my-unit phys.hi)
82 d = device/LUN (my-unit phys.lo)
83 s = slice/partition (my-args)
86 /* Controller currently always 0 */
87 obp_arg.boot_dev_ctrl = 0;
89 /* Get the target, device and slice */
98 snprintf(buf, sizeof(buf), "sd(0,%d,%d):%c", target, device, id[0]);
99 obp_arg.dev_partition = id[0] - 'a';
101 snprintf(buf, sizeof(buf), "sd(0,%d,%d)", target, device);
102 obp_arg.dev_partition = 0;
105 obp_arg.boot_dev_unit = target;
107 obp_arg.boot_dev[0] = buf[0];
108 obp_arg.boot_dev[1] = buf[1];
109 obp_arg.argv[0] = buf;
110 obp_arg.argv[1] = bootargsbuf;
112 } else if (!strncmp(name, "SUNW,fdtwo", 10)) {
114 obp_arg.boot_dev_ctrl = 0;
115 obp_arg.boot_dev_unit = 0;
116 obp_arg.dev_partition = 0;
120 obp_arg.boot_dev[0] = buf[0];
121 obp_arg.boot_dev[1] = buf[1];
122 obp_arg.argv[0] = buf;
123 obp_arg.argv[1] = bootargsbuf;
125 } else if (!strncmp(name, "le", 2)) {
127 obp_arg.boot_dev_ctrl = 0;
128 obp_arg.boot_dev_unit = 0;
129 obp_arg.dev_partition = 0;
133 obp_arg.boot_dev[0] = buf[0];
134 obp_arg.boot_dev[1] = buf[1];
135 obp_arg.argv[0] = buf;
136 obp_arg.argv[1] = bootargsbuf;
140 /* Generate the totphys (total memory available) list */
141 prop = get_property(s_phandle_memory, "reg", &proplen);
142 intprop_ptr = (unsigned int *)prop;
144 for (pp = &totphyslist, i = 0; i < (proplen / sizeof(int)); pp = &(**pp).theres_more, i+=3) {
145 *pp = (struct linux_mlist_v0 *)malloc(sizeof(struct linux_mlist_v0));
146 (**pp).theres_more = NULL;
147 (**pp).start_adr = (char *)intprop_ptr[1];
148 (**pp).num_bytes = intprop_ptr[2];
153 /* Generate the avail (physical memory available) list */
154 prop = get_property(s_phandle_memory, "available", &proplen);
155 intprop_ptr = (unsigned int *)prop;
157 for (pp = &availlist, i = 0; i < (proplen / sizeof(int)); pp = &(**pp).theres_more, i+=3) {
158 *pp = (struct linux_mlist_v0 *)malloc(sizeof(struct linux_mlist_v0));
159 (**pp).theres_more = NULL;
160 (**pp).start_adr = (char *)intprop_ptr[1];
161 (**pp).num_bytes = intprop_ptr[2];
166 /* Generate the prommap (taken virtual memory) list from inverse of available */
167 prop = get_property(s_phandle_mmu, "available", &proplen);
168 intprop_ptr = (unsigned int *)prop;
170 for (pp = &prommaplist, i = 0; i < (proplen / sizeof(int)); pp = &(**pp).theres_more, i+=3) {
171 *pp = (struct linux_mlist_v0 *)malloc(sizeof(struct linux_mlist_v0));
172 (**pp).theres_more = NULL;
173 (**pp).start_adr = (char *)(intprop_ptr[1] + intprop_ptr[2]);
175 if (i + 3 < (proplen / sizeof(int))) {
176 /* Size from next entry */
177 (**pp).num_bytes = (intprop_ptr[4] + intprop_ptr[5]) - (intprop_ptr[1] + intprop_ptr[2]);
179 /* Tail (size from top of virtual memory) */
180 (**pp).num_bytes = 0xffffffffUL - (intprop_ptr[1] + intprop_ptr[2]) + 1;
186 /* Finally set the memory properties */
187 ((struct linux_romvec *)romvec)->pv_v0mem.v0_totphys = &totphyslist;
188 ((struct linux_romvec *)romvec)->pv_v0mem.v0_available = &availlist;
189 ((struct linux_romvec *)romvec)->pv_v0mem.v0_prommap = &prommaplist;
195 ucell address, type, size;
196 int image_retval = 0;
198 /* Get the entry point and the type (see forth/debugging/client.fs) */
199 feval("saved-program-state >sps.entry @");
201 feval("saved-program-state >sps.file-type @");
203 feval("saved-program-state >sps.file-size @");
208 printk("\nJumping to entry point " FMT_ucellx " for type " FMT_ucellx "...\n", address, type);
212 /* Start ELF boot image */
213 image_retval = start_elf((unsigned long)address,
214 (unsigned long)romvec);
219 /* Start ELF image */
220 image_retval = start_elf((unsigned long)address,
221 (unsigned long)romvec);
226 /* Start a.out image */
227 image_retval = start_elf((unsigned long)address,
228 (unsigned long)romvec);
233 /* Start Fcode image */
234 printk("Evaluating FCode...\n");
242 /* Start Forth image */
250 printk("Image returned with return value %#x\n", image_retval);
256 /* Boot preloaded kernel */
258 printk("[sparc] Kernel already loaded\n");
259 start_elf(kernel_image, (unsigned long)romvec);