Logo Search packages:      
Sourcecode: faumachine version File versions  Download package

main_init.c

/* $Id: main_init.c,v 1.117 2009-02-26 12:14:18 vrsieh Exp $ 
 *
 * Copyright (C) 2005-2009 FAUmachine Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */

/* Must be before other includes */
#include "config.h"
#include "build_config.h"
#include "compiler.h"

/* ===================== REAL MODE INIT ============================ */
#ifdef INIT_RM

CODE16;

#include "debug.h"
#include "main_init.h"
#include "entry.h"
#include "io.h"
#include "cmos.h"
#include "var.h"
#include "const.h"
/* Must be part of RM Init -> lies in first 1MB */
#include "logo.h"
#include "bios.lds.h"
#include "traps.h"
#include "rtc.h"
#include "kbd.h"
#include "mouse.h"
#include "smp.h"
#include "pci.h"
#include "mem.h"
#include "video.h"
#include "smi.h"
#include "disk.h"
#include "parallel.h"
#include "acpi-tables.h"
#include "boot.h"

static void
sleep(unsigned short secs)
{
      uint32_t tick_start;
      uint32_t tick_end;
      uint16_t ax, bx, cx, dx;

      asm volatile (
            "\tint $0x1a\n"
            : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx)
            : "0" ((uint16_t) 0x0000)           /* Get Time Ticks */
      );

      tick_start = ((uint32_t) cx << 16) | (uint32_t) dx;

      do {
            asm volatile (
                  "\tint $0x1a\n"
                  : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx)
                  : "0" ((uint16_t) 0x0000)     /* Get Time Ticks */
            );

            tick_end = ((uint32_t) cx << 16) | (uint32_t) dx;
      } while (tick_end - tick_start < secs * 18);
}

static void
biosdata_init(void)
{
      unsigned short sys_conf;
      unsigned char ebda_size;

      ebda_size = (unsigned char) ((sizeof(struct ebda) + 1023) / 1024);

      /* System configuration. */
      sys_conf = 0;
      sys_conf |= 1 << 1;     /* Math coprocessor available */
      var_put(sys_conf, sys_conf);

      /* Serial port io addresses. */
      /* Should go into serial.c - FIXME VOSSI */
      var_put(addr_ser[0], 0x03f8);
      var_put(addr_ser[1], 0x02f8);
      var_put(addr_ser[2], 0x03e8);
      var_put(addr_ser[3], 0x02e8);

      /* EBDA address */
      var_put(ebda_seg, EBDA_SEG);

      /* Memory settings. */
      /* Should go into mem.c - FIXME VOSSI */
      var_put(mem_total, 640 - ebda_size);      /* total 640k - EBDA size */
      var_put(mem_extra, 128);            /* extra 128k */

      ebda_put(size, ebda_size);
}

/* FIXME */
extern void
post(void);

void
init_rm_cpu(int bsp)
{
#ifndef CONFIG_80286_SUPPORT
      /*
       * Load IDT
       */
      asm volatile (
            "mov %0, %%es\n\t"
            "lidt %%es:(%1)\n\t"
            : /* No Output */
            : "r" ((uint16_t) ((uint32_t) idt_descr >> 4)),
              "b" ((uint16_t) ((uint32_t) idt_descr & 0xf))
      );

#ifdef CONFIG_SMI_SUPPORT
      /*
       * Redirect SMI Handler
       */
      smi_redirect(bsp ? 0xa0000 : 0xb0000);
#endif
#endif /* CONFIG_80286_SUPPORT */
}

