]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/i386/cpu_topology.h
xnu-4903.270.47.tar.gz
[apple/xnu.git] / osfmk / i386 / cpu_topology.h
index 86729b9353d0a6f4b9e3a5fb7816c029e581b07a..3e5567331aa295bd8f049bf86af520c4dde03e35 100644 (file)
@@ -1,8 +1,8 @@
 /*
 /*
- * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
- * 
+ *
  * Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this file.
  * Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -22,7 +22,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 #ifdef KERNEL_PRIVATE
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 #ifdef KERNEL_PRIVATE
 /*
  * Cache structure that can be used to identify the cache heirarchy.
  */
 /*
  * Cache structure that can be used to identify the cache heirarchy.
  */
-typedef struct x86_cpu_cache
-{
-    struct x86_cpu_cache *next;                /* next cache at this level/lcpu */
-    uint8_t            maxcpus;        /* maximum # of cpus that can share */
-    uint8_t            nlcpus;         /* # of logical cpus sharing this cache */
-    uint8_t            type;           /* type of cache */
-    uint8_t            level;          /* level of cache */
-    uint16_t           ways;           /* # of ways in cache */
-    uint16_t           partitions;     /* # of partitions in cache */
-    uint16_t           line_size;      /* size of a cache line */
-    uint32_t           cache_size;     /* total size of cache */
-    struct x86_lcpu    *cpus[0];       /* cpus sharing this cache */
+typedef struct x86_cpu_cache {
+       struct x86_cpu_cache *next;     /* next cache at this level/lcpu */
+       struct x86_die      *die;       /* die containing this cache (only for LLC) */
+       uint8_t             maxcpus;    /* maximum # of cpus that can share */
+       uint8_t             nlcpus;     /* # of logical cpus sharing this cache */
+       uint8_t             type;       /* type of cache */
+       uint8_t             level;      /* level of cache */
+       uint16_t            ways;       /* # of ways in cache */
+       uint16_t            partitions; /* # of partitions in cache */
+       uint16_t            line_size;  /* size of a cache line */
+       uint32_t            cache_size; /* total size of cache */
+       struct x86_lcpu     *cpus[0];   /* cpus sharing this cache */
 } x86_cpu_cache_t;
 
 } x86_cpu_cache_t;
 
-#define CPU_CACHE_TYPE_DATA    1       /* data cache */
-#define CPU_CACHE_TYPE_INST    2       /* instruction cache */
-#define CPU_CACHE_TYPE_UNIF    3       /* unified cache */
+#define CPU_CACHE_TYPE_DATA     1       /* data cache */
+#define CPU_CACHE_TYPE_INST     2       /* instruction cache */
+#define CPU_CACHE_TYPE_UNIF     3       /* unified cache */
 
 
-#define CPU_CACHE_DEPTH_L1     0
-#define CPU_CACHE_DEPTH_L2     1
-#define CPU_CACHE_DEPTH_L3     2
+#define CPU_CACHE_DEPTH_L1      0
+#define CPU_CACHE_DEPTH_L2      1
+#define CPU_CACHE_DEPTH_L3      2
 
 
-#define MAX_CACHE_DEPTH                3       /* deepest cache */
+#define MAX_CACHE_DEPTH         3       /* deepest cache */
 
 struct pmc;
 struct cpu_data;
 
 struct pmc;
 struct cpu_data;
