Logo Search packages:      
Sourcecode: m68k-vme-tftplilo version File versions  Download package

bvme.c

/*
 *  VME Linux/m68k TFTP Loader
 *
 *  (c) Copyright 1998 by Nick Holgate
 *
 *  This file is subject to the terms and conditions of the GNU General
 *  Public License.  See the file COPYING for more details.
 */

/*--------------------------------------------------------------------------*/

#include "defs.h"
#include "bvmbug.h"

/*--------------------------------------------------------------------------*/
/* Loader bootblock
 */

static const union {
      BOOTBLOCK   bootblock;
      char        pad[512];
} boot __attribute__ ((section (".boot")))
 =    {{
            BOOT_BLOCK_ID,                      /* BVM LTD\0                                          */
            0,                                        /* start_block (unused for TFTP)          */
            0,                                        /* block_count (unused for TFTP)          */
            0x00010000,                         /* load address for following data        */
            0x00000000,                         /* run offset (start at load address)     */
            {0},                                /* no boot message                                    */
            {0}                                       /* no boot data                                       */
 }};

/*--------------------------------------------------------------------------*/

void
loader_init
(     CALLREGS    *regs
)
{
      put_str("BVME4000/6000 TFTP Linux Loader V" VERSION "\n\n");
}

/*--------------------------------------------------------------------------*/
/* Print character.
 */

void
put_char
(     const int   c
)
{
      BVMBug_putchar(c);
}

/*--------------------------------------------------------------------------*/

unsigned long
get_time
(     void
)
{     unsigned long     date;

      BVMBug_gettime(NULL, &date);
      return date;
}

/*--------------------------------------------------------------------------*/
/* Wait for and return character from keyboard.
 */

int
get_char
(     unsigned long     timeout           /* maximum time to wait for character           */
)
{     int                     c;

      if (timeout)
      {
            /* get timeout second */
            timeout += get_time();

            while ((c = BVMBug_getchar_nowait()) == -1)
            {
                  /* check for timeout */
                  if (get_time() > timeout)
                  {
                        /* timeout */
                        break;
                  }
            }

            return c;
      }

      return BVMBug_getchar();
}

/*--------------------------------------------------------------------------*/
/* return pointer to string containing specified IP address or NULL
 * if not available.
 */

const char *
get_ip
(     IPTYPE                        type
)
{     unsigned long           ip;
      const NETBOOTINFO *nbi = BVMBug_netbootinfo();

      switch (type)
      {
            case IP_CLIENT     : ip = nbi->cipa;       break;
            case IP_SERVER     : ip = nbi->sipa;       break;
            case IP_GATEWAY    : ip = nbi->gipa;       break;
            case IP_NETMASK  : ip = nbi->subnetmask; break;
            default                  : return NULL;
      }
            
      return mkinet(ip);
}

/*--------------------------------------------------------------------------*/
/* return pointer to prototype configuration file name
 */

const char *
config_filename
(     void
)
{     const char  *bootargs = BVMBug_bootargs();

      /* use BVMBug boot argument string if set */
      if (bootargs && bootargs[0])
            return bootargs;

      /* use compiled in default */
      return DEFAULT_CONFIG_FILE_NAME;
}

/*--------------------------------------------------------------------------*/

int
tftp_read
(     const char        *filename,
      unsigned long     count,
      void              *buffer
)
{     int                     status;

      if ((status = BVMBug_tftp_read(filename, &count, buffer, 0)) != SUCCESS)
      {
            printf ("TFTP READ FAILED: BVMBug error #%d\n", status);
            return FAILURE;
      }

      return count;
}

/*--------------------------------------------------------------------------*/

unsigned long
get_compat_booti_version
(     void
)
{
      return COMPAT_BVME6000_BOOTI_VERSION;
}

/*--------------------------------------------------------------------------*/

unsigned long
get_booti_version
(     void
)
{
      return BVME6000_BOOTI_VERSION;
}

