/*-------------------------------------------------------------------------+
|         Function: bsp_start
|      Description: Called before main is invoked.
| Global Variables: None.
|        Arguments: None.
|          Returns: Nothing.
+--------------------------------------------------------------------------*/
void bsp_start_default( void )
{
  int pci_init_retval;

  /*
   *  We need to determine how much memory there is in the system.
   */
  bsp_size_memory();

  /*
   * Calibrate variable for 1ms-loop (see timer.c)
   */
  Calibrate_loop_1ms();

  /*
   * Init rtems interrupt management
   */
  rtems_irq_mngt_init();
  /*
   * Init rtems exceptions management
   */
  rtems_exception_init_mngt();

  /*
   * init PCI Bios interface...
   */
  pci_init_retval = pci_initialize();
  if (pci_init_retval != PCIB_ERR_SUCCESS) {
      printk("PCI bus: could not initialize PCI BIOS interface\n");
  }

  bsp_ide_cmdline_init ();

} /* bsp_start */
Exemplo n.º 2
0
/* This is a very ugly hack. I don't want to change the shared
 * code to support multiple hoses so we hide everything under
 * the hood with horrible kludges for now. Sorry.
 */
void
BSP_pci_initialize(void)
{

#if 0	/* These values are already set up for the shared/pci.c code      */
{
extern pci_config_access_functions pci_indirect_functions;
        /* by means of the PCI_CONFIG_ADDR/PCI_CONFIG_DATA macros (bsp.h) */
	BSP_pci_configuration.pci_config_addr = hoses[0].pci_config_addr;
	BSP_pci_configuration.pci_config_data = hoses[0].pci_config_data;
	BSP_pci_configuration.pci_functions   = &pci_indirect_functions;
}
#endif
	/* initialize the first hose */
	/* scan hose 0 and sets the maximum bus number */
	pci_initialize();
	/* remember the boundary */
	BSP_pci_hose1_bus_base = pci_bus_count();
	/* so far, so good -- now comes the cludgy part: */
	/* hack/reset the bus count */
	ucMaxPCIBus = 0;
	/* scan hose 1 */
	BSP_pci_configuration.pci_config_addr = hoses[1].pci_config_addr;
	BSP_pci_configuration.pci_config_data = hoses[1].pci_config_data;
	pci_initialize();
	/* check for overflow of an unsigned char */
	if ( BSP_pci_hose1_bus_base + pci_bus_count() > 255 ) {
		BSP_panic("Too many PCI busses in the system");
	}
	/* readjust total number */
	ucMaxPCIBus+=BSP_pci_hose1_bus_base;

	/* install new access functions that can hide the hoses */
	BSP_pci_configuration.pci_config_addr = (volatile unsigned char *)0xdeadbeef;
	BSP_pci_configuration.pci_config_data = (volatile unsigned char *)0xdeadbeef;
	BSP_pci_configuration.pci_functions   = &pci_hosed_indirect_functions;
}
Exemplo n.º 3
0
/*
 *  bsp_start
 *
 *  This routine does the bulk of the system initialization.
 */
