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