+struct mca_state;
+
+/*
+ * Define the states that a (logical) CPU can be in.
+ *
+ * LCPU_OFF    This indicates that the CPU is "off".  It requires a full
+ *             restart.  This is the state of a CPU when the system first
+ *             boots or when it comes out of "sleep" (aka S3/S5).
+ *
+ * LCPU_HALT   This indicates that the CPU has been "halted".  It has been
+ *             removed from the system but still retains its internal state
+ *             so that it can be quickly brought back on-line.
+ *
+ * LCPU_NONSCHED       This indicates that the CPU is not schedulable.  It
+ *             will still appear in the system as a viable CPU however no
+ *             work will be sceduled on it.
+ *
+ * LCPU_PAUSE  This indicates that the CPU is "paused".  This is usually
+ *             done only during kernel debug.
+ *
+ * LCPU_IDLE   This indicates that the CPU is idle.  The scheduler has
+ *             determined that there is no work for this CPU to do.
+ *
+ * LCPU_RUN    This indicates that the CPU is running code and performing work.
+ *
+ * In normal system operation, CPUs will usually be transitioning between
+ * LCPU_IDLE and LCPU_RUN.
+ */
+typedef enum lcpu_state {
+       LCPU_OFF            = 0,/* 0 so the right thing happens on boot */
+       LCPU_HALT           = 1,
+       LCPU_NONSCHED       = 2,
+       LCPU_PAUSE          = 3,
+       LCPU_IDLE           = 4,
+       LCPU_RUN            = 5,
+} lcpu_state_t;
 
 
-typedef struct x86_lcpu
-{
-    struct x86_lcpu    *next;  /* next logical cpu in core */
-    struct x86_lcpu    *lcpu;  /* pointer back to self */
-    struct x86_core    *core;  /* core containing the logical cpu */
-    struct cpu_data    *cpu;   /* cpu_data structure */
-    uint32_t           lnum;   /* logical cpu number */
-    uint32_t           pnum;   /* physical cpu number */
-    boolean_t          master; /* logical cpu is the master (boot) CPU */
-    boolean_t          primary;/* logical cpu is primary CPU in package */
-    boolean_t          halted; /* logical cpu is halted */
-    boolean_t          idle;   /* logical cpu is idle */
-    uint64_t           rtcPop; /* when etimer wants a timer pop */
-    uint64_t           rtcDeadline;
-    x86_cpu_cache_t    *caches[MAX_CACHE_DEPTH];
+/*
+ * In each topology structure there are two numbers: a logical number and a
+ * physical number.
+ *
+ * The logical numbers represent the ID of that structure
+ * relative to the enclosing structure and always starts at 0.  So when using
+ * logical numbers, it is necessary to specify all elements in the topology
+ * (ie to "name" a logical CPU using logical numbers, 4 numbers are required:
+ * package, die, core, logical CPU).
+ *
+ * The physical numbers represent the ID of that structure and is unique (for
+ * that structure) across the entire topology.
+ *
+ * The logical CPU structure contains a third number which is the CPU number.
+ * This number is identical to the CPU number used in other parts of the kernel.
+ */
+typedef struct x86_lcpu {
+       struct x86_lcpu     *next_in_core;/* next logical cpu in core */
+       struct x86_lcpu     *next_in_die;/* next logical cpu in die */
+       struct x86_lcpu     *next_in_pkg;/* next logical cpu in package */
+       struct x86_lcpu     *lcpu;      /* pointer back to self */
+       struct x86_core     *core;      /* core containing the logical cpu */
+       struct x86_die      *die;       /* die containing the logical cpu */
+       struct x86_pkg      *package;   /* package containing the logical cpu */
+       struct cpu_data     *cpu;       /* cpu_data structure */
+       uint32_t            flags;
+       uint32_t            cpu_num;    /* cpu number */
+       uint32_t            lnum;       /* logical cpu number (within core) */
+       uint32_t            pnum;       /* physical cpu number */
+       boolean_t           master;     /* logical cpu is the master (boot) CPU */
+       boolean_t           primary;    /* logical cpu is primary CPU in package */
+       volatile lcpu_state_t       state;/* state of the logical CPU */
+       volatile boolean_t  stopped;    /* used to indicate that the CPU has "stopped" */
+       uint64_t            rtcPop;     /* next timer pop programmed */
+       uint64_t            rtcDeadline;/* next etimer-requested deadline */
+       x86_cpu_cache_t     *caches[MAX_CACHE_DEPTH];
+       void                *pmStats;   /* Power management stats for lcpu */
+       void                *pmState;   /* Power management state for lcpu */
 } x86_lcpu_t;
 
 } x86_lcpu_t;
 