void bsp_start( void )
{
  /* uint32_t  board_ID = 0x420; */
  static    int j = 1;
  int       pci_init_retval;

  /*
   * Note: This is the value that works for qemu, and it was
   * unable to be validated on the actual hardware.
   */
  mips_set_sr( 0x04100000 );

  bsp_interrupt_initialize();

  /*
   *  XXX need to figure out a real value. :)
   *  This works for the qemu simulation, but timeing may
   *  be off for the actual hardware.
   */
  bsp_clicks_per_microsecond = 100;

  #if 1
  while ( j != 1 ) {
    int i;
    printk (".");
    for (i=0; i<1000; i++);
  }
  #endif

  /*
   * init PCI Bios interface...
   */
  pci_init_retval = pci_initialize();
  if (pci_init_retval != PCIB_ERR_SUCCESS) {
      printk("PCI bus: could not initialize PCI BIOS interface\n");
  }

  BSP_i8259s_init();

}
Exemplo n.º 4
0
void bsp_start( void )
{
#ifdef CONF_VPD
  int i;
#endif
#ifdef SHOW_LCR1_REGISTER
  unsigned l1cr;
#endif
#ifdef SHOW_LCR2_REGISTER
  unsigned l2cr;
#endif
#ifdef SHOW_LCR3_REGISTER
  unsigned l3cr;
#endif
  uintptr_t intrStackStart;
  uintptr_t intrStackSize;
  ppc_cpu_id_t myCpu;
  ppc_cpu_revision_t myCpuRevision;
  Triv121PgTbl  pt=0;

  /* Till Straumann: 4/2005
   * Need to map the system registers early, so we can printk...
   * (otherwise we silently die)
   */
  /*
   * Kate Feng : PCI 0 domain memory space, want to leave room for the VME window
   */
  setdbat(2, PCI0_MEM_BASE, PCI0_MEM_BASE, 0x10000000, IO_PAGE);

  /* Till Straumann: 2004
   * map the PCI 0, 1 Domain I/O space, GT64260B registers
   * and the reserved area so that the size is the power of 2.
   * 2009 : map the entire 256 M space
   *
   */
  setdbat(3,PCI0_IO_BASE, PCI0_IO_BASE, 0x10000000, IO_PAGE);


  /*
   * Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
   * store the result in global variables so that it can be used latter...
   */
  myCpu   = get_ppc_cpu_type();
  myCpuRevision = get_ppc_cpu_revision();

#ifdef SHOW_LCR1_REGISTER
  l1cr = get_L1CR();
  printk("Initial L1CR value = %x\n", l1cr);
#endif

  /*
   * Initialize the interrupt related settings.
   */
  intrStackStart = (uintptr_t) __rtems_end;
  intrStackSize = rtems_configuration_get_interrupt_stack_size();

  /*
   * Initialize default raw exception handlers.
   */
  ppc_exc_initialize(
    PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
    intrStackStart,
    intrStackSize
  );

  /*
   * Init MMU block address translation to enable hardware
   * access
   * More PCI1 memory mapping to be done after BSP_pgtbl_activate.
   */
  printk("-----------------------------------------\n");
  printk("Welcome to %s on MVME5500-0163\n", _RTEMS_version );
  printk("-----------------------------------------\n");

  BSP_mem_size         =  probeMemoryEnd();

  /* TODO: calculate the BSP_bus_frequency using the REF_CLK bit
   *       of System Status  register
   */
  /* rtems_bsp_delay_in_bus_cycles are defined in registers.h */
  BSP_bus_frequency      = 133333333;
  BSP_processor_frequency    = 1000000000;
  /* P94 : 7455 clocks the TB/DECR at 1/4 of the system bus clock frequency */
  BSP_time_base_divisor      = 4000;

  /* Maybe not setup yet becuase of the warning message */
  /* Allocate and set up the page table mappings
   * This is only available on >604 CPUs.
   *
   * NOTE: This setup routine may modify the available memory
   *       size. It is essential to call it before
   *       calculating the workspace etc.
   */
  pt = BSP_pgtbl_setup(&BSP_mem_size);
  if (!pt)
     printk("WARNING: unable to setup page tables.\n");

  printk("Now BSP_mem_size = 0x%x\n",BSP_mem_size);

  /* P94 : 7455 TB/DECR is clocked by the system bus clock frequency */

  bsp_clicks_per_usec    = BSP_bus_frequency/(BSP_time_base_divisor * 1000);

  /*
   * Initalize RTEMS IRQ system
   */
   BSP_rtems_irq_mng_init(0);

#ifdef SHOW_LCR2_REGISTER
  l2cr = get_L2CR();
  printk("Initial L2CR value = %x\n", l2cr);
#endif

#ifdef SHOW_LCR3_REGISTER
  /* L3CR needs DEC int. handler installed for bsp_delay()*/
  l3cr = get_L3CR();
  printk("Initial L3CR value = %x\n", l3cr);
#endif


  /* Activate the page table mappings only after
   * initializing interrupts because the irq_mng_init()
   * routine needs to modify the text
   */
  if (pt) {
#ifdef SHOW_MORE_INIT_SETTINGS
    printk("Page table setup finished; will activate it NOW...\n");
#endif
    BSP_pgtbl_activate(pt);
  }
  /* Read Configuration Vital Product Data (VPD) */
  if ( I2Cread_eeprom(0xa8, 4,2, &ConfVPD_buff[0], 150))
     printk("I2Cread_eeprom() error \n");
  else {
#ifdef CONF_VPD
    printk("\n");
    for (i=0; i<150; i++) {
      printk("%2x ", ConfVPD_buff[i]);
      if ((i % 20)==0 ) printk("\n");
    }
    printk("\n");
#endif
  }

  /*
   * PCI 1 domain memory space
   */
  setdbat(1, PCI1_MEM_BASE, PCI1_MEM_BASE, 0x10000000, IO_PAGE);


#ifdef SHOW_MORE_INIT_SETTINGS
  printk("Going to start PCI buses scanning and initialization\n");
#endif
  pci_initialize();
#ifdef SHOW_MORE_INIT_SETTINGS
  printk("Number of PCI buses found is : %d\n", pci_bus_count());
#endif

  /* Install our own exception handler (needs PCI) */
  globalExceptHdl = BSP_exceptionHandler;

  /* clear hostbridge errors. MCP signal is not used on the MVME5500
   * PCI config space scanning code will trip otherwise :-(
   */
  _BSP_clear_hostbridge_errors(0, 1 /*quiet*/);

#ifdef SHOW_MORE_INIT_SETTINGS
  printk("MSR %x \n", _read_MSR());
  printk("Exit from bspstart\n");
#endif

}
Exemplo n.º 5
0
void bsp_start( void )
{
  rtems_status_code sc = RTEMS_SUCCESSFUL;
#if !defined(mvme2100)
  unsigned l2cr;
#endif
  uintptr_t intrStackStart;
  uintptr_t intrStackSize;
  ppc_cpu_id_t myCpu;
  ppc_cpu_revision_t myCpuRevision;
  prep_t boardManufacturer;
  motorolaBoard myBoard;
  Triv121PgTbl	pt=0;

  /*
   * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
   * function store the result in global variables so that it can be used
   * later...
   */
  myCpu 	= get_ppc_cpu_type();
  myCpuRevision = get_ppc_cpu_revision();

  /*
   * Init MMU block address translation to enable hardware access
   */

#if !defined(mvme2100)
  /*
   * PC legacy IO space used for inb/outb and all PC compatible hardware
   */
  setdbat(1, _IO_BASE, _IO_BASE, 0x10000000, IO_PAGE);
#endif

  /*
   * PCI devices memory area. Needed to access OpenPIC features
   * provided by the Raven
   *
   * T. Straumann: give more PCI address space
   */
  setdbat(2, PCI_MEM_BASE+PCI_MEM_WIN0, PCI_MEM_BASE+PCI_MEM_WIN0, 0x10000000, IO_PAGE);

  /*
   * Must have acces to open pic PCI ACK registers provided by the RAVEN
   */
  setdbat(3, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE);

#if defined(mvme2100)
  /* Need 0xfec00000 mapped for this */
  EUMBBAR = get_eumbbar();
#endif

  /*
   * enables L1 Cache. Note that the L1_caches_enables() codes checks for
   * relevant CPU type so that the reason why there is no use of myCpu...
   */
  L1_caches_enables();

#if !defined(mvme2100)
  /*
   * Enable L2 Cache. Note that the set_L2CR(L2CR) codes checks for
   * relevant CPU type (mpc750)...
   */
  l2cr = get_L2CR();
#ifdef SHOW_LCR2_REGISTER
  printk("Initial L2CR value = %x\n", l2cr);
#endif
  if ( (! (l2cr & 0x80000000)) && ((int) l2cr == -1))
    set_L2CR(0xb9A14000);
#endif

  /*
   * Initialize the interrupt related settings.
   */
  intrStackStart = (uintptr_t) __rtems_end;
  intrStackSize = rtems_configuration_get_interrupt_stack_size();

  /*
   * Initialize default raw exception handlers.
   */
  sc = ppc_exc_initialize(
    PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
    intrStackStart,
    intrStackSize
  );
  if (sc != RTEMS_SUCCESSFUL) {
    BSP_panic("cannot initialize exceptions");
  }

  select_console(CONSOLE_LOG);

  /*
   * We check that the keyboard is present and immediately
   * select the serial console if not.
   */
#if defined(BSP_KBD_IOBASE)
  { int err;
    err = kbdreset();
    if (err) select_console(CONSOLE_SERIAL);
  }
#else
  select_console(CONSOLE_SERIAL);
#endif

  boardManufacturer   =  checkPrepBoardType(&residualCopy);
  if (boardManufacturer != PREP_Motorola) {
    printk("Unsupported hardware vendor\n");
    while (1);
  }
  myBoard = getMotorolaBoard();

  printk("-----------------------------------------\n");
  printk("Welcome to %s on %s\n", _RTEMS_version,
                                    motorolaBoardToString(myBoard));
  printk("-----------------------------------------\n");
#ifdef SHOW_MORE_INIT_SETTINGS
  printk("Residuals are located at %x\n", (unsigned) &residualCopy);
  printk("Additionnal boot options are %s\n", loaderParam);
  printk("Initial system stack at %x\n",stack);
  printk("Software IRQ stack starts at %x with size %u\n", intrStackStart, intrStackSize);
  printk("-----------------------------------------\n");
#endif

#ifdef TEST_RETURN_TO_PPCBUG
  printk("Hit <Enter> to return to PPCBUG monitor\n");
  printk("When Finished hit GO. It should print <Back from monitor>\n");
  debug_getc();
  _return_to_ppcbug();
  printk("Back from monitor\n");
  _return_to_ppcbug();
#endif /* TEST_RETURN_TO_PPCBUG  */

#ifdef SHOW_MORE_INIT_SETTINGS
  printk("Going to start PCI buses scanning and initialization\n");
#endif

  pci_initialize();
  {
    const struct _int_map *bspmap  = motorolaIntMap(currentBoard);
    if( bspmap ) {
       printk("pci : Configuring interrupt routing for '%s'\n",
          motorolaBoardToString(currentBoard));
       FixupPCI(bspmap, motorolaIntSwizzle(currentBoard));
    }
    else
       printk("pci : Interrupt routing not available for this bsp\n");
 }

#ifdef SHOW_MORE_INIT_SETTINGS
  printk("Number of PCI buses found is : %d\n", pci_bus_count());
#endif
#ifdef TEST_RAW_EXCEPTION_CODE
  printk("Testing exception handling Part 1\n");
  /*
   * Cause a software exception
   */
  __asm__ __volatile ("sc");
  /*
   * Check we can still catch exceptions and return coorectly.
   */
  printk("Testing exception handling Part 2\n");
  __asm__ __volatile ("sc");

  /*
   * Somehow doing the above seems to clobber SPRG0 on the mvme2100.  The
   * interrupt disable mask is stored in SPRG0. Is this a problem?
   */
  ppc_interrupt_set_disable_mask( PPC_INTERRUPT_DISABLE_MASK_DEFAULT);

#endif

/* See above */

  BSP_mem_size            = residualCopy.TotalMemory;
  BSP_bus_frequency       = residualCopy.VitalProductData.ProcessorBusHz;
  BSP_processor_frequency = residualCopy.VitalProductData.ProcessorHz;
  BSP_time_base_divisor   = (residualCopy.VitalProductData.TimeBaseDivisor?
                    residualCopy.VitalProductData.TimeBaseDivisor : 4000);

  /* clear hostbridge errors but leave MCP disabled -
   * PCI config space scanning code will trip otherwise :-(
   */
  _BSP_clear_hostbridge_errors(0 /* enableMCP */, 0/*quiet*/);

  /* Allocate and set up the page table mappings
   * This is only available on >604 CPUs.
   *
   * NOTE: This setup routine may modify the available memory
   *       size. It is essential to call it before
   *       calculating the workspace etc.
   */
  pt = BSP_pgtbl_setup(&BSP_mem_size);

  if (!pt || TRIV121_MAP_SUCCESS != triv121PgTblMap(
            pt, TRIV121_121_VSID, 0xfeff0000, 1,
            TRIV121_ATTR_IO_PAGE, TRIV121_PP_RW_PAGE)) {
	printk("WARNING: unable to setup page tables VME "
               "bridge must share PCI space\n");
  }

  /*
   *  initialize the device driver parameters
   */
  bsp_clicks_per_usec 	 = BSP_bus_frequency/(BSP_time_base_divisor * 1000);

  /*
   * Initalize RTEMS IRQ system
   */
  BSP_rtems_irq_mng_init(0);

  /* Activate the page table mappings only after
   * initializing interrupts because the irq_mng_init()
   * routine needs to modify the text
   */
  if (pt) {
#ifdef  SHOW_MORE_INIT_SETTINGS
    printk("Page table setup finished; will activate it NOW...\n");
#endif
    BSP_pgtbl_activate(pt);
    /* finally, switch off DBAT3 */
    setdbat(3, 0, 0, 0, 0);
  }

#if defined(DEBUG_BATS)
  ShowBATS();
#endif

#ifdef SHOW_MORE_INIT_SETTINGS
  printk("Exit from bspstart\n");
#endif
}
Exemplo n.º 6
0
Arquivo: kernel.c Projeto: Kloniks/muk
void kernel_main(unsigned long magic,
		 unsigned long addr)
{
  multiboot_info_t *mbi;

  if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
    return;

  mbi = (multiboot_info_t*)addr;

  /* kernel init
   */
  serial_init(DEBUG_SERIAL_PORT,
	      DEBUG_SERIAL_SPEED,
	      UART_8BITS_WORD,
	      UART_NO_PARITY,
	      UART_1_STOP_BIT);
  cls();

  cpu_cli();
  printf("[x] interrupts disabled\n");

  gdt_initialize();
  printf("[x] gdt initialized\n");

  idt_initialize();
  printf("[x] idt initialized\n");

  breakpoint_initialize();

#if defined(USE_APIC)
  apic_initialize();
  serial_printl("[x] apic initialized\n");
#else
  pic_initialize();
  serial_printl("[x] pic initialized\n");
#endif /* USE_APIC */

  /* initialize the kernel
   */
  {
    kernel_init(mbi);
  }

  /* memory initialization
   */
  {
    phys_init(mbi);
    phys_debug();
/*     vm_init(); */
/*     unit_test_vm(); */
/*     cpu_hlt(); */
  }

#if defined(USE_PCI)
  pci_initialize();
  pci_list();
#endif

  cpu_sti();

#if defined(USE_TASK)
 {
   /* subsystems
    */
   event_initialize();
   sched_initialize();
   task_initialize();

   /* tasks
    */
   idle_initialize();
   muksh_initialize();
   net_initialize();

/*    task_test(); */

   /* start scheduling
    */
   sched_start();
 }
#endif

 /* endless loop
  */
 serial_printl("[?] kernel loop\n");
 while (1)
   {
     serial_printl("k");
     cpu_hlt();
   }
}
Exemplo n.º 7
0
rtems_task Init(
  rtems_task_argument ignored
)
{
GetLine	*gl       = 0;
char	*symf     = 0, *sysscr=0, *user_script=0, *bufp;
int	argc      = 0;
int	result    = 0;
int	no_net    = 0;
char	*dfltSrv  = 0;
char	*pathspec = 0;
#ifdef NFS_SUPPORT
MntDescRec	bootmnt = { "/boot", 0, 0 };
MntDescRec      homemnt = { "/home", 0, 0 };
#endif
char	*argv[7]={
	"Cexp",	/* program name */
	0,
	0,
	0,
	0
};

  rtems_libio_set_private_env();

#ifdef HAVE_PCIBIOS
#if RTEMS_VERSION_ATLEAST(4,6,99)
  pci_initialize();
#else
  pcib_init();
#endif
#endif

#ifdef STACK_CHECKER_ON
  {
	extern void Stack_check_Initialize();
	Stack_check_Initialize();
  }
#endif

#ifdef HAVE_LIBBSPEXT
  bspExtInit();
#endif

  /* make /tmp directory */
  mkTmpDir();


  printf("Welcome to RTEMS GeSys\n");
  printf("This system $Name: GeSys_2_4 $ was built on %s\n",system_build_date);
  printf("$Id: init.c,v 1.43 2008/03/22 20:36:13 guest Exp $\n");

#ifdef EARLY_CMDLINE_GET
  {
	char *cmdlinetmp;
	EARLY_CMDLINE_GET(&cmdlinetmp);

#ifdef HAVE_LIBNETBOOT
  /* Let libnetboot process the command line string; all
   * special name=value pairs recognized by libnetboot will
   * be removed...
   */
   nvramFixupBsdnetConfig(1, cmdlinetmp);
#endif

	cmdlinePairExtract(cmdlinetmp, putenv, 1);
  }
#endif

#if defined(USE_TECLA)
  /*
   * Install our special line discipline which implements
   * TIOCGWINSZ
   */
  printf("Installing TIOCGWINSZ line discipline: %s.\n",
		 ansiTiocGwinszInstall(7) ? "failed" : "ok");
#endif

  /*
   * Make sure the time-of-day clock is at least initialized.
   * The dummy routine just sets the date to 1/1/2000
   */
  dummy_clock_init();

  cexpInit(cexpExcHandlerInstall);

  printf("To skip initialization, press a key now...");
  fflush(stdout);
  if ( getchar_timeout(fileno(stdin),10) > 0 ) {
	printf("OK; skipping to shell");
	no_net = 1;
	argc   = 1;
  }
  printf("\n");

#ifndef CDROM_IMAGE
#ifndef SKIP_NETINI
#define SKIP_NETINI	getenv("SKIP_NETINI")
#endif
  /* check if we have a real ifconfig (first is loopback) */
  if ( !no_net && (! (SKIP_NETINI) || !BUILTIN_SYMTAB) && rtems_bsdnet_config.ifconfig )
  {
    gesys_network_start();
  }
  else
  {
	fprintf(stderr,"Skipping network initialization - you can do it manually\n");
	fprintf(stderr,"by invoking 'gesys_network_start()' (needs BOOTP/DHCP server)\n");
	argc   = 1;
	no_net = 1;
  }
#endif

#ifndef CDROM_IMAGE
  if ( BOOTPFN ) {
	char *slash,*dot;
	pathspec = malloc(strlen(BOOTPFN) + (BUILTIN_SYMTAB ? strlen(SYSSCRIPT) : strlen(SYMEXT)) + 1);
	strcpy(pathspec, BOOTPFN);
	slash    = strrchr(pathspec,'/');

	if ( BUILTIN_SYMTAB ) {
 		if ( slash )
			strcpy(slash+1,SYSSCRIPT);
		else
			strcpy(pathspec,SYSSCRIPT);
	} else {
		dot      = strrchr(pathspec,'.');
		if (slash>dot)
			dot=0;
		/* substitute suffix */
		if (dot) {
			strcpy(dot,SYMEXT);
		} else {
			strcat(pathspec,SYMEXT);
		}
	}
  }
  {
  char *tarvar;
  void *addr;
  int   len;
  	if ( (tarvar=getenv("TARFS")) && 2 == sscanf(tarvar,"%p:%i",&addr,&len) && len > 0 ) {
		mkdir("/tar",0777);
		rtems_tarfs_load("/tar",addr,len);
  	}
  }
#else
  {
	extern void *gesys_tarfs_image_start;
	extern unsigned long gesys_tarfs_image_size;
	printf("Loading TARFS... %s\n",
		rtems_tarfs_load("/tmp", gesys_tarfs_image_start, gesys_tarfs_image_size) ? "FAILED" : "OK");
	pathspec=strdup(BUILTIN_SYMTAB ? "/tmp/"SYSSCRIPT : "/tmp/rtems.sym");
  }
#endif

  dflt_fname = "rtems.sym";
#ifdef TFTP_SUPPORT
  path_prefix = strdup("/TFTP/BOOTP_HOST/");
#elif defined(NFS_SUPPORT)
  path_prefix = strdup(":/remote/rtems:");
#elif defined(RSH_SUPPORT)
  path_prefix = strdup("~rtems/");
#endif
  getDfltSrv(&dfltSrv);

#ifdef PSIM
  {
  extern int loadTarImg(int verbose, int lun);
  if ( !pathspec ) {
	loadTarImg(1, 0);
	pathspec = strdup("/bin/"SYSSCRIPT);
  } else {
	fprintf(stderr,"PSIM: root tarfs not loaded (pathspec was '%s')\n",pathspec);
  }
  }
#endif


  if ( no_net && ( !pathspec || LOCAL_PATH != pathType(pathspec) ) )
	goto shell_entry;

  /* omit prompting for the symbol file */
  if ( pathspec )
  	goto firstTimeEntry;

  /* no pathspec but a builtin symtab ->
   * skip reading symtab / system script
   */
  if ( BUILTIN_SYMTAB )
	goto bare_entry;


  do {
	chdir("/");
#ifdef NFS_SUPPORT
	if ( releaseMount( &bootmnt ) ) {
		fprintf(stderr,"Unable to unmount /boot NFS - don't know what to do, sorry\n");
		break;
	}
#endif
	freeps(&symf);
	freeps(&user_script);

	if (!gl) {
		assert( gl = new_GetLine(LINE_LENGTH, 10*LINE_LENGTH) );
		/* silence warnings about missing .teclarc */
		gl_configure_getline(gl,0,0,0);
	}

	do {
		printf("Symbol file can be loaded by:\n");
#ifdef NFS_SUPPORT
		printf("   NFS: [<uid>.<gid>@][<host>]:<export_path>:<symfile_path>\n");
#endif
#ifdef TFTP_SUPPORT
		printf("  TFTP: [/TFTP/<host_ip>]<symfile_path>\n");
#endif
#ifdef RSH_SUPPORT
		printf("   RSH: [<host>:]~<user>/<symfile_path>\n");
#endif
#ifdef USE_TECLA
		bufp = gl_get_line(gl, "Enter Symbol File Name: ",
			               pathspec,
                           ( pathspec && *pathspec ) ? strlen(pathspec) : 0 );
#else
		bufp = my_getline(gl, "Enter Symbol File Name: ", LINE_LENGTH);
#endif
	} while (!bufp || !*bufp);
	pathspec = realloc(pathspec, strlen(bufp) + 1);
	strcpy(pathspec, bufp);
	bufp = pathspec + strlen(bufp) - 1;
	while ( bufp >= pathspec && ('\n' == *bufp || '\r' == *bufp) )
		*bufp-- = 0;

firstTimeEntry:


  {
	int fd = -1, ed = -1;
	char *slash;

	getDfltSrv( &dfltSrv );

#ifdef TFTP_SUPPORT
	chdir("/TFTP/BOOTP_HOST/");
#endif

	switch ( pathType(pathspec) ) {
		case LOCAL_PATH:
			fd = open(pathspec,O_RDONLY);
			if ( fd >= 0 )
				symf = strdup(pathspec);
		break;


#ifdef TFTP_SUPPORT
		case TFTP_PATH:
			fd = isTftpPath( &dfltSrv, pathspec, &ed, &symf );
		break;
#endif

#ifdef NFS_SUPPORT
		case NFS_PATH:
    		fd = isNfsPath( &dfltSrv, pathspec, &ed, &symf, &bootmnt );
		break;
#endif

#ifdef RSH_SUPPORT
		case RSH_PATH:
    		fd = rshCopy( &dfltSrv, pathspec, &symf );
		break;
#endif

		default:
			fprintf(stderr,"Unrecognized pathspec; maybe remote FS support is not compiled in ?\n");
		break;
	}

	if ( 0==result && dfltSrv ) {
		/* allow the default server to be overridden by the pathspec
		 * during the first pass (original pathspec from boot)
		 */
		theSrv = strdup(dfltSrv);
	}


	if ( (fd < 0) && !BUILTIN_SYMTAB ) {
		fprintf(stderr,"Unable to open symbol file (%s)\n",
			-11 == fd ? "not a valid pathspec" : strerror(errno));
continue;
	}


	if ( fd >= 0 )
		close(fd);
	if ( ed >= 0 )
		close(ed);

	freeps( &sysscr );
	sysscr = strdup(SYSSCRIPT);

#if defined(RSH_SUPPORT) && !defined(CDROM_IMAGE)
	if ( !ISONTMP(symf) ) {
#endif
		if ( (slash = strrchr(symf,'/')) ) {
			int ch=*(slash+1);
			*(slash+1)=0;
			printf("Change Dir to '%s'",symf);
			if ( chdir(symf) )
				printf(" FAILED: %s",strerror(errno));
			fputc('\n',stdout);
			*(slash+1)=ch;
		}
#if defined(RSH_SUPPORT) && !defined(CDROM_IMAGE)
	} else {
		char *scrspec = malloc( strlen(pathspec) + strlen(SYSSCRIPT) + 1);

		strcpy(scrspec, pathspec);
		if ( (slash = strrchr(scrspec, '/')) )
			strcpy( slash+1, SYSSCRIPT );
		else
			strcpy( scrspec, SYSSCRIPT );

		getDfltSrv( &dfltSrv );

		freeps( &sysscr );
		if ( (fd = rshCopy( &dfltSrv, scrspec, &sysscr )) >= 0 ) {
			close( fd );
		} else {
			freeps( &sysscr );
		}
		freeps(&scrspec);
	}
#endif

bare_entry:
	printf("Trying symfile '%s', system script '%s'\n",
		BUILTIN_SYMTAB ? "BUILTIN" : symf,
		sysscr ? sysscr :"(NONE)");

	argc = 1;
#ifdef DEFAULT_CPU_ARCH_FOR_CEXP
	if ( DEFAULT_CPU_ARCH_FOR_CEXP && *DEFAULT_CPU_ARCH_FOR_CEXP ) {
		argv[argc++] = "-a";
		argv[argc++] = DEFAULT_CPU_ARCH_FOR_CEXP;
	}
#endif
	if ( !BUILTIN_SYMTAB ) {
		argv[argc++] = "-s";
		argv[argc++] = symf;
	}
	if ( sysscr ) {
		argv[argc++] = sysscr;
	}


shell_entry:

	result = argc > 1 ? cexp_main(argc, argv) : 0;

	if ( ISONTMP( symf ) )
		unlink( symf );
	if ( sysscr && ISONTMP( sysscr ) )
		unlink( sysscr );

	freeps(&symf);
	freeps(&sysscr);


	if (!result || CEXP_MAIN_NO_SCRIPT==result) {
		int  rc;

		if (gl) {
			del_GetLine(gl);
			gl = 0;
		}

		freeps(&pathspec);

		/* try a user script */
		if ((user_script=getenv("INIT"))) {

			printf("Trying user script '%s':\n",user_script);

			pathspec = strdup(user_script); user_script = 0;

			getDfltSrv(&dfltSrv);

			switch ( pathType( pathspec ) ) {
#ifdef NFS_SUPPORT
				case NFS_PATH:
					if ( 0 == (rc = isNfsPath( &dfltSrv, pathspec, 0, &user_script, &homemnt ) ) ) {
						/* valid NFS path; try to mount; */
						if ( !bootmnt.uidhost || strcmp( homemnt.uidhost, bootmnt.uidhost ) ||
						     !bootmnt.rpath   || strcmp( homemnt.rpath  , bootmnt.rpath   ) )
							rc = nfsMount(homemnt.uidhost, homemnt.rpath, homemnt.mntpt);
					}
				break;
#endif
				case RSH_PATH:
					fprintf(stderr,"RSH download of user scripts is not supported\n");
					rc = -1;
				break;

#ifdef TFTP_SUPPORT
				case TFTP_PATH:
					rc = isTftpPath( &dfltSrv, pathspec, 0, &user_script );
				break;
#endif

				case LOCAL_PATH:
					/* they might refer to a path on the local FS (already mounted NFS) */
					user_script = pathspec; pathspec = 0;
					rc = 0;
				break;

				default:
					fprintf(stderr,"Invalid path specifier; support for remote FS not compiled in?\n");
					rc = -1;
				break;
			}

			freeps(&pathspec);

			argc = 2;

			if ( rc ) {
				fprintf(stderr,"Unable to determine filesystem for user script\n");
				freeps(&user_script);
				argc = 1;
			} else {
				if ((slash = strrchr(user_script,'/'))) {
					/* chdir to where the user script resides */
					int ch=*(++slash);
					*(slash)=0;
					printf("Change Dir to '%s'\n",user_script);
					chdir(user_script);
					*(slash)=ch;
					argv[1]=slash;
				} else {
					argv[1]=user_script;
				}
			}
			argc=2;
		} else {
			argc=1;
		}
		do {
			result=cexp_main(argc,argv);
			argc=1;
  			freeps(&user_script);
		} while (!result || CEXP_MAIN_NO_SCRIPT==result);
		chdir("/");
#ifdef NFS_SUPPORT
		releaseMount( &homemnt );
#endif
	}
  }

  switch (result) {
		case CEXP_MAIN_NO_SYMS  :
				fprintf(stderr,"CEXP_MAIN_NO_SYMS\n");
				result = 0;
		break;
		case CEXP_MAIN_INVAL_ARG: fprintf(stderr,"CEXP_MAIN_INVAL_ARG\n"); break;
		case CEXP_MAIN_NO_SCRIPT: fprintf(stderr,"CEXP_MAIN_NO_SCRIPT\n"); break;
		case CEXP_MAIN_KILLED   : fprintf(stderr,"CEXP_MAIN_KILLED\n");    break;
		case CEXP_MAIN_NO_MEM   : fprintf(stderr,"CEXP_MAIN_NO_MEM\n");    break;

	default:
		if (result)
			fprintf(stderr,"unknown error\n");
  }

  }  while ( !result ); /* retry asking for a sym-filename */
  if (gl) {
	del_GetLine(gl);
	gl = 0;
  }
  fprintf(stderr,"Unable to execute CEXP - suspending initialization...\n");
  rtems_task_suspend(RTEMS_SELF);
  exit( 1 );
}