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