C_ENTRY void
init_rm(int bsp)
{
      unsigned short startseg;
      unsigned char width;
      unsigned char height;
      const unsigned char *ptr;
      uint16_t x;
      uint16_t y;
      uint16_t n;
      uint16_t ax, bx, cx, dx;
      uint32_t mem_extended;

#ifdef CONFIG_SMP_SUPPORT
      smp_register();
#endif

    if (bsp) { /* FIXME */
      /*
       * Do some POST stuff.
       * Should be done earlier... - FIXME
       */
      post();

      /*
       * Initialize BIOS data area.
       */
      DEBUGPRINT(2, "Init BIOS data\n");
      biosdata_init();

      /*
       * Initialize IDT.
       */
      DEBUGPRINT(2, "Init traps\n");
      trap_init();

#ifdef CONFIG_SMI_SUPPORT
      /*
       * Initialize Chipset
       */
      smi_init_chipset();
#endif /* CONFIG_SMI_SUPPORT */
    }

      /*
       * Initialize CPU
       */
      init_rm_cpu(bsp);

    if (bsp) {
#ifdef CONFIG_SMP_SUPPORT
      smp_aps_start();
#endif

      /*
       * Boot Processor Enables Interrupts
       */
      asm volatile ("sti\n\t");
#ifdef CONFIG_SMI_SUPPORT
      smi_enable();
#endif

      /*
       * Initialize NVRAM on first run.
       */
      DEBUGPRINT(2, "Init cmos_ext\n");
      cmos_init();
      if (! cmos_ext_get(initialized)) {
            setup_defaults();
      }

#ifdef CONFIG_SMP_SUPPORT
      smp_init();
#endif      

      /*
       * Initialize RTC.
       */
      DEBUGPRINT(2, "Init realtime clock\n");
      rtc_init();

      /*
       * Initialize keyboard and mouse.
       */
      DEBUGPRINT(2, "Init keyboard\n");
      kbd_init();
#ifdef CONFIG_MOUSE_SUPPORT
      DEBUGPRINT(2, "Init mouse\n");
      mouse_init();
#endif

      /*
       * Initialize pci devices.
       * If we want to be able to boot from PCI, this has to be
       * done before we scan for PCI expansion ROMs.
       */
#ifdef CONFIG_PCI_SUPPORT      
      DEBUGPRINT(2, "Init PCI devices\n");
      pci_init();
#endif

      /*
       * More operations are handled by the
       * (VGA) cards extension ROM.
       */
      DEBUGPRINT(2, "Init card extension ROMs\n");
      startseg = 0xc000;
      /* FIXME JOSEF: define BIOS-Start symbol */
      /* BIOS start now lower */
      while (startseg < 0xe000) {
            if (get_word(startseg, 0) == 0xAA55) {
                  unsigned short size;

                  call_ext(startseg);

                  /* add size of ROM - byte 2 * 512 */
                  size = get_byte(startseg, 2);
                  /* round up to 2k boundary */
                  if ( size % 4 ) {
                        size += 4 - (size % 4);
                  }
                  startseg += size * 32;
            } else {
                  startseg += 0x80; /* 2k steps */
            }
      }

      /*
       * We're done with scanning for ISA ROMs, now do the same
       * for PCI (VGA only).
       */
#ifdef CONFIG_PCI_SUPPORT      
      DEBUGPRINT(2, "Init PCI extension ROMs\n");
      pci_runexpansionroms(1);
#endif      

#if 0 /* FIXME VOSSI */
      var_put(console_type, VGA_CONSOLE);

      /* check for serial console support */
      if (cmos_ext_get_byte(console) & SERIAL_CONSOLE) {
            var_put(console_type, var_get(console_type) | SERIAL_CONSOLE);
            serial_reset();
      }
#endif

      /*
       * First BIOS screen.
       */
      /* Use text mode 3 (80x25). */
      asm volatile (
            "\tint $0x10\n"
            : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx)
            : "0" ((uint16_t) ((0x00 << 8) | (0x03 << 0))) /* Set Mode 3 */
      );

      /* Load 8x14 font, else our logo looks broken. */
      asm volatile (
            "\tint $0x10\n"
            : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx)
            : "0" ((uint16_t) 0x1111),    /* Load 8x14 Font */
              "1" ((uint16_t) 0)
      );

      DEBUGPRINT(2, "Print BIOS version\n");
      cls();

      gotoxy(0, 24, 0);
      bprintf("Press <Del> to enter setup.");
      gotoxy(0, 0, 0);

      /*
       * Print BIOS version info.
       */
      bprintf("\n");
      bprintf("   FAUmachine BIOS " PACKAGE_VERSION "\n");
      bprintf("   Copyright (C) 2003-2009, University Erlangen-Nuremberg\n");
      bprintf("\n");
      bprintf("\n"); /* FIXME VOSSI */

      bprintf("\n");

      /*
       * Print CPU info.
       */
      DEBUGPRINT(2, "Print found CPUs\n");
