loadbsd.c revision 1.1 1 1.1 mw #include <sys/types.h>
2 1.1 mw #include <a.out.h>
3 1.1 mw #include <stdio.h>
4 1.1 mw
5 1.1 mw #include <exec/types.h>
6 1.1 mw #include <exec/execbase.h>
7 1.1 mw #include <exec/memory.h>
8 1.1 mw #include <libraries/configregs.h>
9 1.1 mw #include <libraries/expansionbase.h>
10 1.1 mw
11 1.1 mw #include <inline/exec.h>
12 1.1 mw #include <inline/expansion.h>
13 1.1 mw
14 1.1 mw struct ExpansionBase *ExpansionBase;
15 1.1 mw
16 1.1 mw #undef __LDPGSZ
17 1.1 mw #define __LDPGSZ 8192
18 1.1 mw
19 1.1 mw void get_mem_config (void **fastmem_start, u_long *fastmem_size, u_long *chipmem_size);
20 1.1 mw
21 1.1 mw int
22 1.1 mw main (int argc, char *argv[])
23 1.1 mw {
24 1.1 mw struct exec e;
25 1.1 mw int fd;
26 1.1 mw
27 1.1 mw if (argc >= 2)
28 1.1 mw {
29 1.1 mw if ((fd = open (argv[1], 0)) >= 0)
30 1.1 mw {
31 1.1 mw if (read (fd, &e, sizeof (e)) == sizeof (e))
32 1.1 mw {
33 1.1 mw if (e.a_magic == NMAGIC)
34 1.1 mw {
35 1.1 mw u_char *kernel;
36 1.1 mw int text_size;
37 1.1 mw struct ConfigDev *cd;
38 1.1 mw int num_cd;
39 1.1 mw
40 1.1 mw ExpansionBase= (struct ExpansionBase *) OpenLibrary ("expansion.library", 0);
41 1.1 mw if (! ExpansionBase) /* not supposed to fail... */
42 1.1 mw abort();
43 1.1 mw for (cd = 0, num_cd = 0; cd = FindConfigDev (cd, -1, -1); num_cd++) ;
44 1.1 mw
45 1.1 mw text_size = (e.a_text + __LDPGSZ - 1) & (-__LDPGSZ);
46 1.1 mw kernel = (u_char *) malloc (text_size + e.a_data + e.a_bss
47 1.1 mw + num_cd*sizeof(*cd) + 4);
48 1.1 mw
49 1.1 mw if (kernel)
50 1.1 mw {
51 1.1 mw if (read (fd, kernel, e.a_text) == e.a_text
52 1.1 mw && read (fd, kernel + text_size, e.a_data) == e.a_data)
53 1.1 mw {
54 1.1 mw int *knum_cd;
55 1.1 mw struct ConfigDev *kcd;
56 1.1 mw void *fastmem_start;
57 1.1 mw u_long fastmem_size, chipmem_size;
58 1.1 mw
59 1.1 mw get_mem_config (&fastmem_start, &fastmem_size, &chipmem_size);
60 1.1 mw
61 1.1 mw if (argc == 3 && !strcmp (argv[2], "-k"))
62 1.1 mw {
63 1.1 mw fastmem_start += 4*1024*1024;
64 1.1 mw fastmem_size -= 4*1024*1024;
65 1.1 mw }
66 1.1 mw
67 1.1 mw printf ("Using %dM FASTMEM at 0x%x, %dM CHIPMEM\n",
68 1.1 mw fastmem_size>>20, fastmem_start, chipmem_size>>20);
69 1.1 mw /* give them a chance to read the information... */
70 1.1 mw sleep(2);
71 1.1 mw
72 1.1 mw bzero (kernel + text_size + e.a_data, e.a_bss);
73 1.1 mw knum_cd = (int *) (kernel + text_size + e.a_data + e.a_bss);
74 1.1 mw *knum_cd = num_cd;
75 1.1 mw if (num_cd)
76 1.1 mw for (kcd = (struct ConfigDev *) (knum_cd+1);
77 1.1 mw cd = FindConfigDev (cd, -1, -1);
78 1.1 mw *kcd++ = *cd) ;
79 1.1 mw startit (kernel,
80 1.1 mw text_size + e.a_data + e.a_bss + num_cd*sizeof(*cd) + 4,
81 1.1 mw e.a_entry, fastmem_start,
82 1.1 mw fastmem_size, chipmem_size);
83 1.1 mw }
84 1.1 mw else
85 1.1 mw fprintf (stderr, "Executable corrupt!\n");
86 1.1 mw }
87 1.1 mw else
88 1.1 mw fprintf (stderr, "Out of memory! (%d)\n", text_size + e.a_data + e.a_bss
89 1.1 mw + num_cd*sizeof(*cd) + 4);
90 1.1 mw }
91 1.1 mw else
92 1.1 mw fprintf (stderr, "Unsupported executable: %o\n", e.a_magic);
93 1.1 mw }
94 1.1 mw else
95 1.1 mw fprintf (stderr, "Can't read header of %s\n", argv[1]);
96 1.1 mw
97 1.1 mw close (fd);
98 1.1 mw }
99 1.1 mw else
100 1.1 mw perror ("open");
101 1.1 mw }
102 1.1 mw else
103 1.1 mw fprintf (stderr, "%0 some-vmunix\n", argv[0]);
104 1.1 mw }
105 1.1 mw
106 1.1 mw
107 1.1 mw void
108 1.1 mw get_mem_config (void **fastmem_start, u_long *fastmem_size, u_long *chipmem_size)
109 1.1 mw {
110 1.1 mw extern struct ExecBase *SysBase;
111 1.1 mw struct MemHeader *mh, *nmh;
112 1.1 mw
113 1.1 mw *fastmem_size = 0;
114 1.1 mw *chipmem_size = 0;
115 1.1 mw
116 1.1 mw /* walk thru the exec memory list */
117 1.1 mw Forbid ();
118 1.1 mw for (mh = (struct MemHeader *) SysBase->MemList.lh_Head;
119 1.1 mw nmh = (struct MemHeader *) mh->mh_Node.ln_Succ;
120 1.1 mw mh = nmh)
121 1.1 mw {
122 1.1 mw if (mh->mh_Attributes & MEMF_CHIP)
123 1.1 mw {
124 1.1 mw /* there should hardly be more than one entry for chip mem, but
125 1.1 mw handle it the same nevertheless */
126 1.1 mw if ((u_int)mh->mh_Upper - (u_int)mh->mh_Lower > *chipmem_size)
127 1.1 mw {
128 1.1 mw *chipmem_size = (u_int)mh->mh_Upper - (u_int)mh->mh_Lower;
129 1.1 mw /* round to multiple of 512K */
130 1.1 mw *chipmem_size = (*chipmem_size + 512*1024 - 1) & -(512*1024);
131 1.1 mw
132 1.1 mw /* chipmem always starts at 0, so don't remember start
133 1.1 mw address */
134 1.1 mw }
135 1.1 mw }
136 1.1 mw else
137 1.1 mw {
138 1.1 mw if ((u_int)mh->mh_Upper - (u_int)mh->mh_Lower > *fastmem_size)
139 1.1 mw {
140 1.1 mw u_int start = (u_int) mh->mh_Lower;
141 1.1 mw u_int end = (u_int) mh->mh_Upper;
142 1.1 mw
143 1.1 mw /* some heuristics.. */
144 1.1 mw start &= -__LDPGSZ;
145 1.1 mw /* get the mem back stolen by incore kickstart on A3000 with
146 1.1 mw V36 bootrom. */
147 1.1 mw if (end == 0x07f80000)
148 1.1 mw end = 0x08000000;
149 1.1 mw
150 1.1 mw *fastmem_size = end - start;
151 1.1 mw *fastmem_start = (void *)start;
152 1.1 mw }
153 1.1 mw }
154 1.1 mw }
155 1.1 mw Permit();
156 1.1 mw }
157 1.1 mw
158 1.1 mw
159 1.1 mw
160 1.1 mw
161 1.1 mw asm ("
162 1.1 mw .set ABSEXECBASE,4
163 1.1 mw
164 1.1 mw .text
165 1.1 mw .globl _startit
166 1.1 mw
167 1.1 mw _startit:
168 1.1 mw movel sp,a3
169 1.1 mw movel 4:w,a6
170 1.1 mw lea pc@(start_super-.+2),a5
171 1.1 mw jmp a6@(-0x1e) | supervisor-call
172 1.1 mw
173 1.1 mw start_super:
174 1.1 mw movew #0x2700,sr
175 1.1 mw
176 1.1 mw | the BSD kernel wants values into the following registers:
177 1.1 mw | a0: fastmem-start
178 1.1 mw | d0: fastmem-size
179 1.1 mw | d1: chipmem-size
180 1.1 mw
181 1.1 mw movel a3@(4),a1 | loaded kernel
182 1.1 mw movel a3@(8),d2 | length of loaded kernel
183 1.1 mw movel a3@(12),a2 | entry point
184 1.1 mw movel a3@(16),a0 | fastmem-start
185 1.1 mw movel a3@(20),d0 | fastmem-size
186 1.1 mw movel a3@(24),d1 | chipmem-size
187 1.1 mw subl a4,a4 | target, load to 0
188 1.1 mw
189 1.1 mw lea pc@(zero-.+2),a3
190 1.1 mw pmove a3@,tc | Turn off MMU
191 1.1 mw lea pc@(nullrp-.+2),a3
192 1.1 mw pmove a3@,crp | Turn off MMU some more
193 1.1 mw pmove a3@,srp | Really, really, turn off MMU
194 1.1 mw
195 1.1 mw | Turn off 68030 TT registers
196 1.1 mw
197 1.1 mw btst #2,(ABSEXECBASE)@(0x129) | AFB_68030,SysBase->AttnFlags
198 1.1 mw beq nott | Skip TT registers if not 68030
199 1.1 mw lea pc@(zero-.+2),a3
200 1.1 mw .word 0xf013,0x0800 | pmove a3@,tt0 (gas only knows about 68851 ops..)
201 1.1 mw .word 0xf013,0x0c00 | pmove a3@,tt1 (gas only knows about 68851 ops..)
202 1.1 mw
203 1.1 mw nott:
204 1.1 mw
205 1.1 mw movew #(1<<9),0xdff096 | disable DMA
206 1.1 mw
207 1.1 mw L0:
208 1.1 mw moveb a1@+,a4@+
209 1.1 mw subl #1,d2
210 1.1 mw bcc L0
211 1.1 mw
212 1.1 mw
213 1.1 mw jmp a2@
214 1.1 mw
215 1.1 mw
216 1.1 mw | A do-nothing MMU root pointer (includes the following long as well)
217 1.1 mw
218 1.1 mw nullrp: .long 0x7fff0001
219 1.1 mw zero: .long 0
220 1.1 mw
221 1.1 mw
222 1.1 mw ");
223 1.1 mw
224