-#define X86CORE_FL_PRESENT     0x80000000      /* core is present */
-#define X86CORE_FL_READY       0x40000000      /* core struct is init'd */
-#define X86CORE_FL_HALTED      0x00008000      /* core is halted */
-#define X86CORE_FL_IDLE                0x00004000      /* core is idle */
-
-typedef struct x86_core
-{
-    struct x86_core    *next;          /* next core in package */
-    struct x86_lcpu    *lcpus;         /* list of logical cpus in core */
-    struct x86_pkg     *package;       /* package containing core */
-    uint32_t           flags;
-    uint32_t           lcore_num;      /* logical core # (unique to package) */
-    uint32_t           pcore_num;      /* physical core # (globally unique) */
-    uint32_t           num_lcpus;      /* Number of logical cpus */
-    uint32_t           active_lcpus;   /* Number of non-halted cpus */
-    struct pmc         *pmc;           /* Pointer to perfmon data */
-    struct hpetTimer   *Hpet;          /* Address of the HPET for this core */
-    uint32_t           HpetVec;        /* Interrupt vector for HPET */
-    uint64_t           HpetInt;        /* Number of HPET Interrupts */
-    uint64_t           HpetCmp;        /* HPET Comparitor */
-    uint64_t           HpetCfg;        /* HPET configuration */
-    uint64_t           HpetTime;
-    void               *pmStats;       /* Power management stats for core */
-    void               *pmState;       /* Power management state for core */
+#define X86CORE_FL_PRESENT      0x80000000      /* core is present */
+#define X86CORE_FL_READY        0x40000000      /* core struct is init'd */
+#define X86CORE_FL_HAS_HPET     0x10000000      /* core has HPET assigned */
+#define X86CORE_FL_HALTED       0x00008000      /* core is halted */
+#define X86CORE_FL_IDLE         0x00004000      /* core is idle */
+
+typedef struct x86_core {
+       struct x86_core     *next_in_die;/* next core in die */
+       struct x86_core     *next_in_pkg;/* next core in package */
+       struct x86_die      *die;       /* die containing the core */
+       struct x86_pkg      *package;   /* package containing core */
+       struct x86_lcpu     *lcpus;     /* list of logical cpus in core */
+       uint32_t            flags;
+       uint32_t            lcore_num;  /* logical core # (unique within die) */
+       uint32_t            pcore_num;  /* physical core # (globally unique) */
+       uint32_t            num_lcpus;  /* Number of logical cpus */
+       uint32_t            active_lcpus;/* Number of {running, idle} cpus */
+       void                *pmStats;   /* Power management stats for core */
+       void                *pmState;   /* Power management state for core */
 } x86_core_t;
 
 } x86_core_t;
 
