home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / cctools / libstuff / arch.c < prev    next >
C/C++ Source or Header  |  1995-03-16  |  10KB  |  322 lines

  1. #include "string.h"
  2. #include <mach/mach.h>
  3. #include "stuff/arch.h"
  4.  
  5. /*
  6.  * The array of all currently know architecture flags (terminated with an entry
  7.  * with all zeros).  Pointer to this returned with get_arch_flags().
  8.  */
  9. #ifdef __DYNAMIC__
  10. static struct arch_flag arch_flags[] = {
  11. #else
  12. static const struct arch_flag arch_flags[] = {
  13. #endif
  14.     { "any",    CPU_TYPE_ANY,      CPU_SUBTYPE_MULTIPLE },
  15.     { "little",    CPU_TYPE_ANY,      CPU_SUBTYPE_LITTLE_ENDIAN },
  16.     { "big",    CPU_TYPE_ANY,      CPU_SUBTYPE_BIG_ENDIAN },
  17.     /* architecture families */
  18.     { "m68k",   CPU_TYPE_MC680x0, CPU_SUBTYPE_MC680x0_ALL },
  19.     { "m98k",   CPU_TYPE_MC98000, CPU_SUBTYPE_MC98000_ALL },
  20.     { "m88k",   CPU_TYPE_MC88000, CPU_SUBTYPE_MC88000_ALL },
  21.     { "i386",   CPU_TYPE_I386,    CPU_SUBTYPE_I386_ALL },
  22.     { "i860",   CPU_TYPE_I860,    CPU_SUBTYPE_I860_ALL },
  23.     { "hppa",   CPU_TYPE_HPPA,    CPU_SUBTYPE_HPPA_ALL },
  24.     { "sparc",    CPU_TYPE_SPARC,   CPU_SUBTYPE_SPARC_ALL },
  25.     /* specific architecture implementations */
  26.     { "m68030", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC68030_ONLY },
  27.     { "m68040", CPU_TYPE_MC680x0, CPU_SUBTYPE_MC68040 },
  28.     { "i486",   CPU_TYPE_I386,    CPU_SUBTYPE_486 },
  29.     { "i486SX", CPU_TYPE_I386,    CPU_SUBTYPE_486SX },
  30.     { "i586",   CPU_TYPE_I386,    CPU_SUBTYPE_586 },
  31.     { "i586SX", CPU_TYPE_I386,    CPU_SUBTYPE_586SX },
  32.     { "hppa7100LC", CPU_TYPE_HPPA,  CPU_SUBTYPE_HPPA_7100LC },
  33.     { NULL,    0,          0 }
  34. };
  35.  
  36. /*
  37.  * get_arch_from_flag() is passed a name of an architecture flag and returns
  38.  * zero if that flag is not known and non-zero if the flag is known.
  39.  * If the pointer to the arch_flag is not NULL it is filled in with the
  40.  * arch_flag struct that matches the name.
  41.  */
  42. __private_extern__
  43. int
  44. get_arch_from_flag(
  45. char *name,
  46. struct arch_flag *arch_flag)
  47. {
  48.     unsigned long i;
  49.  
  50.     for(i = 0; arch_flags[i].name != NULL; i++){
  51.         if(strcmp(arch_flags[i].name, name) == 0){
  52.         if(arch_flag != NULL)
  53.             *arch_flag = arch_flags[i];
  54.         return(1);
  55.         }
  56.     }
  57.     if(arch_flag != NULL)
  58.         memset(arch_flag, '\0', sizeof(struct arch_flag));
  59.     return(0);
  60. }
  61.  
  62. /*
  63.  * get_arch_from_host() gets the architecture from the host this is running on
  64.  * and returns zero if the architecture is not known and zero if the
  65.  * architecture is known.  If the parameters family_arch_flag and
  66.  * specific_arch_flag are not NULL they get fill in with the family
  67.  * architecture and specific architecure for the host.  If the architecture
  68.  * is unknown and the parameters are not NULL then all fields are set to zero.
  69.  */
  70. __private_extern__
  71. int
  72. get_arch_from_host(
  73. struct arch_flag *family_arch_flag,
  74. struct arch_flag *specific_arch_flag)
  75. {
  76.     struct host_basic_info host_basic_info;
  77.     unsigned int count;
  78.     kern_return_t r;
  79.  
  80.     if(family_arch_flag != NULL)
  81.         memset(family_arch_flag, '\0', sizeof(struct arch_flag));
  82.     if(specific_arch_flag != NULL)
  83.         memset(specific_arch_flag, '\0', sizeof(struct arch_flag));
  84.  
  85.     count = HOST_BASIC_INFO_COUNT;
  86.     if((r = host_info(host_self(), HOST_BASIC_INFO,
  87.               (host_info_t)(&host_basic_info),
  88.               &count)) != KERN_SUCCESS)
  89.         return(0);
  90.  
  91.     if(family_arch_flag != NULL){
  92.         family_arch_flag->cputype = host_basic_info.cpu_type;
  93.     }
  94.     if(specific_arch_flag != NULL){
  95.         specific_arch_flag->cputype = host_basic_info.cpu_type;
  96.         specific_arch_flag->cpusubtype = host_basic_info.cpu_subtype;
  97.     }
  98.     switch(host_basic_info.cpu_type){
  99.     case CPU_TYPE_MC680x0:
  100.         switch(host_basic_info.cpu_subtype){
  101.         case CPU_SUBTYPE_MC680x0_ALL:
  102.         case CPU_SUBTYPE_MC68030_ONLY:
  103.         if(family_arch_flag != NULL){
  104.             family_arch_flag->name = "m68k";
  105.             family_arch_flag->cpusubtype = CPU_SUBTYPE_MC680x0_ALL;
  106.         }
  107.         if(specific_arch_flag != NULL){
  108.             specific_arch_flag->name = "m68030";
  109.             /* 
  110.              * There is a "bug" in the kernel for compatiblity that on
  111.              * an 030 machine host_info() returns cpusubtype
  112.              * CPU_SUBTYPE_MC680x0_ALL and not CPU_SUBTYPE_MC68030_ONLY.
  113.              */
  114.             specific_arch_flag->cpusubtype = CPU_SUBTYPE_MC68030_ONLY;
  115.         }
  116.         return(1);
  117.         case CPU_SUBTYPE_MC68040:
  118.         if(family_arch_flag != NULL){
  119.             family_arch_flag->name = "m68k";
  120.             family_arch_flag->cpusubtype = CPU_SUBTYPE_MC680x0_ALL;
  121.         }
  122.         if(specific_arch_flag != NULL)
  123.             specific_arch_flag->name = "m68040";
  124.         return(1);
  125.         }
  126.         break;
  127.     case CPU_TYPE_MC98000:
  128.         switch(host_basic_info.cpu_subtype){
  129.         case CPU_SUBTYPE_MC98000_ALL:
  130.         if(family_arch_flag != NULL){
  131.             family_arch_flag->name = "m98k";
  132.             family_arch_flag->cpusubtype = CPU_SUBTYPE_MC98000_ALL;
  133.         }
  134.         if(specific_arch_flag != NULL)
  135.             specific_arch_flag->name = "m98k";
  136.         return(1);
  137.         }
  138.         break;
  139.     case CPU_TYPE_MC88000:
  140.         switch(host_basic_info.cpu_subtype){
  141.         case CPU_SUBTYPE_MC88000_ALL:
  142.         case CPU_SUBTYPE_MC88110:
  143.         if(family_arch_flag != NULL){
  144.             family_arch_flag->name = "m88k";
  145.             family_arch_flag->cpusubtype = CPU_SUBTYPE_MC88000_ALL;
  146.         }
  147.         if(specific_arch_flag != NULL)
  148.             specific_arch_flag->name = "m88k";
  149.         return(1);
  150.         }
  151.         break;
  152.     case CPU_TYPE_I386:
  153.         switch(host_basic_info.cpu_subtype){
  154.         case CPU_SUBTYPE_I386_ALL:
  155.         /* case CPU_SUBTYPE_386: same value as above */
  156.         if(family_arch_flag != NULL){
  157.             family_arch_flag->name = "i386";
  158.             family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
  159.         }
  160.         if(specific_arch_flag != NULL)
  161.             specific_arch_flag->name = "i386";
  162.         return(1);
  163.         case CPU_SUBTYPE_486:
  164.         if(family_arch_flag != NULL){
  165.             family_arch_flag->name = "i386";
  166.             family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
  167.         }
  168.         if(specific_arch_flag != NULL)
  169.             specific_arch_flag->name = "i486";
  170.         return(1);
  171.         case CPU_SUBTYPE_486SX:
  172.         if(family_arch_flag != NULL){
  173.             family_arch_flag->name = "i386";
  174.             family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
  175.         }
  176.         if(specific_arch_flag != NULL)
  177.             specific_arch_flag->name = "i486SX";
  178.         return(1);
  179.         case CPU_SUBTYPE_586:
  180.         if(family_arch_flag != NULL){
  181.             family_arch_flag->name = "i386";
  182.             family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
  183.         }
  184.         if(specific_arch_flag != NULL)
  185.             specific_arch_flag->name = "i586";
  186.         return(1);
  187.         case CPU_SUBTYPE_586SX:
  188.         if(family_arch_flag != NULL){
  189.             family_arch_flag->name = "i386";
  190.             family_arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL;
  191.         }
  192.         if(specific_arch_flag != NULL)
  193.             specific_arch_flag->name = "i586SX";
  194.         return(1);
  195.         }
  196.         break;
  197.     case CPU_TYPE_I860:
  198.         switch(host_basic_info.cpu_subtype){
  199.         case CPU_SUBTYPE_I860_ALL:
  200.         case CPU_SUBTYPE_I860_860:
  201.         if(family_arch_flag != NULL){
  202.             family_arch_flag->name = "i860";
  203.             family_arch_flag->cpusubtype = CPU_SUBTYPE_I860_ALL;
  204.         }
  205.         if(specific_arch_flag != NULL)
  206.             specific_arch_flag->name = "i860";
  207.         return(1);
  208.         }
  209.         break;
  210.     case CPU_TYPE_HPPA:
  211.         switch(host_basic_info.cpu_subtype){
  212.         case CPU_SUBTYPE_HPPA_ALL:
  213.         if(family_arch_flag != NULL){
  214.             family_arch_flag->name = "hppa";
  215.             family_arch_flag->cpusubtype = CPU_SUBTYPE_HPPA_ALL;
  216.         }
  217.         if(specific_arch_flag != NULL)
  218.             specific_arch_flag->name = "hppa";
  219.         return(1);
  220.         case CPU_SUBTYPE_HPPA_7100LC:
  221.         if(family_arch_flag != NULL){
  222.             family_arch_flag->name = "hppa";
  223.             family_arch_flag->cpusubtype = CPU_SUBTYPE_HPPA_ALL;
  224.         }
  225.         if(specific_arch_flag != NULL)
  226.             specific_arch_flag->name = "hppa7100LC";
  227.         return(1);
  228.           
  229.         }
  230.         break;
  231.     case CPU_TYPE_SPARC:
  232.         switch(host_basic_info.cpu_subtype){
  233.         case /*CPU_SUBTYPE_SPARC_ALL*/0:
  234.         if(family_arch_flag != NULL){
  235.             family_arch_flag->name = "sparc";
  236.             family_arch_flag->cpusubtype = CPU_SUBTYPE_SPARC_ALL;
  237.         }
  238.         if(specific_arch_flag != NULL)
  239.             specific_arch_flag->name = "sparc";
  240.         return(1);
  241.         }
  242.         break;
  243.     }
  244.     return(0);
  245. }
  246.  
  247. /*
  248.  * get_arch_flags() returns a pointer to an array of all currently know
  249.  * architecture flags (terminated with an entry with all zeros).
  250.  */
  251. __private_extern__
  252. const struct arch_flag *
  253. get_arch_flags(
  254. void)
  255. {
  256.     return(arch_flags);
  257. }
  258.  
  259. /*
  260.  * get_arch_name_from_types() returns the name of the architecture for the
  261.  * specified cputype and cpusubtype if known.  If unknown it returns a pointer
  262.  * to the string "unknown".
  263.  */
  264. __private_extern__
  265. const char *
  266. get_arch_name_from_types(
  267. cpu_type_t cputype,
  268. cpu_subtype_t cpusubtype)
  269. {
  270.     unsigned long i;
  271.  
  272.     for(i = 0; arch_flags[i].name != NULL; i++){
  273.         if(arch_flags[i].cputype == cputype &&
  274.            arch_flags[i].cpusubtype == cpusubtype)
  275.         return(arch_flags[i].name);
  276.     }
  277.     return("unknown");
  278. }
  279.  
  280. /*
  281.  * get_arch_family_from_cputype() returns the family architecture for the
  282.  * specified cputype if known.  If unknown it returns NULL.
  283.  */
  284. __private_extern__
  285. const struct arch_flag *
  286. get_arch_family_from_cputype(
  287. cpu_type_t cputype)
  288. {
  289.     unsigned long i;
  290.  
  291.     for(i = 0; arch_flags[i].name != NULL; i++){
  292.         if(arch_flags[i].cputype == cputype)
  293.         return(arch_flags + i);
  294.     }
  295.     return(NULL);
  296. }
  297.  
  298. /*
  299.  * get_byte_sex_from_flag() returns the byte sex of the architecture for the
  300.  * specified cputype and cpusubtype if known.  If unknown it returns
  301.  * UNKNOWN_BYTE_SEX.  If the bytesex can be determined directly as in the case
  302.  * of reading a magic number from a file that should be done and this routine
  303.  * should not be used as it could be out of date.
  304.  */
  305. __private_extern__
  306. enum byte_sex
  307. get_byte_sex_from_flag(
  308. const struct arch_flag *flag)
  309. {
  310.    if(flag->cputype == CPU_TYPE_MC680x0 ||
  311.       flag->cputype == CPU_TYPE_MC88000 ||
  312.       flag->cputype == CPU_TYPE_MC98000 ||
  313.       flag->cputype == CPU_TYPE_HPPA ||
  314.       flag->cputype == CPU_TYPE_SPARC ||
  315.       flag->cputype == CPU_TYPE_I860)
  316.         return BIG_ENDIAN_BYTE_SEX;
  317.     else if(flag->cputype == CPU_TYPE_I386)
  318.         return LITTLE_ENDIAN_BYTE_SEX;
  319.     else
  320.         return UNKNOWN_BYTE_SEX;
  321. }
  322.