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