/*--------------------------------------------------------------------------*/

unsigned long
get_compat_machtype
(     void
)
{
      return COMPAT_MACH_BVME6000;
}

/*--------------------------------------------------------------------------*/

unsigned long
get_machtype
(     void
)
{
      return MACH_BVME6000;
}

/*--------------------------------------------------------------------------*/
/*
 *    This assembler code is copied into the base of the stack, and then executed.
 *    It copies the kernel and ramdisk images to their final resting places.
 *
 *    It is called with:
 *
 *      a0 = address of this code (very top of memory)
 *      a1 = kernel destination address (low memory 0x1000)
 *          a2 = kernel source address
 *          a3 = ramdisk destination address (just below this code)
 *          a4 = ramdisk source address
 *          d0 = kernel size + size of bootinfo data rounded up next multiple of 4
 *          d1 = ramdisk size rounded to next multiple of 1K
 *      d2 = non-zero if BVMBug should be called
 */

__asm(".text\n"
__ALIGN_STR "\n"
".globl " SYMBOL_NAME_STR(startcode_beg) ";\n"
".globl " SYMBOL_NAME_STR(startcode_end) ";\n"
SYMBOL_NAME_STR(startcode_beg) ":                                                                     \n\
                                                | copy the ramdisk to the top of memory               \n\
                                                | (from back to front)                                      \n\
            addl  %d1,%a4                 | src   = (u_long *) (rd_src + rd_size);        \n\
            movel %a3,%a5                                                                                         \n\
            addl  %d1,%a5                 | dest  = (u_long *) (rd_dest + rd_size);       \n\
                                                                                                                        \n\
            bras  2f                      | do                                                              \n\
1:          movel -(%a4),-(%a5)     |   *--dest = *--src;                                       \n\
2:          cmpl  %a3,%a5                 | while (dest > ramdisk_dest)                         \n\
            jgt         1b                      |                                                                       \n\
                                                                                                                        \n\
                                                | copy kernel text and data, and bootinfo       \n\
            movel %a2,%a4                 | limit = (u_long *) (kernel_src + kernel_size);\n\
            addl  %d0,%a4                                                                                         \n\
            movel %a1,%a5                 | dest  = (u_long *) kernel_dest                      \n\
                                                                                                                        \n\
            bras  2f                      | do                                                              \n\
1:          movel (%a2)+,(%a5)+     |  *dest++ = *src++;                                        \n\
2:          cmpl  %a4,%a2                 | while (src < limit)                                       \n\
            jlt         1b                      |                                                                       \n\
                                                                                                                        \n\
            dc.w  0xf498                  | cinva     ic | invalidate instruction cache         \n\
                                                                                                                        \n\
            tstl  %d2                     | call BVMbug?                                                    \n\
            jeq         1f                      | branch if not                                                   \n\
                                                                                                                        \n\
            moveq #22,%d0                 | BVMBug enter                                                    \n\
            trap  #15                                                                                             \n\
                                                                                                                        \n\
1:          jmp         (%a1)             | start kernel                                                    \n\
"
SYMBOL_NAME_STR(startcode_end) ":                                                                     \n\
");

/*--------------------------------------------------------------------------*/

void
print_model
(     void
)
{
      printf("BVME%d00", cpu_type);
}

/*--------------------------------------------------------------------------*/

unsigned long
get_vme_type
(     void
)
{
      return (cpu_type == 40)
                   ? VME_TYPE_BVME4000
                   : VME_TYPE_BVME6000
                   ;
}

/*--------------------------------------------------------------------------*/

int
add_vme_bootinfo
(     void
)
{     unsigned long     vme_type = get_vme_type();

      if (!add_bi_record(BI_VME_TYPE, sizeof(vme_type), &vme_type))
            return FALSE;

      return TRUE;
}

/*-----------------------------< end of file >------------------------------*/

Generated by  Doxygen 1.6.0   Back to index