#ifndef CONFIG_80286_SUPPORT
      bprintf("PENTIUM CPU at 2.00GHz\n");              /* FIXME VOSSI */
#else
      bprintf("CPU Intel 80286 at 6 MHz\n");            
#endif
      bprintf("<CPU ID:%04x Patch ID:None>\n", 0x1234); /* FIXME VOSSI */

      bprintf("\n");

      /*
       * Print FAUmachine logo.
       */
      DEBUGPRINT(2, "Print BIOS logo\n");

      /* Set font for FAUmachine logo. */
      width = const_get(logo[0]);
      height = const_get(logo[1]);
      ptr = &logo[2 + width * height];

      asm volatile (
            "\tmovw %%di, %%es\n"
            "\txchgw %%si, %%bp\n"
            "\tint $0x10\n"
            "\txchgw %%si, %%bp\n"
            : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx)
            : "0" ((uint16_t) 0x1100),          /* Set Font */
              "1" ((uint16_t) ((14 << 8) | 0x04)),    /* ? */
              "2" ((uint16_t) (width * height)),      /* ? */
              "3" ((uint16_t) 0),
              "D" ((uint16_t) PTR_SEG(ptr)),
              "S" ((uint16_t) PTR_OFF(ptr))
      );

      /* Switch to two-font mode. */
      asm volatile (
            "\tint $0x10\n"
            : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx)
            : "0" ((uint16_t) 0x1103),    /* Switch To Two Font Mode */
              "1" ((uint16_t) (1 << 5))   /* ? */
      );

      assert(width <= 17);
      assert(height <= 9);

      /* Print logo (small). */
      for (y = 0; y < 2; y++) {
            for (x = 0; x < 3; x++) {
                  if (y == 0 && x == 0) {
                        continue;
                  }
                  put_byte(0xb800, (80 + 80 * y + x) * 2 + 0, '@');
                  put_byte(0xb800, (80 + 80 * y + x) * 2 + 1, 0x01); /* blue */
            }
      }

      /* Print logo (big). */
      for (y = 0; y < height; y++) {
            for (x = 0; x < width; x++) {
                  put_byte(0xb800, (80 * y + 80 - width + x) * 2 + 0,
                              y * width + x);
                  put_byte(0xb800, (80 * y + 80 - width + x) * 2 + 1,
                              const_get(logo[2 + y * width + x]));
            }
      }

      /*
       * Print Memory info.
       */
      DEBUGPRINT(2, "Check available memory\n");
      bprintf("Memory Test :        K OK");

      /*
       * Initialize memory.
       */
      mem_init();

      /*
       * PnP BIOS start.
       */
#if 0
      /* FIXME VOSSI */
      bprintf("FAUmachine Plug and Play BIOS Extension v1.0\n");
      bprintf("Copyright (C) 2003-2006, University Erlangen-Nuremberg\n");
#else
      bprintf("\n");
      bprintf("\n");
#endif

      bprintf("\n");

      /*
       * Initialize floppy.
       */
      DEBUGPRINT(2, "Init floppy\n");
      floppy_init();

      /*
       * Initialize disks/cdroms.
       */
      DEBUGPRINT(2, "Init disks and cdroms\n");
      disk_init();

      sleep(2);

      /*
       * Back to normal mode. simplest way is to just let the VGABIOS
       * switch to text mode, that implies switching font and everything.
       */
      asm volatile (
            "\tint $0x10\n"
            : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx)
            : "0" ((uint16_t) 0x0003)     /* Set Mode 3 (80x25) */
      );

      if ((kbd_keyavailable()) && (kbd_getkey(1) == 0x5300)) {
            setup_init();
            /* reset system to get SMRAM/PCI IRQ Routing Registers right */
            kbd_system_reset();
      }

      /*
       * Second BIOS screen.
       */

      /* Print frame. */
      y = 0;
      gotoxy(40 - (sizeof("System Configurations") - 1) / 2, y, 0);
      bprintf("System Configurations");

      y++;

      gotoxy(0, y, 0);
      putchar(201); /*   = */
                    /* ||  */
      for (x = 1; x < 79; x++) {
            putchar(205); /* = */
      }
      putchar(187); /* =   */
                    /*  || */

      y++;

      gotoxy(0, y, 0);
      putchar(186); /* || */

      gotoxy(2, y, 0);
      bprintf("%s", "CPU Type");
      gotoxy(20, y, 0);
      bprintf(":");
      gotoxy(22, y, 0);
