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