Home | History | Annotate | Line # | Download | only in loadbsd
loadbsd.c revision 1.1.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