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

📄 smp-imps.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  GRUB  --  GRand Unified Bootloader *  Copyright (C) 1999  Free Software Foundation, Inc. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* *  <Insert copyright here : it must be BSD-like so anyone can use it> * *  Author:  Erich Boleyn  <erich@uruk.org>   http://www.uruk.org/~erich/ * *  Source file implementing Intel MultiProcessor Specification (MPS) *  version 1.1 and 1.4 SMP hardware control for Intel Architecture CPUs, *  with hooks for running correctly on a standard PC without the hardware. * *  This file was created from information in the Intel MPS version 1.4 *  document, order number 242016-004, which can be ordered from the *  Intel literature center. * *  General limitations of this code: * *   (1) : This code has never been tested on an MPS-compatible system with *           486 CPUs, but is expected to work. *   (2) : Presumes "int", "long", and "unsigned" are 32 bits in size, and *	     that 32-bit pointers and memory addressing is used uniformly. */#define _SMP_IMPS_C/* *  XXXXX  The following absolutely must be defined!!! * *  The "KERNEL_PRINT" could be made a null macro with no danger, of *  course, but pretty much nothing would work without the other *  ones defined. */#if 0#define KERNEL_PRINT(x)		/* some kind of print function */#define CMOS_WRITE_BYTE(x,y)	/* write unsigned char "y" at CMOS loc "x" */#define CMOS_READ_BYTE(x)	/* read unsigned char at CMOS loc "x" */#define PHYS_TO_VIRTUAL(x)	/* convert physical address "x" to virtual */#define VIRTUAL_TO_PHYS(x)	/* convert virtual address "x" to physical */#endif/* *  This is the Intel MultiProcessor Spec debugging/display code. */#define IMPS_DEBUG#define KERNEL_PRINT(x)         printf x#define CMOS_WRITE_BYTE(x, y)	cmos_write_byte(x, y)#define CMOS_READ_BYTE(x)	cmos_read_byte(x)#define PHYS_TO_VIRTUAL(x)	(x)#define VIRTUAL_TO_PHYS(x)	(x)static inline unsigned charinb (unsigned short port){  unsigned char data;  __asm __volatile ("inb %1,%0" :"=a" (data):"d" (port));  return data;}static inline voidoutb (unsigned short port, unsigned char val){  __asm __volatile ("outb %0,%1"::"a" (val), "d" (port));}static inline voidcmos_write_byte (int loc, int val){  outb (0x70, loc);  outb (0x71, val);}static inline unsignedcmos_read_byte (int loc){  outb (0x70, loc);  return inb (0x71);}/* *  Includes here */#include "shared.h"#include "apic.h"#include "smp-imps.h"/* *  Defines that are here so as not to be in the global header file. */#define EBDA_SEG_ADDR			0x40E#define BIOS_RESET_VECTOR		0x467#define LAPIC_ADDR_DEFAULT		0xFEE00000uL#define IOAPIC_ADDR_DEFAULT		0xFEC00000uL#define CMOS_RESET_CODE			0xF#define		CMOS_RESET_JUMP		0xa#define CMOS_BASE_MEMORY		0x15/* *  Static defines here for SMP use. */#define DEF_ENTRIES	23static int lapic_dummy = 0;static struct  {    imps_processor proc[2];    imps_bus bus[2];    imps_ioapic ioapic;    imps_interrupt intin[16];    imps_interrupt lintin[2];  }defconfig ={  {    {      IMPS_BCT_PROCESSOR, 0, 0, 0, 0, 0    }    ,    {      IMPS_BCT_PROCESSOR, 1, 0, 0, 0, 0    }  }  ,  {    {      IMPS_BCT_BUS, 0,      {	'E', 'I', 'S', 'A', ' ', ' '      }    }    ,    {      255, 1,      {	'P', 'C', 'I', ' ', ' ', ' '      }    }  }  ,  {    IMPS_BCT_IOAPIC, 0, 0, IMPS_FLAG_ENABLED, IOAPIC_ADDR_DEFAULT  }  ,  {    {      IMPS_BCT_IO_INTERRUPT, IMPS_INT_EXTINT, 0, 0, 0, 0xFF, 0    }    ,    {      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 1, 0xFF, 1    }    ,    {      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 0, 0xFF, 2    }    ,    {      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 3, 0xFF, 3    }    ,    {      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 4, 0xFF, 4    }    ,    {      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 5, 0xFF, 5    }    ,    {      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 6, 0xFF, 6    }    ,    {      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 7, 0xFF, 7    }    ,    {      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 8, 0xFF, 8    }    ,    {      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 9, 0xFF, 9    }    ,    {      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 10, 0xFF, 10    }    ,    {      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 11, 0xFF, 11    }    ,    {      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 12, 0xFF, 12    }    ,    {      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 13, 0xFF, 13    }    ,    {      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 14, 0xFF, 14    }    ,    {      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 15, 0xFF, 15    }  }  ,  {    {      IMPS_BCT_LOCAL_INTERRUPT, IMPS_INT_EXTINT, 0, 0, 15, 0xFF, 0    }    ,    {      IMPS_BCT_LOCAL_INTERRUPT, IMPS_INT_NMI, 0, 0, 15, 0xFF, 1    }  }};/* *  Exported globals here. */static int imps_any_new_apics = 0;#if 0volatile int imps_release_cpus = 0;#endifstatic int imps_enabled = 0;static int imps_num_cpus = 1;static unsigned imps_lapic_addr = ((unsigned) (&lapic_dummy)) - LAPIC_ID;static unsigned char imps_cpu_apic_map[IMPS_MAX_CPUS];static unsigned char imps_apic_cpu_map[IMPS_MAX_CPUS];/* *  MPS checksum function * *  Function finished. */static intget_checksum (unsigned start, int length){  unsigned sum = 0;  while (length-- > 0)    {      sum += *((unsigned char *) (start++));    }  return (sum & 0xFF);}/* *  Primary function for booting individual CPUs. * *  This must be modified to perform whatever OS-specific initialization *  that is required. */static intboot_cpu (imps_processor * proc){  unsigned bootaddr, accept_status;  unsigned bios_reset_vector = PHYS_TO_VIRTUAL (BIOS_RESET_VECTOR);  /* %%%%% ESB */  extern char patch_code[];  bootaddr = 256 * 1024;  memmove ((char *) bootaddr, patch_code, 32);  /*   *  Generic CPU startup sequence starts here.   */  /* set BIOS reset vector */  CMOS_WRITE_BYTE (CMOS_RESET_CODE, CMOS_RESET_JUMP);  *((volatile unsigned *) bios_reset_vector) = bootaddr << 12;  /* clear the error register */  if (proc->apic_ver & 0x10)    {      IMPS_LAPIC_WRITE (LAPIC_ESR, 0);      accept_status = IMPS_LAPIC_READ (LAPIC_ESR);    }#if 0  /* assert INIT IPI */  cfg = IMPS_LAPIC_READ (LAPIC_ICR + 1);  cfg &= LAPIC_DEST_MASK;  IMPS_LAPIC_WRITE (LAPIC_ICR + 1, cfg);  cfg = IMPS_LAPIC_READ (LAPIC_ACR);  cfg &=;  /* %%%%% ESB finish adding startup sequence */#endif  /* clean up BIOS reset vector */  CMOS_WRITE_BYTE (CMOS_RESET_CODE, 0);  *((volatile unsigned *) bios_reset_vector) = 0;  /*   *  Generic CPU startup sequence ends here.   */  KERNEL_PRINT (("\n"));  return 1;  /* XXXXX add OS-specific initialization here! */}/* *  read bios stuff and fill tables */static voidadd_processor (imps_processor * proc){  int apicid = proc->apic_id;  KERNEL_PRINT (("  Processor [APIC id %d ver %d]:  ",		 apicid, proc->apic_ver));  if (!(proc->flags & IMPS_FLAG_ENABLED))    {      KERNEL_PRINT (("DISABLED\n"));      return;    }  if (proc->apic_ver > 0xF)    {      imps_any_new_apics = 1;    }  if (proc->flags & (IMPS_CPUFLAG_BOOT))    {      KERNEL_PRINT (("#0  Bootstrap Processor (BSP)\n"));      return;    }  imps_cpu_apic_map[imps_num_cpus] = apicid;  imps_apic_cpu_map[apicid] = imps_num_cpus;  if (boot_cpu (proc))

⌨️ 快捷键说明

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