-#define X86PKG_FL_PRESENT      0x80000000      /* package is present */
-#define X86PKG_FL_READY                0x40000000      /* package struct init'd */
-#define X86PKG_FL_HAS_HPET     0x10000000      /* package has HPET assigned */
-#define X86PKG_FL_HALTED       0x00008000      /* package is halted */
-#define X86PKG_FL_IDLE         0x00004000      /* package is idle */
-
-typedef struct x86_pkg
-{
-    struct x86_pkg     *next;          /* next package */
-    struct x86_core    *cores;         /* list of cores in package */
-    uint32_t           flags;
-    uint32_t           lpkg_num;       /* logical package # */
-    uint32_t           ppkg_num;       /* physical package # */
-    uint32_t           num_cores;      /* number of cores in package */
-    struct hpetTimer   *Hpet;          /* address of HPET for this package */
-    uint32_t           HpetVec;        /* Interrupt vector for HPET */
-    uint64_t           HpetInt;        /* Number of HPET interrupts */
-    uint64_t           HpetCmp;        /* HPET comparitor */
-    uint64_t           HpetCfg;        /* HPET configuration */
-    uint64_t           HpetTime;
-    void               *pmStats;       /* Power Management stats for package*/
-    void               *pmState;       /* Power Management state for package*/
+#define X86DIE_FL_PRESENT       0x80000000      /* die is present */
+#define X86DIE_FL_READY         0x40000000      /* die struct is init'd */
+
+typedef struct x86_die {
+       struct x86_die      *next_in_pkg;/* next die in package */
+       struct x86_lcpu     *lcpus;     /* list of lcpus in die */
+       struct x86_core     *cores;     /* list of cores in die */
+       struct x86_pkg      *package;   /* package containing the die */
+       uint32_t            flags;
+       uint32_t            ldie_num;   /* logical die # (unique to package) */
+       uint32_t            pdie_num;   /* physical die # (globally unique) */
+       uint32_t            num_cores;  /* Number of cores in die */
+       x86_cpu_cache_t     *LLC;       /* LLC contained in this die */
+       void                *pmStats;   /* Power Management stats for die */
+       void                *pmState;   /* Power Management state for die */
+} x86_die_t;
+
+#define X86PKG_FL_PRESENT       0x80000000      /* package is present */
+#define X86PKG_FL_READY         0x40000000      /* package struct init'd */
+#define X86PKG_FL_HAS_HPET      0x10000000      /* package has HPET assigned */
+#define X86PKG_FL_HALTED        0x00008000      /* package is halted */
+#define X86PKG_FL_IDLE          0x00004000      /* package is idle */
+
+typedef struct x86_pkg {
+       struct x86_pkg      *next;      /* next package */
+       struct x86_lcpu     *lcpus;     /* list of logical cpus in package */
+       struct x86_core     *cores;     /* list of cores in package */
+       struct x86_die      *dies;      /* list of dies in package */
+       uint32_t            flags;
+       uint32_t            lpkg_num;   /* logical package # */
+       uint32_t            ppkg_num;   /* physical package # */
+       uint32_t            num_dies;   /* number of dies in package */
+       void                *pmStats;   /* Power Management stats for package*/
+       void                *pmState;   /* Power Management state for package*/
+       struct mca_state    *mca_state; /* MCA state for memory errors */
+       uint64_t            package_idle_exits;
+       uint32_t            num_idle;
 } x86_pkg_t;
 
 } x86_pkg_t;
 
-extern x86_pkg_t       *x86_pkgs;      /* root of all CPU packages */
+extern x86_pkg_t        *x86_pkgs;      /* root of all CPU packages */
+
+typedef struct x86_topology_parameters {
+       uint32_t            LLCDepth;
+       uint32_t            nCoresSharingLLC;
+       uint32_t            nLCPUsSharingLLC;
+       uint32_t            maxSharingLLC;
+       uint32_t            nLThreadsPerCore;
+       uint32_t            nPThreadsPerCore;
+       uint32_t            nLCoresPerDie;
+       uint32_t            nPCoresPerDie;
+       uint32_t            nLDiesPerPackage;
+       uint32_t            nPDiesPerPackage;
+       uint32_t            nLThreadsPerDie;
+       uint32_t            nPThreadsPerDie;
+       uint32_t            nLThreadsPerPackage;
+       uint32_t            nPThreadsPerPackage;
+       uint32_t            nLCoresPerPackage;
+       uint32_t            nPCoresPerPackage;
+       uint32_t            nPackages;
+       boolean_t           stable;
+} x86_topology_parameters_t;
 
 /* Called after cpu discovery */
 
 /* Called after cpu discovery */
-extern void            cpu_topology_start(void);
+extern void             cpu_topology_sort(int ncpus);
+extern kern_return_t    cpu_topology_start_cpu(int cpunum);
 
 
-extern int idlehalt;
 
 #endif /* _I386_CPU_TOPOLOGY_H_ */
 #endif /* KERNEL_PRIVATE */
 
 #endif /* _I386_CPU_TOPOLOGY_H_ */
 #endif /* KERNEL_PRIVATE */