diff options
Diffstat (limited to 'perl-install/c/smp.c')
-rw-r--r-- | perl-install/c/smp.c | 511 |
1 files changed, 0 insertions, 511 deletions
diff --git a/perl-install/c/smp.c b/perl-install/c/smp.c deleted file mode 100644 index 2438418bb..000000000 --- a/perl-install/c/smp.c +++ /dev/null @@ -1,511 +0,0 @@ -/* -[_Anarchy_(alan@lightning.swansea.uk.linux.org)] you should do one check - though - if the board seems to be SMP and the CPU in /proc/cpuinfo is non - intel dont install an SMP kernel - thats a dual pentium board with a cyrix - or similar single cpu in it -*/ - - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <string.h> -#include <errno.h> - -#ifdef __alpha__ -int alphaDetectSMP(void) -{ - int issmp = 0; - FILE *f; - - f = fopen("/proc/cpuinfo", "r"); - if (f) { - char buff[1024]; - - while (fgets (buff, 1024, f) != NULL) { - if (!strncmp (buff, "cpus detected\t\t: ", 17)) { - if (strtoul (buff + 17, NULL, 0) > 1) - issmp = 1; - break; - } - } - fclose(f); - } else - return -1; - - return issmp; -} -#endif /* __alpha__ */ - -#ifdef __sparc__ -int sparcDetectSMP(void) -{ - int issmp = 0; - FILE *f; - - f = fopen("/proc/cpuinfo", "r"); - if (f) { - char buff[1024]; - - while (fgets (buff, 1024, f) != NULL) { - if (!strncmp (buff, "ncpus probed\t: ", 15)) { - if (strtoul (buff + 15, NULL, 0) > 1) - issmp = 1; - break; - } - } - fclose(f); - } else - return -1; - - return issmp; -} -#endif /* __sparc__ */ - -/* just a placeholder for now - don't have an SMP machine - need something in place to build - s.benedict */ - -#ifdef __powerpc__ -int ppcDetectSMP(void) -{ - int issmp = 0; - FILE *f; - - f = fopen("/proc/cpuinfo", "r"); - if (f) { - char buff[1024]; - - while (fgets (buff, 1024, f) != NULL) { - if (!strncmp (buff, "ncpus active\t: ", 15)) { - if (strtoul (buff + 15, NULL, 0) > 1) - issmp = 1; - break; - } - } - fclose(f); - } else - return -1; - - return issmp; -} -#endif /* __powerpc__ */ - -#if defined(__i386__) || defined(__x86_64__) -/* - * Copyright (c) 1996, by Steve Passe - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. The name of the developer may NOT be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id$ - */ - -/* - * mptable.c - */ - -#define VMAJOR 2 -#define VMINOR 0 -#define VDELTA 12 - -/* - * this will cause the raw mp table to be dumped to /tmp/mpdump - * -#define RAW_DUMP - */ - -#define MP_SIG 0x5f504d5f /* _MP_ */ -#define EXTENDED_PROCESSING_READY -#define OEM_PROCESSING_READY_NOT - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/types.h> - -#define LINUX 1 -#if LINUX -typedef unsigned int vm_offset_t; -#else -#include <machine/types.h> -#endif - -/* EBDA is @ 40:0e in real-mode terms */ -#define EBDA_POINTER 0x040e /* location of EBDA pointer */ - -/* CMOS 'top of mem' is @ 40:13 in real-mode terms */ -#define TOPOFMEM_POINTER 0x0413 /* BIOS: base memory size */ - -#define DEFAULT_TOPOFMEM 0xa0000 - -#define BIOS_BASE 0xf0000 -#define BIOS_BASE2 0xe0000 -#define BIOS_SIZE 0x10000 -#define ONE_KBYTE 1024 - -#define GROPE_AREA1 0x80000 -#define GROPE_AREA2 0x90000 -#define GROPE_SIZE 0x10000 - -/* MP Floating Pointer Structure */ -typedef struct MPFPS { - char signature[ 4 ]; - void* pap; - u_char length; - u_char spec_rev; - u_char checksum; - u_char mpfb1; - u_char mpfb2; - u_char mpfb3; - u_char mpfb4; - u_char mpfb5; -} mpfps_t; - -/* MP Configuration Table Header */ -typedef struct MPCTH { - char signature[ 4 ]; - u_short base_table_length; - u_char spec_rev; - u_char checksum; - u_char oem_id[ 8 ]; - u_char product_id[ 12 ]; - void* oem_table_pointer; - u_short oem_table_size; - u_short entry_count; - void* apic_address; - u_short extended_table_length; - u_char extended_table_checksum; - u_char reserved; -} mpcth_t; - -typedef struct PROCENTRY { - u_char type; - u_char apicID; - u_char apicVersion; - u_char cpuFlags; - u_long cpuSignature; - u_long featureFlags; - u_long reserved1; - u_long reserved2; -} ProcEntry; - -#define PROCENTRY_FLAG_EN 0x01 - -static void seekEntry( vm_offset_t addr ); -static void apic_probe( vm_offset_t* paddr, int* where ); -static void readEntry( void* entry, int size ); - -/* global data */ -static int pfd; /* physical /dev/mem fd */ -static int verbose = 0; -static int grope = 0; - -static int -readType() -{ - u_char type; - - if ( read( pfd, &type, sizeof( u_char ) ) != sizeof( u_char ) ) { - perror( "type read" ); - fprintf( stderr, "\npfd: %d", pfd ); - fflush( stderr ); - exit( 1 ); - } - - if ( lseek( pfd, -1, SEEK_CUR ) < 0 ) { - perror( "type seek" ); - exit( 1 ); - } - - return (int)type; -} - -extern int intelDetectSMP(void); - -// old detection -static int intelDetectSMP_mptable(void) -{ - vm_offset_t paddr; - int where; - mpfps_t mpfps; - int rc = 0; - int ncpus = 0; - - /* open physical memory for access to MP structures */ - if ( (pfd = open( "/dev/mem", O_RDONLY )) < 0 ) { - return 0; - } - - /* probe for MP structures */ - apic_probe( &paddr, &where ); - if ( where <= 0 ) - return 0; - - seekEntry( paddr ); - readEntry( &mpfps, sizeof( mpfps_t ) ); - - if (mpfps.mpfb1) - /* old style */ - rc = 1; - else { - /* go to the config table */ - mpcth_t cth; - int count, i; - - paddr = (vm_offset_t) mpfps.pap; - seekEntry( paddr ); - readEntry( &cth, sizeof( cth ) ); - /* if we don't have any entries, the kernel sure - won't be able to set up mp. Needs at least one entry - for smp kernel */ - if (cth.entry_count <= 1) { - close (pfd); - return 0; - } - count = cth.entry_count; - for (i = 0; i < count; i++) { - if ( readType() == 0 ) { - ProcEntry entry; - readEntry( &entry, sizeof( entry ) ); - if (entry.cpuFlags & PROCENTRY_FLAG_EN) - ncpus++; - } - } - if (ncpus > 1) - rc = 1; - } - - close (pfd); - return rc; -} - -/* - * set PHYSICAL address of MP floating pointer structure - */ -#define NEXT(X) ((X) += 4) -static void -apic_probe( vm_offset_t* paddr, int* where ) -{ - /* - * c rewrite of apic_probe() by Jack F. Vogel - */ - - int x; - u_short segment; - vm_offset_t target; - u_int buffer[ BIOS_SIZE / sizeof( int ) ]; - - if ( verbose ) - printf( "\n" ); - - /* search Extended Bios Data Area, if present */ - if ( verbose ) - printf( " looking for EBDA pointer @ 0x%04x, ", EBDA_POINTER ); - seekEntry( (vm_offset_t)EBDA_POINTER ); - readEntry( &segment, 2 ); - if ( segment ) { /* search EBDA */ - target = (vm_offset_t)segment << 4; - if ( verbose ) - printf( "found, searching EBDA @ 0x%08x\n", target ); - seekEntry( target ); - readEntry( buffer, ONE_KBYTE ); - - for ( x = 0; x < ONE_KBYTE / sizeof ( unsigned int ); NEXT(x) ) { - if ( buffer[ x ] == MP_SIG ) { - *where = 1; - *paddr = (x * sizeof( unsigned int )) + target; - return; - } - } - } - else { - if ( verbose ) - printf( "NOT found\n" ); - } - - /* read CMOS for real top of mem */ - seekEntry( (vm_offset_t)TOPOFMEM_POINTER ); - readEntry( &segment, 2 ); - --segment; /* less ONE_KBYTE */ - target = segment * 1024; - if ( verbose ) - printf( " searching CMOS 'top of mem' @ 0x%08x (%dK)\n", - target, segment ); - seekEntry( target ); - readEntry( buffer, ONE_KBYTE ); - - for ( x = 0; x < ONE_KBYTE / sizeof ( unsigned int ); NEXT(x) ) { - if ( buffer[ x ] == MP_SIG ) { - *where = 2; - *paddr = (x * sizeof( unsigned int )) + target; - return; - } - } - - /* we don't necessarily believe CMOS, check base of the last 1K of 640K */ - if ( target != (DEFAULT_TOPOFMEM - 1024)) { - target = (DEFAULT_TOPOFMEM - 1024); - if ( verbose ) - printf( " searching default 'top of mem' @ 0x%08x (%dK)\n", - target, (target / 1024) ); - seekEntry( target ); - readEntry( buffer, ONE_KBYTE ); - - for ( x = 0; x < ONE_KBYTE / sizeof ( unsigned int ); NEXT(x) ) { - if ( buffer[ x ] == MP_SIG ) { - *where = 3; - *paddr = (x * sizeof( unsigned int )) + target; - return; - } - } - } - - /* search the BIOS */ - if ( verbose ) - printf( " searching BIOS @ 0x%08x\n", BIOS_BASE ); - seekEntry( BIOS_BASE ); - readEntry( buffer, BIOS_SIZE ); - - for ( x = 0; x < BIOS_SIZE / sizeof( unsigned int ); NEXT(x) ) { - if ( buffer[ x ] == MP_SIG ) { - *where = 4; - *paddr = (x * sizeof( unsigned int )) + BIOS_BASE; - return; - } - } - - /* search the extended BIOS */ - if ( verbose ) - printf( " searching extended BIOS @ 0x%08x\n", BIOS_BASE2 ); - seekEntry( BIOS_BASE2 ); - readEntry( buffer, BIOS_SIZE ); - - for ( x = 0; x < BIOS_SIZE / sizeof( unsigned int ); NEXT(x) ) { - if ( buffer[ x ] == MP_SIG ) { - *where = 5; - *paddr = (x * sizeof( unsigned int )) + BIOS_BASE2; - return; - } - } - - if ( grope ) { - /* search additional memory */ - target = GROPE_AREA1; - if ( verbose ) - printf( " groping memory @ 0x%08x\n", target ); - seekEntry( target ); - readEntry( buffer, GROPE_SIZE ); - - for ( x = 0; x < GROPE_SIZE / sizeof( unsigned int ); NEXT(x) ) { - if ( buffer[ x ] == MP_SIG ) { - *where = 6; - *paddr = (x * sizeof( unsigned int )) + GROPE_AREA1; - return; - } - } - - target = GROPE_AREA2; - if ( verbose ) - printf( " groping memory @ 0x%08x\n", target ); - seekEntry( target ); - readEntry( buffer, GROPE_SIZE ); - - for ( x = 0; x < GROPE_SIZE / sizeof( unsigned int ); NEXT(x) ) { - if ( buffer[ x ] == MP_SIG ) { - *where = 7; - *paddr = (x * sizeof( unsigned int )) + GROPE_AREA2; - return; - } - } - } - - *where = 0; - *paddr = (vm_offset_t)0; -} - - -/* - * - */ -static void -seekEntry( vm_offset_t addr ) -{ - if ( lseek( pfd, (off_t)addr, SEEK_SET ) < 0 ) { - return; - perror( "/dev/mem seek" ); - exit( 1 ); - } -} - - -/* - * - */ -static void -readEntry( void* entry, int size ) -{ - if ( read( pfd, entry, size ) != size ) { - return; - perror( "readEntry" ); - exit( 1 ); - } -} - - -#endif /* __i386__ */ - -int detectSMP(void) -{ - static int isSMP = -1; - - if (isSMP != -1) - return isSMP; - -#ifdef __i386__ - return isSMP = intelDetectSMP() || intelDetectSMP_mptable(); -#elif __sparc__ - return isSMP = sparcDetectSMP(); -#elif __alpha__ - return isSMP = alphaDetectSMP(); -#elif __powerpc__ - return isSMP = ppcDetectSMP(); -#elif __ia64__ - /* TODO: Update to check against /proc/pal/cpuX */ - return isSMP = 1; -#elif __x86_64__ - return isSMP = intelDetectSMP() || intelDetectSMP_mptable(); -#else - #error unknown architecture -#endif -} - -#if TEST -int main() { - if (detectSMP()) - printf("has smp\n"); - else - printf("no smp\n"); -} -#endif |