#ifndef CONFIG_80286_SUPPORT
      bprintf("%s", "PENTIUM II");  /* FIXME VOSSI */
#else
      bprintf("%s", "80286\n");
#endif

      gotoxy(42, y, 0);
      bprintf("%s", "Base Memory");
      gotoxy(60, y, 0);
      bprintf(":");
      gotoxy(62, y, 0);
      bprintf("%7uK", (uint16_t)var_get(mem_total));

      gotoxy(79, y, 0);
      putchar(186); /* || */

      y++;

      gotoxy(0, y, 0);
      putchar(186); /* || */

      gotoxy(2, y, 0);
      bprintf("%s", "Co-Processor");
      gotoxy(20, y, 0);
      bprintf(":");
      gotoxy(22, y, 0);
#ifndef CONFIG_80286_SUPPORT
      bprintf("%s", "Installed");   /* FIXME VOSSI */
#else
      bprintf("%s", "None\n");
#endif

      gotoxy(42, y, 0);
      bprintf("%s", "Extended Memory");
      gotoxy(60, y, 0);
      bprintf(":");
      gotoxy(62, y, 0);
      mem_extended = var_get(mem_size) / 1024;
      if (mem_extended > 1024)
            mem_extended -= 1024;
      else
            mem_extended = 0;
      bprintf("%7luK", (uint32_t) (mem_extended));

      gotoxy(79, y, 0);
      putchar(186); /* || */

      y++;

      gotoxy(0, y, 0);
      putchar(186); /* || */

      gotoxy(2, y, 0);
      bprintf("%s", "CPU Clock");
      gotoxy(20, y, 0);
      bprintf(":");
      gotoxy(22, y, 0);
#ifndef CONFIG_80286_SUPPORT
      bprintf("%s", "2.00GHz");     /* FIXME VOSSI */
#else
      bprintf("%s", "6 MHz\n");
