summaryrefslogtreecommitdiffstats
path: root/perl-install/c/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/c/smp.c')
-rw-r--r--perl-install/c/smp.c201
1 files changed, 154 insertions, 47 deletions
diff --git a/perl-install/c/smp.c b/perl-install/c/smp.c
index 2438418bb..9cc75978d 100644
--- a/perl-install/c/smp.c
+++ b/perl-install/c/smp.c
@@ -64,30 +64,132 @@ int sparcDetectSMP(void)
}
#endif /* __sparc__ */
-/* just a placeholder for now - don't have an SMP machine
- need something in place to build - s.benedict */
-
#ifdef __powerpc__
+/* minifind.c -- simple find library
+ *
+ * Copyright (c) 2002 Terra Soft Solutions, Inc.
+ * Written by Dan Burcaw <dburcaw@terrasoftsolutions.com>
+ *
+ * This software may be freely redistributed under the terms of the GNU
+ * library public license.
+ *
+ * You should have received a copy of the GNU Library Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <dirent.h>
+#include <malloc.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+struct pathNode
+{
+ char *path;
+ struct pathNode *next;
+};
+
+struct findNode
+{
+ struct pathNode *result;
+ struct pathNode *exclude;
+};
+
+// insert a node at head of linked-list
+static void insert_node(struct pathNode *n, char *path)
+{
+ struct pathNode *new = (struct pathNode *) malloc(sizeof(struct pathNode));
+ new->path = path;
+ new->next = n->next;
+ n->next = new;
+}
+
+// return input strip less last character
+static char *stripLastChar(char *in)
+{
+ char *out = malloc(sizeof(char)*strlen(in));
+ snprintf(out, strlen(in) - 1, "%s", in);
+ return out;
+}
+
+// do the work
+static char *minifind(char *dir, char *search, struct findNode *list)
+{
+ char *d = NULL;
+ int n;
+ struct dirent **namelist;
+ struct stat buf;
+
+ if (dir[strlen(dir)-1] == '/')
+ dir = stripLastChar(dir);
+
+ // check is there is an exact filematch to dir
+ // when search is not specified
+ if (search == NULL)
+ {
+ if (lstat(dir, &buf) == 0)
+ insert_node(list->result, dir);
+ return 0;
+ }
+
+ n = scandir(dir, &namelist, 0, alphasort);
+ if (n >= 0)
+ {
+ while (n--)
+ {
+ d = malloc(sizeof(char) * (strlen(dir) \
+ + strlen(namelist[n]->d_name)+1));
+ sprintf(d, "%s/%s", dir, namelist[n]->d_name);
+ if (strstr(namelist[n]->d_name, search))
+ insert_node(list->result, d);
+
+ if ((lstat(d, &buf) == 0) && S_ISDIR(buf.st_mode))
+ {
+ if (strcmp(namelist[n]->d_name, ".") &&
+ strcmp(namelist[n]->d_name, ".."))
+ d = minifind(d, search, list);
+ }
+ free(namelist[n]);
+ }
+ free(namelist);
+ return d;
+ }
+ return 0;
+}
+
int ppcDetectSMP(void)
{
- int issmp = 0;
+ int issmp = -1;
FILE *f;
-
- f = fopen("/proc/cpuinfo", "r");
- if (f) {
- char buff[1024];
+ struct findNode *list = (struct findNode *) malloc(sizeof(struct findNode));
+ struct pathNode *n;
- while (fgets (buff, 1024, f) != NULL) {
- if (!strncmp (buff, "ncpus active\t: ", 15)) {
- if (strtoul (buff + 15, NULL, 0) > 1)
- issmp = 1;
- break;
+ list->result = (struct pathNode *) malloc(sizeof(struct pathNode));
+ list->result->path = NULL;
+ list->result->next = list->result;
+
+ minifind("/proc/device-tree/cpus", "device_type", list);
+
+ for (n = list->result->next; n != list->result; n = n->next)
+ {
+ f = fopen(n->path, "r");
+ if (f) {
+ char buff[1024];
+ while (fgets (buff, 1024, f) != NULL) {
+ if (!strncmp (buff, "cpu", 3))
+ {
+ issmp++;
+ break;
+ }
+ }
+ fclose(f);
}
}
- fclose(f);
- } else
- return -1;
-
+
return issmp;
}
#endif /* __powerpc__ */
@@ -152,6 +254,11 @@ typedef unsigned int vm_offset_t;
#include <machine/types.h>
#endif
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef vm_offset_t addr_t;
+
/* EBDA is @ 40:0e in real-mode terms */
#define EBDA_POINTER 0x040e /* location of EBDA pointer */
@@ -172,43 +279,43 @@ typedef unsigned int vm_offset_t;
/* 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;
+ addr_t pap;
+ u8 length;
+ u8 spec_rev;
+ u8 checksum;
+ u8 mpfb1;
+ u8 mpfb2;
+ u8 mpfb3;
+ u8 mpfb4;
+ u8 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;
+ u16 base_table_length;
+ u8 spec_rev;
+ u8 checksum;
+ u8 oem_id[ 8 ];
+ u8 product_id[ 12 ];
+ addr_t oem_table_pointer;
+ u16 oem_table_size;
+ u16 entry_count;
+ addr_t apic_address;
+ u16 extended_table_length;
+ u8 extended_table_checksum;
+ u8 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;
+ u8 type;
+ u8 apicID;
+ u8 apicVersion;
+ u8 cpuFlags;
+ u32 cpuSignature;
+ u32 featureFlags;
+ u32 reserved1;
+ u32 reserved2;
} ProcEntry;
#define PROCENTRY_FLAG_EN 0x01
@@ -274,7 +381,7 @@ static int intelDetectSMP_mptable(void)
mpcth_t cth;
int count, i;
- paddr = (vm_offset_t) mpfps.pap;
+ paddr = mpfps.pap;
seekEntry( paddr );
readEntry( &cth, sizeof( cth ) );
/* if we don't have any entries, the kernel sure