|
|
1.1 root 1: /*
2: *
3: */
4: #undef BOOTSTRAP
5: #include "config.h"
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/sys_info.h"
12: #include "openprom.h"
13: #include "boot.h"
14: #include "context.h"
15:
16: uint32_t kernel_image;
17: uint32_t kernel_size;
18: uint32_t qemu_cmdline;
19: uint32_t cmdline_size;
20: char boot_device;
21: const void *romvec;
22:
23: void go(void)
24: {
25: ucell address, type, size;
26: int image_retval = 0, proplen, unit, part;
27: phandle_t chosen;
28: char *prop, *id, bootid;
29: static char bootpathbuf[128], bootargsbuf[128], buf[128];
30:
31: /* Get the entry point and the type (see forth/debugging/client.fs) */
32: feval("saved-program-state >sps.entry @");
33: address = POP();
34: feval("saved-program-state >sps.file-type @");
35: type = POP();
36: feval("saved-program-state >sps.file-size @");
37: size = POP();
38:
39: /* SPARC32 is slightly unusual in that before invoking any loaders, a romvec array
40: needs to be set up to pass certain parameters using a C struct. Hence this section
41: extracts the relevant boot information and places it in obp_arg. */
42:
43: /* Get the name of the selected boot device, along with the device and unit number */
44: chosen = find_dev("/chosen");
45: prop = get_property(chosen, "bootpath", &proplen);
46: strncpy(bootpathbuf, prop, proplen);
47: prop = get_property(chosen, "bootargs", &proplen);
48: strncpy(bootargsbuf, prop, proplen);
49:
50: /* Set bootpath pointer used in romvec table to the bootpath */
51: push_str(bootpathbuf);
52: fword("pathres-resolve-aliases");
53: bootpath = pop_fstr_copy();
54: printk("bootpath: %s\n", bootpath);
55:
56: if (!strncmp(bootpathbuf, "cd", 2) || !strncmp(bootpathbuf, "disk", 4)) {
57:
58: /* Controller currently always 0 */
59: obp_arg.boot_dev_ctrl = 0;
60:
61: /* Grab the device and unit number string (in form unit,partition) */
62: push_str(bootpathbuf);
63: feval("pathres-resolve-aliases ascii @ right-split 2drop");
64: id = pop_fstr_copy();
65:
66: /* A bit hacky, but we have no atoi() function */
67: unit = id[0] - '0';
68: part = id[2] - '0';
69:
70: obp_arg.boot_dev_unit = unit;
71: obp_arg.dev_partition = part;
72:
73: /* Generate the "oldpath"
74: FIXME: hardcoding this looks almost definitely wrong.
75: With sd(0,2,0):b we get to see the solaris kernel though */
76: if (!strncmp(bootpathbuf, "disk", 4)) {
77: bootid = 'd';
78: } else {
79: bootid = 'b';
80: }
81:
82: snprintf(buf, sizeof(buf), "sd(0,%d,%d):%c", unit, part, bootid);
83:
84: obp_arg.boot_dev[0] = buf[0];
85: obp_arg.boot_dev[1] = buf[1];
86: obp_arg.argv[0] = buf;
87: obp_arg.argv[1] = bootargsbuf;
88:
89: } else if (!strncmp(bootpathbuf, "floppy", 6)) {
90:
91: obp_arg.boot_dev_ctrl = 0;
92: obp_arg.boot_dev_unit = 0;
93: obp_arg.dev_partition = 0;
94:
95: strcpy(buf, "fd()");
96:
97: obp_arg.boot_dev[0] = buf[0];
98: obp_arg.boot_dev[1] = buf[1];
99: obp_arg.argv[0] = buf;
100: obp_arg.argv[1] = bootargsbuf;
101:
102: } else if (!strncmp(bootpathbuf, "net", 3)) {
103:
104: obp_arg.boot_dev_ctrl = 0;
105: obp_arg.boot_dev_unit = 0;
106: obp_arg.dev_partition = 0;
107:
108: strcpy(buf, "le()");
109:
110: obp_arg.boot_dev[0] = buf[0];
111: obp_arg.boot_dev[1] = buf[1];
112: obp_arg.argv[0] = buf;
113: obp_arg.argv[1] = bootargsbuf;
114:
115: }
116:
117: printk("\nJumping to entry point " FMT_ucellx " for type " FMT_ucellx "...\n", address, type);
118:
119: switch (type) {
120: case 0x0:
121: /* Start ELF boot image */
122: image_retval = start_elf((unsigned long)address,
123: (unsigned long)romvec);
124:
125: break;
126:
127: case 0x1:
128: /* Start ELF image */
129: image_retval = start_elf((unsigned long)address,
130: (unsigned long)romvec);
131:
132: break;
133:
134: case 0x5:
135: /* Start a.out image */
136: image_retval = start_elf((unsigned long)address,
137: (unsigned long)romvec);
138:
139: break;
140:
141: case 0x10:
142: /* Start Fcode image */
143: printk("Evaluating FCode...\n");
144: PUSH(address);
145: PUSH(1);
146: fword("byte-load");
147: image_retval = 0;
148: break;
149:
150: case 0x11:
151: /* Start Forth image */
152: PUSH(address);
153: PUSH(size);
154: fword("eval2");
155: image_retval = 0;
156: break;
157: }
158:
159: printk("Image returned with return value %#x\n", image_retval);
160: }
161:
162:
163: void boot(void)
164: {
165: /* Boot preloaded kernel */
166: if (kernel_size) {
167: printk("[sparc] Kernel already loaded\n");
168: start_elf(kernel_image, (unsigned long)romvec);
169: }
170: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.