⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rombios.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 5 页
字号:
void uart_tx_byte(base_port, data)    Bit16u base_port;    Bit8u data;{    uart_wait_to_tx_byte(base_port);    outb(base_port + UART_THR, data);    uart_wait_until_sent(base_port);}#endif  voidwrch(c)  Bit8u  c;{  ASM_START  push bp  mov  bp, sp  push bx  mov  ah, #0x0e  mov  al, 4[bp]  xor  bx,bx  int  #0x10  pop  bx  pop  bp  ASM_END}   voidsend(action, c)  Bit16u action;  Bit8u  c;{#if BX_DEBUG_SERIAL  if (c == '\n') uart_tx_byte(BX_DEBUG_PORT, '\r');  uart_tx_byte(BX_DEBUG_PORT, c);#endif#ifdef HVMASSIST  outb(0xE9, c);#endif#if BX_VIRTUAL_PORTS  if (action & BIOS_PRINTF_DEBUG) outb(DEBUG_PORT, c);  if (action & BIOS_PRINTF_INFO) outb(INFO_PORT, c);#endif  if (action & BIOS_PRINTF_SCREEN) {    if (c == '\n') wrch('\r');    wrch(c);  }}  voidput_int(action, val, width, neg)  Bit16u action;  short val, width;  bx_bool neg;{  short nval = val / 10;  if (nval)    put_int(action, nval, width - 1, neg);  else {    while (--width > 0) send(action, ' ');    if (neg) send(action, '-');  }  send(action, val - (nval * 10) + '0');}  voidput_uint(action, val, width, neg)  Bit16u action;  unsigned short val;  short width;  bx_bool neg;{  unsigned short nval = val / 10;  if (nval)    put_uint(action, nval, width - 1, neg);  else {    while (--width > 0) send(action, ' ');    if (neg) send(action, '-');  }  send(action, val - (nval * 10) + '0');}//--------------------------------------------------------------------------// bios_printf()//   A compact variable argument printf function which prints its output via//   an I/O port so that it can be logged by Bochs/Plex.  //   Currently, only %x is supported (or %02x, %04x, etc).////   Supports %[format_width][format]//   where format can be d,x,c,s//--------------------------------------------------------------------------  voidbios_printf(action, s)  Bit16u action;  Bit8u *s;{  Bit8u c, format_char;  bx_bool  in_format;  short i;  Bit16u  *arg_ptr;  Bit16u   arg_seg, arg, nibble, shift_count, format_width;  arg_ptr = &s;  arg_seg = get_SS();  in_format = 0;  format_width = 0;  if ((action & BIOS_PRINTF_DEBHALT) == BIOS_PRINTF_DEBHALT) {#if BX_VIRTUAL_PORTS    outb(PANIC_PORT2, 0x00);#endif    bios_printf (BIOS_PRINTF_SCREEN, "FATAL: ");  }  while (c = read_byte(get_CS(), s)) {    if ( c == '%' ) {      in_format = 1;      format_width = 0;      }    else if (in_format) {      if ( (c>='0') && (c<='9') ) {        format_width = (format_width * 10) + (c - '0');        }      else {        arg_ptr++; // increment to next arg        arg = read_word(arg_seg, arg_ptr);        if (c == 'x') {          if (format_width == 0)            format_width = 4;          for (i=format_width-1; i>=0; i--) {            nibble = (arg >> (4 * i)) & 0x000f;            send (action, (nibble<=9)? (nibble+'0') : (nibble-10+'A'));            }          }        else if (c == 'u') {          put_uint(action, arg, format_width, 0);          }        else if (c == 'd') {          if (arg & 0x8000)            put_int(action, -arg, format_width - 1, 1);          else            put_int(action, arg, format_width, 0);          }        else if (c == 's') {          bios_printf(action & (~BIOS_PRINTF_HALT), arg);          }        else if (c == 'c') {          send(action, arg);          }        else          BX_PANIC("bios_printf: unknown format\n");          in_format = 0;        }      }    else {      send(action, c);      }    s ++;    }  if (action & BIOS_PRINTF_HALT) {    // freeze in a busy loop.  ASM_START    cli halt2_loop:    hlt    jmp halt2_loopASM_END    }}//--------------------------------------------------------------------------// keyboard_init//--------------------------------------------------------------------------// this file is based on LinuxBIOS implementation of keyboard.c// could convert to #asm to gain space  voidkeyboard_init(){    Bit16u max;    /* ------------------- Flush buffers ------------------------*/    /* Wait until buffer is empty */    max=0xffff;    while ( (inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x00);    /* flush incoming keys */    max=0x2000;    while (--max > 0) {        outb(0x80, 0x00);        if (inb(0x64) & 0x01) {            inb(0x60);            max = 0x2000;            }        }      // Due to timer issues, and if the IPS setting is > 15000000,     // the incoming keys might not be flushed here. That will    // cause a panic a few lines below.  See sourceforge bug report :    // [ 642031 ] FATAL: Keyboard RESET error:993    /* ------------------- controller side ----------------------*/    /* send cmd = 0xAA, self test 8042 */    outb(0x64, 0xaa);    /* Wait until buffer is empty */    max=0xffff;    while ( (inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x00);    if (max==0x0) keyboard_panic(00);    /* Wait for data */    max=0xffff;    while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x01);    if (max==0x0) keyboard_panic(01);    /* read self-test result, 0x55 should be returned from 0x60 */    if ((inb(0x60) != 0x55)){        keyboard_panic(991);    }    /* send cmd = 0xAB, keyboard interface test */    outb(0x64,0xab);    /* Wait until buffer is empty */    max=0xffff;    while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x10);    if (max==0x0) keyboard_panic(10);    /* Wait for data */    max=0xffff;    while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x11);    if (max==0x0) keyboard_panic(11);    /* read keyboard interface test result, */    /* 0x00 should be returned form 0x60 */    if ((inb(0x60) != 0x00)) {        keyboard_panic(992);    }    /* Enable Keyboard clock */    outb(0x64,0xae);    outb(0x64,0xa8);    /* ------------------- keyboard side ------------------------*/    /* reset kerboard and self test  (keyboard side) */    outb(0x60, 0xff);    /* Wait until buffer is empty */    max=0xffff;    while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x20);    if (max==0x0) keyboard_panic(20);    /* Wait for data */    max=0xffff;    while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x21);    if (max==0x0) keyboard_panic(21);    /* keyboard should return ACK */    if ((inb(0x60) != 0xfa)) {        keyboard_panic(993);    }    /* Wait for data */    max=0xffff;    while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x31);    if (max==0x0) keyboard_panic(31);    if ((inb(0x60) != 0xaa)) {        keyboard_panic(994);    }    /* Disable keyboard */    outb(0x60, 0xf5);    /* Wait until buffer is empty */    max=0xffff;    while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x40);    if (max==0x0) keyboard_panic(40);    /* Wait for data */    max=0xffff;    while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x41);    if (max==0x0) keyboard_panic(41);    /* keyboard should return ACK */    if ((inb(0x60) != 0xfa)) {        keyboard_panic(995);    }    /* Write Keyboard Mode */    outb(0x64, 0x60);    /* Wait until buffer is empty */    max=0xffff;    while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x50);    if (max==0x0) keyboard_panic(50);    /* send cmd: scan code convert, disable mouse, enable IRQ 1 */    outb(0x60, 0x61);    /* Wait until buffer is empty */    max=0xffff;    while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x60);    if (max==0x0) keyboard_panic(60);    /* Enable keyboard */    outb(0x60, 0xf4);    /* Wait until buffer is empty */    max=0xffff;    while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x70);    if (max==0x0) keyboard_panic(70);    /* Wait for data */    max=0xffff;    while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x71);    if (max==0x0) keyboard_panic(70);    /* keyboard should return ACK */    if ((inb(0x60) != 0xfa)) {        keyboard_panic(996);    }    outb(0x80, 0x77);}//--------------------------------------------------------------------------// keyboard_panic//--------------------------------------------------------------------------  voidkeyboard_panic(status)  Bit16u status;{  // If you're getting a 993 keyboard panic here,   // please see the comment in keyboard_init    BX_PANIC("Keyboard error:%u\n",status);}#define CMOS_SHUTDOWN_S3 0xFE//--------------------------------------------------------------------------// machine_reset//--------------------------------------------------------------------------  voidmachine_reset(){ASM_START;we must check whether CMOS_SHUTDOWN_S3 is set or not;if it is s3 resume, just jmp back to normal Post Entry;below port io will prevent s3 resume  mov al, #0x0f  out 0x70, al  in al, 0x71  cmp al, #0xFE  jz postASM_END  /* Frob the keyboard reset line to reset the processor */  outb(0x64, 0x60); /* Map the flags register at data port (0x60) */  outb(0x60, 0x14); /* Set the flags to system|disable */  outb(0x64, 0xfe); /* Pulse output 0 (system reset) low */  BX_PANIC("Couldn't reset the machine\n");}//--------------------------------------------------------------------------// clobber_entry_point//    Because PV drivers in HVM guests detach some of the emulated devices, //    it is not safe to do a soft reboot by just dropping to real mode and//    jumping at ffff:0000. -- the boot drives might have disappeared!//    This rather foul function overwrites(!) the BIOS entry point //    to point at machine-reset, which will cause the Xen tools to//    rebuild the whole machine from scratch.//--------------------------------------------------------------------------  void clobber_entry_point() {    /* The instruction at the entry point is one byte (0xea) for the     * jump opcode, then two bytes of address, then two of segment.      * Overwrite the address bytes.*/    write_word(0xffff, 0x0001, machine_reset); }//--------------------------------------------------------------------------// shutdown_status_panic//   called when the shutdown statsu is not implemented, displays the status//--------------------------------------------------------------------------  voidshutdown_status_panic(status)  Bit16u status;{  BX_PANIC("Unimplemented shutdown status: %02x\n",(Bit8u)status);}//--------------------------------------------------------------------------// print_bios_banner//   displays a the bios version//--------------------------------------------------------------------------voidprint_bios_banner(){  printf(BX_APPNAME" BIOS, %d cpu%s, ", BX_SMP_PROCESSORS, BX_SMP_PROCESSORS>1?"s":"");  printf("%s %s\n", bios_cvs_version_string, bios_date_string);#if BX_TCGBIOS  printf("TCG-enabled BIOS.\n");#endif  printf("\n");}//--------------------------------------------------------------------------// BIOS Boot Specification 1.0.1 compatibility//// Very basic support for the BIOS Boot Specification, which allows expansion // ROMs to register themselves as boot devices, instead of just stealing the // INT 19h boot vector.// // This is a hack: to do it properly requires a proper PnP BIOS and we aren't// one; we just lie to the option ROMs to make them behave correctly. // We also don't support letting option ROMs register as bootable disk // drives (BCVs), only as bootable devices (BEVs). //// http://www.phoenix.com/en/Customer+Services/White+Papers-Specs/pc+industry+specifications.htm//--------------------------------------------------------------------------/* 256 bytes at 0x9ff00 -- 0x9ffff is used for the IPL boot table. */#define IPL_SEG              0x9ff0#define IPL_TABLE_OFFSET     0x0000#define IPL_TABLE_ENTRIES    8#define IPL_COUNT_OFFSET     0x0080  /* u16: number of valid table entries */#define IPL_SEQUENCE_OFFSET  0x0082  /* u16: next boot device */struct ipl_entry {  Bit16u type;  Bit16u flags;  Bit32u vector;  Bit32u description;  Bit32u reserved;};static void init_boot_vectors() {  struct ipl_entry e;   Bit16u count = 0;  Bit16u ss = get_SS();  /* Clear out the IPL table. */  memsetb(IPL_SEG, IPL_TABLE_OFFSET, 0, 0xff);  /* Floppy drive */  e.type = 1; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;  memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));  count++;  /* First HDD */  e.type = 2; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;  memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));  count++;#if BX_ELTORITO_BOOT  /* CDROM */  e.type = 3; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;  memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));  count++;#endif    /* Remember how many devices we have */  write_word(IPL_SEG, IPL_COUNT_OFFSET, count);  /* Not tried booting anything yet */  write_word(IPL_SEG, IPL_SEQUENCE_OFFSET, 0xffff);}static Bit8uget_boot_vector(i, e)Bit16u i; struct ipl_entry *e; {  Bit16u count;  Bit16u ss = get_SS();  /* Get the count of boot devices, and refuse to overrun the array */  count = read_word(IPL_SEG, IPL_COUNT_OFFSET);  if (i >= count) return 0;  /* OK to read this device */  memcpyb(ss, e, IPL_SEG, IPL_TABLE_OFFSET + i * sizeof (*e), sizeof (*e));  return 1;}//--------------------------------------------------------------------------// print_boot_device//   displays the boot device//--------------------------------------------------------------------------static char drivetypes[][10]={"", "Floppy","Hard Disk","CD-Rom", "Network"};voidprint_boot_device(type)  Bit16u type;{  /* NIC appears as type 0x80 */   if (type == 0x80 ) type = 0x4;  if (type == 0 || type > 0x4) BX_PANIC("Bad drive type\n");   printf("Booting from %s...\n", drivetypes[type]);}//--------------------------------------------------------------------------// print_boot_failure//   displays the reason why boot failed

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -