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

📄 pcmb_smp.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 3 页
字号:
//==========================================================================////      pcmb_smp.c////      HAL SMP implementation////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// eCos 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 or (at your option) any later version.//// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):    nickg// Contributors: nickg// Date:         2001-08-03// Purpose:      HAL SMP implementation// Description:  This file contains SMP support functions.////####DESCRIPTIONEND####////========================================================================*/#include <pkgconf/hal.h>#include <pkgconf/hal_i386.h>#include <pkgconf/hal_i386_pcmb.h>#ifdef CYGPKG_HAL_SMP_SUPPORT#ifdef CYGPKG_KERNEL#include <pkgconf/kernel.h>#endif#include <cyg/infra/cyg_type.h>         // Base types#include <cyg/infra/cyg_trac.h>         // tracing macros#include <cyg/infra/cyg_ass.h>          // assertion macros#include <cyg/infra/diag.h>#include <cyg/hal/hal_intr.h>#include <cyg/hal/hal_io.h>#include <cyg/hal/hal_smp.h>// ------------------------------------------------------------------------// Debugging/diagnostic controls// Setting this to 1 causes the parsing of the MP structures and the// initialization of the APIC and IOAPIC to be reported on the// diagnostic channel.#define SHOW_DIAGNOSTICS 0// Setting this to 1 causes various things to be displayed on the PC// screen during normal operation. These are mostly for my own use,// and may be somewhat obscure to anyone else.#define SCREEN_DIAGNOSTICS 0#if SCREEN_DIAGNOSTICS==0#undef PC_WRITE_SCREEN#undef PC_WRITE_SCREEN_8#undef PC_WRITE_SCREEN_16#undef PC_WRITE_SCREEN_32#define PC_WRITE_SCREEN( pos, ch )#define PC_WRITE_SCREEN_8( pos, val )#define PC_WRITE_SCREEN_16( pos, val )#define PC_WRITE_SCREEN_32( pos, val )#endif// ------------------------------------------------------------------------static int streq( const char *s1, const char *s2 ){    while( *s1 == *s2 && *s1 && *s2 ) s1++,s2++;    return !(*s2-*s1);}/*------------------------------------------------------------------------*/// MP FPS structure:#define MP_FPS_SIGNATURE         0#define MP_FPS_MPCT              4#define MP_FPS_LENGTH            8#define MP_FPS_REV               9#define MP_FPS_CSUM             10#define MP_FPS_FEATURE1         11#define MP_FPS_FEATURE2         12#define MP_FPS_FEATURE3         13#define MP_FPS_FEATURE4         14#define MP_FPS_FEATURE5         15#define MP_FPS_SIZE             16#define MP_FPS_SIGNATURE_VALUE  0x5f504d5f/*------------------------------------------------------------------------*/// MP config table structure// Header structure:#define MPCT_HDR_SIGNATURE      0#define MPCT_HDR_LENGTH         4#define MPCT_HDR_REV            6#define MPCT_HDR_CHECKSUM       7#define MPCT_HDR_OEM_ID         8#define MPCT_HDR_PROD_ID        16#define MPCT_HDR_OEM_TAB        28#define MPCT_HDR_OEM_TAB_SIZE   32#define MPCT_HDR_ENTRY_COUNT    34#define MPCT_HDR_LOCAL_APIC     36#define MPCT_HDR_XTAB_LENGTH    40#define MPCT_HDR_XTAB_CHECKSUM  42#define MPCT_HDR_SIZE           44#define MPCT_HDR_SIGNATURE_VAL  0x504d4350#define MPCT_ENTRY_TYPE_PROCESSOR       0#define MPCT_ENTRY_TYPE_BUS             1#define MPCT_ENTRY_TYPE_IOAPIC          2#define MPCT_ENTRY_TYPE_INTERRUPT_IO    3#define MPCT_ENTRY_TYPE_INTERRUPT_LOCAL 4#define MPCT_ENTRY_PROC_TYPE            0#define MPCT_ENTRY_PROC_APIC_ID         1#define MPCT_ENTRY_PROC_APIC_VER        2#define MPCT_ENTRY_PROC_CPU_FLAGS       3#define MPCT_ENTRY_PROC_CPU_SIGNATURE   4#define MPCT_ENTRY_PROC_FEATURE_FLAGS   8#define MPCT_ENTRY_PROC_RESERVED0       12#define MPCT_ENTRY_PROC_RESERVED1       16#define MPCT_ENTRY_PROC_SIZE            20#define MPCT_ENTRY_BUS_TYPE             0#define MPCT_ENTRY_BUS_ID               1#define MPCT_ENTRY_BUS_TYPE_STRING      2#define MPCT_ENTRY_BUS_SIZE             8#define MPCT_ENTRY_IOAPIC_TYPE          0#define MPCT_ENTRY_IOAPIC_ID            1#define MPCT_ENTRY_IOAPIC_VER           2#define MPCT_ENTRY_IOAPIC_FLAGS         3#define MPCT_ENTRY_IOAPIC_ADDRESS       4#define MPCT_ENTRY_IOAPIC_SIZE          8#define MPCT_ENTRY_IOINT_TYPE           0#define MPCT_ENTRY_IOINT_INT_TYPE       1#define MPCT_ENTRY_IOINT_FLAGS          2#define MPCT_ENTRY_IOINT_SOURCE_BUS     4#define MPCT_ENTRY_IOINT_SOURCE_IRQ     5#define MPCT_ENTRY_IOINT_DEST_APIC      6#define MPCT_ENTRY_IOINT_DEST_INT       7#define MPCT_ENTRY_IOINT_SIZE           8#define MPCT_ENTRY_LOCINT_TYPE          0#define MPCT_ENTRY_LOCINT_INT_TYPE      1#define MPCT_ENTRY_LOCINT_FLAGS         2#define MPCT_ENTRY_LOCINT_SOURCE_BUS    4#define MPCT_ENTRY_LOCINT_SOURCE_IRQ    5#define MPCT_ENTRY_LOCINT_DEST_APIC     6#define MPCT_ENTRY_LOCINT_DEST_INT      7#define MPCT_ENTRY_LOCINT_SIZE          8/*------------------------------------------------------------------------*/// Exported SMP configurationCYG_ADDRESS cyg_hal_smp_local_apic;CYG_ADDRESS cyg_hal_smp_io_apic;CYG_WORD32 cyg_hal_smp_cpu_count = 0;CYG_BYTE cyg_hal_smp_cpu_flags[HAL_SMP_CPU_MAX];CYG_BYTE cyg_hal_isa_bus_id = 0xff;CYG_BYTE cyg_hal_isa_bus_irq[16];CYG_BYTE cyg_hal_pci_bus_id = 0xff;CYG_BYTE cyg_hal_pci_bus_irq[4];HAL_SPINLOCK_TYPE cyg_hal_ioapic_lock;/*------------------------------------------------------------------------*/// Staticsstatic CYG_ADDRESS     mp_fps;static CYG_ADDRESS     mpct;/*------------------------------------------------------------------------*/static CYG_WORD32 mp_checksum(CYG_BYTE *p, CYG_WORD32 len){	CYG_WORD32 sum = 0;	while (len--) sum += *p++;	return sum & 0xFF;}/*------------------------------------------------------------------------*/static cyg_bool cyg_hal_scan_smp_config( CYG_ADDRESS base, CYG_ADDRWORD size ){#if SHOW_DIAGNOSTICS                            diag_printf("Scan for MP struct: %08x..%08x\n",base,base+size);#endif            while( size > 0 )    {        CYG_WORD32 sig;        HAL_READMEM_UINT32( base, sig );                if( sig == MP_FPS_SIGNATURE_VALUE )        {            CYG_BYTE val8;            // We have a candidate for the floating structure#if SHOW_DIAGNOSTICS                                            diag_printf("MP_FPS candidate found at %08x\n",base);#endif             HAL_READMEM_UINT8( base+MP_FPS_LENGTH, val8 );            if( val8 != 1 )                break;            HAL_READMEM_UINT8( base+MP_FPS_REV, val8 );            if( val8 != 1 && val8 != 4 )                break;            if( mp_checksum( (CYG_BYTE *)base, MP_FPS_SIZE ) != 0 )                break;            mp_fps = base;            HAL_READMEM_UINT32( base+MP_FPS_MPCT, mpct );#if SHOW_DIAGNOSTICS                                            diag_printf("MPCT at %08x\n",mpct);#endif            return 1;         }        base += 16;        size -= 16;    }    return 0;}/*------------------------------------------------------------------------*/static cyg_bool cyg_hal_find_smp_config( void ){    // check bottom 1k    if( cyg_hal_scan_smp_config(0x00000, 0x00400 ) )        return 1;    // check top 1k of RAM    if( cyg_hal_scan_smp_config(0x9fc00, 0x00400 ) )        return 1;    // check BIOS ROM    if( cyg_hal_scan_smp_config(0xf0000, 0x10000 ) )        return 1;    }/*------------------------------------------------------------------------*/static cyg_bool cyg_hal_parse_smp_config( void ){    CYG_WORD32 val32;    CYG_WORD16 val16;    CYG_BYTE val8;    int i;    #if SHOW_DIAGNOSTICS    {                diag_printf("FPS address:         %08x\n",mp_fps);        HAL_READMEM_UINT32( mp_fps+MP_FPS_SIGNATURE, val32);        diag_printf("FPS signature:       %08x\n",val32);        HAL_READMEM_UINT32( mp_fps+MP_FPS_MPCT, val32);        diag_printf("FPS MPCT address:    %08x\n",val32);        HAL_READMEM_UINT8( mp_fps+MP_FPS_LENGTH, val8);        diag_printf("FPS length:          %02x\n",val8);        HAL_READMEM_UINT8( mp_fps+MP_FPS_REV, val8);        diag_printf("FPS spec rev:        %02x\n",val8);        HAL_READMEM_UINT8( mp_fps+MP_FPS_CSUM, val8);        diag_printf("FPS checksum:        %02x\n",val8);        for( i = 0; i < 5; i++ )        {            HAL_READMEM_UINT8( mp_fps+MP_FPS_FEATURE1, val8);            diag_printf("FPS feature byte %d:  %02x\n",i,val8);        }    }#endif        if( mpct )    {        HAL_READMEM_UINT32( mpct+MPCT_HDR_SIGNATURE, val32);        if( val32 != MPCT_HDR_SIGNATURE_VAL )            return 0;        HAL_READMEM_UINT16( mpct+MPCT_HDR_LENGTH, val16);        if( mp_checksum( (CYG_BYTE *)mpct, val16 ) != 0 )            return 0;        #if SHOW_DIAGNOSTICS        {            char id[13];            diag_printf("MPCT address:                 %08x\n",mpct);            HAL_READMEM_UINT32( mpct+MPCT_HDR_SIGNATURE, val32);            diag_printf("MPCT signature:               %08x\n",val32);            HAL_READMEM_UINT16( mpct+MPCT_HDR_LENGTH, val16);            diag_printf("MPCT length:                  %04x\n",val16);            HAL_READMEM_UINT8( mpct+MPCT_HDR_REV, val8);            diag_printf("MPCT spec rev:                %02x\n",val8);            HAL_READMEM_UINT8( mpct+MPCT_HDR_CHECKSUM, val8);            diag_printf("MPCT checksum:                %02x\n",val8);            for( i = 0; i < 8; i++ )            {                HAL_READMEM_UINT8( mpct+MPCT_HDR_OEM_ID+i, val8);                id[i] = val8;            }            id[i] = 0;            diag_printf("MPCT OEM Id:                  %s\n",id);                    for( i = 0; i < 12; i++ )            {                HAL_READMEM_UINT8( mpct+MPCT_HDR_PROD_ID+i, val8);                id[i] = val8;            }            id[i] = 0;            diag_printf("MPCT Product Id:              %s\n",id);            HAL_READMEM_UINT32( mpct+MPCT_HDR_OEM_TAB, val32);            diag_printf("MPCT OEM table:               %08x\n",val32);            HAL_READMEM_UINT16( mpct+MPCT_HDR_OEM_TAB_SIZE, val16);            diag_printf("MPCT OEM table size:          %04x\n",val16);            HAL_READMEM_UINT16( mpct+MPCT_HDR_ENTRY_COUNT, val16);            diag_printf("MPCT entry count:             %04x\n",val16);            HAL_READMEM_UINT32( mpct+MPCT_HDR_LOCAL_APIC, val32);            diag_printf("MPCT local APIC:              %08x\n",val32);            HAL_READMEM_UINT16( mpct+MPCT_HDR_XTAB_LENGTH, val16);            diag_printf("MPCT extended table length:   %04x\n",val16);            HAL_READMEM_UINT8( mpct+MPCT_HDR_XTAB_CHECKSUM, val8);            diag_printf("MPCT extended table checksum: %02x\n",val8);        }#endif            // Extract the data we need from the structure        HAL_READMEM_UINT32( mpct+MPCT_HDR_LOCAL_APIC, cyg_hal_smp_local_apic);                // now parse the base table, looking for processor and IOAPIC entries.        {            CYG_WORD16 entries;            CYG_ADDRESS entry = mpct + MPCT_HDR_SIZE;                    HAL_READMEM_UINT16( mpct+MPCT_HDR_ENTRY_COUNT, entries);#if SHOW_DIAGNOSTICS                        diag_printf("\nBase table:\n");#endif                        while( entries-- )            {                CYG_BYTE type;                HAL_READMEM_UINT8( entry, type );                switch( type )                {                case MPCT_ENTRY_TYPE_PROCESSOR:#if SHOW_DIAGNOSTICS                                        diag_printf("        Processor\n");                    HAL_READMEM_UINT8( entry+MPCT_ENTRY_PROC_APIC_ID, val8 );                    diag_printf("                APIC ID:                  %02x\n",val8);                    HAL_READMEM_UINT8( entry+MPCT_ENTRY_PROC_APIC_VER, val8 );                    diag_printf("                APIC Version:             %02x\n",val8);                    HAL_READMEM_UINT8( entry+MPCT_ENTRY_PROC_CPU_FLAGS, val8 );                    diag_printf("                CPU Flags:                %02x\n",val8);                    HAL_READMEM_UINT8( entry+MPCT_ENTRY_PROC_CPU_SIGNATURE, val32 );                    diag_printf("                CPU Signature:            %08x\n",val32);                    HAL_READMEM_UINT8( entry+MPCT_ENTRY_PROC_FEATURE_FLAGS, val32 );                    diag_printf("                Feature flags:            %08x\n",val32);#endif                    {                        CYG_BYTE cpuid;                        // Index CPUs by their APIC IDs                        HAL_READMEM_UINT8( entry+MPCT_ENTRY_PROC_APIC_ID, cpuid );                        // Get flags for this CPU.                        HAL_READMEM_UINT8(entry+MPCT_ENTRY_PROC_CPU_FLAGS, cyg_hal_smp_cpu_flags[cpuid]);                                                cyg_hal_smp_cpu_count++;      // count another CPU                    }                                        entry += MPCT_ENTRY_PROC_SIZE;                    break;                case MPCT_ENTRY_TYPE_BUS:                    {

⌨️ 快捷键说明

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