#endif

      gotoxy(42, y, 0);
      bprintf("%s", "Cache Memory");
      gotoxy(60, y, 0);
      bprintf(":");
      gotoxy(62, y, 0);
      bprintf("%8s", "None"); /* FIXME VOSSI */

      gotoxy(79, y, 0);
      putchar(186); /* || */

      y++;

      gotoxy(0, y, 0);
      putchar(199); /* ||- */
      for (x = 1; x < 79; x++) {
            putchar(196); /* - */
      }
      putchar(182); /* -|| */

      y++;

      gotoxy(0, y, 0);
      putchar(186); /* || */

      gotoxy(2, y, 0);
      bprintf("%s", "Diskette Drive  A");
      gotoxy(20, y, 0);
      bprintf(":");
      gotoxy(22, y, 0);
      bprintf("%s", get_identify_floppy(0));

      gotoxy(42, y, 0);
      bprintf("%s", "Display Type");
      gotoxy(60, y, 0);
      bprintf(":");
      gotoxy(62, y, 0);
      bprintf("%s", "EGA/VGA");     /* FIXME VOSSI */

      gotoxy(79, y, 0);
      putchar(186); /* || */

      y++;

      gotoxy(0, y, 0);
      putchar(186); /* || */

      gotoxy(2, y, 0);
      bprintf("%s", "Diskette Drive  B");
      gotoxy(20, y, 0);
      bprintf(":");
      gotoxy(22, y, 0);
      bprintf("%s", get_identify_floppy(1));

      gotoxy(42, y, 0);
      bprintf("%s", "Serial Port(s)");
      gotoxy(60, y, 0);
      bprintf(":");
      gotoxy(62, y, 0);
      if (var_get(addr_ser[0]) == 0
       && var_get(addr_ser[1]) == 0
       && var_get(addr_ser[2]) == 0
       && var_get(addr_ser[3]) == 0) {
            bprintf("None");
      } else {
            for (n = 0; n < 4; n++) {
                  if (var_get(addr_ser[n]) != 0) {
                        bprintf("%03X ", var_get(addr_ser[n]));
                  }
            }
      }

      gotoxy(79, y, 0);
      putchar(186); /* || */

      y++;

      gotoxy(0, y, 0);
      putchar(186); /* || */

      gotoxy(2, y, 0);
      bprintf("%s", "Pri. Master  Disk");
      gotoxy(20, y, 0);
      bprintf(":");
      gotoxy(22, y, 0);
      bprintf("%s", "XXX");   /* FIXME VOSSI */

      gotoxy(42, y, 0);
      bprintf("%s", "Parallel Port(s)");
      gotoxy(60, y, 0);
      bprintf(":");
      gotoxy(62, y, 0);
      if (var_get(addr_par[0]) == 0
       && var_get(addr_par[1]) == 0
       && var_get(addr_par[2]) == 0) {
            bprintf("None");
      } else {
            for (n = 0; n < 3; n++) {
                  if (var_get(addr_par[n]) != 0) {
                        bprintf("%03X ", var_get(addr_par[n]));
                  }
            }
      }

      gotoxy(79, y, 0);
      putchar(186); /* || */

      y++;

      gotoxy(0, y, 0);
      putchar(186); /* || */

      gotoxy(2, y, 0);
      bprintf("%s", "Pri. Slave   Disk");
      gotoxy(20, y, 0);
      bprintf(":");
      gotoxy(22, y, 0);
      bprintf("%s", "XXX");   /* FIXME VOSSI */

      gotoxy(42, y, 0);
      bprintf("%s", "EDO DRAM at Row(s)");
      gotoxy(60, y, 0);
      bprintf(":");
      gotoxy(62, y, 0);
      /* FIXME VOSSI */

      gotoxy(79, y, 0);
      putchar(186); /* || */

      y++;

      gotoxy(0, y, 0);
      putchar(186); /* || */

      gotoxy(2, y, 0);
      bprintf("%s", "Sec. Master  Disk");
      gotoxy(20, y, 0);
      bprintf(":");
      gotoxy(22, y, 0);
      bprintf("%s", "XXX");   /* FIXME VOSSI */

      gotoxy(79, y, 0);
      putchar(186); /* || */

      y++;

      gotoxy(0, y, 0);
      putchar(186); /* || */

      gotoxy(2, y, 0);
      bprintf("%s", "Sec. Slave   Disk");
      gotoxy(20, y, 0);
      bprintf(":");
      gotoxy(22, y, 0);
      bprintf("%s", "XXX");   /* FIXME VOSSI */

      gotoxy(79, y, 0);
      putchar(186); /* || */

      y++;

      gotoxy(0, y, 0);
      putchar(200); /* ||  */
                    /*   = */
      for (x = 1; x < 79; x++) {
            putchar(205); /* = */
      }
      putchar(188); /*  || */
                    /* =   */

      /* serial_init(); */    /* FIXME VOSSI */
      DEBUGPRINT(2, "Init parallel port\n");
      parallel_init();

      bprintf("\n");

      /*
       * Print S.M.A.R.T. info.
       */
      /* FIXME VOSSI */

      /*
       * Initialize PCI Option ROMs (Non-VGA only)
       */
#ifdef CONFIG_PCI_SUPPORT      
      DEBUGPRINT(2, "Init PCI extension ROMs\n");
      pci_runexpansionroms(0);
#endif      

      bprintf("\n");
#ifdef CONFIG_PCI_SUPPORT
      /*
       * Print PCI info.
       */
      DEBUGPRINT(2, "Print PCI devices\n");
      bprintf("PCI device listing ...\n");
      pci_listdevices("");
#endif
      sleep(2);

#ifdef CONFIG_ACPI_SUPPORT
      /*
       * Initialize and copy ACPI tables.
       */
      acpi_tables_init();
#endif

      cmos_exit();
    }
}

#endif /* INIT_RM */

Generated by  Doxygen 1.6.0   Back to index