]> git.saurik.com Git - apple/xnu.git/commitdiff
xnu-1486.2.11.tar.gz mac-os-x-1062 v1486.2.11
authorApple <opensource@apple.com>
Thu, 12 Nov 2009 18:00:07 +0000 (18:00 +0000)
committerApple <opensource@apple.com>
Thu, 12 Nov 2009 18:00:07 +0000 (18:00 +0000)
62 files changed:
bsd/conf/files
bsd/dev/i386/sysctl.c
bsd/hfs/hfs_catalog.c
bsd/hfs/hfs_catalog.h
bsd/hfs/hfs_vnops.c
bsd/hfs/hfs_xattr.c
bsd/kern/bsd_init.c
bsd/kern/kern_aio.c
bsd/kern/kern_descrip.c
bsd/kern/kern_event.c
bsd/kern/kern_mib.c
bsd/kern/mach_loader.c
bsd/net/bpf.c
bsd/net/dlil.c
bsd/net/route.c
bsd/netinet/ip_output.c
bsd/netinet/tcp_input.c
bsd/netinet6/ip6_forward.c
bsd/netinet6/ip6_input.c
bsd/netinet6/ip6_output.c
bsd/netinet6/raw_ip6.c
bsd/sys/file_internal.h
bsd/vfs/vfs_xattr.c
config/MasterVersion
iokit/IOKit/IOCatalogue.h
iokit/IOKit/IOMemoryDescriptor.h
iokit/IOKit/IOReturn.h
iokit/IOKit/IOService.h
iokit/Kernel/IOCatalogue.cpp
iokit/Kernel/IOMemoryDescriptor.cpp
iokit/Kernel/IOServicePM.cpp
iokit/Kernel/IOServicePMPrivate.h
iokit/conf/MASTER
kgmacros
libkern/c++/OSKext.cpp
libsa/bootstrap.cpp
osfmk/i386/commpage/commpage.c
osfmk/i386/cpu_capabilities.h
osfmk/i386/cpu_threads.c
osfmk/i386/cpuid.c
osfmk/i386/cpuid.h
osfmk/i386/lowglobals.h
osfmk/i386/lowmem_vectors.s
osfmk/i386/mp.c
osfmk/i386/mp_desc.c
osfmk/i386/pmCPU.c
osfmk/i386/pmCPU.h
osfmk/i386/rtclock.c
osfmk/i386/rtclock.h
osfmk/i386/tsc.c
osfmk/kdp/kdp.c
osfmk/kdp/kdp_core.h
osfmk/kdp/kdp_internal.h
osfmk/kdp/kdp_private.h
osfmk/kdp/kdp_protocol.h
osfmk/kdp/kdp_udp.c
osfmk/kern/sched_prim.c
osfmk/mach/machine.h
osfmk/ppc/lowglobals.h
osfmk/ppc/lowmem_vectors.s
osfmk/x86_64/lowglobals.h
osfmk/x86_64/lowmem_vectors.s

index 61afa6bf3057bd3225327732ba7886c5ddaaf82e..95f856c21f260df3046830c93f4707b22740b30f 100644 (file)
@@ -292,7 +292,7 @@ bsd/netinet6/icmp6.c                        optional inet6
 bsd/netinet6/in6.c                     optional inet6
 bsd/netinet6/in6_cksum.c               optional inet6
 bsd/netinet6/in6_gif.c                 optional gif inet6
-bsd/netinet6/ip6_fw.c                      optional inet6
+bsd/netinet6/ip6_fw.c                      optional inet6 ipfw2
 bsd/netinet6/ip6_forward.c             optional inet6
 bsd/netinet6/in6_ifattach.c            optional inet6
 bsd/netinet6/ip6_input.c               optional inet6
index 13d4355b98d2ebc6efc1aa1421799099a688dd00..2b9609d530dff3b88078cf3283bb972e9903ad32 100644 (file)
 #include <i386/tsc.h>
 
 static int
-hw_cpu_sysctl SYSCTL_HANDLER_ARGS
+_i386_cpu_info SYSCTL_HANDLER_ARGS
 {
     __unused struct sysctl_oid *unused_oidp = oidp;
-    i386_cpu_info_t *cpu_info = cpuid_info();
-    void *ptr = (uint8_t *)cpu_info + (uintptr_t)arg1;
+    void *ptr = arg1;
     int value;
 
     if (arg2 == -1) {
@@ -59,20 +58,55 @@ hw_cpu_sysctl SYSCTL_HANDLER_ARGS
 }
 
 static int
-hw_cpu_sysctl_nonzero SYSCTL_HANDLER_ARGS
+i386_cpu_info SYSCTL_HANDLER_ARGS
 {
-    i386_cpu_info_t *cpu_info = cpuid_info();
-    void *ptr = (uint8_t *)cpu_info + (uintptr_t)arg1;
+    void *ptr = (uint8_t *)cpuid_info() + (uintptr_t)arg1;
+    return _i386_cpu_info(oidp, ptr, arg2, req);
+}
+
+static int
+i386_cpu_info_nonzero SYSCTL_HANDLER_ARGS
+{
+    void *ptr = (uint8_t *)cpuid_info() + (uintptr_t)arg1;
     int value = *(uint32_t *)ptr;
 
     if (value == 0)
         return ENOENT;
 
-    return hw_cpu_sysctl(oidp, arg1, arg2, req);
+    return _i386_cpu_info(oidp, ptr, arg2, req);
+}
+static int
+cpu_mwait SYSCTL_HANDLER_ARGS
+{
+    i386_cpu_info_t *cpu_info = cpuid_info();
+    void *ptr = (uint8_t *)cpu_info->cpuid_mwait_leafp + (uintptr_t)arg1;
+    if (cpu_info->cpuid_mwait_leafp == NULL)
+        return ENOENT;
+    return _i386_cpu_info(oidp, ptr, arg2, req);
+}
+
+static int
+cpu_thermal SYSCTL_HANDLER_ARGS
+{
+    i386_cpu_info_t *cpu_info = cpuid_info();
+    void *ptr = (uint8_t *)cpu_info->cpuid_thermal_leafp + (uintptr_t)arg1;
+    if (cpu_info->cpuid_thermal_leafp == NULL)
+        return ENOENT;
+    return _i386_cpu_info(oidp, ptr, arg2, req);
+}
+
+static int
+cpu_arch_perf SYSCTL_HANDLER_ARGS
+{
+    i386_cpu_info_t *cpu_info = cpuid_info();
+    void *ptr = (uint8_t *)cpu_info->cpuid_arch_perf_leafp + (uintptr_t)arg1;
+    if (cpu_info->cpuid_arch_perf_leafp == NULL)
+        return ENOENT;
+    return _i386_cpu_info(oidp, ptr, arg2, req);
 }
 
 static int
-hw_cpu_features SYSCTL_HANDLER_ARGS
+cpu_features SYSCTL_HANDLER_ARGS
 {
     __unused struct sysctl_oid *unused_oidp = oidp;
     __unused void *unused_arg1 = arg1;
@@ -86,7 +120,7 @@ hw_cpu_features SYSCTL_HANDLER_ARGS
 }
 
 static int
-hw_cpu_extfeatures SYSCTL_HANDLER_ARGS
+cpu_extfeatures SYSCTL_HANDLER_ARGS
 {
     __unused struct sysctl_oid *unused_oidp = oidp;
     __unused void *unused_arg1 = arg1;
@@ -100,7 +134,7 @@ hw_cpu_extfeatures SYSCTL_HANDLER_ARGS
 }
 
 static int
-hw_cpu_logical_per_package SYSCTL_HANDLER_ARGS
+cpu_logical_per_package SYSCTL_HANDLER_ARGS
 {
        __unused struct sysctl_oid *unused_oidp = oidp;
        __unused void *unused_arg1 = arg1;
@@ -115,7 +149,7 @@ hw_cpu_logical_per_package SYSCTL_HANDLER_ARGS
 }
 
 static int
-hw_cpu_flex_ratio_desired SYSCTL_HANDLER_ARGS
+cpu_flex_ratio_desired SYSCTL_HANDLER_ARGS
 {
        __unused struct sysctl_oid *unused_oidp = oidp;
        __unused void *unused_arg1 = arg1;
@@ -129,7 +163,7 @@ hw_cpu_flex_ratio_desired SYSCTL_HANDLER_ARGS
 }
 
 static int
-hw_cpu_flex_ratio_min SYSCTL_HANDLER_ARGS
+cpu_flex_ratio_min SYSCTL_HANDLER_ARGS
 {
        __unused struct sysctl_oid *unused_oidp = oidp;
        __unused void *unused_arg1 = arg1;
@@ -143,7 +177,7 @@ hw_cpu_flex_ratio_min SYSCTL_HANDLER_ARGS
 }
 
 static int
-hw_cpu_flex_ratio_max SYSCTL_HANDLER_ARGS
+cpu_flex_ratio_max SYSCTL_HANDLER_ARGS
 {
        __unused struct sysctl_oid *unused_oidp = oidp;
        __unused void *unused_arg1 = arg1;
@@ -161,80 +195,80 @@ SYSCTL_NODE(_machdep, OID_AUTO, cpu, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, max_basic, CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_max_basic),sizeof(uint32_t),
-           hw_cpu_sysctl, "IU", "Max Basic Information value");
+           i386_cpu_info, "IU", "Max Basic Information value");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, max_ext, CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_max_ext), sizeof(uint32_t),
-           hw_cpu_sysctl, "IU", "Max Extended Function Information value");
+           i386_cpu_info, "IU", "Max Extended Function Information value");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, vendor, CTLTYPE_STRING | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_vendor), 0,
-           hw_cpu_sysctl, "A", "CPU vendor");
+           i386_cpu_info, "A", "CPU vendor");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, brand_string, CTLTYPE_STRING | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_brand_string), 0,
-           hw_cpu_sysctl, "A", "CPU brand string");
+           i386_cpu_info, "A", "CPU brand string");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, family, CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_family), sizeof(uint8_t),
-           hw_cpu_sysctl, "I", "CPU family");
+           i386_cpu_info, "I", "CPU family");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, model, CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_model), sizeof(uint8_t),
-           hw_cpu_sysctl, "I", "CPU model");
+           i386_cpu_info, "I", "CPU model");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, extmodel, CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_extmodel), sizeof(uint8_t),
-           hw_cpu_sysctl, "I", "CPU extended model");
+           i386_cpu_info, "I", "CPU extended model");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, extfamily, CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_extfamily), sizeof(uint8_t),
-           hw_cpu_sysctl, "I", "CPU extended family");
+           i386_cpu_info, "I", "CPU extended family");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, stepping, CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_stepping), sizeof(uint8_t),
-           hw_cpu_sysctl, "I", "CPU stepping");
+           i386_cpu_info, "I", "CPU stepping");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, feature_bits, CTLTYPE_QUAD | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_features), sizeof(uint64_t),
-           hw_cpu_sysctl, "IU", "CPU features");
+           i386_cpu_info, "IU", "CPU features");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, extfeature_bits, CTLTYPE_QUAD | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_extfeatures), sizeof(uint64_t),
-           hw_cpu_sysctl, "IU", "CPU extended features");
+           i386_cpu_info, "IU", "CPU extended features");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, signature, CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_signature), sizeof(uint32_t),
-           hw_cpu_sysctl, "I", "CPU signature");
+           i386_cpu_info, "I", "CPU signature");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, brand, CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_brand), sizeof(uint8_t),
-           hw_cpu_sysctl, "I", "CPU brand");
+           i386_cpu_info, "I", "CPU brand");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, features, CTLTYPE_STRING | CTLFLAG_RD, 
            0, 0,
-           hw_cpu_features, "A", "CPU feature names");
+           cpu_features, "A", "CPU feature names");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, extfeatures, CTLTYPE_STRING | CTLFLAG_RD, 
            0, 0,
-           hw_cpu_extfeatures, "A", "CPU extended feature names");
+           cpu_extfeatures, "A", "CPU extended feature names");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, logical_per_package,
            CTLTYPE_INT | CTLFLAG_RD, 
            0, 0,
-           hw_cpu_logical_per_package, "I", "CPU logical cpus per package");
+           cpu_logical_per_package, "I", "CPU logical cpus per package");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, cores_per_package,
            CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_cores_per_package),
            sizeof(uint32_t),
-           hw_cpu_sysctl, "I", "CPU cores per package");
+           i386_cpu_info, "I", "CPU cores per package");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, microcode_version,
            CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_microcode_version),
            sizeof(uint32_t),
-           hw_cpu_sysctl, "I", "Microcode version number");
+           i386_cpu_info, "I", "Microcode version number");
 
 
 SYSCTL_NODE(_machdep_cpu, OID_AUTO, mwait, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
@@ -242,27 +276,27 @@ SYSCTL_NODE(_machdep_cpu, OID_AUTO, mwait, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
 
 SYSCTL_PROC(_machdep_cpu_mwait, OID_AUTO, linesize_min,
            CTLTYPE_INT | CTLFLAG_RD, 
-           (void *)offsetof(i386_cpu_info_t, cpuid_mwait_linesize_min),
+           (void *)offsetof(cpuid_mwait_leaf_t, linesize_min),
            sizeof(uint32_t),
-           hw_cpu_sysctl, "I", "Monitor/mwait minimum line size");
+           cpu_mwait, "I", "Monitor/mwait minimum line size");
 
 SYSCTL_PROC(_machdep_cpu_mwait, OID_AUTO, linesize_max,
            CTLTYPE_INT | CTLFLAG_RD, 
-           (void *)offsetof(i386_cpu_info_t, cpuid_mwait_linesize_max),
+           (void *)offsetof(cpuid_mwait_leaf_t, linesize_max),
            sizeof(uint32_t),
-           hw_cpu_sysctl, "I", "Monitor/mwait maximum line size");
+           cpu_mwait, "I", "Monitor/mwait maximum line size");
 
 SYSCTL_PROC(_machdep_cpu_mwait, OID_AUTO, extensions,
            CTLTYPE_INT | CTLFLAG_RD, 
-           (void *)offsetof(i386_cpu_info_t, cpuid_mwait_extensions),
+           (void *)offsetof(cpuid_mwait_leaf_t, extensions),
            sizeof(uint32_t),
-           hw_cpu_sysctl, "I", "Monitor/mwait extensions");
+           cpu_mwait, "I", "Monitor/mwait extensions");
 
 SYSCTL_PROC(_machdep_cpu_mwait, OID_AUTO, sub_Cstates,
            CTLTYPE_INT | CTLFLAG_RD, 
-           (void *)offsetof(i386_cpu_info_t, cpuid_mwait_sub_Cstates),
+           (void *)offsetof(cpuid_mwait_leaf_t, sub_Cstates),
            sizeof(uint32_t),
-           hw_cpu_sysctl, "I", "Monitor/mwait sub C-states");
+           cpu_mwait, "I", "Monitor/mwait sub C-states");
 
 
 SYSCTL_NODE(_machdep_cpu, OID_AUTO, thermal, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
@@ -270,27 +304,27 @@ SYSCTL_NODE(_machdep_cpu, OID_AUTO, thermal, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
 
 SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, sensor,
            CTLTYPE_INT | CTLFLAG_RD, 
-           (void *)offsetof(i386_cpu_info_t, cpuid_thermal_sensor),
+           (void *)offsetof(cpuid_thermal_leaf_t, sensor),
            sizeof(boolean_t),
-           hw_cpu_sysctl, "I", "Thermal sensor present");
+           cpu_thermal, "I", "Thermal sensor present");
 
 SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, dynamic_acceleration,
            CTLTYPE_INT | CTLFLAG_RD, 
-           (void *)offsetof(i386_cpu_info_t, cpuid_thermal_dynamic_acceleration),
+           (void *)offsetof(cpuid_thermal_leaf_t, dynamic_acceleration),
            sizeof(boolean_t),
-           hw_cpu_sysctl, "I", "Dynamic Acceleration Technology");
+           cpu_thermal, "I", "Dynamic Acceleration Technology (Turbo Mode)");
 
 SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, thresholds,
            CTLTYPE_INT | CTLFLAG_RD, 
-           (void *)offsetof(i386_cpu_info_t, cpuid_thermal_thresholds),
+           (void *)offsetof(cpuid_thermal_leaf_t, thresholds),
            sizeof(uint32_t),
-           hw_cpu_sysctl, "I", "Number of interrupt thresholds");
+           cpu_thermal, "I", "Number of interrupt thresholds");
 
 SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, ACNT_MCNT,
            CTLTYPE_INT | CTLFLAG_RD, 
-           (void *)offsetof(i386_cpu_info_t, cpuid_thermal_ACNT_MCNT),
+           (void *)offsetof(cpuid_thermal_leaf_t, ACNT_MCNT),
            sizeof(boolean_t),
-           hw_cpu_sysctl, "I", "ACNT_MCNT capability");
+           cpu_thermal, "I", "ACNT_MCNT capability");
 
 
 SYSCTL_NODE(_machdep_cpu, OID_AUTO, arch_perf, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
@@ -298,45 +332,45 @@ SYSCTL_NODE(_machdep_cpu, OID_AUTO, arch_perf, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
 
 SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, version,
            CTLTYPE_INT | CTLFLAG_RD, 
-           (void *)offsetof(i386_cpu_info_t, cpuid_arch_perf_version),
+           (void *)offsetof(cpuid_arch_perf_leaf_t, version),
            sizeof(uint8_t),
-           hw_cpu_sysctl, "I", "Architectural Performance Version Number");
+           cpu_arch_perf, "I", "Architectural Performance Version Number");
 
 SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, number,
            CTLTYPE_INT | CTLFLAG_RD, 
-           (void *)offsetof(i386_cpu_info_t, cpuid_arch_perf_number),
+           (void *)offsetof(cpuid_arch_perf_leaf_t, number),
            sizeof(uint8_t),
-           hw_cpu_sysctl, "I", "Number of counters per logical cpu");
+           cpu_arch_perf, "I", "Number of counters per logical cpu");
 
 SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, width,
            CTLTYPE_INT | CTLFLAG_RD, 
-           (void *)offsetof(i386_cpu_info_t, cpuid_arch_perf_width),
+           (void *)offsetof(cpuid_arch_perf_leaf_t, width),
            sizeof(uint8_t),
-           hw_cpu_sysctl, "I", "Bit width of counters");
+           cpu_arch_perf, "I", "Bit width of counters");
 
 SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, events_number,
            CTLTYPE_INT | CTLFLAG_RD, 
-           (void *)offsetof(i386_cpu_info_t, cpuid_arch_perf_events_number),
+           (void *)offsetof(cpuid_arch_perf_leaf_t, events_number),
            sizeof(uint8_t),
-           hw_cpu_sysctl, "I", "Number of monitoring events");
+           cpu_arch_perf, "I", "Number of monitoring events");
 
 SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, events,
            CTLTYPE_INT | CTLFLAG_RD, 
-           (void *)offsetof(i386_cpu_info_t, cpuid_arch_perf_events),
+           (void *)offsetof(cpuid_arch_perf_leaf_t, events),
            sizeof(uint32_t),
-           hw_cpu_sysctl, "I", "Bit vector of events");
+           cpu_arch_perf, "I", "Bit vector of events");
 
 SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, fixed_number,
            CTLTYPE_INT | CTLFLAG_RD, 
-           (void *)offsetof(i386_cpu_info_t, cpuid_arch_perf_fixed_number),
+           (void *)offsetof(cpuid_arch_perf_leaf_t, fixed_number),
            sizeof(uint8_t),
-           hw_cpu_sysctl, "I", "Number of fixed-function counters");
+           cpu_arch_perf, "I", "Number of fixed-function counters");
 
 SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, fixed_width,
            CTLTYPE_INT | CTLFLAG_RD, 
-           (void *)offsetof(i386_cpu_info_t, cpuid_arch_perf_fixed_width),
+           (void *)offsetof(cpuid_arch_perf_leaf_t, fixed_width),
            sizeof(uint8_t),
-           hw_cpu_sysctl, "I", "Bit-width of fixed-function counters");
+           cpu_arch_perf, "I", "Bit-width of fixed-function counters");
 
 
 SYSCTL_NODE(_machdep_cpu, OID_AUTO, cache, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
@@ -346,19 +380,19 @@ SYSCTL_PROC(_machdep_cpu_cache, OID_AUTO, linesize,
            CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_cache_linesize),
            sizeof(uint32_t),
-           hw_cpu_sysctl, "I", "Cacheline size");
+           i386_cpu_info, "I", "Cacheline size");
 
 SYSCTL_PROC(_machdep_cpu_cache, OID_AUTO, L2_associativity,
            CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_cache_L2_associativity),
            sizeof(uint32_t),
-           hw_cpu_sysctl, "I", "L2 cache associativity");
+           i386_cpu_info, "I", "L2 cache associativity");
 
 SYSCTL_PROC(_machdep_cpu_cache, OID_AUTO, size,
            CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_cache_size),
            sizeof(uint32_t),
-           hw_cpu_sysctl, "I", "Cache size (in Kbytes)");
+           i386_cpu_info, "I", "Cache size (in Kbytes)");
 
 
 SYSCTL_NODE(_machdep_cpu, OID_AUTO, tlb, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
@@ -373,7 +407,7 @@ SYSCTL_PROC(_machdep_cpu_tlb_inst, OID_AUTO, small,
            (void *)offsetof(i386_cpu_info_t,
                             cpuid_tlb[TLB_INST][TLB_SMALL][0]),
            sizeof(uint32_t),
-           hw_cpu_sysctl_nonzero, "I",
+           i386_cpu_info_nonzero, "I",
            "Number of small page instruction TLBs");
 
 SYSCTL_PROC(_machdep_cpu_tlb_data, OID_AUTO, small,
@@ -381,7 +415,7 @@ SYSCTL_PROC(_machdep_cpu_tlb_data, OID_AUTO, small,
            (void *)offsetof(i386_cpu_info_t,
                             cpuid_tlb[TLB_DATA][TLB_SMALL][0]),
            sizeof(uint32_t),
-           hw_cpu_sysctl_nonzero, "I",
+           i386_cpu_info_nonzero, "I",
            "Number of small page data TLBs (1st level)");
 
 SYSCTL_PROC(_machdep_cpu_tlb_data, OID_AUTO, small_level1,
@@ -389,7 +423,7 @@ SYSCTL_PROC(_machdep_cpu_tlb_data, OID_AUTO, small_level1,
            (void *)offsetof(i386_cpu_info_t,
                             cpuid_tlb[TLB_DATA][TLB_SMALL][1]),
            sizeof(uint32_t),
-           hw_cpu_sysctl_nonzero, "I",
+           i386_cpu_info_nonzero, "I",
            "Number of small page data TLBs (2nd level)");
 
 SYSCTL_PROC(_machdep_cpu_tlb_inst, OID_AUTO, large,
@@ -397,7 +431,7 @@ SYSCTL_PROC(_machdep_cpu_tlb_inst, OID_AUTO, large,
            (void *)offsetof(i386_cpu_info_t,
                             cpuid_tlb[TLB_INST][TLB_LARGE][0]),
            sizeof(uint32_t),
-           hw_cpu_sysctl_nonzero, "I",
+           i386_cpu_info_nonzero, "I",
            "Number of large page instruction TLBs");
 
 SYSCTL_PROC(_machdep_cpu_tlb_data, OID_AUTO, large,
@@ -405,7 +439,7 @@ SYSCTL_PROC(_machdep_cpu_tlb_data, OID_AUTO, large,
            (void *)offsetof(i386_cpu_info_t,
                             cpuid_tlb[TLB_DATA][TLB_LARGE][0]),
            sizeof(uint32_t),
-           hw_cpu_sysctl_nonzero, "I",
+           i386_cpu_info_nonzero, "I",
            "Number of large page data TLBs (1st level)");
 
 SYSCTL_PROC(_machdep_cpu_tlb_data, OID_AUTO, large_level1,
@@ -413,14 +447,14 @@ SYSCTL_PROC(_machdep_cpu_tlb_data, OID_AUTO, large_level1,
            (void *)offsetof(i386_cpu_info_t,
                             cpuid_tlb[TLB_DATA][TLB_LARGE][1]),
            sizeof(uint32_t),
-           hw_cpu_sysctl_nonzero, "I",
+           i386_cpu_info_nonzero, "I",
            "Number of large page data TLBs (2nd level)");
 
 SYSCTL_PROC(_machdep_cpu_tlb, OID_AUTO, shared,
            CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_stlb),
            sizeof(uint32_t),
-           hw_cpu_sysctl_nonzero, "I",
+           i386_cpu_info_nonzero, "I",
            "Number of shared TLBs");
 
 
@@ -431,26 +465,26 @@ SYSCTL_PROC(_machdep_cpu_address_bits, OID_AUTO, physical,
            CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_address_bits_physical),
            sizeof(uint32_t),
-           hw_cpu_sysctl, "I", "Number of physical address bits");
+           i386_cpu_info, "I", "Number of physical address bits");
 
 SYSCTL_PROC(_machdep_cpu_address_bits, OID_AUTO, virtual,
            CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, cpuid_address_bits_virtual),
            sizeof(uint32_t),
-           hw_cpu_sysctl, "I", "Number of virtual address bits");
+           i386_cpu_info, "I", "Number of virtual address bits");
 
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, core_count,
            CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, core_count),
            sizeof(uint32_t),
-           hw_cpu_sysctl, "I", "Number of enabled cores per package");
+           i386_cpu_info, "I", "Number of enabled cores per package");
 
 SYSCTL_PROC(_machdep_cpu, OID_AUTO, thread_count,
            CTLTYPE_INT | CTLFLAG_RD, 
            (void *)offsetof(i386_cpu_info_t, thread_count),
            sizeof(uint32_t),
-           hw_cpu_sysctl, "I", "Number of enabled threads per package");
+           i386_cpu_info, "I", "Number of enabled threads per package");
 
 SYSCTL_NODE(_machdep_cpu, OID_AUTO, flex_ratio, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
        "Flex ratio");
@@ -458,17 +492,17 @@ SYSCTL_NODE(_machdep_cpu, OID_AUTO, flex_ratio, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
 SYSCTL_PROC(_machdep_cpu_flex_ratio, OID_AUTO, desired,
            CTLTYPE_INT | CTLFLAG_RD, 
            0, 0,
-           hw_cpu_flex_ratio_desired, "I", "Flex ratio desired (0 disabled)");
+           cpu_flex_ratio_desired, "I", "Flex ratio desired (0 disabled)");
 
 SYSCTL_PROC(_machdep_cpu_flex_ratio, OID_AUTO, min,
            CTLTYPE_INT | CTLFLAG_RD, 
            0, 0,
-           hw_cpu_flex_ratio_min, "I", "Flex ratio min (efficiency)");
+           cpu_flex_ratio_min, "I", "Flex ratio min (efficiency)");
 
 SYSCTL_PROC(_machdep_cpu_flex_ratio, OID_AUTO, max,
            CTLTYPE_INT | CTLFLAG_RD, 
            0, 0,
-           hw_cpu_flex_ratio_max, "I", "Flex ratio max (non-turbo)");
+           cpu_flex_ratio_max, "I", "Flex ratio max (non-turbo)");
 
 uint64_t pmap_pv_hashlist_walks;
 uint64_t pmap_pv_hashlist_cnts;
index 5e7e13d99e4baad1fa2b396db06487084e8021fd..bb48eda7fb1cd4b131c212a52bb400f590724a57 100644 (file)
@@ -2669,6 +2669,27 @@ getdirentries_callback(const CatalogKey *ckp, const CatalogRecord *crp,
 
        /* We're done when parent directory changes */
        if (state->cbs_parentID != curID) {
+               /*
+                * If the parent ID is different from curID this means we've hit
+                * the EOF for the directory.  To help future callers, we mark
+                * the cbs_eof boolean.  However, we should only mark the EOF 
+                * boolean if we're about to return from this function. 
+                *
+                * This is because this callback function does its own uiomove
+                * to get the data to userspace.  If we set the boolean before determining
+                * whether or not the current entry has enough room to write its
+                * data to userland, we could fool the callers of this catalog function
+                * into thinking they've hit EOF earlier than they really would have.
+                * In that case, we'd know that we have more entries to process and
+                * send to userland, but we didn't have enough room.  
+                * 
+                * To be safe, we mark cbs_eof here ONLY for the cases where we know we're 
+                * about to return and won't write any new data back
+                * to userland.  In the stop_after_pack case, we'll set this boolean
+                * regardless, so it's slightly safer to let that logic mark the boolean,
+                * especially since it's closer to the return of this function.
+                */              
+
                if (state->cbs_extended) {
                        /* The last record has not been returned yet, so we 
                         * want to stop after packing the last item 
@@ -2676,10 +2697,12 @@ getdirentries_callback(const CatalogKey *ckp, const CatalogRecord *crp,
                        if (state->cbs_hasprevdirentry) { 
                                stop_after_pack = true;
                        } else {
+                               state->cbs_eof = true;
                                state->cbs_result = ENOENT;
                                return (0);     /* stop */
                        }                               
                } else {
+                       state->cbs_eof = true;
                        state->cbs_result = ENOENT;
                        return (0);     /* stop */
                }
@@ -3057,6 +3080,12 @@ cat_getdirentries(struct hfsmount *hfsmp, int entrycnt, directoryhint_t *dirhint
        state.cbs_nlinks = 0;
        state.cbs_maxlinks = maxlinks;
        state.cbs_linkinfo = (linkinfo_t *)((char *)buffer + MAXPATHLEN);
+       /*
+        * We need to set cbs_eof to false regardless of whether or not the
+        * control flow is actually in the extended case, since we use this
+        * field to track whether or not we've returned EOF from the iterator function.
+        */
+       state.cbs_eof = false;
 
        iterator = (BTreeIterator *) ((char *)state.cbs_linkinfo + (maxlinks * sizeof(linkinfo_t)));
        key = (CatalogKey *)&iterator->key;
@@ -3065,7 +3094,6 @@ cat_getdirentries(struct hfsmount *hfsmp, int entrycnt, directoryhint_t *dirhint
        if (extended) {
                state.cbs_direntry = (struct direntry *)((char *)iterator + sizeof(BTreeIterator));
                state.cbs_prevdirentry = state.cbs_direntry + 1;
-               state.cbs_eof = false;
        }
        /*
         * Attempt to build a key from cached filename
@@ -3186,8 +3214,14 @@ cat_getdirentries(struct hfsmount *hfsmp, int entrycnt, directoryhint_t *dirhint
        /* Note that state.cbs_index is still valid on errors */
        *items = state.cbs_index - index;
        index = state.cbs_index;
-
+       
+       /*
+        * Also note that cbs_eof is set in all cases if we ever hit EOF
+        * during the enumeration by the catalog callback.  Mark the directory's hint
+        * descriptor as having hit EOF.
+        */
        if (state.cbs_eof) {
+               dirhint->dh_desc.cd_flags |= CD_EOF;
                *eofflag = 1;
        }
        
index 2eaf3811f447b6f7747c209a896ecb852296105d..6c1eaa1303d46b4fe0616df1c04b3d787a41b4ab 100644 (file)
@@ -63,9 +63,18 @@ struct cat_desc {
        const u_int8_t * cd_nameptr; /* pointer to cnode name */
 };
 
-/* cd_flags */
+/* cd_flags 
+ *
+ * CD_EOF is used by hfs_vnop_readdir / cat_getdirentries to indicate EOF was
+ * encountered during a directory enumeration.  When this flag is observed
+ * on the next call to hfs_vnop_readdir it tells the caller that there's no
+ * need to descend into the catalog as EOF was encountered during the last call.
+ * This flag should only be set on the descriptor embedded in the directoryhint. 
+ */
+
 #define        CD_HASBUF       0x01    /* allocated filename buffer */
 #define CD_DECOMPOSED  0x02    /* name is fully decomposed */
+#define CD_EOF         0x04    /* see above */
 #define        CD_ISMETA       0x40    /* describes a metadata file */
 #define        CD_ISDIR        0x80    /* describes a directory */
 
index 726e230e51cbbbf94fdd5f0247fbfd8a10fd3f9c..9114d0a994b28693a59b356b34c42cef0c2f2676 100644 (file)
@@ -217,6 +217,8 @@ hfs_vnop_mknod(struct vnop_mknod_args *ap)
 static int
 hfs_ref_data_vp(struct cnode *cp, struct vnode **data_vp, int skiplock)
 {
+       int vref = 0;
+
        if (!data_vp || !cp) /* sanity check incoming parameters */
                return EINVAL;
        
@@ -227,9 +229,12 @@ hfs_ref_data_vp(struct cnode *cp, struct vnode **data_vp, int skiplock)
        if (c_vp) {
                /* we already have a data vnode */
                *data_vp = c_vp;
-               vnode_ref(*data_vp);
+               vref = vnode_ref(*data_vp);
                if (!skiplock) hfs_unlock(cp);
-               return 0;
+               if (vref == 0) {
+                       return 0;
+               }
+               return EINVAL;
        }
        /* no data fork vnode in the cnode, so ask hfs for one. */
 
@@ -242,10 +247,13 @@ hfs_ref_data_vp(struct cnode *cp, struct vnode **data_vp, int skiplock)
        
        if (0 == hfs_vget(VTOHFS(cp->c_rsrc_vp), cp->c_cnid, data_vp, 1) &&
                0 != data_vp) {
-               vnode_ref(*data_vp);
+               vref = vnode_ref(*data_vp);
                vnode_put(*data_vp);
                if (!skiplock) hfs_unlock(cp);
-               return 0;
+               if (vref == 0) {
+                       return 0;
+               }
+               return EINVAL;
        }
        /* there was an error getting the vnode */
        *data_vp = NULL;
@@ -3693,6 +3701,25 @@ hfs_vnop_readdir(ap)
        if (index == 0) {
                dirhint->dh_threadhint = cp->c_dirthreadhint;
        }
+       else {
+               /*
+                * If we have a non-zero index, there is a possibility that during the last
+                * call to hfs_vnop_readdir we hit EOF for this directory.  If that is the case
+                * then we don't want to return any new entries for the caller.  Just return 0
+                * items, mark the eofflag, and bail out.  Because we won't have done any work, the 
+                * code at the end of the function will release the dirhint for us.  
+                *
+                * Don't forget to unlock the catalog lock on the way out, too.
+                */
+               if (dirhint->dh_desc.cd_flags & CD_EOF) {
+                       error = 0;
+                       eofflag = 1;
+                       uio_setoffset(uio, startoffset);
+                       hfs_systemfile_unlock (hfsmp, lockflags);
+
+                       goto seekoffcalc;
+               }
+       }
 
        /* Pack the buffer with dirent entries. */
        error = cat_getdirentries(hfsmp, cp->c_entries, dirhint, uio, extended, &items, &eofflag);
@@ -4208,31 +4235,20 @@ hfs_makenode(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
        if (S_ISWHT(mode)) {
                goto exit;
        }
-       
-       /* 
-        * We need to release the cnode lock on dcp before calling into
-        * hfs_getnewvnode to make sure we don't double lock this node 
-        */
-       if (dcp) {
-               dcp->c_flag &= ~C_DIR_MODIFICATION;
-               wakeup((caddr_t)&dcp->c_flag);
-               
-               hfs_unlock(dcp);
-               /* so we don't double-unlock it later */
-               dcp = NULL;
-       }
 
        /*
         * Create a vnode for the object just created.
         * 
-        * NOTE: Because we have just unlocked the parent directory above (dcp), 
-        * we are open to a race condition wherein another thread could look up the 
-        * entry we just added to the catalog and delete it BEFORE we actually get the 
-        * vnode out of the call below. In that case, we may return ENOENT because the 
-        * cnode was already marked for C_DELETE. This is because we are grabbing the cnode 
-        * out of the hash via the CNID/fileid provided in attr, and  with the parent 
-        * directory unlocked, it is now accessible. In this case, the VFS should re-drive the
-        * create operation to re-attempt.
+        * NOTE: Maintaining the cnode lock on the parent directory is important,
+        * as it prevents race conditions where other threads want to look up entries 
+        * in the directory and/or add things as we are in the process of creating
+        * the vnode below.  However, this has the potential for causing a 
+        * double lock panic when dealing with shadow files on a HFS boot partition. 
+        * The panic could occur if we are not cleaning up after ourselves properly 
+        * when done with a shadow file or in the error cases.  The error would occur if we 
+        * try to create a new vnode, and then end up reclaiming another shadow vnode to 
+        * create the new one.  However, if everything is working properly, this should
+        * be a non-issue as we would never enter that reclaim codepath.
         *
         * The cnode is locked on successful return.
         */
@@ -4246,8 +4262,7 @@ exit:
        cat_releasedesc(&out_desc);
        
        /*
-        * In case we get here via error handling, make sure we release cnode lock on dcp if we 
-        * didn't do it already.
+        * Make sure we release cnode lock on dcp.
         */
        if (dcp) {
                dcp->c_flag &= ~C_DIR_MODIFICATION;
index fc5cd3f7c7f373e6a7d68eeeec8ece8db82584a8..915fbe874ad56ab6d29623112c33caf8a079a1df 100644 (file)
@@ -724,19 +724,33 @@ hfs_vnop_setxattr(struct vnop_setxattr_args *ap)
                if (result) {
                        return (result);
                }
-               /* VNOP_WRITE will update timestamps accordingly */
+               /* 
+                * VNOP_WRITE marks the vnode as needing a modtime update.
+                */
                result = VNOP_WRITE(rvp, uio, 0, ap->a_context);
                
-               /* if open unlinked, force it inactive */
+               /* if open unlinked, force it inactive and recycle */
                if (openunlinked) {
                        int vref;
                        vref = vnode_ref (rvp);
                        if (vref == 0) {
                                vnode_rele(rvp);
                        }
-                       vnode_recycle (rvp);    
+                       vnode_recycle (rvp);
                }
+               else {
+                       /* re-lock the cnode so we can update the modtimes */
+                       if ((result = hfs_lock(VTOC(vp), HFS_EXCLUSIVE_LOCK))) {
+                               vnode_recycle(rvp);
+                               vnode_put(rvp);
+                               return (result);
+                       }
 
+                       /* HFS fsync the resource fork to force it out to disk */
+                       result = hfs_fsync (rvp, MNT_NOWAIT, 0, vfs_context_proc(ap->a_context));
+
+                       hfs_unlock(cp);
+               }
 
                vnode_put(rvp);
                return (result);
index f36d6d4ceac344d0e8edbc5ff30440c8814a05fc..e54d4284f234798fccad845a1c17111f86dbd678 100644 (file)
 
 #include <pexpert/pexpert.h>
 
-#if CONFIG_EMBEDDED
-#include <libkern/OSKextLib.h>
-#endif
-
 void * get_user_regs(thread_t);                /* XXX kludge for <machine/thread.h> */
 void IOKitInitializeTime(void);                /* XXX */
 void IOSleep(unsigned int);            /* XXX */
@@ -970,16 +966,6 @@ bsd_init(void)
        consider_zone_gc(FALSE);
 #endif
 
-#if CONFIG_EMBEDDED
-       /*
-        * XXX workaround for:
-        * <rdar://problem/6378731> Kirkwood7A135: PPP KEXT no longer loads
-        */
-       OSKextLoadKextWithIdentifier("com.apple.nke.ppp");
-       OSKextLoadKextWithIdentifier("com.apple.nke.l2tp");
-       OSKextLoadKextWithIdentifier("com.apple.nke.pptp");
-#endif
-
        bsd_init_kprintf("done\n");
 }
 
index b829fa26d1eb338499606364d82ec2ff570d7723..a2983db0a5a75bff05d78543de2664b260f150a7 100644 (file)
@@ -1200,7 +1200,7 @@ check_for_our_aiocbp:
         */
 
        error = msleep1(&p->AIO_SUSPEND_SLEEP_CHAN, aio_proc_mutex(p), PCATCH | PWAIT | PDROP, "aio_suspend", abstime); /* XXX better priority? */
-       if ( error == THREAD_AWAKENED ) {
+       if ( error == 0 ) {
                /* 
                 * got our wakeup call from aio_work_thread().
                 * Since we can get a wakeup on this channel from another thread in the 
@@ -1211,7 +1211,7 @@ check_for_our_aiocbp:
                 */
                goto check_for_our_aiocbp;
        }
-       else if ( error == THREAD_TIMED_OUT ) {
+       else if ( error == EWOULDBLOCK ) {
                /* our timeout expired */
                error = EAGAIN;
        }
index ddf2bb279c5a58f4a5b4acaedf8fa7c1049ceb5a..dbe726901a606ce8d566a58826b569ce8869d270 100644 (file)
@@ -4699,9 +4699,10 @@ filetype_issendable(file_type_t fdtype)
                case DTYPE_VNODE:
                case DTYPE_SOCKET:
                case DTYPE_PIPE:
+               case DTYPE_PSXSHM:
                        return TRUE;
                default:
-                       /* DTYPE_KQUEUE, DTYPE_FSEVENTS, DTYPE_PSXSHM, DTYPE_PSXSEM */
+                       /* DTYPE_KQUEUE, DTYPE_FSEVENTS, DTYPE_PSXSEM */
                        return FALSE;
        }
 }
index 92448a3f5b2e8b7bda0656221ed2b91ed74d9f71..1a0f609ca828a718151f96e7156ecaa605a85eb0 100644 (file)
@@ -1510,19 +1510,27 @@ kevent_register(struct kqueue *kq, struct kevent64_s *kev, __unused struct proc
 
                        error = fops->f_attach(kn);
 
-                       /*
-                        * Anyone trying to drop this knote will yield to
-                        * us, since KN_ATTACHING is set.
-                        */
                        kqlock(kq);
-                       if (error != 0 || (kn->kn_status & KN_DROPPING)) {
-                               if (error == 0) {
-                                       kn->kn_fop->f_detach(kn);
-                               }
+                       if (error != 0) {
+                               /*
+                                * Failed to attach correctly, so drop.
+                                * All other possible users/droppers
+                                * have deferred to us.
+                                */
                                kn->kn_status |= KN_DROPPING;
                                kqunlock(kq);
                                knote_drop(kn, p);
                                goto done;
+                       } else if (kn->kn_status & KN_DROPPING) {
+                               /*
+                                * Attach succeeded, but someone else
+                                * deferred their drop - now we have
+                                * to do it for them (after detaching).
+                                */
+                               kqunlock(kq);
+                               kn->kn_fop->f_detach(kn);
+                               knote_drop(kn, p);
+                               goto done;
                        }
                        kn->kn_status &= ~KN_ATTACHING;
                        kqunlock(kq);
index 14e071826ebe85ecb5ee7cf4a395332e7fc18a2a..af3ed82cc320bfa745c33a0d12bc18792c3e1d02 100644 (file)
@@ -609,31 +609,8 @@ sysctl_mib_init(void)
        x86_64_flag = ((_get_cpu_capabilities() & k64Bit) == k64Bit)? 1 : 0;
 
        /* hw.cpufamily */
-       switch (cpuid_info()->cpuid_family) {
-       case 6:
-               switch (cpuid_info()->cpuid_model) {
-               case 13:
-                       cpufamily = CPUFAMILY_INTEL_6_13;
-                       break;
-               case 14:
-                       cpufamily = CPUFAMILY_INTEL_6_14; /* Core Solo/Duo */
-                       break;
-               case 15:
-                       cpufamily = CPUFAMILY_INTEL_6_15; /* Core 2 */
-                       break;
-               case 23:
-                       cpufamily = CPUFAMILY_INTEL_6_23;
-                       break;
-               case 26:
-                       cpufamily = CPUFAMILY_INTEL_6_26;
-                       break;
-               default:
-                       cpufamily = CPUFAMILY_UNKNOWN;
-               }
-               break;
-       default:
-               cpufamily = CPUFAMILY_UNKNOWN;
-       }
+       cpufamily = cpuid_cpufamily();
+
        /* hw.cacheconfig */
        cacheconfig[0] = ml_cpu_cache_sharing(0);
        cacheconfig[1] = ml_cpu_cache_sharing(1);
index 89181a010230ef3e49cb43ad0928f24252928470..a6a0ab766cfa5318e08cadb0c74feaf394b2928f 100644 (file)
@@ -319,9 +319,13 @@ load_machfile(
        } else
                map = new_map;
 
+#ifndef        CONFIG_ENFORCE_SIGNED_CODE
+       /* This turns off faulting for executable pages, which allows to 
+        * circumvent Code Signing Enforcement */
        if ( (header->flags & MH_ALLOW_STACK_EXECUTION) )
                vm_map_disable_NX(map);
-               
+#endif
+       
        if (!result)
                result = &myresult;
 
index 74ac085698f7ebed0785bfe721e4cc549cbf7e8f..d9ec5b13733aad96530454555c87b8d00ec1772d 100644 (file)
@@ -94,7 +94,6 @@
 #include <sys/ttycom.h>
 #include <sys/filedesc.h>
 #include <sys/uio_internal.h>
-#include <sys/fcntl.h>
 #include <sys/file_internal.h>
 #include <sys/event.h>
 
@@ -470,20 +469,6 @@ bpf_attachd(struct bpf_d *d, struct bpf_if *bp)
        bp->bif_dlist = d;
        
        if (first) {
-               bpf_tap_mode tap_mode;
-
-               switch ((d->bd_oflags & (FREAD | FWRITE))) {
-                       case FREAD:
-                               tap_mode = BPF_TAP_INPUT;
-                               break;
-                       case FWRITE:
-                               tap_mode = BPF_TAP_OUTPUT;
-                               break;
-                       default:
-                               tap_mode = BPF_TAP_INPUT_OUTPUT;
-                               break;
-               }
-
                /* Find the default bpf entry for this ifp */
                if (bp->bif_ifp->if_bpf == NULL) {
                        struct bpf_if   *primary;
@@ -497,10 +482,10 @@ bpf_attachd(struct bpf_d *d, struct bpf_if *bp)
                
                /* Only call dlil_set_bpf_tap for primary dlt */
                if (bp->bif_ifp->if_bpf == bp)
-                       dlil_set_bpf_tap(bp->bif_ifp, tap_mode, bpf_tap_callback);
+                       dlil_set_bpf_tap(bp->bif_ifp, BPF_TAP_INPUT_OUTPUT, bpf_tap_callback);
                
                if (bp->bif_tap)
-                       error = bp->bif_tap(bp->bif_ifp, bp->bif_dlt, tap_mode);
+                       error = bp->bif_tap(bp->bif_ifp, bp->bif_dlt, BPF_TAP_INPUT_OUTPUT);
        }
 
        return error;
index d679efc8b1401919f88395666ee0ad3374b6e801..e82208b12ef23f845d1d71eaddf2ee394d18f18f 100644 (file)
@@ -1522,6 +1522,22 @@ preout_again:
 
        do {
                if (raw == 0 && ifp->if_framer) {
+                       int rcvif_set = 0;
+
+                       /*
+                        * If this is a broadcast packet that needs to be
+                        * looped back into the system, set the inbound ifp
+                        * to that of the outbound ifp.  This will allow
+                        * us to determine that it is a legitimate packet
+                        * for the system.  Only set the ifp if it's not
+                        * already set, just to be safe.
+                        */
+                       if ((m->m_flags & (M_BCAST | M_LOOP)) &&
+                           m->m_pkthdr.rcvif == NULL) {
+                               m->m_pkthdr.rcvif = ifp;
+                               rcvif_set = 1;
+                       }
+
                        retval = ifp->if_framer(ifp, &m, dest, dst_linkaddr, frame_type); 
                        if (retval) {
                                if (retval != EJUSTRETURN) {
@@ -1529,6 +1545,18 @@ preout_again:
                                }
                                goto next;
                        }
+
+                       /*
+                        * Clear the ifp if it was set above, and to be
+                        * safe, only if it is still the same as the
+                        * outbound ifp we have in context.  If it was
+                        * looped back, then a copy of it was sent to the
+                        * loopback interface with the rcvif set, and we
+                        * are clearing the one that will go down to the
+                        * layer below.
+                        */
+                       if (rcvif_set && m->m_pkthdr.rcvif == ifp)
+                               m->m_pkthdr.rcvif = NULL;
                }
        
 #if BRIDGE
@@ -2579,7 +2607,7 @@ ifnet_attach(
 #define _offsetof(t, m) ((uintptr_t)((caddr_t)&((t *)0)->m))
                masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;
                socksize = masklen + ifp->if_addrlen;
-#define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
+#define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(u_int32_t) - 1)))
                if ((u_int32_t)socksize < sizeof(struct sockaddr_dl))
                        socksize = sizeof(struct sockaddr_dl);
                socksize = ROUNDUP(socksize);
index 66082731e3f515d0475cb843a2fc0b799a17f687..937341b00a139fbc0d60355a646248c78b3196df 100644 (file)
@@ -1756,7 +1756,8 @@ makeroute:
                 * it doesn't fire when we call it there because the node
                 * hasn't been added to the tree yet.
                 */
-               if (!(rt->rt_flags & RTF_HOST) && rt_mask(rt) != 0) {
+               if (req == RTM_ADD &&
+                   !(rt->rt_flags & RTF_HOST) && rt_mask(rt) != 0) {
                        struct rtfc_arg arg;
                        arg.rnh = rnh;
                        arg.rt0 = rt;
@@ -1842,7 +1843,7 @@ rt_fixchange(struct radix_node *rn, void *vp)
        struct rtentry *rt0 = ap->rt0;
        struct radix_node_head *rnh = ap->rnh;
        u_char *xk1, *xm1, *xk2, *xmp;
-       int i, len, mlen;
+       int i, len;
 
        lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
 
@@ -1867,19 +1868,24 @@ rt_fixchange(struct radix_node *rn, void *vp)
        xm1 = (u_char *)rt_mask(rt0);
        xk2 = (u_char *)rt_key(rt);
 
-       /* avoid applying a less specific route */
-       xmp = (u_char *)rt_mask(rt->rt_parent);
-       mlen = rt_key(rt->rt_parent)->sa_len;
-       if (mlen > rt_key(rt0)->sa_len) {
-               RT_UNLOCK(rt);
-               return (0);
-       }
-
-       for (i = rnh->rnh_treetop->rn_offset; i < mlen; i++) {
-               if ((xmp[i] & ~(xmp[i] ^ xm1[i])) != xmp[i]) {
+       /*
+        * Avoid applying a less specific route; do this only if the parent
+        * route (rt->rt_parent) is a network route, since otherwise its mask
+        * will be NULL if it is a cloning host route.
+        */
+       if ((xmp = (u_char *)rt_mask(rt->rt_parent)) != NULL) {
+               int mlen = rt_mask(rt->rt_parent)->sa_len;
+               if (mlen > rt_mask(rt0)->sa_len) {
                        RT_UNLOCK(rt);
                        return (0);
                }
+
+               for (i = rnh->rnh_treetop->rn_offset; i < mlen; i++) {
+                       if ((xmp[i] & ~(xmp[i] ^ xm1[i])) != xmp[i]) {
+                               RT_UNLOCK(rt);
+                               return (0);
+                       }
+               }
        }
 
        for (i = rnh->rnh_treetop->rn_offset; i < len; i++) {
index 2a1fef6d446d9b6e0c1c4f1e764e1e417b87bc33..eaf005f60cdd87b7532d5731f648a7920e72babd 100644 (file)
@@ -629,10 +629,13 @@ loopit:
                ro->ro_rt->rt_use++;
                if (ro->ro_rt->rt_flags & RTF_GATEWAY)
                        dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
-               if (ro->ro_rt->rt_flags & RTF_HOST)
+               if (ro->ro_rt->rt_flags & RTF_HOST) {
                        isbroadcast = (ro->ro_rt->rt_flags & RTF_BROADCAST);
-               else
+               } else {
+                       /* Become a regular mutex */
+                       RT_CONVERT_LOCK(ro->ro_rt);
                        isbroadcast = in_broadcast(dst->sin_addr, ifp);
+               }
                RT_UNLOCK(ro->ro_rt);
        }
 
@@ -1390,11 +1393,14 @@ skip_ipsec:
                        ro_fwd->ro_rt->rt_use++;
                        if (ro_fwd->ro_rt->rt_flags & RTF_GATEWAY)
                                dst = (struct sockaddr_in *)ro_fwd->ro_rt->rt_gateway;
-                       if (ro_fwd->ro_rt->rt_flags & RTF_HOST)
+                       if (ro_fwd->ro_rt->rt_flags & RTF_HOST) {
                                isbroadcast =
                                    (ro_fwd->ro_rt->rt_flags & RTF_BROADCAST);
-                       else
+                       } else {
+                               /* Become a regular mutex */
+                               RT_CONVERT_LOCK(ro_fwd->ro_rt);
                                isbroadcast = in_broadcast(dst->sin_addr, ifp);
+                       }
                        RT_UNLOCK(ro_fwd->ro_rt);
                        rtfree(ro->ro_rt);
                        ro->ro_rt = ro_fwd->ro_rt;
index b642c4298ba4c725747ff42622f7c8c8344093be..e7fda107f4a0ff73bc50891ea0ae101146184f46 100644 (file)
@@ -1035,26 +1035,62 @@ findpcb:
                        head_ifscope = (inp->inp_flags & INP_BOUND_IF) ?
                            inp->inp_boundif : IFSCOPE_NONE;
 
-#if !IPSEC
                        /*
-                        * Current IPsec implementation makes incorrect IPsec
-                        * cache if this check is done here.
-                        * So delay this until duplicated socket is created.
+                        * If the state is LISTEN then ignore segment if it contains an RST.
+                        * If the segment contains an ACK then it is bad and send a RST.
+                        * If it does not contain a SYN then it is not interesting; drop it.
+                        * If it is from this socket, drop it, it must be forged.
                         */
                        if ((thflags & (TH_RST|TH_ACK|TH_SYN)) != TH_SYN) {
-                               /*
-                                * Note: dropwithreset makes sure we don't
-                                * send a RST in response to a RST.
-                                */
+                               if (thflags & TH_RST) {
+                                       goto drop;
+                               }
                                if (thflags & TH_ACK) {
+                                       tp = NULL;
                                        tcpstat.tcps_badsyn++;
                                        rstreason = BANDLIM_RST_OPENPORT;
                                        goto dropwithreset;
                                }
+
+                               /* We come here if there is no SYN set */
+                               tcpstat.tcps_badsyn++;
                                goto drop;
                        }
-#endif
                        KERNEL_DEBUG(DBG_FNC_TCP_NEWCONN | DBG_FUNC_START,0,0,0,0,0);
+                       if (th->th_dport == th->th_sport) {
+#if INET6
+                               if (isipv6) {
+                                       if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
+                                                       &ip6->ip6_src))
+                                               goto drop;
+                               } else
+#endif /* INET6 */
+                                       if (ip->ip_dst.s_addr == ip->ip_src.s_addr)
+                                               goto drop;
+                       }
+                       /*
+                        * RFC1122 4.2.3.10, p. 104: discard bcast/mcast SYN
+                        * in_broadcast() should never return true on a received
+                        * packet with M_BCAST not set.
+                        *
+                        * Packets with a multicast source address should also
+                        * be discarded.
+                        */
+                       if (m->m_flags & (M_BCAST|M_MCAST))
+                               goto drop;
+#if INET6
+                       if (isipv6) {
+                               if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
+                                       IN6_IS_ADDR_MULTICAST(&ip6->ip6_src))
+                                       goto drop;
+                       } else
+#endif
+                       if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
+                               IN_MULTICAST(ntohl(ip->ip_src.s_addr)) ||
+                               ip->ip_src.s_addr == htonl(INADDR_BROADCAST) ||
+                               in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif))
+                               goto drop;
+
 
 #if INET6
                        /*
@@ -1146,8 +1182,6 @@ findpcb:
                        so = so2;
                        tcp_lock(so, 1, 0);
                        /*
-                        * This is ugly, but ....
-                        *
                         * Mark socket as temporary until we're
                         * committed to keeping it.  The code at
                         * ``drop'' and ``dropwithreset'' check the
@@ -1155,9 +1189,10 @@ findpcb:
                         * socket created here should be discarded.
                         * We mark the socket as discardable until
                         * we're committed to it below in TCPS_LISTEN.
+                        * There are some error conditions in which we
+                        * have to drop the temporary socket.
                         */
                        dropsocket++;
-
                        /*
                         * Inherit INP_BOUND_IF from listener; testing if
                         * head_ifscope is non-zero is sufficient, since it
@@ -1179,7 +1214,7 @@ findpcb:
                                inp->inp_vflag &= ~INP_IPV6;
                                inp->inp_vflag |= INP_IPV4;
 #endif /* INET6 */
-                       inp->inp_laddr = ip->ip_dst;
+                               inp->inp_laddr = ip->ip_dst;
 #if INET6
                        }
 #endif /* INET6 */
@@ -1200,30 +1235,6 @@ findpcb:
                                tcp_unlock(oso, 1, 0);
                                goto drop;
                        }
-#if IPSEC
-                       /*
-                        * To avoid creating incorrectly cached IPsec
-                        * association, this is need to be done here.
-                        *
-                        * Subject: (KAME-snap 748)
-                        * From: Wayne Knowles <w.knowles@niwa.cri.nz>
-                        * ftp://ftp.kame.net/pub/mail-list/snap-users/748
-                        */
-                       if ((thflags & (TH_RST|TH_ACK|TH_SYN)) != TH_SYN) {
-                               /*
-                                * Note: dropwithreset makes sure we don't
-                                * send a RST in response to a RST.
-                                */
-                               tcp_lock(oso, 0, 0);    /* release ref on parent */
-                               tcp_unlock(oso, 1, 0);
-                               if (thflags & TH_ACK) {
-                                       tcpstat.tcps_badsyn++;
-                                       rstreason = BANDLIM_RST_OPENPORT;
-                                       goto dropwithreset;
-                               }
-                               goto drop;
-                       }
-#endif
 #if INET6
                        if (isipv6) {
                                /*
@@ -1664,12 +1675,7 @@ findpcb:
        switch (tp->t_state) {
 
        /*
-        * If the state is LISTEN then ignore segment if it contains an RST.
-        * If the segment contains an ACK then it is bad and send a RST.
-        * If it does not contain a SYN then it is not interesting; drop it.
-        * If it is from this socket, drop it, it must be forged.
-        * Don't bother responding if the destination was a broadcast.
-        * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial
+        * Initialize tp->rcv_nxt, and tp->irs, select an initial
         * tp->iss, and send a segment:
         *     <SEQ=ISS><ACK=RCV_NXT><CTL=SYN,ACK>
         * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss.
@@ -1686,47 +1692,6 @@ findpcb:
 #if 1
                lck_mtx_assert(((struct inpcb *)so->so_pcb)->inpcb_mtx, LCK_MTX_ASSERT_OWNED);
 #endif
-               if (thflags & TH_RST) 
-                       goto drop;
-               if (thflags & TH_ACK) {
-                       rstreason = BANDLIM_RST_OPENPORT;
-                       goto dropwithreset;
-               }
-               if ((thflags & TH_SYN) == 0)
-                       goto drop;
-               if (th->th_dport == th->th_sport) {
-#if INET6
-                       if (isipv6) {
-                               if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
-                                                      &ip6->ip6_src))
-                                       goto drop;
-                       } else
-#endif /* INET6 */
-                       if (ip->ip_dst.s_addr == ip->ip_src.s_addr)
-                               goto drop;
-               }
-               /*
-                * RFC1122 4.2.3.10, p. 104: discard bcast/mcast SYN
-                * in_broadcast() should never return true on a received
-                * packet with M_BCAST not set.
-                *
-                * Packets with a multicast source address should also
-                * be discarded.
-                */
-               if (m->m_flags & (M_BCAST|M_MCAST))
-                       goto drop;
-#if INET6
-               if (isipv6) {
-                       if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
-                           IN6_IS_ADDR_MULTICAST(&ip6->ip6_src))
-                               goto drop;
-               } else
-#endif
-               if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
-                   IN_MULTICAST(ntohl(ip->ip_src.s_addr)) ||
-                   ip->ip_src.s_addr == htonl(INADDR_BROADCAST) ||
-                   in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif))
-                       goto drop;
 #if INET6
                if (isipv6) {
                        MALLOC(sin6, struct sockaddr_in6 *, sizeof *sin6,
index c9f7075f40a02dc89c529c3492492e4077bc4c13..202d8ccb1a9d90d175c59a3e6c91fb2a3b073022 100644 (file)
@@ -552,6 +552,7 @@ ip6_forward(struct mbuf *m, struct route_in6 *ip6forward_rt,
                type = ND_REDIRECT;
        }
 
+#if IPFW2
        /*
         * Check with the firewall...
         */
@@ -571,6 +572,7 @@ ip6_forward(struct mbuf *m, struct route_in6 *ip6forward_rt,
                /* We still have the extra ref on rt */
                RT_LOCK(rt);
        }
+#endif
 
        /*
         * Fake scoped addresses. Note that even link-local source or
index 390be10d1703e311491a2dcc8a1d53197e39e979..1c19434ab1fa88cc9a65e92e039a75ca37c87550 100644 (file)
@@ -170,10 +170,12 @@ int ip6_ours_check_algorithm;
 int in6_init2done = 0;
 
 
+#if IPFW2
 /* firewall hooks */
 ip6_fw_chk_t *ip6_fw_chk_ptr;
 ip6_fw_ctl_t *ip6_fw_ctl_ptr;
 int ip6_fw_enable = 1;
+#endif
 
 struct ip6stat ip6stat;
 
@@ -481,6 +483,7 @@ ip6_input(m)
 
        ip6stat.ip6s_nxthist[ip6->ip6_nxt]++;
 
+#if IPFW2
        /*
         * Check with the firewall...
         */
@@ -497,6 +500,7 @@ ip6_input(m)
                        return;
                }
        }
+#endif
 
        /*
         * Check against address spoofing/corruption.
index 2827c1ca4b2670c041850a6968fcd6aa5d84c443..e426933c6f8bf16f5043b531250757eef22df864 100644 (file)
@@ -1009,6 +1009,7 @@ skip_ipsec2:;
        in6_clearscope(&ip6->ip6_dst);
 #endif
 
+#if IPFW2
        /*
         * Check with the firewall...
         */
@@ -1025,6 +1026,7 @@ skip_ipsec2:;
                        goto done;
                }
        }
+#endif
 
        /*
         * If the outgoing packet contains a hop-by-hop options header,
index 8fb3931cbd8920f3a665d39f5d852a4339a0a7d0..762258e4554d67e4d1ec39f5a64660f39820b12a 100644 (file)
@@ -515,11 +515,13 @@ rip6_output(
        return(error);
 }
 
+#if IPFW2
 static void
 load_ip6fw(void)
 {
        ip6_fw_init();
 }
+#endif
 
 /*
  * Raw IPv6 socket option processing.
@@ -545,6 +547,7 @@ rip6_ctloutput(
        switch (sopt->sopt_dir) {
        case SOPT_GET:
                switch (sopt->sopt_name) {
+#if IPFW2
                case IPV6_FW_ADD:
                case IPV6_FW_GET:
                        if (ip6_fw_ctl_ptr == 0)
@@ -554,6 +557,7 @@ rip6_ctloutput(
                        else
                                error = ENOPROTOOPT;
                        break;
+#endif
 
                case MRT6_INIT:
                case MRT6_DONE:
@@ -572,6 +576,7 @@ rip6_ctloutput(
 
        case SOPT_SET:
                switch (sopt->sopt_name) {
+#if IPFW2
                case IPV6_FW_ADD:
                case IPV6_FW_DEL:
                case IPV6_FW_FLUSH:
@@ -583,6 +588,7 @@ rip6_ctloutput(
                        else
                                error = ENOPROTOOPT;
                        break;
+#endif
 
                case MRT6_INIT:
                case MRT6_DONE:
index 6ac9ffb748ed8dd9266ed919111038f3bf201c59..5ee8ea4fe4bc721de3936f455f13b9db92c51d85 100644 (file)
@@ -99,14 +99,7 @@ struct fileproc {
 #define FP_INCREATE    0x0001
 #define FP_INCLOSE     0x0002
 #define FP_INSELECT    0x0004
-/*
- * see <rdar://problem/6647955>
- */
-#if CONFIG_EMBEDDED
-#define FP_INCHRREAD   0x0000
-#else
-#define FP_INCHRREAD   0x0008
-#endif
+#define FP_INCHRREAD   0x0000  /* disable FP_INCHRREAD <rdar://6986929> */
 #define FP_WRITTEN     0x0010
 #define FP_CLOSING     0x0020
 #define FP_WAITCLOSE   0x0040
index a1288ffc6155853b55ac54506fba581e6e720105..32c2eb625f1eeaa9af0b3c251d3b55c8f7ba4042 100644 (file)
@@ -703,6 +703,7 @@ getshadowfile(vnode_t vp, vnode_t *svpp, int makestream, size_t *rsrcsize,
        /* Create the shadow stream file. */
        error = VNOP_CREATE(dvp, &svp, &cn, &va, context);
        if (error == 0) {
+               vnode_recycle(svp);
                *creator = 1;
        } else if ((error == EEXIST) && !makestream) {
                error = VNOP_LOOKUP(dvp, &svp, &cn, context);
index ec4aa8f99095ca585badbf9d3d4365e643f8c5d1..44aab8c5cc8fceb84dfe8569460cf68453a3208f 100644 (file)
@@ -1,4 +1,4 @@
-10.0.0
+10.2.0
 
 # The first line of this file contains the master version number for the kernel.
 # All other instances of the kernel version in xnu are derived from this file.
index d63943e6a91ab5267730252e65a3d8aeae89e000..f087396fddba14851a481ebf4716dc86810383d8 100644 (file)
@@ -214,14 +214,6 @@ public:
     virtual bool serialize(OSSerialize * s) const;
 
     bool serializeData(IOOptionBits kind, OSSerialize * s) const;
-    
-    /*!
-        @function removePersonalities
-        @abstract Remove exact personalities from the database.
-        @param personalitiesArray  An array of personalities to remove.
-        @result Returns true if all personalities are removed successfully. Failure is due to a memory allocation failure.
-    */
-    bool removePersonalities(OSArray * personalitiesArray);
 
 /* This stuff is no longer used at all we keep it around for PPC/i386
  * binary compatibility only. Symbols are no longer exported.
index 1186b89a159300b88aa745fefd46f40e6c70762f..fb6afd0ac7ed2302d38607f4011f115db17198dc 100644 (file)
@@ -116,6 +116,7 @@ enum
 {
     kIOPreparationIDUnprepared = 0,
     kIOPreparationIDUnsupported = 1,
+    kIOPreparationIDAlwaysPrepared = 2,
 };
 
 /*! @class IOMemoryDescriptor : public OSObject
index ae24a19d60caa09e7199f0d426def986507eed91..38811b63ae59e0ec9616f220c024da05a8c9a2d8 100644 (file)
@@ -60,6 +60,7 @@ typedef       kern_return_t           IOReturn;
 #define sub_iokit_ahci                    err_sub(12)
 #define sub_iokit_powermanagement         err_sub(13)
 //#define sub_iokit_hidsystem             err_sub(14)
+#define sub_iokit_scsi                    err_sub(16)
 //#define sub_iokit_pccard                err_sub(21)
 
 #define sub_iokit_vendor_specific         err_sub(-2)
index 1285e37bad6b40852bff4103405aeb7d6ce0af06..f2f51392912a6c020255b6799af818c736183d43 100644 (file)
@@ -1785,9 +1785,7 @@ private:
     void all_done ( void );
     void start_ack_timer ( void );
     void stop_ack_timer ( void );
-    unsigned long compute_settle_time ( void );
-    IOReturn startSettleTimer ( unsigned long delay );
-    IOReturn ask_parent ( unsigned long requestedState );
+    void startSettleTimer( void );
     bool checkForDone ( void );
     bool responseValid ( unsigned long x, int pid );
     void computeDesiredState ( unsigned long tempDesire = 0 );
@@ -1840,6 +1838,7 @@ private:
        void removePowerClient( const OSSymbol * client );
        uint32_t getPowerStateForClient( const OSSymbol * client );
     IOReturn requestPowerState( const OSSymbol * client, uint32_t state );
+    IOReturn requestDomainPower( unsigned long ourPowerState, IOOptionBits options = 0 );
 #endif /* XNU_KERNEL_PRIVATE */
 };
 
index d7738cb393a85da64508cc3b88403ca87164c415..8c51eed8472570af85d563a859785dffc1ebf317 100644 (file)
@@ -656,64 +656,6 @@ static IOReturn _removeDrivers( OSArray * array, OSDictionary * matching )
     return ret;
 }
 
-bool IOCatalogue::removePersonalities(OSArray * personalitiesToRemove)
-{
-    bool                   result           = true;
-    OSArray              * arrayCopy        = NULL;  // do not release
-    OSCollectionIterator * iterator         = NULL;  // must release
-    OSDictionary         * personality      = NULL;  // do not release
-    OSDictionary         * checkPersonality = NULL;  // do not release
-    unsigned int           count, i;
-
-    // remove configs from catalog.
-
-    arrayCopy = OSArray::withArray(array);
-    if (!arrayCopy) {
-        result = false;
-        goto finish;
-    }
-
-    iterator = OSCollectionIterator::withCollection(arrayCopy);
-    arrayCopy->release();
-    if (!iterator) {
-        result = false;
-        goto finish;
-    }
-
-    array->flushCollection();
-
-    count = personalitiesToRemove->getCount();
-
-   /* Go through the old catalog's list of personalities and add back any that
-    * are *not* found in 'personalitiesToRemove'.
-    */
-    while ((personality = (OSDictionary *)iterator->getNextObject())) {
-        bool found = false;
-
-        for (i = 0; i < count; i++) {
-            checkPersonality = OSDynamicCast(OSDictionary,
-                personalitiesToRemove->getObject(i));
-
-           /* Do isEqualTo() with the single-arg version to make an exact
-            * comparison (unlike _removeDrivers() above).
-            */
-            if (personality->isEqualTo(checkPersonality)) {
-                found = true;
-                break;
-            }
-        }
-
-        if (!found) {
-            array->setObject(personality);
-        }
-    }
-
-finish:
-
-    OSSafeRelease(iterator);
-    return result;
-}
-
 IOReturn IOCatalogue::terminateDrivers(OSDictionary * matching)
 {
     IOReturn ret;
index 9aef6a1a0e23952d7958a853cd1f1e9491f390ed..f60f612dc45f796afb3f17c85aea6429258fb598 100644 (file)
@@ -1174,8 +1174,16 @@ uint64_t
 IOGeneralMemoryDescriptor::getPreparationID( void )
 {
     ioGMDData *dataP;
-    if (!_wireCount || !(dataP = getDataP(_memoryEntries)))
+
+    if (!_wireCount)
        return (kIOPreparationIDUnprepared);
+
+    if (_flags & (kIOMemoryTypePhysical | kIOMemoryTypePhysical64))
+       return (kIOPreparationIDAlwaysPrepared);
+
+    if (!_memoryEntries || !(dataP = getDataP(_memoryEntries)))
+       return (kIOPreparationIDUnprepared);
+
     if (kIOPreparationIDUnprepared == dataP->fPreparationID)
     {
 #if defined(__ppc__ )
@@ -1229,11 +1237,11 @@ IOReturn IOGeneralMemoryDescriptor::dmaCommandOperation(DMACommandOps op, void *
 #if IOMD_DEBUG_DMAACTIVE
     } else if (kIOMDSetDMAActive == op) {
        IOGeneralMemoryDescriptor * md = const_cast<IOGeneralMemoryDescriptor *>(this);
-       md->__iomd_reservedA++;
+       OSIncrementAtomic(&md->__iomd_reservedA);
     } else if (kIOMDSetDMAInactive == op) {
        IOGeneralMemoryDescriptor * md = const_cast<IOGeneralMemoryDescriptor *>(this);
        if (md->__iomd_reservedA)
-           md->__iomd_reservedA--;
+           OSDecrementAtomic(&md->__iomd_reservedA);
        else
            panic("kIOMDSetDMAInactive");
 #endif /* IOMD_DEBUG_DMAACTIVE */
@@ -2951,7 +2959,8 @@ IOReturn IOMemoryDescriptor::doUnmap(
        length     = ((IOMemoryMap *) __address)->fLength;
     }
 
-    if( _memEntry && (addressMap == kernel_map) && (kIOMemoryBufferPageable & _flags))
+    if ((addressMap == kernel_map) 
+        && ((kIOMemoryBufferPageable & _flags) || !_memEntry))
        addressMap = IOPageableMapForAddress( address );
 
 #if DEBUG
index 2f46106084b756cdb12be868213afd4815b0088a..fd150a4f64290e91816765fe434a652f47b606ff 100644 (file)
@@ -69,13 +69,6 @@ static uint64_t computeTimeDeltaNS( const AbsoluteTime * start )
 OSDefineMetaClassAndStructors(IOPMprot, OSObject)
 #endif
 
-// log setPowerStates longer than (ns):
-#define LOG_SETPOWER_TIMES      (50ULL * 1000ULL * 1000ULL)
-// log app responses longer than (ns):
-#define LOG_APP_RESPONSE_TIMES  (100ULL * 1000ULL * 1000ULL)
-// use message tracer to log messages longer than (ns):
-#define LOG_APP_RESPONSE_MSG_TRACER  (3 * 1000ULL * 1000ULL * 1000ULL)
-
 //*********************************************************************************
 // Globals
 //*********************************************************************************
@@ -107,10 +100,9 @@ static uint32_t getPMRequestType( void )
 // Macros
 //*********************************************************************************
 
-#define PM_ERROR(x...)          do { kprintf(x); IOLog(x); } while (false)
-#define PM_DEBUG(x...)          do { kprintf(x); } while (false)
-
-#define PM_TRACE(x...)          do {  \
+#define PM_ERROR(x...)              do { kprintf(x); IOLog(x); } while (false)
+#define PM_DEBUG(x...)              do { kprintf(x); } while (false)
+#define PM_TRACE(x...)              do {  \
        if (kIOLogDebugPower & gIOKitDebug) kprintf(x); } while (false)
 
 #define PM_CONNECT(x...)
@@ -147,6 +139,21 @@ do {                                  \
 #define kIOPMPowerStateMax          0xFFFFFFFF  
 
 #define IS_PM_ROOT()                (this == gIOPMRootNode)
+#define IS_POWER_DROP               (fHeadNotePowerState < fCurrentPowerState)
+#define IS_POWER_RISE               (fHeadNotePowerState > fCurrentPowerState)
+
+// log setPowerStates longer than (ns):
+#define LOG_SETPOWER_TIMES          (50ULL * 1000ULL * 1000ULL)
+// log app responses longer than (ns):
+#define LOG_APP_RESPONSE_TIMES      (100ULL * 1000ULL * 1000ULL)
+// use message tracer to log messages longer than (ns):
+#define LOG_APP_RESPONSE_MSG_TRACER (3 * 1000ULL * 1000ULL * 1000ULL)
+
+#define RESERVE_DOMAIN_POWER        1
+
+enum {
+    kReserveDomainPower = 1
+};
 
 //*********************************************************************************
 // PM machine states
@@ -475,7 +482,7 @@ void IOService::PMinit ( void )
 //*********************************************************************************
 // [private] PMfree
 //
-// Free up the data created in PMinit, if it exists.
+// Free the data created by PMinit. Only called from IOService::free().
 //*********************************************************************************
 
 void IOService::PMfree ( void )
@@ -590,8 +597,6 @@ void IOService::joinPMtree ( IOService * driver )
 // [deprecated] youAreRoot
 //
 // Power Managment is informing us that we are the root power domain.
-// The only difference between us and any other power domain is that
-// we have no parent and therefore never call it.
 //*********************************************************************************
 
 IOReturn IOService::youAreRoot ( void )
@@ -1793,7 +1798,7 @@ void IOService::handlePowerDomainDidChangeTo ( IOPMRequest * request )
        {
                PM_TRACE("%s::powerDomainDidChangeTo parentsKnowState = true\n",
                        getName());
-               ask_parent( fDesiredPowerState );
+               requestDomainPower( fDesiredPowerState );
        }
 
 exit_no_ack:
@@ -1906,20 +1911,20 @@ void IOService::rebuildChildClampBits ( void )
 //*********************************************************************************
 // [public] requestPowerDomainState
 //
-// The child of a power domain calls it parent here to request power of a certain
-// character.
+// Called on a power parent when a child's power requirement changes.
 //*********************************************************************************
 
-IOReturn IOService::requestPowerDomainState (
-       IOPMPowerFlags          desiredState,
-       IOPowerConnection *     whichChild,
-       unsigned long           specification )
+IOReturn IOService::requestPowerDomainState(
+    IOPMPowerFlags      childRequestPowerFlags,
+    IOPowerConnection * childConnection,
+    unsigned long              specification )
 {
-    unsigned long              i;
-    unsigned long              computedState;
-    unsigned long              theDesiredState;
-       IOService *                     child;
-       IOPMRequest *           childRequest;
+    unsigned long       ps;
+       IOPMPowerFlags          outputPowerFlags;
+    IOService *         child;
+       IOPMRequest *       subRequest;
+    bool                preventIdle, preventSleep; 
+    bool                adjustPower = false;
 
     if (!initialized)
                return IOPMNotYetInitialized;
@@ -1930,131 +1935,144 @@ IOReturn IOService::requestPowerDomainState (
                return kIOReturnSuccess;
        }
 
-       theDesiredState = desiredState & ~(kIOPMPreventIdleSleep | kIOPMPreventSystemSleep);
+    OUR_PMLog(kPMLogRequestDomain, childRequestPowerFlags, specification);
 
-    OUR_PMLog(kPMLogRequestDomain, desiredState, specification);
-
-       if (!isChild(whichChild, gIOPowerPlane))
+       if (!isChild(childConnection, gIOPowerPlane))
                return kIOReturnNotAttached;
 
-    if (fControllingDriver == NULL || !fPowerStates)
+    if (!fControllingDriver || !fNumberOfPowerStates)
         return IOPMNotYetInitialized;
 
-       child = (IOService *) whichChild->getChildEntry(gIOPowerPlane);
+       child = (IOService *) childConnection->getChildEntry(gIOPowerPlane);
        assert(child);
 
-    switch (specification) {
-        case IOPMLowestState:
-            i = 0;
-            while ( i < fNumberOfPowerStates )
-            {
-                if ( ( fPowerStates[i].outputPowerCharacter & theDesiredState) ==
-                                        (theDesiredState & fOutputPowerCharacterFlags) )
-                {
-                    break;
-                }
-                i++;
-            }
-            if ( i >= fNumberOfPowerStates )
-            {
-                return IOPMNoSuchState;
-            }
-            break;
+    preventIdle  = ((childRequestPowerFlags & kIOPMPreventIdleSleep) != 0);
+    preventSleep = ((childRequestPowerFlags & kIOPMPreventSystemSleep) != 0);
+    childRequestPowerFlags &= ~(kIOPMPreventIdleSleep | kIOPMPreventSystemSleep);
 
-        case IOPMNextLowerState:
-            i = fCurrentPowerState - 1;
-            while ( (int) i >= 0 )
-            {
-                if ( ( fPowerStates[i].outputPowerCharacter & theDesiredState) ==
-                                        (theDesiredState & fOutputPowerCharacterFlags) )
-                {
-                    break;
-                }
-                i--;
-            }
-            if ( (int) i < 0 )
-            {
-                return IOPMNoSuchState;
-            }
-            break;
+    // Merge in the power flags contributed by this power parent
+    // at its current or impending power state. 
 
-        case IOPMHighestState:
-            i = fNumberOfPowerStates;
-            while ( (int) i >= 0 )
-            {
-                i--;
-                if ( ( fPowerStates[i].outputPowerCharacter & theDesiredState) ==
-                                        (theDesiredState & fOutputPowerCharacterFlags) )
-                {
-                    break;
-                }
-            }
-            if ( (int) i < 0 )
-            {
-                return IOPMNoSuchState;
-            }
-            break;
+    outputPowerFlags = fPowerStates[fCurrentPowerState].outputPowerCharacter;
+       if ((fMachineState != kIOPM_Finished) && (getPMRootDomain() != this))
+       {
+               if (IS_POWER_DROP)
+               {
+                       // Use the lower power state when dropping power. 
+                       // Must be careful since a power drop can be canceled
+                       // from the following states:
+                       // - kIOPM_OurChangeTellClientsPowerDown
+                       // - kIOPM_OurChangeTellPriorityClientsPowerDown
+                       //
+                       // The child must not wait for this parent to raise power
+                       // if the power drop was cancelled. The solution is to cancel
+                       // the power drop if possible, then schedule an adjustment to
+                       // re-evaluate our correct power state.
+                       //
+                       // Root domain is excluded to avoid idle sleep issues. And permit
+                       // root domain children to pop up when system is going to sleep.
+
+                       if ((fMachineState == kIOPM_OurChangeTellClientsPowerDown) ||
+                               (fMachineState == kIOPM_OurChangeTellPriorityClientsPowerDown))
+                       {
+                               fDoNotPowerDown = true;     // cancel power drop
+                               adjustPower     = true;     // schedule an adjustment
+                               PM_TRACE("%s: power drop cancelled in state %u by %s\n",
+                                       getName(), fMachineState, child->getName());
+                       }
+                       else
+                       {
+                               // Beyond cancellation point, report the impending state.
+                               outputPowerFlags =
+                                       fPowerStates[fHeadNotePowerState].outputPowerCharacter;
+                       }
+               }
+               else
+               {
+                       // When raising power, must report the output power flags from
+                       // child's perspective. A child power request may arrive while
+                       // parent is transitioning upwards. If a request arrives after
+                       // setParentInfo() has already recorded the output power flags
+                       // for the next power state, then using the power supplied by
+                       // fCurrentPowerState is incorrect, and might cause the child
+                       // to wait when it should not.
+                       
+                       outputPowerFlags = childConnection->parentCurrentPowerFlags();
+               }
+    }
+    child->fHeadNoteDomainTargetFlags |= outputPowerFlags;
 
-        case IOPMNextHigherState:
-            i = fCurrentPowerState + 1;
-            while ( i < fNumberOfPowerStates )
-            {
-                if ( ( fPowerStates[i].outputPowerCharacter & theDesiredState) ==
-                                        (theDesiredState & fOutputPowerCharacterFlags) )
-                {
-                    break;
-                }
-                i++;
-            }
-            if ( i == fNumberOfPowerStates )
-            {
-                return IOPMNoSuchState;
-            }
-            break;
+    // Map child's requested power flags to one of our power state.
 
-        default:
-            return IOPMBadSpecification;
+    for (ps = 0; ps < fNumberOfPowerStates; ps++)
+    {
+        if ((fPowerStates[ps].outputPowerCharacter & childRequestPowerFlags) ==
+            (fOutputPowerCharacterFlags & childRequestPowerFlags))
+            break;
+    }
+    if (ps >= fNumberOfPowerStates)
+    {
+        ps = 0;  // should never happen
     }
 
-    computedState = i;
+    // Conditions that warrants a power adjustment on this parent.
+    // Adjust power will also propagate any changes to the child's
+    // prevent idle/sleep flags towards the root domain.
+
+    if (!childConnection->childHasRequestedPower() ||
+        (ps != childConnection->getDesiredDomainState()) ||
+        (childConnection->getPreventIdleSleepFlag() != preventIdle) ||
+        (childConnection->getPreventSystemSleepFlag() != preventSleep))
+        adjustPower = true;
+
+#if ENABLE_DEBUG_LOGS
+    if (adjustPower)
+    {
+        PM_DEBUG("requestPowerDomainState[%s]: %s, init %d, %u->%u\n",
+            getName(), child->getName(),
+            !childConnection->childHasRequestedPower(),
+            (uint32_t) childConnection->getDesiredDomainState(),
+            (uint32_t) ps);
+    }
+#endif
 
        // Record the child's desires on the connection.
 #if SUPPORT_IDLE_CANCEL
-       bool attemptCancel = ((kIOPMPreventIdleSleep & desiredState) && !whichChild->getPreventIdleSleepFlag());
+       bool attemptCancel = (preventIdle && !childConnection->getPreventIdleSleepFlag());
 #endif
-       whichChild->setDesiredDomainState( computedState );
-       whichChild->setPreventIdleSleepFlag( desiredState & kIOPMPreventIdleSleep );
-       whichChild->setPreventSystemSleepFlag( desiredState & kIOPMPreventSystemSleep );
-       whichChild->setChildHasRequestedPower();
-
-       if (whichChild->getReadyFlag() == false)
-               return IOPMNoErr;
+       childConnection->setChildHasRequestedPower();
+       childConnection->setDesiredDomainState( ps );
+       childConnection->setPreventIdleSleepFlag( preventIdle );
+       childConnection->setPreventSystemSleepFlag( preventSleep );
 
        // Schedule a request to re-evaluate all children desires and
        // adjust power state. Submit a request if one wasn't pending,
        // or if the current request is part of a call tree.
 
-    if (!fDeviceOverrides && (!fAdjustPowerScheduled || gIOPMRequest->getRootRequest()))
+    if (adjustPower && !fDeviceOverrides &&
+        (!fAdjustPowerScheduled || gIOPMRequest->getRootRequest()))
     {
-               childRequest = acquirePMRequest( this, kIOPMRequestTypeAdjustPowerState, gIOPMRequest );
-               if (childRequest)
+               subRequest = acquirePMRequest(
+            this, kIOPMRequestTypeAdjustPowerState, gIOPMRequest );
+               if (subRequest)
                {
-                       submitPMRequest( childRequest );
+                       submitPMRequest( subRequest );
                        fAdjustPowerScheduled = true;
                }
-       }
+    }
+
 #if SUPPORT_IDLE_CANCEL
        if (attemptCancel)
        {
-               childRequest = acquirePMRequest( this, kIOPMRequestTypeIdleCancel );
-               if (childRequest)
+               subRequest = acquirePMRequest( this, kIOPMRequestTypeIdleCancel );
+               if (subRequest)
                {
-                       submitPMRequest( childRequest );
+                       submitPMRequest( subRequest );
                }
        }
 #endif
 
-       return IOPMNoErr;
+    return kIOReturnSuccess;
 }
 
 //*********************************************************************************
@@ -3452,6 +3470,223 @@ bool IOService::notifyChild ( IOPowerConnection * theNub, bool is_prechange )
        return (IOPMAckImplied == ret);
 }
 
+// MARK: -
+// MARK: Power Change Initiated by Driver
+
+//*********************************************************************************
+// [private] OurChangeStart
+//
+// Begin the processing of a power change initiated by us.
+//*********************************************************************************
+
+void IOService::OurChangeStart ( void )
+{
+       PM_ASSERT_IN_GATE();
+    OUR_PMLog( kPMLogStartDeviceChange, fHeadNotePowerState, fCurrentPowerState );
+
+       // fMaxCapability is our maximum possible power state based on the current
+       // power state of our parents.  If we are trying to raise power beyond the
+       // maximum, send an async request for more power to all parents.
+
+    if (!IS_PM_ROOT() && (fMaxCapability < fHeadNotePowerState))
+    {
+        fHeadNoteFlags |= kIOPMNotDone;
+        requestDomainPower(fHeadNotePowerState);
+        OurChangeFinish();
+        return;
+    }
+
+       // Redundant power changes skips to the end of the state machine.
+
+    if (!fInitialChange && (fHeadNotePowerState == fCurrentPowerState))
+       {
+               OurChangeFinish();
+               return;
+    }
+    fInitialChange = false;
+
+#if ROOT_DOMAIN_RUN_STATES
+    // Change started, but may not complete...
+    // Can be canceled (power drop) or deferred (power rise).
+
+    getPMRootDomain()->handlePowerChangeStartForService(
+                        /* service */       this,
+                        /* RD flags */      &fRootDomainState,
+                        /* new pwr state */ fHeadNotePowerState,
+                        /* change flags */  fHeadNoteFlags );
+#endif
+
+       // Two separate paths, depending if power is being raised or lowered.
+       // Lowering power is subject to approval by clients of this service.
+
+    if (IS_POWER_DROP)
+    {
+               // Next machine state for a power drop.
+        fMachineState = kIOPM_OurChangeTellClientsPowerDown;
+        fDoNotPowerDown = false;
+
+        // Ask apps and kernel clients permission to lower power.      
+        fOutOfBandParameter = kNotifyApps;
+               askChangeDown(fHeadNotePowerState);
+    }
+       else
+       {
+        // This service is raising power and parents are able to support the
+        // new power state. However a parent may have already committed to
+        // drop power, which might force this object to temporarily drop power.
+        // This results in "oscillations" before the state machines converge
+        // to a steady state.
+        //
+        // To prevent this, a child must make a power reservation against all
+        // parents before raising power. If the reservation fails, indicating
+        // that the child will be unable to sustain the higher power state,
+        // then the child will signal the parent to adjust power, and the child
+        // will defer its power change.
+
+#if RESERVE_DOMAIN_POWER
+        IOReturn ret;
+
+        // Reserve parent power necessary to achieve fHeadNotePowerState.
+        ret = requestDomainPower( fHeadNotePowerState, kReserveDomainPower );
+        if (ret != kIOReturnSuccess)
+        {
+            // Reservation failed, defer power rise.
+            fHeadNoteFlags |= kIOPMNotDone;
+            OurChangeFinish();
+            return;
+        }
+#endif
+               // Notify interested drivers and children.
+        notifyAll( kIOPM_OurChangeSetPowerState, kNotifyWillChange );
+    }
+}
+
+//*********************************************************************************
+
+struct IOPMRequestDomainPowerContext {
+    IOService *     child;              // the requesting child
+    IOPMPowerFlags  requestPowerFlags;  // power flags requested by child
+};
+
+static void
+requestDomainPowerApplier(
+    IORegistryEntry *   entry,
+    void *              inContext )
+{
+    IOPowerConnection *             connection;
+    IOService *                     parent;
+    IOPMRequestDomainPowerContext * context;
+
+    if ((connection = OSDynamicCast(IOPowerConnection, entry)) == 0)
+        return;
+    parent = (IOService *) connection->copyParentEntry(gIOPowerPlane);
+    if (!parent)
+        return;
+
+    assert(inContext);
+    context = (IOPMRequestDomainPowerContext *) inContext;
+
+    if (connection->parentKnowsState() && connection->getReadyFlag())
+    {
+        parent->requestPowerDomainState(
+            context->requestPowerFlags,
+            connection,
+            IOPMLowestState);
+    }
+
+    parent->release();
+}
+
+//*********************************************************************************
+// [private] requestDomainPower
+//*********************************************************************************
+
+IOReturn IOService::requestDomainPower(
+    unsigned long   ourPowerState,
+    IOOptionBits    options )
+{
+    const IOPMPowerState *          powerStateEntry;
+    IOPMPowerFlags                  requestPowerFlags;
+    unsigned long                   maxPowerState;
+    IOPMRequestDomainPowerContext   context;
+
+       PM_ASSERT_IN_GATE();
+    assert(ourPowerState < fNumberOfPowerStates);
+    if (ourPowerState >= fNumberOfPowerStates)
+        return kIOReturnBadArgument;
+    if (IS_PM_ROOT())
+        return kIOReturnSuccess;
+
+    // Fetch the input power flags for the requested power state.
+    // Parent request is stated in terms of required power flags.
+
+       powerStateEntry = &fPowerStates[ourPowerState];
+       requestPowerFlags = powerStateEntry->inputPowerRequirement;
+
+    if (powerStateEntry->capabilityFlags & (kIOPMChildClamp | kIOPMPreventIdleSleep))
+        requestPowerFlags |= kIOPMPreventIdleSleep;
+    if (powerStateEntry->capabilityFlags & (kIOPMChildClamp2 | kIOPMPreventSystemSleep))
+        requestPowerFlags |= kIOPMPreventSystemSleep;
+
+    // Disregard the "previous request" for power reservation.
+
+    if (((options & kReserveDomainPower) == 0) &&
+        (fPreviousRequest == requestPowerFlags))
+    {
+        // skip if domain already knows our requirements
+        goto done;
+    }
+    fPreviousRequest = requestPowerFlags;
+
+    context.child              = this;
+    context.requestPowerFlags  = requestPowerFlags;
+    fHeadNoteDomainTargetFlags = 0;
+    applyToParents(requestDomainPowerApplier, &context, gIOPowerPlane);
+
+    if (options & kReserveDomainPower)
+    {
+        maxPowerState = fControllingDriver->maxCapabilityForDomainState(
+                            fHeadNoteDomainTargetFlags );
+
+        if (maxPowerState < fHeadNotePowerState)
+        {
+            PM_TRACE("%s: power desired %u:0x%x got %u:0x%x\n",
+                getName(),
+                (uint32_t) ourPowerState, (uint32_t) requestPowerFlags,
+                (uint32_t) maxPowerState, (uint32_t) fHeadNoteDomainTargetFlags);
+            return kIOReturnNoPower;
+        }
+    }
+
+done:
+    return kIOReturnSuccess;
+}
+
+//*********************************************************************************
+// [private] OurSyncStart
+//*********************************************************************************
+
+void IOService::OurSyncStart ( void )
+{
+       PM_ASSERT_IN_GATE();
+
+    if (fInitialChange)
+        return;
+
+#if ROOT_DOMAIN_RUN_STATES
+    getPMRootDomain()->handlePowerChangeStartForService(
+                        /* service */       this,
+                        /* RD flags */      &fRootDomainState,
+                        /* new pwr state */ fHeadNotePowerState,
+                        /* change flags */  fHeadNoteFlags );
+#endif
+
+    fMachineState     = kIOPM_SyncNotifyDidChange;
+    fDriverCallReason = kDriverCallInformPreChange;
+
+    notifyChildren();
+}
+
 //*********************************************************************************
 // [private] OurChangeTellClientsPowerDown
 //
@@ -3526,20 +3761,14 @@ void IOService::OurChangeSetPowerState ( void )
 // [private] OurChangeWaitForPowerSettle
 //
 // Our controlling driver has changed power state on the hardware
-// during a power change we initiated.  Here we see if we need to wait
-// for power to settle before continuing.  If not, we continue processing
-// (notifying interested parties post-change).  If so, we wait and
-// continue later.
+// during a power change we initiated. Wait for the driver specified
+// settle time to expire, before notifying interested parties post-change.
 //*********************************************************************************
 
-void IOService::OurChangeWaitForPowerSettle ( void )
+void IOService::OurChangeWaitForPowerSettle( void )
 {
        fMachineState = kIOPM_OurChangeNotifyInterestedDriversDidChange;
-    fSettleTimeUS = compute_settle_time();
-    if ( fSettleTimeUS )
-    {
-               startSettleTimer(fSettleTimeUS);
-       }
+    startSettleTimer();
 }
 
 //*********************************************************************************
@@ -3569,51 +3798,138 @@ void IOService::OurChangeFinish ( void )
     all_done();
 }
 
-//*********************************************************************************
-// [private] ParentDownTellPriorityClientsPowerDown
-//
-// All applications and kernel clients have been notified of a power lowering
-// initiated by the parent and we had to wait for responses.  Here
-// we notify any priority clients.  If they all ack, we continue with the power change.
-// If at least one doesn't, we have to wait for it to acknowledge and then continue.
-//*********************************************************************************
-
-void IOService::ParentDownTellPriorityClientsPowerDown ( void )
-{
-    fMachineState = kIOPM_ParentDownNotifyInterestedDriversWillChange;
-       tellChangeDown2(fHeadNotePowerState);
-}
+// MARK: -
+// MARK: Power Change Initiated by Parent
 
 //*********************************************************************************
-// [private] ParentDownNotifyInterestedDriversWillChange
+// [private] ParentChangeStart
 //
-// All applications and kernel clients have been notified of a power lowering
-// initiated by the parent and we had to wait for their responses.  Here we notify
-// any interested drivers and power domain children.  If they all ack, we continue
-// with the power change.
-// If at least one doesn't, we have to wait for it to acknowledge and then continue.
+// Here we begin the processing of a power change initiated by our parent.
 //*********************************************************************************
 
-void IOService::ParentDownNotifyInterestedDriversWillChange ( void )
+IOReturn IOService::ParentChangeStart ( void )
 {
-    IOPMrootDomain  *rootDomain;
-    if ((rootDomain = getPMRootDomain()) == this)
+       PM_ASSERT_IN_GATE();
+    OUR_PMLog( kPMLogStartParentChange, fHeadNotePowerState, fCurrentPowerState );
+
+    // Power domain is lowering power
+    if ( fHeadNotePowerState < fCurrentPowerState )
     {
-        rootDomain->tracePoint(kIOPMTracePointSystemSleepDriversPhase);
-    }
+               // TODO: redundant? See handlePowerDomainWillChangeTo()
+               setParentInfo( fHeadNoteParentFlags, fHeadNoteParentConnection, true );
 
-       notifyAll( kIOPM_ParentDownSetPowerState, kNotifyWillChange );
-}
+#if ROOT_DOMAIN_RUN_STATES
+        getPMRootDomain()->handlePowerChangeStartForService(
+                            /* service */       this,
+                            /* RD flags */      &fRootDomainState,
+                            /* new pwr state */ fHeadNotePowerState,
+                            /* change flags */  fHeadNoteFlags );
+#endif
 
-//*********************************************************************************
-// [private] ParentDownSetPowerState
-//
-// We had to wait for it, but all parties have acknowledged our pre-change
-// notification of a power lowering initiated by the parent.
-// Here we instruct our controlling driver
-// to put the hardware in the state it needs to be in when the domain is
-// lowered.  If it does so, we continue processing
-// (waiting for settle and acknowledging the parent.)
+       // tell apps and kernel clients
+       fInitialChange = false;
+        fMachineState = kIOPM_ParentDownTellPriorityClientsPowerDown;
+               tellChangeDown1(fHeadNotePowerState);
+        return IOPMWillAckLater;
+    }
+
+    // Power domain is raising power
+    if ( fHeadNotePowerState > fCurrentPowerState )
+    {
+        if ( fDesiredPowerState > fCurrentPowerState )
+        {
+            if ( fDesiredPowerState < fHeadNotePowerState )
+            {
+                // We power up, but not all the way
+                fHeadNotePowerState = fDesiredPowerState;
+                               fHeadNotePowerArrayEntry = &fPowerStates[fDesiredPowerState];
+                OUR_PMLog(kPMLogAmendParentChange, fHeadNotePowerState, 0);
+             }
+        } else {
+            // We don't need to change
+            fHeadNotePowerState = fCurrentPowerState;
+                       fHeadNotePowerArrayEntry = &fPowerStates[fCurrentPowerState];                   
+            OUR_PMLog(kPMLogAmendParentChange, fHeadNotePowerState, 0);
+        }
+    }
+
+    if ( fHeadNoteFlags & kIOPMDomainDidChange )
+       {
+        if ( fHeadNotePowerState > fCurrentPowerState )
+        {
+#if ROOT_DOMAIN_RUN_STATES
+            getPMRootDomain()->handlePowerChangeStartForService(
+                                /* service */       this,
+                                /* RD flags */      &fRootDomainState,
+                                /* new pwr state */ fHeadNotePowerState,
+                                /* change flags */  fHeadNoteFlags );
+#endif
+
+            // Parent did change up - start our change up
+            fInitialChange = false;
+            notifyAll( kIOPM_ParentUpSetPowerState, kNotifyWillChange );
+            return IOPMWillAckLater;
+        }
+        else if (fHeadNoteFlags & kIOPMSynchronize)
+        {
+            // We do not need to change power state, but notify
+            // children to propagate tree synchronization.
+            fMachineState     = kIOPM_SyncNotifyDidChange;
+            fDriverCallReason = kDriverCallInformPreChange;
+            notifyChildren();
+            return IOPMWillAckLater;
+        }
+    }
+
+    all_done();
+    return IOPMAckImplied;
+}
+
+//*********************************************************************************
+// [private] ParentDownTellPriorityClientsPowerDown
+//
+// All applications and kernel clients have been notified of a power lowering
+// initiated by the parent and we had to wait for responses.  Here
+// we notify any priority clients.  If they all ack, we continue with the power change.
+// If at least one doesn't, we have to wait for it to acknowledge and then continue.
+//*********************************************************************************
+
+void IOService::ParentDownTellPriorityClientsPowerDown ( void )
+{
+    fMachineState = kIOPM_ParentDownNotifyInterestedDriversWillChange;
+       tellChangeDown2(fHeadNotePowerState);
+}
+
+//*********************************************************************************
+// [private] ParentDownNotifyInterestedDriversWillChange
+//
+// All applications and kernel clients have been notified of a power lowering
+// initiated by the parent and we had to wait for their responses.  Here we notify
+// any interested drivers and power domain children.  If they all ack, we continue
+// with the power change.
+// If at least one doesn't, we have to wait for it to acknowledge and then continue.
+//*********************************************************************************
+
+void IOService::ParentDownNotifyInterestedDriversWillChange ( void )
+{
+    IOPMrootDomain  *rootDomain;
+    if ((rootDomain = getPMRootDomain()) == this)
+    {
+        rootDomain->tracePoint(kIOPMTracePointSystemSleepDriversPhase);
+    }
+
+       notifyAll( kIOPM_ParentDownSetPowerState, kNotifyWillChange );
+}
+
+//*********************************************************************************
+// [private] ParentDownSetPowerState
+//
+// We had to wait for it, but all parties have acknowledged our pre-change
+// notification of a power lowering initiated by the parent.
+// Here we instruct our controlling driver
+// to put the hardware in the state it needs to be in when the domain is
+// lowered.  If it does so, we continue processing
+// (waiting for settle and acknowledging the parent.)
 // If it doesn't, we have to wait for it to acknowledge and then continue.
 //*********************************************************************************
 
@@ -3642,11 +3958,7 @@ void IOService::ParentDownSetPowerState ( void )
 void IOService::ParentDownWaitForPowerSettle ( void )
 {
        fMachineState = kIOPM_ParentDownNotifyDidChangeAndAcknowledgeChange;
-    fSettleTimeUS = compute_settle_time();
-    if ( fSettleTimeUS )
-    {
-       startSettleTimer(fSettleTimeUS);
-       }
+    startSettleTimer();
 }
 
 //*********************************************************************************
@@ -3722,11 +4034,7 @@ void IOService::ParentUpSetPowerState ( void )
 void IOService::ParentUpWaitForSettleTime ( void )
 {
        fMachineState = kIOPM_ParentUpNotifyInterestedDriversDidChange;
-    fSettleTimeUS = compute_settle_time();
-    if ( fSettleTimeUS )
-    {
-        startSettleTimer(fSettleTimeUS);
-    }
+    startSettleTimer();
 }
 
 //*********************************************************************************
@@ -3788,10 +4096,7 @@ void IOService::all_done ( void )
         if ( !( fHeadNoteFlags & kIOPMNotDone) )
         {
                        // we changed, tell our parent
-                       if ( !IS_PM_ROOT() )
-                       {
-                               ask_parent(fHeadNotePowerState);
-                       }
+            requestDomainPower(fHeadNotePowerState);
 
             // yes, did power raise?
             if ( fCurrentPowerState < fHeadNotePowerState )
@@ -3876,67 +4181,74 @@ void IOService::settleTimerExpired ( void )
 }
 
 //*********************************************************************************
-// [private] compute_settle_time
+// settle_timer_expired
 //
-// Compute the power-settling delay in microseconds for the
-// change from myCurrentState to head_note_state.
+// Holds a retain while the settle timer callout is in flight.
 //*********************************************************************************
 
-unsigned long IOService::compute_settle_time ( void )
+static void
+settle_timer_expired( thread_call_param_t arg0, thread_call_param_t arg1 )
 {
-    unsigned long      totalTime;
-    unsigned long      i;
+       IOService * me = (IOService *) arg0;
+
+       if (gIOPMWorkLoop && gIOPMReplyQueue)
+       {
+               gIOPMWorkLoop->runAction(
+            OSMemberFunctionCast(IOWorkLoop::Action, me, &IOService::settleTimerExpired),
+            me);
+               gIOPMReplyQueue->signalWorkAvailable();
+       }
+       me->release();
+}
+
+//*********************************************************************************
+// [private] startSettleTimer
+//
+// Calculate a power-settling delay in microseconds and start a timer.
+//*********************************************************************************
+
+void IOService::startSettleTimer( void )
+{
+    AbsoluteTime        deadline;
+    unsigned long       i;
+    uint32_t            settleTime = 0;
+       boolean_t           pending;
 
        PM_ASSERT_IN_GATE();
 
-    // compute total time to attain the new state
-    totalTime = 0;
     i = fCurrentPowerState;
 
-    // we're lowering power
+    // lowering power
     if ( fHeadNotePowerState < fCurrentPowerState )
     {
         while ( i > fHeadNotePowerState )
         {
-            totalTime +=  fPowerStates[i].settleDownTime;
+            settleTime += (uint32_t) fPowerStates[i].settleDownTime;
             i--;
         }
     }
 
-    // we're raising power
+    // raising power
     if ( fHeadNotePowerState > fCurrentPowerState )
     {
         while ( i < fHeadNotePowerState )
         {
-            totalTime +=  fPowerStates[i+1].settleUpTime;
+            settleTime += (uint32_t) fPowerStates[i+1].settleUpTime;
             i++;
         }
     }
 
-    return totalTime;
-}
-
-//*********************************************************************************
-// [private] startSettleTimer
-//
-// Enter a power-settling delay in microseconds and start a timer for that delay.
-//*********************************************************************************
-
-IOReturn IOService::startSettleTimer ( unsigned long delay )
-{
-    AbsoluteTime       deadline;
-       boolean_t               pending;
-
-       retain();
-    clock_interval_to_deadline(delay, kMicrosecondScale, &deadline);
-    pending = thread_call_enter_delayed(fSettleTimer, deadline);
-       if (pending) release();
-
-    return IOPMNoErr;
+    if (settleTime)
+    {
+        retain();
+        clock_interval_to_deadline(settleTime, kMicrosecondScale, &deadline);
+        pending = thread_call_enter_delayed(fSettleTimer, deadline);
+        if (pending) release();
+    }
 }
 
 //*********************************************************************************
-// [public] ackTimerTick
+// [private] ackTimerTick
 //
 // The acknowledgement timeout periodic timer has ticked.
 // If we are awaiting acks for a power change notification,
@@ -4142,264 +4454,6 @@ IOService::ack_timer_expired ( thread_call_param_t arg0, thread_call_param_t arg
        me->release();
 }
 
-//*********************************************************************************
-// settle_timer_expired
-//
-// Thread call function. Holds a retain while the callout is in flight.
-//*********************************************************************************
-
-static void
-settle_timer_expired ( thread_call_param_t arg0, thread_call_param_t arg1 )
-{
-       IOService * me = (IOService *) arg0;
-
-       if (gIOPMWorkLoop && gIOPMReplyQueue)
-       {
-               gIOPMWorkLoop->runAction(
-            OSMemberFunctionCast(IOWorkLoop::Action, me, &IOService::settleTimerExpired),
-            me);
-               gIOPMReplyQueue->signalWorkAvailable();
-       }
-       me->release();
-}
-
-//*********************************************************************************
-// [private] ParentChangeStart
-//
-// Here we begin the processing of a power change initiated by our parent.
-//*********************************************************************************
-
-IOReturn IOService::ParentChangeStart ( void )
-{
-       PM_ASSERT_IN_GATE();
-    OUR_PMLog( kPMLogStartParentChange, fHeadNotePowerState, fCurrentPowerState );
-
-    // Power domain is lowering power
-    if ( fHeadNotePowerState < fCurrentPowerState )
-    {
-               setParentInfo( fHeadNoteParentFlags, fHeadNoteParentConnection, true );
-
-#if ROOT_DOMAIN_RUN_STATES
-        getPMRootDomain()->handlePowerChangeStartForService(
-                            /* service */       this,
-                            /* RD flags */      &fRootDomainState,
-                            /* new pwr state */ fHeadNotePowerState,
-                            /* change flags */  fHeadNoteFlags );
-#endif
-
-       // tell apps and kernel clients
-       fInitialChange = false;
-        fMachineState = kIOPM_ParentDownTellPriorityClientsPowerDown;
-               tellChangeDown1(fHeadNotePowerState);
-        return IOPMWillAckLater;
-    }
-
-    // Power domain is raising power
-    if ( fHeadNotePowerState > fCurrentPowerState )
-    {
-        if ( fDesiredPowerState > fCurrentPowerState )
-        {
-            if ( fDesiredPowerState < fHeadNotePowerState )
-            {
-                // We power up, but not all the way
-                fHeadNotePowerState = fDesiredPowerState;
-                               fHeadNotePowerArrayEntry = &fPowerStates[fDesiredPowerState];
-                OUR_PMLog(kPMLogAmendParentChange, fHeadNotePowerState, 0);
-             }
-        } else {
-            // We don't need to change
-            fHeadNotePowerState = fCurrentPowerState;
-                       fHeadNotePowerArrayEntry = &fPowerStates[fCurrentPowerState];                   
-            OUR_PMLog(kPMLogAmendParentChange, fHeadNotePowerState, 0);
-        }
-    }
-
-    if ( fHeadNoteFlags & kIOPMDomainDidChange )
-       {
-        if ( fHeadNotePowerState > fCurrentPowerState )
-        {
-#if ROOT_DOMAIN_RUN_STATES
-            getPMRootDomain()->handlePowerChangeStartForService(
-                                /* service */       this,
-                                /* RD flags */      &fRootDomainState,
-                                /* new pwr state */ fHeadNotePowerState,
-                                /* change flags */  fHeadNoteFlags );
-#endif
-
-            // Parent did change up - start our change up
-            fInitialChange = false;
-            notifyAll( kIOPM_ParentUpSetPowerState, kNotifyWillChange );
-            return IOPMWillAckLater;
-        }
-        else if (fHeadNoteFlags & kIOPMSynchronize)
-        {
-            // We do not need to change power state, but notify
-            // children to propagate tree synchronization.
-            fMachineState     = kIOPM_SyncNotifyDidChange;
-            fDriverCallReason = kDriverCallInformPreChange;
-            notifyChildren();
-            return IOPMWillAckLater;
-        }
-    }
-
-    all_done();
-    return IOPMAckImplied;
-}
-
-//*********************************************************************************
-// [private] OurChangeStart
-//
-// Here we begin the processing of a power change initiated by us.
-//*********************************************************************************
-
-void IOService::OurChangeStart ( void )
-{
-       PM_ASSERT_IN_GATE();
-    OUR_PMLog( kPMLogStartDeviceChange, fHeadNotePowerState, fCurrentPowerState );
-
-       // fMaxCapability is our maximum possible power state based on the current
-       // power state of our parents.  If we are trying to raise power beyond the
-       // maximum, send an async request for more power to all parents.
-
-    if (!IS_PM_ROOT() && (fMaxCapability < fHeadNotePowerState))
-    {
-        fHeadNoteFlags |= kIOPMNotDone;
-               ask_parent(fHeadNotePowerState);
-        OurChangeFinish();
-        return;
-    }
-
-       // Redundant power changes skips to the end of the state machine.
-
-    if (!fInitialChange && (fHeadNotePowerState == fCurrentPowerState))
-       {
-               OurChangeFinish();
-               return;
-    }
-    fInitialChange = false;
-
-#if ROOT_DOMAIN_RUN_STATES
-    getPMRootDomain()->handlePowerChangeStartForService(
-                        /* service */       this,
-                        /* RD flags */      &fRootDomainState,
-                        /* new pwr state */ fHeadNotePowerState,
-                        /* change flags */  fHeadNoteFlags );
-#endif
-
-       // Two separate paths, depending if power is being raised or lowered.
-       // Lowering power is subject to client approval.
-
-    if ( fHeadNotePowerState < fCurrentPowerState )
-    {
-               // Next state when dropping power.
-        fMachineState = kIOPM_OurChangeTellClientsPowerDown;
-        fDoNotPowerDown = false;
-
-        // Ask apps and kernel clients permission to lower power.      
-        fOutOfBandParameter = kNotifyApps;
-               askChangeDown(fHeadNotePowerState);
-    }
-       else
-       {
-               // Notify interested drivers and children.
-        notifyAll( kIOPM_OurChangeSetPowerState, kNotifyWillChange );
-    }
-}
-
-//*********************************************************************************
-// [private] OurSyncStart
-//*********************************************************************************
-
-void IOService::OurSyncStart ( void )
-{
-       PM_ASSERT_IN_GATE();
-
-    if (fInitialChange)
-        return;
-
-#if ROOT_DOMAIN_RUN_STATES
-    getPMRootDomain()->handlePowerChangeStartForService(
-                        /* service */       this,
-                        /* RD flags */      &fRootDomainState,
-                        /* new pwr state */ fHeadNotePowerState,
-                        /* change flags */  fHeadNoteFlags );
-#endif
-
-    fMachineState     = kIOPM_SyncNotifyDidChange;
-    fDriverCallReason = kDriverCallInformPreChange;
-
-    notifyChildren();
-}
-
-//*********************************************************************************
-// [private] ask_parent
-//
-// Call the power domain parent to ask for a higher power state in the domain
-// or to suggest a lower power state.
-//*********************************************************************************
-
-IOReturn IOService::ask_parent ( unsigned long requestedState )
-{
-    OSIterator *                       iter;
-    OSObject *                         next;
-    IOPowerConnection *                connection;
-    IOService *                                parent;
-       const IOPMPowerState *  powerStatePtr;
-    unsigned long                      ourRequest;
-
-       PM_ASSERT_IN_GATE();
-    if (requestedState >= fNumberOfPowerStates)
-        return IOPMNoErr;
-
-       powerStatePtr = &fPowerStates[requestedState];
-       ourRequest    = powerStatePtr->inputPowerRequirement;
-
-    if ( powerStatePtr->capabilityFlags & (kIOPMChildClamp | kIOPMPreventIdleSleep) )
-    {
-        ourRequest |= kIOPMPreventIdleSleep;
-    }
-    if ( powerStatePtr->capabilityFlags & (kIOPMChildClamp2 | kIOPMPreventSystemSleep) )
-    {
-        ourRequest |= kIOPMPreventSystemSleep;
-    }
-
-    // is this a new desire?
-    if ( fPreviousRequest == ourRequest )
-    {  
-        // no, the parent knows already, just return
-        return IOPMNoErr;
-    }
-
-    if ( IS_PM_ROOT() )
-    {
-        return IOPMNoErr;
-    }
-    fPreviousRequest = ourRequest;
-
-    iter = getParentIterator(gIOPowerPlane);
-    if ( iter )
-    {
-        while ( (next = iter->getNextObject()) )
-        {
-            if ( (connection = OSDynamicCast(IOPowerConnection, next)) )
-            {
-                parent = (IOService *)connection->copyParentEntry(gIOPowerPlane);
-                if ( parent ) {
-                    if ( parent->requestPowerDomainState(
-                                               ourRequest, connection, IOPMLowestState) != IOPMNoErr )
-                    {
-                        OUR_PMLog(kPMLogRequestDenied, fPreviousRequest, 0);
-                    }
-                    parent->release();
-                }
-            }
-        }
-        iter->release();
-    }
-
-    return IOPMNoErr;
-}
-
 //*********************************************************************************
 // [private] notifyControllingDriver
 //*********************************************************************************
@@ -6045,6 +6099,9 @@ void IOService::deassertPMThreadCall( void )
     PM_UNLOCK();
 }
 
+// MARK: -
+// MARK: IOPMRequest
+
 //*********************************************************************************
 // IOPMRequest Class
 //
@@ -6173,6 +6230,9 @@ void IOPMRequest::detachRootRequest( void )
     }
 }
 
+// MARK: -
+// MARK: IOPMRequestQueue
+
 //*********************************************************************************
 // IOPMRequestQueue Class
 //
@@ -6267,6 +6327,9 @@ void IOPMRequestQueue::signalWorkAvailable( void )
        IOEventSource::signalWorkAvailable();
 }
 
+// MARK: -
+// MARK: IOPMWorkQueue
+
 //*********************************************************************************
 // IOPMWorkQueue Class
 //
@@ -6335,6 +6398,9 @@ bool IOPMWorkQueue::checkForWork( void )
        return false;
 }
 
+// MARK: -
+// MARK: IOPMCompletionQueue
+
 //*********************************************************************************
 // IOPMCompletionQueue Class
 //*********************************************************************************
@@ -6396,6 +6462,9 @@ bool IOPMCompletionQueue::checkForWork( void )
        return more;
 }
 
+// MARK: -
+// MARK: IOServicePM
+
 OSDefineMetaClassAndStructors(IOServicePM, OSObject)
 
 //*********************************************************************************
index 227715d5fba6c1a0e9ee3d89ddb0048b7b6adf7c..772ac518cc41573c0af9ae70ab9d98eafab24960 100644 (file)
@@ -66,6 +66,9 @@ private:
     // Power flags supplied by all parents (domain).
     unsigned long           HeadNoteDomainFlags;
 
+    // Power flags supplied by domain accounting for parent changes.
+    IOPMPowerFlags          HeadNoteDomainTargetFlags;
+
     // Connection attached to the changing parent.
     IOPowerConnection *     HeadNoteParentConnection;
     
@@ -205,6 +208,7 @@ private:
 #define fHeadNotePowerState         pwrMgt->HeadNotePowerState
 #define fHeadNotePowerArrayEntry    pwrMgt->HeadNotePowerArrayEntry
 #define fHeadNoteDomainFlags        pwrMgt->HeadNoteDomainFlags
+#define fHeadNoteDomainTargetFlags  pwrMgt->HeadNoteDomainTargetFlags
 #define fHeadNoteParentConnection   pwrMgt->HeadNoteParentConnection
 #define fHeadNoteParentFlags        pwrMgt->HeadNoteParentFlags
 #define fHeadNotePendingAcks        pwrMgt->HeadNotePendingAcks
@@ -257,7 +261,7 @@ private:
 #define fRemoveInterestSet          pwrMgt->RemoveInterestSet
 #define fStrictTreeOrder            pwrMgt->StrictTreeOrder
 #define fNotifyChildArray           pwrMgt->NotifyChildArray
-#define fIdleTimerStopped                      pwrMgt->IdleTimerStopped
+#define fIdleTimerStopped           pwrMgt->IdleTimerStopped
 #define fAdjustPowerScheduled       pwrMgt->AdjustPowerScheduled
 #define fActivityTicklePowerState   pwrMgt->ActivityTicklePowerState
 #define fPMVars                     pwrMgt->PMVars
@@ -371,9 +375,9 @@ class IOPMRequest : public IOCommand
 protected:
     IOService *          fTarget;        // request target
     IOPMRequest *        fRequestNext;   // the next request in the chain
-       IOPMRequest *            fRequestRoot;   // the root request in the issue tree
+    IOPMRequest *        fRequestRoot;   // the root request in the issue tree
     IOItemCount          fWorkWaitCount; // execution blocked if non-zero
-       IOItemCount                      fFreeWaitCount; // completion blocked if non-zero      
+    IOItemCount          fFreeWaitCount; // completion blocked if non-zero
     uint32_t             fType;          // request type
 
     IOPMCompletionAction fCompletionAction;
@@ -401,12 +405,12 @@ public:
         return fRequestNext;
     }
 
-       inline IOPMRequest * getRootRequest( void ) const
-       {
+    inline IOPMRequest * getRootRequest( void ) const
+    {
         if (fRequestRoot) return fRequestRoot;
         if (fCompletionAction) return (IOPMRequest *) this;
-               return 0;
-       }
+        return 0;
+    }
 
     inline uint32_t      getType( void ) const
     {
index cb7e708c8c3b0ac13dac4e82646275ec93f4774d..0cb4dbb61e35f206674e1dc053f93997f46a5a24 100644 (file)
@@ -74,9 +74,9 @@ options               CONFIG_SLEEP    #                               # <config_sleep>
 #
 #  configurable kernel related resources 
 #
-options   CONFIG_MAX_THREADS=32                # <medium,large,xlarge>
-options   CONFIG_MAX_THREADS=32                # <small,xsmall>
-options   CONFIG_MAX_THREADS=32                # <bsmall>
+options   CONFIG_MAX_THREADS=64                # <medium,large,xlarge>
+options   CONFIG_MAX_THREADS=64                # <small,xsmall>
+options   CONFIG_MAX_THREADS=64                # <bsmall>
 
 #
 #  configurable kernel - use these options to strip strings from panic
index 216fcd4cd5ad4c161cec372ddd084786217dd246..4f6fc2bbe0d6bd3b96434801b887c45f9abd15d8 100644 (file)
--- a/kgmacros
+++ b/kgmacros
@@ -111,7 +111,12 @@ document kgm
 |     resume_off     Don't resume when detaching from gdb 
 |
 |     sendcore      Configure kernel to send a coredump to the specified IP
+|     sendsyslog     Configure kernel to send a system log to the specified IP
+|     sendpaniclog   Configure kernel to send a panic log to the specified IP
 |     disablecore    Configure the kernel to disable coredump transmission
+|     getdumpinfo    Retrieve the current remote dump parameters
+|     setdumpinfo    Configure the remote dump parameters
+|
 |     switchtocorethread Corefile version of "switchtoact"
 |     resetcorectx   Corefile version of "resetctx"
 |
@@ -208,6 +213,7 @@ document kgm
 |     showallgdbcorestacks Corefile equivalent of "showallgdbstacks"
 |     kdp-reenter      Schedule reentry into the debugger and continue.
 |     kdp-reboot       Restart remote target
+|     kdp-version       Get KDP version number
 |
 |     zstack           Print zalloc caller stack (zone leak debugging)
 |     findoldest       Find oldest zone leak debugging record
@@ -276,6 +282,26 @@ set $kgm_mtype_x86_mask = 0xFEFFFFFF
 set $kgm_mtype = ((unsigned int *)&_mh_execute_header)[1]
 set $kgm_lp64 = $kgm_mtype & 0x01000000
 
+set $kgm_manual_pkt_ppc    = 0x549C
+set $kgm_manual_pkt_i386   = 0x249C
+set $kgm_manual_pkt_x86_64 = 0xFFFFFF8000002930
+set $kgm_manual_pkt_arm    = 0xFFFF04A0
+
+set $kgm_kdp_pkt_data_len   = 128
+
+# part of data packet
+set $kgm_kdp_pkt_hdr_req_off = 0
+set $kgm_kdp_pkt_hdr_seq_off = 1
+set $kgm_kdp_pkt_hdr_len_off = 2
+set $kgm_kdp_pkt_hdr_key_off = 4
+
+# after data packet
+set $kgm_kdp_pkt_len_off     = $kgm_kdp_pkt_data_len
+set $kgm_kdp_pkt_input_off   = $kgm_kdp_pkt_data_len + 4
+
+set $kgm_kdp_pkt_hostreboot = 0x13
+set $kgm_kdp_pkt_hdr_size   = 8
+
 set $kgm_lcpu_self      = 0xFFFE
 
 set $kgm_reg_depth = 0
@@ -291,6 +317,37 @@ set $kgm_show_data_alwaysbytes = 0
 
 set $kgm_show_kmod_syms = 0
 
+# send a manual packet header that doesn't require knowing the location
+# of everything.
+define manualhdrint
+       set $req = $arg0
+
+       set $hdrp = (uint32_t *) $kgm_manual_pkt_i386
+       if ($kgm_mtype == $kgm_mtype_ppc)
+          set $hdrp = (uint32_t *) $kgm_manual_pkt_ppc
+          set $req = $req << 1 # shift to deal with endiannness
+       end
+       if ($kgm_mtype == $kgm_mtype_x86_64)
+          set $hdrp = (uint64_t *) $kgm_manual_pkt_x86_64
+       end
+       if ($kgm_mtype == $kgm_mtype_arm)
+          set $hdrp = (uint32_t *) $kgm_manual_pkt_arm
+       end
+
+       set $pkt_hdr = *$hdrp
+       set *((uint8_t *) ($pkt_hdr + $kgm_kdp_pkt_input_off))    = 0
+       set *((uint32_t *) ($pkt_hdr + $kgm_kdp_pkt_len_off))     = $kgm_kdp_pkt_hdr_size
+
+       set *((uint8_t *) ($pkt_hdr + $kgm_kdp_pkt_hdr_req_off))  = $req
+       set *((uint8_t *) ($pkt_hdr + $kgm_kdp_pkt_hdr_seq_off))  = 0
+       set *((uint16_t *) ($pkt_hdr + $kgm_kdp_pkt_hdr_len_off)) = $kgm_kdp_pkt_hdr_size
+       set *((uint32_t *) ($pkt_hdr + $kgm_kdp_pkt_hdr_key_off)) = 0
+       set *((uint8_t *) ($pkt_hdr + $kgm_kdp_pkt_input_off))    = 1
+
+       # dummy to make sure manual packet is executed
+       set $kgm_dummy = &_mh_execute_header
+end
+
 # Print a pointer
 define showptr
     if $kgm_lp64
@@ -1820,18 +1877,18 @@ define switchtoact
        if ($kgm_mtype == $kgm_mtype_i386)
                set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state
                if ($kdp_act_counter == 0)
-                       set $kdpstate = *($kdpstatep)
+                  set $kdpstate = *($kdpstatep)
                end     
                set $kdp_act_counter = $kdp_act_counter + 1
 
                set $kgm_statep = (struct x86_kernel_state *) \
                                        ($newact->kernel_stack + kernel_stack_size \
                                         - sizeof(struct x86_kernel_state))
-               set $kdpstatep->ebx = $kgm_statep->k_ebx 
+               set $kdpstatep->ebx = $kgm_statep->k_ebx 
                set $kdpstatep->ebp = $kgm_statep->k_ebp 
                set $kdpstatep->edi = $kgm_statep->k_edi 
                set $kdpstatep->esi = $kgm_statep->k_esi 
-               set $kdpstatep->eip = $kgm_statep->k_eip 
+               set $kdpstatep->eip = $kgm_statep->k_eip 
                flushregs
                flushstack
                set $pc = $kgm_statep->k_eip
@@ -1840,20 +1897,20 @@ define switchtoact
        if ($kgm_mtype == $kgm_mtype_x86_64)
                set $kdpstatep = (struct x86_saved_state64 *) kdp.saved_state
                if ($kdp_act_counter == 0)
-                       set $kdpstate = *($kdpstatep)
+                  set $kdpstate = *($kdpstatep)
                end     
                set $kdp_act_counter = $kdp_act_counter + 1
 
                set $kgm_statep = (struct x86_kernel_state *) \
                                        ($newact->kernel_stack + kernel_stack_size \
                                         - sizeof(struct x86_kernel_state))
-               set $kdpstatep->rbx = $kgm_statep->k_rbx 
-               set $kdpstatep->rbp = $kgm_statep->k_rbp 
-               set $kdpstatep->r12 = $kgm_statep->k_r12 
-               set $kdpstatep->r13 = $kgm_statep->k_r13 
-               set $kdpstatep->r14 = $kgm_statep->k_r14 
-               set $kdpstatep->r15 = $kgm_statep->k_r15 
-               set $kdpstatep->isf.rsp = $kgm_statep->k_rsp 
+               set $kdpstatep->rbx = $kgm_statep->k_rbx 
+               set $kdpstatep->rbp = $kgm_statep->k_rbp 
+               set $kdpstatep->r12 = $kgm_statep->k_r12 
+               set $kdpstatep->r13 = $kgm_statep->k_r13 
+               set $kdpstatep->r14 = $kgm_statep->k_r14 
+               set $kdpstatep->r15 = $kgm_statep->k_r15 
+               set $kdpstatep->isf.rsp = $kgm_statep->k_rsp 
                flushregs
                flushstack
                set $pc = $kgm_statep->k_rip
@@ -1914,7 +1971,7 @@ define switchtoctx
        select 0
        if ($kgm_mtype == $kgm_mtype_ppc)
                if ($kdp_act_counter == 0)
-               set $kdpstate = (struct savearea *) kdp.saved_state
+                  set $kdpstate = (struct savearea *) kdp.saved_state
                end
                set $kdp_act_counter = $kdp_act_counter + 1
                set (struct savearea *) kdp.saved_state=(struct savearea *) $arg0
@@ -2062,7 +2119,8 @@ define hook-detach
 end
 
 define resume_on
-       set noresume_on_disconnect = 0
+        set $resume = KDP_DUMPINFO_SETINFO | KDP_DUMPINFO_RESUME
+        dumpinfoint $resume
 end
 
 document resume_on
@@ -2072,7 +2130,8 @@ document resume_on
 end
 
 define resume_off
-       set noresume_on_disconnect = 1
+        set $noresume = KDP_DUMPINFO_SETINFO | KDP_DUMPINFO_NORESUME
+        dumpinfoint $noresume
 end
 
 document resume_off
@@ -2366,47 +2425,202 @@ Syntax: showuserstack <address of thread activation>
 |macro in some cases.
 end
 
-#Stopgap until gdb can generate the HOSTREBOOT packet
 define kdp-reboot
-#Alternatively, set *(*(unsigned **) 0x2498) = 1 (or 0x5498 on PPC)
-       set flag_kdp_trigger_reboot = 1
+# Alternatively, set *(*(unsigned **) 0x2498) = 1 
+# (or 0x5498 on PPC, 0xffffff8000002928 on x86_64, 0xffff049c on arm)
+       manualhdrint $kgm_kdp_pkt_hostreboot
        continue
 end
 
 document kdp-reboot
 Syntax: kdp-reboot
-|Reboot the remote target machine; not guaranteed to succeed. Requires symbols
-|until gdb support for the HOSTREBOOT packet is implemented.
+|Reboot the remote target machine; not guaranteed to succeed. 
+end
+
+define kdpversionint
+       # set up the manual KDP packet
+       set manual_pkt.input = 0
+       set manual_pkt.len = sizeof(kdp_version_req_t)
+       set $kgm_pkt = (kdp_version_req_t *)&manual_pkt.data
+       set $kgm_pkt->hdr.request  = KDP_VERSION
+       set $kgm_pkt->hdr.len      = sizeof(kdp_version_req_t)
+       set $kgm_pkt->hdr.is_reply = 0
+       set $kgm_pkt->hdr.seq      = 0
+       set $kgm_pkt->hdr.key      = 0
+       set manual_pkt.input       = 1
+       # dummy to make sure manual packet is executed
+       set $kgm_dummy = &_mh_execute_header
+       set $kgm_pkt = (kdp_version_reply_t *)&manual_pkt.data
+       set $kgm_kdp_version = $kgm_pkt->version
+       set $kgm_kdp_feature = $kgm_pkt->feature
+end
+
+define kdp-version
+       kdpversionint
+       printf "KDP VERSION = %d, FEATURE = 0x%x\n", $kgm_kdp_version, $kgm_kdp_feature
+end
+
+document kdp-version
+Syntax: kdp-version
+|Get the KDP protocol version being used by the kernel.
+end
+
+define dumpinfoint
+       # set up the manual KDP packet
+       set manual_pkt.input        = 0
+
+       set manual_pkt.len          = sizeof(kdp_dumpinfo_req_t)
+       set $kgm_pkt                = (kdp_dumpinfo_req_t *)manual_pkt.data
+       set $kgm_pkt->hdr.request  = KDP_DUMPINFO
+       set $kgm_pkt->hdr.len      = sizeof(kdp_dumpinfo_req_t)
+       set $kgm_pkt->hdr.is_reply = 0
+       set $kgm_pkt->hdr.seq      = 0
+       set $kgm_pkt->hdr.key      = 0
+       set $kgm_pkt->type         = $arg0 
+       set $kgm_pkt->name         = ""
+       set $kgm_pkt->destip       = ""
+       set $kgm_pkt->routerip     = ""
+       set $kgm_pkt->port         = 0
+
+       if $argc > 1
+                 set $kgm_pkt->name      = "$arg1"
+       end
+       if $argc > 2
+          set $kgm_pkt->destip    = "$arg2"
+       end
+       if $argc > 3
+                 set $kgm_pkt->routerip  = "$arg3"
+       end
+       if $argc > 4
+                 set $kgm_pkt->port      = $arg4
+       end
+
+       set manual_pkt.input       = 1
+       # dummy to make sure manual packet is executed
+       set $kgm_dummy = &_mh_execute_header
 end
 
 define sendcore
-       set kdp_trigger_core_dump = 1
-       set kdp_flag |= 0x40
-       set panicd_ip_str = "$arg0"
-       set panicd_specified = 1
-       set disable_debug_output = 0
-       set disableConsoleOutput = 0
-       set logPanicDataToScreen = 1
-       set reattach_wait = 1
-       resume_off
+       if $argc > 1
+                 dumpinfoint KDP_DUMPINFO_CORE $arg1 $arg0
+       else
+                 dumpinfoint KDP_DUMPINFO_CORE \0 $arg0
+       end
 end
 
 document sendcore
-Syntax: sendcore <IP address>
+Syntax: sendcore <IP address> [filename]
 |Configure the kernel to transmit a kernel coredump to a server (kdumpd) 
 |at the specified IP address. This is useful when the remote target has
 |not been previously configured to transmit coredumps, and you wish to
 |preserve kernel state for later examination. NOTE: You must issue a "continue"
 |command after using this macro to trigger the kernel coredump. The kernel
 |will resume waiting in the debugger after completion of the coredump. You
-|may disable coredumps by executing the "disablecore" macro.
+|may disable coredumps by executing the "disablecore" macro. You can 
+|optionally specify the filename to be used for the generated core file.
+end
+
+define sendsyslog
+       if $argc > 1
+                 dumpinfoint KDP_DUMPINFO_SYSTEMLOG $arg1 $arg0
+       else
+                 dumpinfoint KDP_DUMPINFO_SYSTEMLOG \0 $arg0
+       end
+end
+
+document sendsyslog
+Syntax: sendsyslog <IP address> [filename]
+|Configure the kernel to transmit a kernel system log to a server (kdumpd) 
+|at the specified IP address. NOTE: You must issue a "continue"
+|command after using this macro to trigger the kernel system log. The kernel
+|will resume waiting in the debugger after completion. You can optionally
+|specify the name to be used for the generated system log.
+end
+
+define sendpaniclog
+       if panicstr 
+         if $argc > 1
+            dumpinfoint KDP_DUMPINFO_PANICLOG $arg1 $arg0
+         else
+            dumpinfoint KDP_DUMPINFO_PANICLOG \0 $arg0
+         end
+       else
+         printf "No panic log available.\n"
+       end
+end
+
+document sendpaniclog
+Syntax: sendpaniclog <IP address> [filename]
+|Configure the kernel to transmit a kernel paniclog to a server (kdumpd) 
+|at the specified IP address. NOTE: You must issue a "continue"
+|command after using this macro to trigger the kernel panic log. The kernel
+|will resume waiting in the debugger after completion. You can optionally
+|specify the name to be used for the generated panic log.
+end
+
+define getdumpinfo
+       dumpinfoint KDP_DUMPINFO_GETINFO
+       set $kgm_dumpinfo = (kdp_dumpinfo_reply_t *) manual_pkt.data
+       if $kgm_dumpinfo->type & KDP_DUMPINFO_REBOOT
+                 printf "Sysem will reboot after kernel info gets dumped.\n"
+       else
+                 printf "Sysem will not reboot after kernel info gets dumped.\n"
+       end
+       if $kgm_dumpinfo->type & KDP_DUMPINFO_NORESUME
+                 printf "System will allow a re-attach after a KDP disconnect.\n"
+       else
+                 printf "System will resume after a KDP disconnect.\n"
+       end
+       set $kgm_dumpinfo_type = $kgm_dumpinfo->type & KDP_DUMPINFO_MASK
+       if $kgm_dumpinfo_type == KDP_DUMPINFO_DISABLE
+                 printf "Kernel not setup for remote dumps.\n"
+       else
+          printf "Remote dump type: "
+          if $kgm_dumpinfo_type == KDP_DUMPINFO_CORE
+            printf "Core file\n"
+         end
+          if $kgm_dumpinfo_type == KDP_DUMPINFO_PANICLOG
+            printf "Panic log\n"
+         end
+          if $kgm_dumpinfo_type == KDP_DUMPINFO_SYSTEMLOG
+            printf "System log\n"
+         end
+
+         printf "Name: "
+         if $kgm_dumpinfo->name[0] == '\0'
+            printf "(autogenerated)\n"
+          else
+            printf "%s\n", $kgm_dumpinfo->name
+          end            
+
+         printf "Network Info: %s[%d] ", $kgm_dumpinfo->destip, $kgm_dumpinfo->port
+         if $kgm_dumpinfo->routerip[0] == '\0'
+            printf "\n"
+         else
+            printf "Router: %s\n", $kgm_dumpinfo->routerip
+         end
+       end
+end
+
+document getdumpinfo
+Syntax: getdumpinfo
+|Retrieve the current remote dump settings. 
+end
+
+define setdumpinfo
+       dumpinfoint KDP_DUMPINFO_SETINFO $arg0 $arg1 $arg2 $arg3
+end
+
+document setdumpinfo
+Syntax: setdumpinfo <filename> <ip> <router> <port>
+|Configure the current remote dump settings. Specify \0 if you
+|want to use the defaults (filename) or previously configured
+|settings (ip/router). Specify 0 for the port if you wish to 
+|use the previously configured/default setting for that.
 end
 
 define disablecore
-       set kdp_trigger_core_dump = 0
-       set kdp_flag |= 0x40
-       set kdp_flag &= ~0x10
-       set panicd_specified = 0
+       dumpinfoint KDP_DUMPINFO_DISABLE
 end
 
 document disablecore
@@ -3212,12 +3426,20 @@ Syntax: (gdb) findregistryprop <entry>
 end
 
 define findregistryentryint
-    set $kgm_namekey   = (OSSymbol *) $kgm_reg_plane->nameKey
-    set $kgm_childkey  = (OSSymbol *) $kgm_reg_plane->keys[1]
-    if $kgm_findregistry_verbose
-       printf "Searching"
+    if !$kgm_reg_plane
+       set $kgm_reg_plane = (IORegistryPlane *) gIOServicePlane
+    end
+
+    if !$kgm_reg_plane
+       printf "Please load kgmacros after KDP attaching to the target.\n"
+    else
+       set $kgm_namekey   = (OSSymbol *) $kgm_reg_plane->nameKey
+       set $kgm_childkey  = (OSSymbol *) $kgm_reg_plane->keys[1]
+       if $kgm_findregistry_verbose
+          printf "Searching"
+       end
+       findregistryentryrecurse _ $arg0 0 0
     end
-    findregistryentryrecurse _ $arg0 0 0
 end
 
 define _findregistryentry
@@ -3353,10 +3575,17 @@ define showregistryentryrecurse
 end
 
 define showregistryentryint
-    set $kgm_namekey   = (OSSymbol *) $kgm_reg_plane->nameKey
-    set $kgm_childkey  = (OSSymbol *) $kgm_reg_plane->keys[1]
+    if !$kgm_reg_plane
+       set $kgm_reg_plane = (IORegistryPlane *) gIOServicePlane
+    end
 
-    showregistryentryrecurse _ $arg0 0 0
+    if !$kgm_reg_plane
+       printf "Please load kgmacros after KDP attaching to the target.\n"
+    else        
+       set $kgm_namekey   = (OSSymbol *) $kgm_reg_plane->nameKey
+       set $kgm_childkey  = (OSSymbol *) $kgm_reg_plane->keys[1]
+       showregistryentryrecurse _ $arg0 0 0
+    end
 end
 
 define showregistry
@@ -7116,9 +7345,17 @@ define showregistryentryrecursepmstate
 end
 
 define showregistryentryintpmstate
-    set $kgm_namekey   = (OSSymbol *) $kgm_reg_plane->nameKey
-    set $kgm_childkey  = (OSSymbol *) $kgm_reg_plane->keys[1]
-    showregistryentryrecursepmstate _ $arg0 0 0
+    if !$kgm_reg_plane
+       set $kgm_reg_plane = (IORegistryPlane *) gIOServicePlane
+    end
+
+    if !$kgm_reg_plane
+       printf "Please load kgmacros after KDP attaching to the target.\n"
+    else
+       set $kgm_namekey   = (OSSymbol *) $kgm_reg_plane->nameKey
+       set $kgm_childkey  = (OSSymbol *) $kgm_reg_plane->keys[1]
+       showregistryentryrecursepmstate _ $arg0 0 0
+    end
 end
 
 define showregistrypmstate
@@ -9873,6 +10110,7 @@ Syntax: (gdb) showallworkloopthreads
 | best-effort guess to find any workloops that are actually not blocked in a continuation. For a
 | complete list, it is best to compare the output of this macro against the output of 'showallstacks'.
 end
+
 define showthreadfortid
        set $kgm_id_found = 0
        
index e4c15bfc2bba1b54e51f92d7c5cb9e7ddcd851b2..9f41164919163edbcac23146f4fc6899191da70c 100644 (file)
@@ -190,8 +190,6 @@ static IORecursiveLock    * sKextLock                  = NULL;
 static OSDictionary       * sKextsByID                 = NULL;
 static OSArray            * sLoadedKexts               = NULL;
 
-static OSArray            * sPrelinkedPersonalities    = NULL;
-
 // Requests to kextd waiting to be picked up.
 static OSArray            * sKernelRequests            = NULL;
 // Identifier of kext load requests in sKernelRequests
@@ -867,9 +865,8 @@ OSKext::setKextdActive(Boolean active)
 {
     IORecursiveLockLock(sKextLock);
     sKextdActive = active;
-    if (sPrelinkedPersonalities) {
-        gIOCatalogue->removePersonalities(sPrelinkedPersonalities);
-        OSSafeReleaseNULL(sPrelinkedPersonalities);
+    if (sKernelRequests->getCount()) {
+        OSKextPingKextd();
     }
     IORecursiveLockUnlock(sKextLock);
 
@@ -920,7 +917,7 @@ OSKext::willShutdown(void)
         goto finish;
     }
 
-        OSKextPingKextd();
+    OSKextPingKextd();
 
 finish:
     IORecursiveLockUnlock(sKextLock);
@@ -7089,7 +7086,7 @@ OSKext::requestResource(
         goto finish;
     }
 
-        OSKextPingKextd();
+    OSKextPingKextd();
 
     result = kOSReturnSuccess;
     if (requestTagOut) {
@@ -7670,20 +7667,6 @@ finish:
     return result;
 }
 
-/*********************************************************************
-*********************************************************************/
-/* static */
-void
-OSKext::setPrelinkedPersonalities(OSArray * personalitiesArray)
-{
-    sPrelinkedPersonalities = personalitiesArray;
-    if (sPrelinkedPersonalities) {
-        sPrelinkedPersonalities->retain();
-        gIOCatalogue->addDrivers(sPrelinkedPersonalities);
-    }
-    return;
-}
-
 /*********************************************************************
 *********************************************************************/
 /* static */
index 3808b953af7b03b20d103e2ca7a046e69bdb8bb5..286255265522d2d569741ff5a96e5639c2b8779f 100644 (file)
@@ -437,7 +437,7 @@ KLDBootstrap::readPrelinkedExtensions(
     }
 
     if (personalitiesArray->getCount()) {
-        OSKext::setPrelinkedPersonalities(personalitiesArray);
+        gIOCatalogue->addDrivers(personalitiesArray);
     }
 
    /* Store the number of prelinked kexts in the registry so we can tell
index dea334e43de2274d95de19bc3a848831f5b08f13..14785f5bb64b55f5c0359371e1d836614852aa22 100644 (file)
 #include <mach/machine.h>
 #include <mach/vm_map.h>
 #include <mach/mach_vm.h>
+#include <mach/machine.h>
+#include <i386/cpuid.h>
 #include <i386/tsc.h>
 #include <i386/rtclock.h>
 #include <i386/cpu_data.h>
 #include <i386/machine_routines.h>
 #include <i386/misc_protos.h>
+#include <i386/cpuid.h>
 #include <machine/cpu_capabilities.h>
 #include <machine/commpage.h>
 #include <machine/pmap.h>
index 3fb02d33f03daa2d0de2d555f56f4af29f7f88e0..470e8a3e73cdbb347f21c606f32d0ecb03989144 100644 (file)
@@ -52,7 +52,8 @@
 #define        k64Bit                          0x00000200      /* processor supports EM64T (not what mode you're running in) */
 #define        kHasSSE4_1                      0x00000400
 #define        kHasSSE4_2                      0x00000800
-
+#define        kHasAES                         0x00001000
+#define        kInOrderPipeline                0x00002000      /* in-order execution */
 #define        kSlow                           0x00004000      /* tsc < nanosecond */
 #define        kUP                             0x00008000      /* set if (kNumCPUs == 1) */
 #define        kNumCPUs                        0x00FF0000      /* number of CPUs (see _NumCPUs() below) */
index 529da7af5c245614056eaac1140618f92a77a750..d6c63c252850b3922b0c693eea0925ce374cd813 100644 (file)
@@ -27,6 +27,7 @@
  */
 #include <vm/vm_kern.h>
 #include <kern/kalloc.h>
+#include <kern/etimer.h>
 #include <mach/machine.h>
 #include <i386/cpu_threads.h>
 #include <i386/cpuid.h>
@@ -180,7 +181,8 @@ x86_LLC_info(void)
      */
     topoParms.maxSharingLLC = nCPUsSharing;
 
-    topoParms.nCoresSharingLLC = nCPUsSharing;
+    topoParms.nCoresSharingLLC = nCPUsSharing / (cpuinfo->thread_count /
+                                                cpuinfo->core_count);
     topoParms.nLCPUsSharingLLC = nCPUsSharing;
 
     /*
@@ -241,6 +243,12 @@ initTopoParms(void)
     topoParms.nLThreadsPerPackage = topoParms.nLThreadsPerCore * topoParms.nLCoresPerPackage;
     topoParms.nPThreadsPerPackage = topoParms.nPThreadsPerCore * topoParms.nPCoresPerPackage;
 
+    DBG("\nCache Topology Parameters:\n");
+    DBG("\tLLC Depth:           %d\n", topoParms.LLCDepth);
+    DBG("\tCores Sharing LLC:   %d\n", topoParms.nCoresSharingLLC);
+    DBG("\tThreads Sharing LLC: %d\n", topoParms.nLCPUsSharingLLC);
+    DBG("\tmax Sharing of LLC:  %d\n", topoParms.maxSharingLLC);
+
     DBG("\nLogical Topology Parameters:\n");
     DBG("\tThreads per Core:  %d\n", topoParms.nLThreadsPerCore);
     DBG("\tCores per Die:     %d\n", topoParms.nLCoresPerDie);
@@ -1087,7 +1095,7 @@ validate_topology(void)
            /*
             * Make sure that the die has the correct number of cores.
             */
-           DBG("Die(%d)->cores: ");
+           DBG("Die(%d)->cores: ", die->pdie_num);
            nCores = 0;
            core = die->cores;
            while (core != NULL) {
@@ -1158,7 +1166,7 @@ validate_topology(void)
             */
            nCPUs = 0;
            lcpu = core->lcpus;
-           DBG("Core(%d)->lcpus: ");
+           DBG("Core(%d)->lcpus: ", core->pcore_num);
            while (lcpu != NULL) {
                if (lcpu->core == NULL)
                    panic("CPU(%d)->core is NULL",
index a5c88990dc732daf59b29e61f2e4225cade2aac7..c247a157df5b7f6459589a9dd4a53d2b29e51bc4 100644 (file)
@@ -49,9 +49,9 @@
 #define quad(hi,lo)    (((uint64_t)(hi)) << 32 | (lo))
 
 /* Only for 32bit values */
-#define bit(n)         (1U << (n))
-#define bitmask(h,l)   ((bit(h)|(bit(h)-1)) & ~(bit(l)-1))
-#define bitfield(x,h,l)        ((((x) & bitmask(h,l)) >> l))
+#define bit32(n)               (1U << (n))
+#define bitmask32(h,l)         ((bit32(h)|(bit32(h)-1)) & ~(bit32(l)-1))
+#define bitfield32(x,h,l)      ((((x) & bitmask32(h,l)) >> l))
 
 /*
  * Leaf 2 cache descriptor encodings.
@@ -185,15 +185,23 @@ static cpuid_cache_descriptor_t intel_cpuid_leaf2_descriptor_table[] = {
        { 0xD0, CACHE,  L3,             4,      512*K,  64  },  
        { 0xD1, CACHE,  L3,             4,      1*M,    64  },  
        { 0xD2, CACHE,  L3,             4,      2*M,    64  },  
+       { 0xD3, CACHE,  L3,             4,      4*M,    64  },  
+       { 0xD4, CACHE,  L3,             4,      8*M,    64  },  
        { 0xD6, CACHE,  L3,             8,      1*M,    64  },  
        { 0xD7, CACHE,  L3,             8,      2*M,    64  },  
        { 0xD8, CACHE,  L3,             8,      4*M,    64  },  
+       { 0xD9, CACHE,  L3,             8,      8*M,    64  },  
+       { 0xDA, CACHE,  L3,             8,      12*M,   64  },  
        { 0xDC, CACHE,  L3,             12,     1536*K, 64  },  
        { 0xDD, CACHE,  L3,             12,     3*M,    64  },  
        { 0xDE, CACHE,  L3,             12,     6*M,    64  },  
+       { 0xDF, CACHE,  L3,             12,     12*M,   64  },  
+       { 0xE0, CACHE,  L3,             12,     18*M,   64  },  
        { 0xE2, CACHE,  L3,             16,     2*M,    64  },  
        { 0xE3, CACHE,  L3,             16,     4*M,    64  },  
        { 0xE4, CACHE,  L3,             16,     8*M,    64  },  
+       { 0xE5, CACHE,  L3,             16,     16*M,   64  },  
+       { 0xE6, CACHE,  L3,             16,     24*M,   64  },  
        { 0xF0, PREFETCH, NA,           NA,     64,     NA  },  
        { 0xF1, PREFETCH, NA,           NA,     128,    NA  }   
 };
@@ -219,12 +227,12 @@ static i386_cpu_info_t    *cpuid_cpu_infop = NULL;
 static i386_cpu_info_t cpuid_cpu_info;
 
 #if defined(__x86_64__)
-static void _do_cpuid(uint32_t selector, uint32_t *result)
+static void cpuid_fn(uint32_t selector, uint32_t *result)
 {
        do_cpuid(selector, result);
 }
 #else
-static void _do_cpuid(uint32_t selector, uint32_t *result)
+static void cpuid_fn(uint32_t selector, uint32_t *result)
 {
        if (cpu_mode_is64bit()) {
               asm("call _cpuid64"
@@ -256,7 +264,7 @@ cpuid_set_cache_info( i386_cpu_info_t * info_p )
        /* Get processor cache descriptor info using leaf 2.  We don't use
         * this internally, but must publish it for KEXTs.
         */
-       _do_cpuid(2, cpuid_result);
+       cpuid_fn(2, cpuid_result);
        for (j = 0; j < 4; j++) {
                if ((cpuid_result[j] >> 31) == 1)       /* bit31 is validity */
                        continue;
@@ -266,7 +274,7 @@ cpuid_set_cache_info( i386_cpu_info_t * info_p )
        for (i = 1; i < info_p->cache_info[0]; i++) {
                if (i*16 > sizeof(info_p->cache_info))
                        break;
-               _do_cpuid(2, cpuid_result);
+               cpuid_fn(2, cpuid_result);
                for (j = 0; j < 4; j++) {
                        if ((cpuid_result[j] >> 31) == 1) 
                                continue;
@@ -280,7 +288,7 @@ cpuid_set_cache_info( i386_cpu_info_t * info_p )
         * Most processors Mac OS X supports implement this flavor of CPUID.
         * Loop over each cache on the processor.
         */
-       _do_cpuid(0, cpuid_result);
+       cpuid_fn(0, cpuid_result);
        if (cpuid_result[eax] >= 4)
                cpuid_deterministic_supported = TRUE;
 
@@ -300,17 +308,17 @@ cpuid_set_cache_info( i386_cpu_info_t * info_p )
                reg[ecx] = index;       /* index starting at 0 */
                cpuid(reg);
 //kprintf("cpuid(4) index=%d eax=%p\n", index, reg[eax]);
-               cache_type = bitfield(reg[eax], 4, 0);
+               cache_type = bitfield32(reg[eax], 4, 0);
                if (cache_type == 0)
                        break;          /* no more caches */
-               cache_level             = bitfield(reg[eax],  7,  5);
-               cache_sharing           = bitfield(reg[eax], 25, 14) + 1;
+               cache_level             = bitfield32(reg[eax],  7,  5);
+               cache_sharing           = bitfield32(reg[eax], 25, 14) + 1;
                info_p->cpuid_cores_per_package 
-                                       = bitfield(reg[eax], 31, 26) + 1;
-               cache_linesize          = bitfield(reg[ebx], 11,  0) + 1;
-               cache_partitions        = bitfield(reg[ebx], 21, 12) + 1;
-               cache_associativity     = bitfield(reg[ebx], 31, 22) + 1;
-               cache_sets              = bitfield(reg[ecx], 31,  0) + 1;
+                                       = bitfield32(reg[eax], 31, 26) + 1;
+               cache_linesize          = bitfield32(reg[ebx], 11,  0) + 1;
+               cache_partitions        = bitfield32(reg[ebx], 21, 12) + 1;
+               cache_associativity     = bitfield32(reg[ebx], 31, 22) + 1;
+               cache_sets              = bitfield32(reg[ecx], 31,  0) + 1;
                                
                /* Map type/levels returned by CPUID into cache_type_t */
                switch (cache_level) {
@@ -443,20 +451,20 @@ cpuid_set_cache_info( i386_cpu_info_t * info_p )
 static void
 cpuid_set_generic_info(i386_cpu_info_t *info_p)
 {
-       uint32_t        cpuid_reg[4];
+       uint32_t        reg[4];
         char            str[128], *p;
 
        /* do cpuid 0 to get vendor */
-       _do_cpuid(0, cpuid_reg);
-       info_p->cpuid_max_basic = cpuid_reg[eax];
-       bcopy((char *)&cpuid_reg[ebx], &info_p->cpuid_vendor[0], 4); /* ug */
-       bcopy((char *)&cpuid_reg[ecx], &info_p->cpuid_vendor[8], 4);
-       bcopy((char *)&cpuid_reg[edx], &info_p->cpuid_vendor[4], 4);
+       cpuid_fn(0, reg);
+       info_p->cpuid_max_basic = reg[eax];
+       bcopy((char *)&reg[ebx], &info_p->cpuid_vendor[0], 4); /* ug */
+       bcopy((char *)&reg[ecx], &info_p->cpuid_vendor[8], 4);
+       bcopy((char *)&reg[edx], &info_p->cpuid_vendor[4], 4);
        info_p->cpuid_vendor[12] = 0;
 
        /* get extended cpuid results */
-       _do_cpuid(0x80000000, cpuid_reg);
-       info_p->cpuid_max_ext = cpuid_reg[eax];
+       cpuid_fn(0x80000000, reg);
+       info_p->cpuid_max_ext = reg[eax];
 
        /* check to see if we can get brand string */
        if (info_p->cpuid_max_ext >= 0x80000004) {
@@ -464,12 +472,12 @@ cpuid_set_generic_info(i386_cpu_info_t *info_p)
                 * The brand string 48 bytes (max), guaranteed to
                 * be NUL terminated.
                 */
-               _do_cpuid(0x80000002, cpuid_reg);
-               bcopy((char *)cpuid_reg, &str[0], 16);
-               _do_cpuid(0x80000003, cpuid_reg);
-               bcopy((char *)cpuid_reg, &str[16], 16);
-               _do_cpuid(0x80000004, cpuid_reg);
-               bcopy((char *)cpuid_reg, &str[32], 16);
+               cpuid_fn(0x80000002, reg);
+               bcopy((char *)reg, &str[0], 16);
+               cpuid_fn(0x80000003, reg);
+               bcopy((char *)reg, &str[16], 16);
+               cpuid_fn(0x80000004, reg);
+               bcopy((char *)reg, &str[32], 16);
                for (p = str; *p != '\0'; p++) {
                        if (*p != ' ') break;
                }
@@ -489,29 +497,29 @@ cpuid_set_generic_info(i386_cpu_info_t *info_p)
     
        /* Get cache and addressing info. */
        if (info_p->cpuid_max_ext >= 0x80000006) {
-               _do_cpuid(0x80000006, cpuid_reg);
-               info_p->cpuid_cache_linesize   = bitfield(cpuid_reg[ecx], 7, 0);
+               cpuid_fn(0x80000006, reg);
+               info_p->cpuid_cache_linesize   = bitfield32(reg[ecx], 7, 0);
                info_p->cpuid_cache_L2_associativity =
-                                                bitfield(cpuid_reg[ecx],15,12);
-               info_p->cpuid_cache_size       = bitfield(cpuid_reg[ecx],31,16);
-               _do_cpuid(0x80000008, cpuid_reg);
+                                                bitfield32(reg[ecx],15,12);
+               info_p->cpuid_cache_size       = bitfield32(reg[ecx],31,16);
+               cpuid_fn(0x80000008, reg);
                info_p->cpuid_address_bits_physical =
-                                                bitfield(cpuid_reg[eax], 7, 0);
+                                                bitfield32(reg[eax], 7, 0);
                info_p->cpuid_address_bits_virtual =
-                                                bitfield(cpuid_reg[eax],15, 8);
+                                                bitfield32(reg[eax],15, 8);
        }
 
        /* get processor signature and decode */
-       _do_cpuid(1, cpuid_reg);
-       info_p->cpuid_signature = cpuid_reg[eax];
-       info_p->cpuid_stepping  = bitfield(cpuid_reg[eax],  3,  0);
-       info_p->cpuid_model     = bitfield(cpuid_reg[eax],  7,  4);
-       info_p->cpuid_family    = bitfield(cpuid_reg[eax], 11,  8);
-       info_p->cpuid_type      = bitfield(cpuid_reg[eax], 13, 12);
-       info_p->cpuid_extmodel  = bitfield(cpuid_reg[eax], 19, 16);
-       info_p->cpuid_extfamily = bitfield(cpuid_reg[eax], 27, 20);
-       info_p->cpuid_brand     = bitfield(cpuid_reg[ebx],  7,  0);
-       info_p->cpuid_features  = quad(cpuid_reg[ecx], cpuid_reg[edx]);
+       cpuid_fn(1, reg);
+       info_p->cpuid_signature = reg[eax];
+       info_p->cpuid_stepping  = bitfield32(reg[eax],  3,  0);
+       info_p->cpuid_model     = bitfield32(reg[eax],  7,  4);
+       info_p->cpuid_family    = bitfield32(reg[eax], 11,  8);
+       info_p->cpuid_type      = bitfield32(reg[eax], 13, 12);
+       info_p->cpuid_extmodel  = bitfield32(reg[eax], 19, 16);
+       info_p->cpuid_extfamily = bitfield32(reg[eax], 27, 20);
+       info_p->cpuid_brand     = bitfield32(reg[ebx],  7,  0);
+       info_p->cpuid_features  = quad(reg[ecx], reg[edx]);
 
        /* Fold extensions into family/model */
        if (info_p->cpuid_family == 0x0f)
@@ -521,112 +529,145 @@ cpuid_set_generic_info(i386_cpu_info_t *info_p)
 
        if (info_p->cpuid_features & CPUID_FEATURE_HTT)
                info_p->cpuid_logical_per_package =
-                               bitfield(cpuid_reg[ebx], 23, 16);
+                               bitfield32(reg[ebx], 23, 16);
        else
                info_p->cpuid_logical_per_package = 1;
 
        if (info_p->cpuid_max_ext >= 0x80000001) {
-               _do_cpuid(0x80000001, cpuid_reg);
+               cpuid_fn(0x80000001, reg);
                info_p->cpuid_extfeatures =
-                               quad(cpuid_reg[ecx], cpuid_reg[edx]);
+                               quad(reg[ecx], reg[edx]);
        }
 
        /* Fold in the Invariant TSC feature bit, if present */
        if (info_p->cpuid_max_ext >= 0x80000007) {
-               _do_cpuid(0x80000007, cpuid_reg);  
+               cpuid_fn(0x80000007, reg);  
                info_p->cpuid_extfeatures |=
-                               cpuid_reg[edx] & (uint32_t)CPUID_EXTFEATURE_TSCI;
+                               reg[edx] & (uint32_t)CPUID_EXTFEATURE_TSCI;
        }
 
        /* Find the microcode version number a.k.a. signature a.k.a. BIOS ID */
         info_p->cpuid_microcode_version =
                 (uint32_t) (rdmsr64(MSR_IA32_BIOS_SIGN_ID) >> 32);
 
-       if (info_p->cpuid_model == CPUID_MODEL_NEHALEM) {
-               /*
-                * For Nehalem, find the number of enabled cores and threads
-                * (which determines whether SMT/Hyperthreading is active).
-                */
-               uint64_t msr_core_thread_count = rdmsr64(MSR_CORE_THREAD_COUNT);
-               info_p->core_count   = bitfield((uint32_t)msr_core_thread_count, 31, 16);
-               info_p->thread_count = bitfield((uint32_t)msr_core_thread_count, 15,  0);
-       }
-       
        if (info_p->cpuid_max_basic >= 0x5) {
+               cpuid_mwait_leaf_t      *cmp = &info_p->cpuid_mwait_leaf;
+
                /*
                 * Extract the Monitor/Mwait Leaf info:
                 */
-               _do_cpuid(5, cpuid_reg);
-               info_p->cpuid_mwait_linesize_min = cpuid_reg[eax];
-               info_p->cpuid_mwait_linesize_max = cpuid_reg[ebx];
-               info_p->cpuid_mwait_extensions   = cpuid_reg[ecx];
-               info_p->cpuid_mwait_sub_Cstates  = cpuid_reg[edx];
+               cpuid_fn(5, reg);
+               cmp->linesize_min = reg[eax];
+               cmp->linesize_max = reg[ebx];
+               cmp->extensions   = reg[ecx];
+               cmp->sub_Cstates  = reg[edx];
+               info_p->cpuid_mwait_leafp = cmp;
        }
 
        if (info_p->cpuid_max_basic >= 0x6) {
+               cpuid_thermal_leaf_t    *ctp = &info_p->cpuid_thermal_leaf;
+
                /*
                 * The thermal and Power Leaf:
                 */
-               _do_cpuid(6, cpuid_reg);
-               info_p->cpuid_thermal_sensor =
-                                       bitfield(cpuid_reg[eax], 0, 0);
-               info_p->cpuid_thermal_dynamic_acceleration =
-                                       bitfield(cpuid_reg[eax], 1, 1);
-               info_p->cpuid_thermal_thresholds =
-                                       bitfield(cpuid_reg[ebx], 3, 0);
-               info_p->cpuid_thermal_ACNT_MCNT =
-                                       bitfield(cpuid_reg[ecx], 0, 0);
+               cpuid_fn(6, reg);
+               ctp->sensor               = bitfield32(reg[eax], 0, 0);
+               ctp->dynamic_acceleration = bitfield32(reg[eax], 1, 1);
+               ctp->thresholds           = bitfield32(reg[ebx], 3, 0);
+               ctp->ACNT_MCNT            = bitfield32(reg[ecx], 0, 0);
+               info_p->cpuid_thermal_leafp = ctp;
        }
 
        if (info_p->cpuid_max_basic >= 0xa) {
+               cpuid_arch_perf_leaf_t  *capp = &info_p->cpuid_arch_perf_leaf;
+
                /*
                 * Architectural Performance Monitoring Leaf:
                 */
-               _do_cpuid(0xa, cpuid_reg);
-               info_p->cpuid_arch_perf_version =
-                                       bitfield(cpuid_reg[eax], 7, 0);
-               info_p->cpuid_arch_perf_number =
-                                       bitfield(cpuid_reg[eax],15, 8);
-               info_p->cpuid_arch_perf_width =
-                                       bitfield(cpuid_reg[eax],23,16);
-               info_p->cpuid_arch_perf_events_number =
-                                       bitfield(cpuid_reg[eax],31,24);
-               info_p->cpuid_arch_perf_events =
-                                       cpuid_reg[ebx];
-               info_p->cpuid_arch_perf_fixed_number =
-                                       bitfield(cpuid_reg[edx], 4, 0);
-               info_p->cpuid_arch_perf_fixed_width =
-                                       bitfield(cpuid_reg[edx],12, 5);
+               cpuid_fn(0xa, reg);
+               capp->version       = bitfield32(reg[eax],  7,  0);
+               capp->number        = bitfield32(reg[eax], 15,  8);
+               capp->width         = bitfield32(reg[eax], 23, 16);
+               capp->events_number = bitfield32(reg[eax], 31, 24);
+               capp->events        = reg[ebx];
+               capp->fixed_number  = bitfield32(reg[edx],  4,  0);
+               capp->fixed_width   = bitfield32(reg[edx], 12,  5);
+               info_p->cpuid_arch_perf_leafp = capp;
        }
 
        return;
 }
 
+static uint32_t
+cpuid_set_cpufamily(i386_cpu_info_t *info_p)
+{
+       uint32_t cpufamily = CPUFAMILY_UNKNOWN;
+
+       switch (info_p->cpuid_family) {
+       case 6:
+               switch (info_p->cpuid_model) {
+               case 13:
+                       cpufamily = CPUFAMILY_INTEL_6_13;
+                       break;
+               case 14:
+                       cpufamily = CPUFAMILY_INTEL_YONAH;
+                       break;
+               case 15:
+                       cpufamily = CPUFAMILY_INTEL_MEROM;
+                       break;
+               case 23:
+                       cpufamily = CPUFAMILY_INTEL_PENRYN;
+                       break;
+               case CPUID_MODEL_NEHALEM:
+               case CPUID_MODEL_FIELDS:
+               case CPUID_MODEL_DALES:
+               case CPUID_MODEL_NEHALEM_EX:
+                       cpufamily = CPUFAMILY_INTEL_NEHALEM;
+                       break;
+               }
+               break;
+       }
+
+       info_p->cpuid_cpufamily = cpufamily;
+       return cpufamily;
+}
+
 void
 cpuid_set_info(void)
 {
-       bzero((void *)&cpuid_cpu_info, sizeof(cpuid_cpu_info));
+       i386_cpu_info_t         *info_p = &cpuid_cpu_info;
+       
+       bzero((void *)info_p, sizeof(cpuid_cpu_info));
 
-       cpuid_set_generic_info(&cpuid_cpu_info);
+       cpuid_set_generic_info(info_p);
 
        /* verify we are running on a supported CPU */
-       if ((strncmp(CPUID_VID_INTEL, cpuid_cpu_info.cpuid_vendor,
+       if ((strncmp(CPUID_VID_INTEL, info_p->cpuid_vendor,
                     min(strlen(CPUID_STRING_UNKNOWN) + 1,
-                        sizeof(cpuid_cpu_info.cpuid_vendor)))) ||
-          (cpuid_cpu_info.cpuid_family != 6) ||
-          (cpuid_cpu_info.cpuid_model < 13))
+                        sizeof(info_p->cpuid_vendor)))) ||
+          (cpuid_set_cpufamily(info_p) == CPUFAMILY_UNKNOWN))
                panic("Unsupported CPU");
 
-       cpuid_cpu_info.cpuid_cpu_type = CPU_TYPE_X86;
-       cpuid_cpu_info.cpuid_cpu_subtype = CPU_SUBTYPE_X86_ARCH1;
+       info_p->cpuid_cpu_type = CPU_TYPE_X86;
+       info_p->cpuid_cpu_subtype = CPU_SUBTYPE_X86_ARCH1;
 
        cpuid_set_cache_info(&cpuid_cpu_info);
 
-       if (cpuid_cpu_info.core_count == 0) {
-               cpuid_cpu_info.core_count =
-                       cpuid_cpu_info.cpuid_cores_per_package;
-               cpuid_cpu_info.thread_count =
-                       cpuid_cpu_info.cpuid_logical_per_package;
+       /*
+        * Find the number of enabled cores and threads
+        * (which determines whether SMT/Hyperthreading is active).
+        */
+       switch (info_p->cpuid_cpufamily) {
+       case CPUFAMILY_INTEL_NEHALEM: {
+               uint64_t msr = rdmsr64(MSR_CORE_THREAD_COUNT);
+               info_p->core_count   = bitfield32((uint32_t)msr, 31, 16);
+               info_p->thread_count = bitfield32((uint32_t)msr, 15,  0);
+               break;
+               }
+       }
+       if (info_p->core_count == 0) {
+               info_p->core_count   = info_p->cpuid_cores_per_package;
+               info_p->thread_count = info_p->cpuid_logical_per_package;
        }
 
        cpuid_cpu_info.cpuid_model_string = ""; /* deprecated */
@@ -795,6 +836,12 @@ cpuid_family(void)
        return cpuid_info()->cpuid_family;
 }
 
+uint32_t
+cpuid_cpufamily(void)
+{
+       return cpuid_info()->cpuid_cpufamily;
+}
+
 cpu_type_t
 cpuid_cputype(void)
 {
index e43ec1282ab03f8780b58e8b8e08d9e1006cad5e..135ededc36f7ef0122995c6d47e9d11bf7c20c4a 100644 (file)
 #define CPUID_MODEL_MEROM      15
 #define CPUID_MODEL_PENRYN     23
 #define CPUID_MODEL_NEHALEM    26
+#define CPUID_MODEL_ATOM       28
+#define CPUID_MODEL_FIELDS     30      /* Lynnfield, Clarksfield, Jasper */
+#define CPUID_MODEL_DALES      31      /* Havendale, Auburndale */
+#define CPUID_MODEL_NEHALEM_EX 46
 
 #ifndef ASSEMBLER
 #include <stdint.h>
@@ -184,13 +188,40 @@ typedef struct {
        { value, type, size, linesize }
 #endif /* KERNEL */
 
+/* Monitor/mwait Leaf: */
+typedef struct {
+       uint32_t        linesize_min;
+       uint32_t        linesize_max;
+       uint32_t        extensions;
+       uint32_t        sub_Cstates;
+} cpuid_mwait_leaf_t;
+
+/* Thermal and Power Management Leaf: */
+typedef struct {
+       boolean_t       sensor;
+       boolean_t       dynamic_acceleration;
+       uint32_t        thresholds;
+       boolean_t       ACNT_MCNT;
+} cpuid_thermal_leaf_t;
+
+/* Architectural Performance Monitoring Leaf: */
+typedef struct {
+       uint8_t         version;
+       uint8_t         number;
+       uint8_t         width;
+       uint8_t         events_number;
+       uint32_t        events;
+       uint8_t         fixed_number;
+       uint8_t         fixed_width;
+} cpuid_arch_perf_leaf_t;
+
 /* Physical CPU info - this is exported out of the kernel (kexts), so be wary of changes */
 typedef struct {
        char            cpuid_vendor[16];
        char            cpuid_brand_string[48];
        const char      *cpuid_model_string;
 
-       cpu_type_t      cpuid_type;                                     /* this is *not* a cpu_type_t in our <mach/machine.h> */
+       cpu_type_t      cpuid_type;     /* this is *not* a cpu_type_t in our <mach/machine.h> */
        uint8_t         cpuid_family;
        uint8_t         cpuid_model;
        uint8_t         cpuid_extmodel;
@@ -214,27 +245,15 @@ typedef struct {
        cpu_type_t      cpuid_cpu_type;                 /* <mach/machine.h> */
        cpu_subtype_t   cpuid_cpu_subtype;              /* <mach/machine.h> */  
 
-       /* Monitor/mwait Leaf: */
-       uint32_t        cpuid_mwait_linesize_min;
-       uint32_t        cpuid_mwait_linesize_max;
-       uint32_t        cpuid_mwait_extensions;
-       uint32_t        cpuid_mwait_sub_Cstates;
-
-       /* Thermal and Power Management Leaf: */
-       boolean_t       cpuid_thermal_sensor;
-       boolean_t       cpuid_thermal_dynamic_acceleration;
-       uint32_t        cpuid_thermal_thresholds;
-       boolean_t       cpuid_thermal_ACNT_MCNT;
-
-       /* Architectural Performance Monitoring Leaf: */
-       uint8_t         cpuid_arch_perf_version;
-       uint8_t         cpuid_arch_perf_number;
-       uint8_t         cpuid_arch_perf_width;
-       uint8_t         cpuid_arch_perf_events_number;
-       uint32_t        cpuid_arch_perf_events;
-       uint8_t         cpuid_arch_perf_fixed_number;
-       uint8_t         cpuid_arch_perf_fixed_width;
-       
+       /* Per-vendor info */
+       cpuid_mwait_leaf_t      cpuid_mwait_leaf;       
+#define cpuid_mwait_linesize_max       cpuid_mwait_leaf.linesize_max
+#define cpuid_mwait_linesize_min       cpuid_mwait_leaf.linesize_min
+#define cpuid_mwait_extensions         cpuid_mwait_leaf.extensions
+#define cpuid_mwait_sub_Cstates                cpuid_mwait_leaf.sub_Cstates
+       cpuid_thermal_leaf_t    cpuid_thermal_leaf;
+       cpuid_arch_perf_leaf_t  cpuid_arch_perf_leaf;
+
        /* Cache details: */
        uint32_t        cpuid_cache_linesize;
        uint32_t        cpuid_cache_L2_associativity;
@@ -260,6 +279,13 @@ typedef struct {
        /* Max leaf ids available from CPUID */
        uint32_t        cpuid_max_basic;
        uint32_t        cpuid_max_ext;
+
+       /* Family-specific info links */
+       uint32_t                cpuid_cpufamily;
+       cpuid_mwait_leaf_t      *cpuid_mwait_leafp;     
+       cpuid_thermal_leaf_t    *cpuid_thermal_leafp;
+       cpuid_arch_perf_leaf_t  *cpuid_arch_perf_leafp;
+
 } i386_cpu_info_t;
 
 #ifdef __cplusplus
@@ -280,6 +306,7 @@ extern char *               cpuid_get_extfeature_names(uint64_t, char *, unsigned);
 extern uint64_t                cpuid_features(void);
 extern uint64_t                cpuid_extfeatures(void);
 extern uint32_t                cpuid_family(void);
+extern uint32_t                cpuid_cpufamily(void);
        
 extern void            cpuid_get_info(i386_cpu_info_t *info_p);
 extern i386_cpu_info_t *cpuid_info(void);
index 5b8d2ba977222eac9e4c10a4e3b2088dc41e911e..33de7450af16e9b4548d6fd2304073ed97d6a205 100644 (file)
@@ -73,7 +73,8 @@ typedef struct lowglo {
        uint32_t        lgDevSlot2;             /* 0x2490 For developer use */
        uint32_t        lgOSVersion;            /* 0x2494 Pointer to OS version string */
        uint32_t        lgRebootFlag;           /* 0x2498 Pointer to debugger reboot trigger */
-       uint32_t        lgRsv49C[729];          /* 0x549C Reserved - push to 1 page */
+       uint32_t        lgManualPktAddr;        /* 0x249C Pointer to manual packet structure */
+       uint32_t        lgRsv49C[728];          /* 0x24A0 Reserved - push to 1 page */
 } lowglo;
 #pragma pack()
 extern lowglo lowGlo;
index b274b8ee50f3548ed70cb44f005eec07fd1dd3ea..45b74dd108db629243ce4710f682c3799fa16ab7 100644 (file)
@@ -96,7 +96,9 @@ EXT(lowGlo):
        .long   EXT(osversion)          /* 0x2494 Pointer to osversion string */
 #if MACH_KDP
        .long   EXT(flag_kdp_trigger_reboot) /* 0x2498 Pointer to debugger reboot trigger */
+       .long   EXT(manual_pkt)              /* 0x249C Poiner to debugger manual packet address */
 #else
        .long   0                       /* 0x2498 Reserved */
+       .long   0                       /* 0x249C Reserved */
 #endif
-       .fill   729, 4, 0
+       .fill   728, 4, 0
index e11c8f6c5a6039d1eed6dbce1c794f1f1d7fe170..837a094f509053dec8b695a67949e7256d1d6eab 100644 (file)
@@ -48,6 +48,7 @@
 #include <kern/machine.h>
 #include <kern/pms.h>
 #include <kern/misc_protos.h>
+#include <kern/etimer.h>
 
 #include <vm/vm_map.h>
 #include <vm/vm_kern.h>
 #endif /* MP_DEBUG */
 
 
+#define ABS(v)         (((v) > 0)?(v):-(v))
+
 void           slave_boot_init(void);
 
 #if MACH_KDB
@@ -116,6 +119,7 @@ static int          cpu_signal_handler(x86_saved_state_t *regs);
 static int             NMIInterruptHandler(x86_saved_state_t *regs);
 
 boolean_t              smp_initialized = FALSE;
+uint32_t               TSC_sync_margin = 0xFFF;
 volatile boolean_t     force_immediate_debugger_NMI = FALSE;
 volatile boolean_t     pmap_tlb_flush_timeout = FALSE;
 decl_simple_lock_data(,mp_kdp_lock);
@@ -216,20 +220,37 @@ smp_init(void)
 
        install_real_mode_bootstrap(slave_pstart);
 
+       if (PE_parse_boot_argn("TSC_sync_margin",
+                               &TSC_sync_margin, sizeof(TSC_sync_margin)))
+               kprintf("TSC sync Margin 0x%x\n", TSC_sync_margin);
        smp_initialized = TRUE;
 
        return;
 }
 
+typedef struct {
+       int                     target_cpu;
+       int                     target_lapic;
+       int                     starter_cpu;
+} processor_start_info_t;
+static processor_start_info_t  start_info        __attribute__((aligned(64)));
+
+/* 
+ * Cache-alignment is to avoid cross-cpu false-sharing interference.
+ */
+static volatile long           tsc_entry_barrier __attribute__((aligned(64)));
+static volatile long           tsc_exit_barrier  __attribute__((aligned(64)));
+static volatile uint64_t       tsc_target        __attribute__((aligned(64)));
+
 /*
  * Poll a CPU to see when it has marked itself as running.
  */
 static void
 mp_wait_for_cpu_up(int slot_num, unsigned int iters, unsigned int usecdelay)
 {
-       while (iters-- > 0) {
+       while (iters-- > 0) {
                if (cpu_datap(slot_num)->cpu_running)
-                       break;
+                       break;
                delay(usecdelay);
        }
 }
@@ -240,7 +261,7 @@ mp_wait_for_cpu_up(int slot_num, unsigned int iters, unsigned int usecdelay)
 kern_return_t
 intel_startCPU_fast(int slot_num)
 {
-       kern_return_t   rc;
+       kern_return_t   rc;
 
        /*
         * Try to perform a fast restart
@@ -271,17 +292,29 @@ intel_startCPU_fast(int slot_num)
         */
        if (cpu_datap(slot_num)->cpu_running)
                return(KERN_SUCCESS);
-       else
+       else
                return(KERN_FAILURE);
 }
 
-typedef struct {
-       int     target_cpu;
-       int     target_lapic;
-       int     starter_cpu;
-} processor_start_info_t;
+static void
+started_cpu(void)
+{
+       /* Here on the started cpu with cpu_running set TRUE */
 
-static processor_start_info_t start_info;
+       if (TSC_sync_margin &&
+           start_info.target_cpu == cpu_number()) {
+               /*
+                * I've just started-up, synchronize again with the starter cpu
+                * and then snap my TSC.
+                */
+               tsc_target   = 0;
+               atomic_decl(&tsc_entry_barrier, 1);
+               while (tsc_entry_barrier != 0)
+                       ;       /* spin for starter and target at barrier */
+               tsc_target = rdtsc64();
+               atomic_decl(&tsc_exit_barrier, 1);
+       }
+}
 
 static void
 start_cpu(void *arg)
@@ -305,6 +338,37 @@ start_cpu(void *arg)
        i *= 10000;
 #endif
        mp_wait_for_cpu_up(psip->target_cpu, i*100, 100);
+       if (TSC_sync_margin &&
+           cpu_datap(psip->target_cpu)->cpu_running) {
+               /*
+                * Compare the TSC from the started processor with ours.
+                * Report and log/panic if it diverges by more than
+                * TSC_sync_margin (TSC_SYNC_MARGIN) ticks. This margin
+                * can be overriden by boot-arg (with 0 meaning no checking).
+                */
+               uint64_t        tsc_starter;
+               int64_t         tsc_delta;
+               atomic_decl(&tsc_entry_barrier, 1);
+               while (tsc_entry_barrier != 0)
+                       ;       /* spin for both processors at barrier */
+               tsc_starter = rdtsc64();
+               atomic_decl(&tsc_exit_barrier, 1);
+               while (tsc_exit_barrier != 0)
+                       ;       /* spin for target to store its TSC */
+               tsc_delta = tsc_target - tsc_starter;
+               kprintf("TSC sync for cpu %d: 0x%016llx delta 0x%llx (%lld)\n",
+                       psip->target_cpu, tsc_target, tsc_delta, tsc_delta);
+               if (ABS(tsc_delta) > (int64_t) TSC_sync_margin) { 
+#if DEBUG
+                       panic(
+#else
+                       printf(
+#endif
+                               "Unsynchronized  TSC for cpu %d: "
+                                       "0x%016llx, delta 0x%llx\n",
+                               psip->target_cpu, tsc_target, tsc_delta);
+               }
+       }
 }
 
 extern char    prot_mode_gdt[];
@@ -349,6 +413,8 @@ intel_startCPU(
        start_info.starter_cpu  = cpu_number();
        start_info.target_cpu   = slot_num;
        start_info.target_lapic = lapic;
+       tsc_entry_barrier = 2;
+       tsc_exit_barrier = 2;
 
        /*
         * Perform the processor startup sequence with all running
@@ -357,6 +423,8 @@ intel_startCPU(
         */
        mp_rendezvous_no_intrs(start_cpu, (void *) &start_info);
 
+       start_info.target_cpu = 0;
+
        ml_set_interrupts_enabled(istate);
        lck_mtx_unlock(&mp_cpu_boot_lock);
 
@@ -1020,6 +1088,7 @@ i386_activate_cpu(void)
 
        simple_lock(&x86_topo_lock);
        cdp->cpu_running = TRUE;
+       started_cpu();
        simple_unlock(&x86_topo_lock);
 }
 
index 709e2b4b34c9455b6823cff1f38abb67f6d6595b..084038e4b4705db7b25b2a0f4c031e7de42e529d 100644 (file)
@@ -62,6 +62,7 @@
 #include <kern/cpu_data.h>
 #include <mach/mach_types.h>
 #include <mach/machine.h>
+#include <kern/etimer.h>
 #include <mach/vm_map.h>
 #include <mach/machine/vm_param.h>
 #include <vm/vm_kern.h>
@@ -278,11 +279,7 @@ struct fake_descriptor64 kernel_ldt_desc64 = {
 struct fake_descriptor64 kernel_tss_desc64 = {
        0,
        sizeof(struct x86_64_tss)-1,
-#ifdef __x86_64__
-       SZ_G,
-#else
        0,
-#endif
        ACC_P|ACC_PL_K|ACC_TSS,
        0
 };
@@ -569,8 +566,6 @@ cpu_desc_init64(cpu_data_t *cdp)
                /*
                 * Master CPU uses the tables built at boot time.
                 * Just set the index pointers to the low memory space.
-                * Note that in 64-bit mode these are addressed in the
-                * double-mapped window (uber-space).
                 */
                cdi->cdi_ktss = (void *)&master_ktss64;
                cdi->cdi_sstk = (vm_offset_t) &master_sstk.top;
@@ -604,8 +599,7 @@ cpu_desc_init64(cpu_data_t *cdp)
                cpu_desc_table64_t      *cdt = (cpu_desc_table64_t *) cdp->cpu_desc_tablep;
                /*
                 * Per-cpu GDT, IDT, KTSS descriptors are allocated in kernel 
-                * heap (cpu_desc_table) . 
-                * On K32 they're double-mapped in uber-space (over 4GB).
+                * heap (cpu_desc_table). 
                 * LDT descriptors are mapped into a separate area.
                 */
                cdi->cdi_gdt.ptr  = (struct fake_descriptor *)cdt->gdt;
@@ -694,7 +688,7 @@ cpu_desc_load64(cpu_data_t *cdp)
         *
         * Refer to commpage/cpu_number.s for the IDT limit trick.
         */
-       gdtptr64.length = GDTSZ * sizeof(struct real_descriptor64) - 1;
+       gdtptr64.length = GDTSZ * sizeof(struct real_descriptor) - 1;
        gdtptr64.offset[0] = (uint32_t) cdi->cdi_gdt.ptr;
        gdtptr64.offset[1] = KERNEL_UBER_BASE_HI32;
        idtptr64.length = 0x1000 + cdp->cpu_number;
@@ -707,7 +701,7 @@ cpu_desc_load64(cpu_data_t *cdp)
        ml_load_desc64();
 #else
        /* Load the GDT, LDT, IDT and TSS */
-       cdi->cdi_gdt.size = sizeof(struct real_descriptor64)*GDTSZ - 1;
+       cdi->cdi_gdt.size = sizeof(struct real_descriptor)*GDTSZ - 1;
        cdi->cdi_idt.size = 0x1000 + cdp->cpu_number;
        lgdt((unsigned long *) &cdi->cdi_gdt);
        lidt((unsigned long *) &cdi->cdi_idt);
index e3142fe4caec7f99044b42fc1985a212f0f68fc4..56fe44b1722b903e98ddc86360c4685c7a5605e5 100644 (file)
@@ -41,6 +41,7 @@
 #include <kern/machine.h>
 #include <kern/pms.h>
 #include <kern/processor.h>
+#include <kern/etimer.h>
 #include <i386/cpu_threads.h>
 #include <i386/pmCPU.h>
 #include <i386/cpuid.h>
@@ -619,6 +620,12 @@ pmSendIPI(int cpu)
     lapic_send_ipi(cpu, LAPIC_PM_INTERRUPT);
 }
 
+static rtc_nanotime_t *
+pmGetNanotimeInfo(void)
+{
+    return(&rtc_nanotime_info);
+}
+
 /*
  * Called by the power management kext to register itself and to get the
  * callbacks it might need into other kernel functions.  This interface
@@ -648,6 +655,7 @@ pmKextRegister(uint32_t version, pmDispatch_t *cpuFuncs,
        callbacks->ThreadBind           = thread_bind;
        callbacks->GetSavedRunCount     = pmGetSavedRunCount;
        callbacks->pmSendIPI            = pmSendIPI;
+       callbacks->GetNanotimeInfo      = pmGetNanotimeInfo;
        callbacks->topoParms            = &topoParms;
     } else {
        panic("Version mis-match between Kernel and CPU PM");
index 65c7b9e9cf20abdfc04ee02bc614a1638a1e3a66..5609df50e3860165846b454a724fd61c6a09d896 100644 (file)
@@ -30,6 +30,7 @@
 #define _I386_PMCPU_H_
 
 #include <i386/cpu_topology.h>
+#include <i386/rtclock.h>
 
 #ifndef ASSEMBLER
 
@@ -37,7 +38,7 @@
  * This value should be changed each time that pmDsipatch_t or pmCallBacks_t
  * changes.
  */
-#define PM_DISPATCH_VERSION    17
+#define PM_DISPATCH_VERSION    18
 
 /*
  * Dispatch table for functions that get installed when the power
@@ -97,6 +98,7 @@ typedef struct {
     processor_t                (*ThreadBind)(processor_t proc);
     uint32_t           (*GetSavedRunCount)(void);
     void               (*pmSendIPI)(int cpu);
+    rtc_nanotime_t     *(*GetNanotimeInfo)(void);
     x86_topology_parameters_t  *topoParms;
 } pmCallBacks_t;
 
index 6c1b18483b76718a4cb6e944700a1d2e6fda3b3b..13410afc889769213a8653c74c7e93d0aeb45391 100644 (file)
@@ -52,6 +52,7 @@
 #include <kern/misc_protos.h>
 #include <kern/spl.h>
 #include <kern/assert.h>
+#include <kern/etimer.h>
 #include <mach/vm_prot.h>
 #include <vm/pmap.h>
 #include <vm/vm_kern.h>                /* for kernel_map */
index ec3e922d83384dafb17d6c7d00c6a0a785a54c6e..35280788ab5b3f49ccab595fbe57cc857e5a8be1 100644 (file)
@@ -53,7 +53,9 @@ typedef struct rtc_nanotime {
        uint32_t        spare1;
 } rtc_nanotime_t;
 
+#if 0
 #include <kern/etimer.h>
+#endif
 
 struct cpu_data;
 
index 6744a9097582329859e7f47e4b74143425c30117..0a7f882a3ec4f58330a9ba14d9c6ad429de68d02 100644 (file)
@@ -142,13 +142,8 @@ tsc_init(void)
         */
        busFreq = EFI_FSB_frequency();
 
-       if (cpuid_info()->cpuid_family != CPU_FAMILY_PENTIUM_M) {
-               panic("tsc_init: unknown CPU family: 0x%X\n",
-                       cpuid_info()->cpuid_family);
-       }
-
-       switch (cpuid_info()->cpuid_model) {
-       case CPUID_MODEL_NEHALEM: {
+       switch (cpuid_cpufamily()) {
+       case CPUFAMILY_INTEL_NEHALEM: {
                uint64_t cpu_mhz;
                uint64_t msr_flex_ratio;
                uint64_t msr_platform_info;
index 21a29d47af24d025b83e315282bb961d142dd901..dbacccfd85276f1c0aa275a0ba302b7f286ac8e5 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <kdp/kdp_internal.h>
 #include <kdp/kdp_private.h>
+#include <kdp/kdp_core.h>
 
 #include <libsa/types.h>
 
@@ -80,11 +81,12 @@ static kdp_dispatch_t
 /*17 */ kdp_breakpoint64_remove,
 /*18 */ kdp_kernelversion,
 /*19 */ kdp_readphysmem64,
-/*20 */ kdp_writephysmem64,
-/*21 */ kdp_readioport,
-/*22 */ kdp_writeioport,
-/*23 */ kdp_readmsr64,
-/*24 */ kdp_writemsr64,
+/*1A */ kdp_writephysmem64,
+/*1B */ kdp_readioport,
+/*1C */ kdp_writeioport,
+/*1D */ kdp_readmsr64,
+/*1E */ kdp_writemsr64,
+/*1F */ kdp_dumpinfo,
     };
     
 kdp_glob_t     kdp;
@@ -95,7 +97,7 @@ kdp_glob_t    kdp;
  * Version 11 of the KDP Protocol adds support for 64-bit wide memory
  * addresses (read/write and breakpoints) as well as a dedicated
  * kernelversion request. Version 12 adds read/writing of physical
- * memory with 64-bit wide memory addresses.
+ * memory with 64-bit wide memory addresses. 
  */
 #define KDP_VERSION 12
 
@@ -219,31 +221,42 @@ kdp_connect(
     kdp_connect_req_t  *rq = &pkt->connect_req;
     size_t             plen = *len;
     kdp_connect_reply_t        *rp = &pkt->connect_reply;
+    uint16_t            rport, eport;
+    uint32_t            key;
+    uint8_t             seq;
 
     if (plen < sizeof (*rq))
        return (FALSE);
 
     dprintf(("kdp_connect seq %x greeting %s\n", rq->hdr.seq, rq->greeting));
 
+    rport = rq->req_reply_port;
+    eport = rq->exc_note_port;
+    key   = rq->hdr.key;
+    seq   = rq->hdr.seq;
     if (kdp.is_conn) {
-       if (rq->hdr.seq == kdp.conn_seq)        /* duplicate request */
+       if ((seq == kdp.conn_seq) &&    /* duplicate request */
+            (rport == kdp.reply_port) &&
+            (eport == kdp.exception_port) &&
+            (key == kdp.session_key))
            rp->error = KDPERR_NO_ERROR;
-       else
+       else 
            rp->error = KDPERR_ALREADY_CONNECTED;
     }
     else { 
-       kdp.reply_port = rq->req_reply_port;
-       kdp.exception_port = rq->exc_note_port;
-       kdp.is_conn = TRUE;
-       kdp.conn_seq = rq->hdr.seq;
-    
+       kdp.reply_port     = rport;
+       kdp.exception_port = eport;
+       kdp.is_conn        = TRUE;
+       kdp.conn_seq       = seq;
+        kdp.session_key    = key;
+
        rp->error = KDPERR_NO_ERROR;
     }
 
     rp->hdr.is_reply = 1;
     rp->hdr.len = sizeof (*rp);
     
-    *reply_port = kdp.reply_port;
+    *reply_port = rport;
     *len = rp->hdr.len;
     
     if (current_debugger == KDP_CUR_DB)    
@@ -276,6 +289,7 @@ kdp_disconnect(
     kdp.reply_port = kdp.exception_port = 0;
     kdp.is_halted = kdp.is_conn = FALSE;
     kdp.exception_seq = kdp.conn_seq = 0;
+    kdp.session_key = 0;
 
     if ((panicstr != NULL) && (return_on_panic == 0))
            reattach_wait = 1;
@@ -1278,3 +1292,36 @@ kdp_writemsr64(
     
        return (TRUE);
 }
+
+static boolean_t
+kdp_dumpinfo(
+       kdp_pkt_t       *pkt,
+       int             *len,
+       unsigned short  *reply_port
+              )
+{
+       kdp_dumpinfo_req_t   *rq = &pkt->dumpinfo_req;
+       kdp_dumpinfo_reply_t *rp = &pkt->dumpinfo_reply;
+       size_t  plen = *len;
+       
+       if (plen < sizeof (*rq))
+               return (FALSE);
+       
+       dprintf(("kdp_dumpinfo file=%s destip=%s routerip=%s\n", rq->name, rq->destip, rq->routerip));
+       rp->hdr.is_reply = 1;
+       rp->hdr.len = sizeof (*rp);
+       
+        if ((rq->type & KDP_DUMPINFO_MASK) != KDP_DUMPINFO_GETINFO) {
+            kdp_set_dump_info(rq->type, rq->name, rq->destip, rq->routerip, 
+                                rq->port);
+        }
+
+        /* gather some stats for reply */
+        kdp_get_dump_info(&rp->type, rp->name, rp->destip, rp->routerip, 
+                          &rp->port);
+
+       *reply_port = kdp.reply_port;
+       *len = rp->hdr.len;
+    
+       return (TRUE);
+}
index d2b59ebfbb803efe0280ab9a4707b21420507173..99a278720c69fab92df0d88bca2e9e62271f1517 100644 (file)
@@ -80,8 +80,12 @@ struct       corehdr {
 #define CORE_REMOTE_PORT 1069 /* hardwired, we can't really query the services file */
 
 void kdp_panic_dump (void);
-
 void abort_panic_transfer (void);
+void kdp_set_dump_info(const uint32_t flags, const char *file, const char *destip,
+                       const char *routerip, const uint32_t port);
+void kdp_get_dump_info(uint32_t *flags, char *file, char *destip, char *routerip, 
+                       uint32_t *port);
+
 
 struct corehdr *create_panic_header(unsigned int request, const char *corename, unsigned length, unsigned block);
 
index d619f6d227ddb0957d69c4658c9968e90da6ec44..337dad81d3bcef8f5cdc2157e50561083ffdbbce 100644 (file)
 #include <libsa/types.h>
 
 typedef struct {
-    unsigned short             reply_port;
+    void                       *saved_state;
+    thread_t                   kdp_thread;
+    int                                kdp_cpu;
+    uint32_t                    session_key;
     unsigned int               conn_seq;
+    unsigned short             reply_port;
+    unsigned short             exception_port;
     boolean_t                  is_conn;
-    void                       *saved_state;
     boolean_t                  is_halted;
-    unsigned short             exception_port;
     unsigned char              exception_seq;
     boolean_t                  exception_ack_needed;
-    int                                kdp_cpu;
-    thread_t                   kdp_thread;
 } kdp_glob_t;
 
 extern kdp_glob_t      kdp;
 
 extern volatile int    kdp_flag;
+extern int            noresume_on_disconnect;
 
 #define KDP_READY       0x1
 #define KDP_ARP         0x2
@@ -61,6 +63,7 @@ extern volatile int   kdp_flag;
 #define DBG_POST_CORE     0x40
 #define PANIC_LOG_DUMP    0x80
 #define REBOOT_POST_CORE  0x100
+#define SYSTEM_LOG_DUMP   0x200
 typedef boolean_t
 (*kdp_dispatch_t) (
     kdp_pkt_t *,
@@ -200,4 +203,3 @@ kdp_machine_msr64_read(kdp_readmsr64_req_t *, caddr_t /* data */, uint16_t /* lc
 
 int
 kdp_machine_msr64_write(kdp_writemsr64_req_t *, caddr_t /* data */, uint16_t /* lcpu */);
-
index ac72296769c8942c1e167afe544a63f96072a28b..07e5123ff4248a1518b7ce6b86039e2db48a5767 100644 (file)
@@ -211,3 +211,6 @@ kdp_readmsr64(kdp_pkt_t *, int *, unsigned short *);
 
 static boolean_t
 kdp_writemsr64(kdp_pkt_t *, int *, unsigned short *);
+
+static boolean_t
+kdp_dumpinfo(kdp_pkt_t *, int *, unsigned short *);
index 723382ca5d3404d9aa194923e1a048ca6c5f1b9c..fb9d294823da0fe59b82e351371a65d6997f96a1 100644 (file)
  * Definition of remote debugger protocol.
  */
 
+
+#ifdef MACH_KERNEL_PRIVATE
 #include       <mach/vm_prot.h>
 #include       <stdint.h>
+#endif
+
+#ifdef KDP_PROXY_PACK_SUPPORT
+#pragma pack(1)
+#define KDP_PACKED
+#else
+#define KDP_PACKED __attribute__((packed))
+#endif
 
 /*
  * Retransmit parameters
@@ -46,7 +56,6 @@
 #endif /* DDEBUG_DEBUG || DEBUG_DEBUG */
 #define        KDP_REXMIT_TRIES        8       /* xmit 8 times, then give up */
 
-#define KDP_PACKED __attribute__((packed))
 
 /*
  * (NMI) Attention Max Wait Time
@@ -124,12 +133,35 @@ typedef enum {
         /* msr access (64-bit) */
        KDP_READMSR64,  KDP_WRITEMSR64,
 
+        /* get/dump panic/corefile info */
+        KDP_DUMPINFO,
+
        /* keep this last */
        KDP_INVALID_REQUEST
 } kdp_req_t;
 
+typedef enum {
+        KDP_DUMPINFO_GETINFO    = 0x00000000, 
+        KDP_DUMPINFO_SETINFO    = 0x00000001, 
+        KDP_DUMPINFO_CORE       = 0x00000102, 
+        KDP_DUMPINFO_PANICLOG   = 0x00000103, 
+        KDP_DUMPINFO_SYSTEMLOG  = 0x00000104, 
+        KDP_DUMPINFO_DISABLE    = 0x00000105, 
+        KDP_DUMPINFO_MASK       = 0x00000FFF,
+        KDP_DUMPINFO_DUMP       = 0x00000100,
+
+        KDP_DUMPINFO_REBOOT     = 0x10000000,
+        KDP_DUMPINFO_NORESUME   = 0x20000000,
+        KDP_DUMPINFO_RESUME     = 0x00000000, /* default behaviour */
+        KDP_DUMPINFO_NOINTR     = 0x40000000, /* don't interrupt */
+        KDP_DUMPINFO_INTR       = 0x00000000, /* default behaviour */
+} kdp_dumpinfo_t;
+
 /*
  * Common KDP packet header
+ * NOTE: kgmacros has a non-symboled version of kdp_hdr_t so that some basic information.
+ *       can be gathered from a kernel without any symbols. changes to this structure
+ *       need to be reflected in kgmacros as well.
  */
 typedef struct {
        kdp_req_t       request:7;      /* kdp_req_t, request type */
@@ -147,10 +179,10 @@ typedef enum {
        KDPERR_ALREADY_CONNECTED,
        KDPERR_BAD_NBYTES,
        KDPERR_BADFLAVOR,               /* bad flavor in w/r regs */
+
        KDPERR_MAX_BREAKPOINTS = 100,
        KDPERR_BREAKPOINT_NOT_FOUND = 101,
        KDPERR_BREAKPOINT_ALREADY_SET = 102
-
 } kdp_error_t;
 
 /*
@@ -582,6 +614,28 @@ typedef struct {
        kdp_hdr_t       hdr;
 } KDP_PACKED kdp_termination_ack_t;
 
+/*
+ * KDP_DUMPINFO
+ */
+typedef struct {                       /* KDP_DUMPINFO request */
+       kdp_hdr_t       hdr;
+        char            name[50];       
+       char            destip[16];
+       char            routerip[16];
+       uint32_t        port;
+       kdp_dumpinfo_t  type;
+} KDP_PACKED kdp_dumpinfo_req_t;
+
+typedef struct {                       /* KDP_DUMPINFO reply */
+       kdp_hdr_t       hdr;
+        char            name[50];       
+       char            destip[16];
+       char            routerip[16];
+       uint32_t        port;
+       kdp_dumpinfo_t  type;
+} KDP_PACKED kdp_dumpinfo_reply_t;
+
+
 typedef union {
        kdp_hdr_t               hdr;
        kdp_connect_req_t       connect_req;
@@ -639,9 +693,27 @@ typedef union {
        kdp_readmsr64_reply_t   readmsr64_reply;
        kdp_writemsr64_req_t    writemsr64_req;
        kdp_writemsr64_reply_t  writemsr64_reply;
+       kdp_dumpinfo_req_t      dumpinfo_req;
+       kdp_dumpinfo_reply_t    dumpinfo_reply;
 } kdp_pkt_t;
 
 #define MAX_KDP_PKT_SIZE       1200    /* max packet size */
 #define MAX_KDP_DATA_SIZE      1024    /* max r/w data per packet */
 
+/*
+ * Support relatively small request/responses here.
+ * If kgmacros needs to make a larger request, increase
+ * this buffer size
+ */
+#define KDP_MANUAL_PACKET_SIZE 128
+struct kdp_manual_pkt {
+    unsigned char      data[KDP_MANUAL_PACKET_SIZE];
+    unsigned int       len;
+    boolean_t          input;
+} KDP_PACKED;
+
+#ifdef KDP_PROXY_PACK_SUPPORT
+#pragma pack()
+#endif
+
 #endif // _KDP_PROTOCOL_H_
index c43049684468edd458f880a9a26508ac806a8b80..5cab18769328e1e3a7fcd19a74fafa08a1cc2878 100644 (file)
@@ -58,6 +58,8 @@
 
 #include <mach/memory_object_types.h>
 
+#include <sys/msgbuf.h>
+
 #include <string.h>
 
 #define DO_ALIGN       1       /* align all packet data accesses */
@@ -87,16 +89,7 @@ static struct {
     boolean_t          input;
 } pkt, saved_reply;
 
-/*
- * Support relatively small request/responses here.
- * If kgmacros needs to make a larger request, increase
- * this buffer size
- */
-static struct {
-    unsigned char      data[128];
-    unsigned int       len;
-    boolean_t          input;
-} manual_pkt;
+struct kdp_manual_pkt manual_pkt;
 
 struct {
     struct {
@@ -139,6 +132,7 @@ static uint32_t target_ip = 0;
 
 static volatile boolean_t panicd_specified = FALSE;
 static boolean_t router_specified = FALSE;
+static boolean_t corename_specified = FALSE;
 static unsigned int panicd_port = CORE_REMOTE_PORT;
 
 static struct ether_addr etherbroadcastaddr = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
@@ -150,6 +144,7 @@ static struct ether_addr current_resolved_MAC = {{0, 0, 0 , 0, 0, 0}};
 
 static boolean_t flag_panic_dump_in_progress = FALSE;
 static boolean_t flag_router_mac_initialized = FALSE;
+static boolean_t flag_dont_abort_panic_dump  = FALSE;
 
 static boolean_t flag_arp_resolved = FALSE;
 
@@ -160,6 +155,7 @@ unsigned int SEGSIZE = 512;
 
 static char panicd_ip_str[20];
 static char router_ip_str[20];
+static char corename_str[50];
 
 static unsigned int panic_block = 0;
 volatile unsigned int kdp_trigger_core_dump = 0;
@@ -286,6 +282,9 @@ kdp_register_send_receive(
        if (!PE_parse_boot_argn("panicd_port", &panicd_port, sizeof (panicd_port)))
                panicd_port = CORE_REMOTE_PORT;
 
+       if (PE_parse_boot_argn("_panicd_corename", &corename_str, sizeof (corename_str)))
+               corename_specified = TRUE;
+
        kdp_flag |= KDP_READY;
        if (current_debugger == NO_CUR_DB)
                current_debugger = KDP_CUR_DB;
@@ -387,8 +386,9 @@ ip_sum(
 
 static void
 kdp_reply(
-       unsigned short          reply_port
-       )
+          unsigned short               reply_port,
+          const boolean_t         sideband
+          )
 {
        struct udpiphdr         aligned_ui, *ui = &aligned_ui;
        struct ip               aligned_ip, *ip = &aligned_ip;
@@ -447,12 +447,14 @@ kdp_reply(
        pkt.len += (unsigned int)sizeof (struct ether_header);
     
        // save reply for possible retransmission
-       bcopy((char *)&pkt, (char *)&saved_reply, sizeof(pkt));
+       if (!sideband)
+               bcopy((char *)&pkt, (char *)&saved_reply, sizeof(pkt));
 
        (*kdp_en_send_pkt)(&pkt.data[pkt.off], pkt.len);
 
        // increment expected sequence number
-       exception_seq++;
+       if (!sideband) 
+               exception_seq++;
 }
 
 static void
@@ -731,12 +733,14 @@ kdp_poll(void)
        }
        /* If we receive a kernel debugging packet whilst a 
         * core dump is in progress, abort the transfer and 
-        * enter the debugger.
+        * enter the debugger if not told otherwise. 
         */
        else
                if (flag_panic_dump_in_progress)
                {
-                       abort_panic_transfer();
+                       if (!flag_dont_abort_panic_dump) {
+                               abort_panic_transfer();
+                       }
                        return;
                }
 
@@ -875,7 +879,8 @@ kdp_handler(
            (*kdp_en_send_pkt)(&saved_reply.data[saved_reply.off],
                            saved_reply.len);
            goto again;
-       } else if (hdr->seq != exception_seq) {
+       } else if ((hdr->seq != exception_seq) &&
+                   (hdr->request != KDP_CONNECT)) {
            printf("kdp: bad sequence %d (want %d)\n",
                        hdr->seq, exception_seq);
            goto again;
@@ -901,7 +906,24 @@ kdp_handler(
        if (kdp_packet((unsigned char*)&pkt.data[pkt.off], 
                        (int *)&pkt.len, 
                        (unsigned short *)&reply_port)) {
-           kdp_reply(reply_port);
+            boolean_t sideband = FALSE;
+
+            /* if it's an already connected error message, 
+             * send a sideband reply for that. for successful connects,
+             * make sure the sequence number is correct. */
+            if (hdr->request == KDP_CONNECT) {
+                kdp_connect_reply_t *rp = 
+                       (kdp_connect_reply_t *) &pkt.data[pkt.off];
+                kdp_error_t err = rp->error;
+
+                if (err == KDPERR_NO_ERROR) {
+                    exception_seq = hdr->seq;
+                } else if (err == KDPERR_ALREADY_CONNECTED) {
+                    sideband = TRUE;
+                }
+            } 
+
+           kdp_reply(reply_port, sideband);
        }
 
 again:
@@ -1011,7 +1033,7 @@ kdp_connection_wait(void)
                    if (kdp_packet((unsigned char *)&pkt.data[pkt.off], 
                                (int *)&pkt.len, 
                                (unsigned short *)&reply_port))
-                               kdp_reply(reply_port);
+                           kdp_reply(reply_port, FALSE);
                    if (hdr->request == KDP_REATTACH) {
                                reattach_wait = 0;
                                hdr->request=KDP_DISCONNECT;
@@ -1168,9 +1190,10 @@ kdp_raise_exception(
      */
 
     if (1 == kdp_trigger_core_dump) {
-       kdp_flag &= ~PANIC_LOG_DUMP;
        kdp_flag |= KDP_PANIC_DUMP_ENABLED;
        kdp_panic_dump();
+       if (kdp_flag & REBOOT_POST_CORE)
+               kdp_machine_reboot();
        kdp_trigger_core_dump = 0;
       }
 
@@ -1206,6 +1229,7 @@ kdp_reset(void)
        kdp.reply_port = kdp.exception_port = 0;
        kdp.is_halted = kdp.is_conn = FALSE;
        kdp.exception_seq = kdp.conn_seq = 0;
+        kdp.session_key = 0;
 }
 
 struct corehdr *
@@ -1299,32 +1323,52 @@ create_panic_header(unsigned int request, const char *corename,
        return coreh;
 }
 
+static int kdp_send_crashdump_seek(char *corename, uint64_t seek_off)
+{
+       int panic_error;
+
+#if defined(__LP64__)
+       if (kdp_feature_large_crashdumps) {
+               panic_error = kdp_send_crashdump_pkt(KDP_SEEK, corename, 
+                                                    sizeof(seek_off),
+                                                    &seek_off);
+       } else
+#endif
+       {
+               uint32_t off = (uint32_t) seek_off;
+               panic_error = kdp_send_crashdump_pkt(KDP_SEEK, corename, 
+                                                    sizeof(off), &off);
+       }
+
+       if (panic_error < 0) {
+               printf ("kdp_send_crashdump_pkt failed with error %d\n",
+                       panic_error);
+               return panic_error;
+       }
+
+       return 0;
+}
+
 int kdp_send_crashdump_data(unsigned int request, char *corename,
     uint64_t length, caddr_t txstart)
 {
-       caddr_t txend = txstart + length;
        int panic_error = 0;
 
-       if (length <= SEGSIZE) {
-               if ((panic_error = kdp_send_crashdump_pkt(request, corename, length, (caddr_t) txstart)) < 0) {
+       while (length > 0) {
+               uint64_t chunk = MIN(SEGSIZE, length);
+               
+               panic_error = kdp_send_crashdump_pkt(request, corename, chunk,
+                                                    (caddr_t) txstart);
+               if (panic_error < 0) {
                        printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error);
-                       return panic_error ;
-               }
-       }
-       else
-       {
-               while (txstart <= (txend - SEGSIZE))  {
-                       if ((panic_error = kdp_send_crashdump_pkt(KDP_DATA, NULL, SEGSIZE, txstart)) < 0) {
-                               printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error);
-                               return panic_error;
-                       }
-                       txstart += SEGSIZE;
-                       if (!(panic_block % 2000))
-                               kdb_printf_unbuffered(".");
-               }
-               if (txstart < txend) {
-                       kdp_send_crashdump_pkt(request, corename, (unsigned int)(txend - txstart), txstart);
+                       return panic_error;
                }
+
+               if (!(panic_block % 2000))
+                       kdb_printf_unbuffered(".");
+
+               txstart += chunk;
+               length  -= chunk;
        }
        return 0;
 }
@@ -1362,6 +1406,13 @@ TRANSMIT_RETRY:
        th = create_panic_header(request, corename, (unsigned)length, panic_block);
 
        if (request == KDP_DATA) {
+               /* as all packets are SEGSIZE in length, the last packet
+                * may end up with trailing bits. make sure that those
+                * bits aren't confusing. */
+               if (length < SEGSIZE)
+                       memset(th->th_data + length, 'X', 
+                               SEGSIZE - (uint32_t) length);
+
                if (!kdp_machine_vm_read((mach_vm_address_t)(intptr_t)panic_data, (caddr_t) th->th_data, length)) {
                        memset ((caddr_t) th->th_data, 'X', (size_t)length);
                }
@@ -1508,11 +1559,124 @@ kdp_get_xnu_version(char *versionbuf)
 
 extern char *inet_aton(const char *cp, struct in_addr *pin);
 
+void
+kdp_set_dump_info(const uint32_t flags, const char *filename, 
+                  const char *destipstr, const char *routeripstr,
+                  const uint32_t port)
+{
+       uint32_t cmd;
+
+       if (destipstr && (destipstr[0] != '\0')) {
+               strlcpy(panicd_ip_str, destipstr, sizeof(panicd_ip_str));
+               panicd_specified = 1;
+       }
+
+       if (routeripstr && (routeripstr[0] != '\0')) {
+               strlcpy(router_ip_str, routeripstr, sizeof(router_ip_str));
+               router_specified = 1;
+       }
+
+       if (filename && (filename[0] != '\0')) {
+               strlcpy(corename_str, filename, sizeof(corename_str));
+               corename_specified = TRUE;
+       } else {
+               corename_specified = FALSE;
+       }
+
+       if (port) 
+               panicd_port = port;
+
+        /* on a disconnect, should we stay in KDP or not? */
+        noresume_on_disconnect = (flags & KDP_DUMPINFO_NORESUME) ? 1 : 0;
+
+       if ((flags & KDP_DUMPINFO_DUMP) == 0)
+               return;
+
+       /* the rest of the commands can modify kdp_flags */
+       cmd = flags & KDP_DUMPINFO_MASK;
+        if (cmd == KDP_DUMPINFO_DISABLE) {
+               kdp_flag &= ~KDP_PANIC_DUMP_ENABLED;
+               panicd_specified       = 0;
+               kdp_trigger_core_dump  = 0;
+               return;
+        }
+
+       kdp_flag &= ~REBOOT_POST_CORE;
+       if (flags & KDP_DUMPINFO_REBOOT)
+            kdp_flag |= REBOOT_POST_CORE;
+
+       kdp_flag &= ~PANIC_LOG_DUMP;
+       if (cmd == KDP_DUMPINFO_PANICLOG)
+            kdp_flag |= PANIC_LOG_DUMP;
+       
+       kdp_flag &= ~SYSTEM_LOG_DUMP;
+       if (cmd == KDP_DUMPINFO_SYSTEMLOG)
+            kdp_flag |= SYSTEM_LOG_DUMP;
+
+       /* trigger a dump */
+       kdp_flag |= DBG_POST_CORE;
+
+       flag_dont_abort_panic_dump = (flags & KDP_DUMPINFO_NOINTR) ? 
+               TRUE : FALSE;
+
+       reattach_wait          = 1;
+       logPanicDataToScreen   = 1;
+       disableConsoleOutput   = 0;
+       disable_debug_output   = 0;
+       kdp_trigger_core_dump  = 1;
+}
+
+void
+kdp_get_dump_info(uint32_t *flags, char *filename, char *destipstr, 
+                  char *routeripstr, uint32_t *port)
+{
+       if (destipstr) {
+               if (panicd_specified)
+                       strlcpy(destipstr, panicd_ip_str, 
+                                sizeof(panicd_ip_str));
+               else 
+                       destipstr[0] = '\0';
+       }
+
+       if (routeripstr) {
+               if (router_specified)
+                       strlcpy(routeripstr, router_ip_str,
+                                sizeof(router_ip_str));
+               else
+                       routeripstr[0] = '\0';
+       }
+
+       if (filename) {
+               if (corename_specified)
+                       strlcpy(filename, corename_str, 
+                                sizeof(corename_str));
+               else 
+                       filename[0] = '\0';
+
+       }
+
+       if (port) 
+               *port = panicd_port;
+
+       if (flags) {
+               *flags = 0;
+                if (!panicd_specified) 
+                       *flags |= KDP_DUMPINFO_DISABLE;
+                else if (kdp_flag & PANIC_LOG_DUMP)
+                       *flags |= KDP_DUMPINFO_PANICLOG;
+               else
+                       *flags |= KDP_DUMPINFO_CORE;
+
+               if (noresume_on_disconnect)
+                       *flags |= KDP_DUMPINFO_NORESUME;
+       }
+}
+
+
 /* Primary dispatch routine for the system dump */
 void 
 kdp_panic_dump(void)
 {
-       char corename[50];
        char coreprefix[10];
        int panic_error;
 
@@ -1539,21 +1703,25 @@ kdp_panic_dump(void)
 
        kdp_get_xnu_version((char *) &pkt.data[0]);
 
-       /* Panic log bit takes precedence over core dump bit */
-       if ((panicstr != (char *) 0) && (kdp_flag & PANIC_LOG_DUMP))
-               strncpy(coreprefix, "paniclog", sizeof(coreprefix));
-       else
-               strncpy(coreprefix, "core", sizeof(coreprefix));
+        if (!corename_specified) {
+            /* Panic log bit takes precedence over core dump bit */
+            if ((panicstr != (char *) 0) && (kdp_flag & PANIC_LOG_DUMP))
+               strlcpy(coreprefix, "paniclog", sizeof(coreprefix));
+            else if (kdp_flag & SYSTEM_LOG_DUMP) 
+               strlcpy(coreprefix, "systemlog", sizeof(coreprefix));
+           else
+               strlcpy(coreprefix, "core", sizeof(coreprefix));
   
-       abstime = mach_absolute_time();
-       pkt.data[20] = '\0';
-       snprintf (corename, sizeof(corename), "%s-%s-%d.%d.%d.%d-%x", 
-           coreprefix, &pkt.data[0],
-           (current_ip & 0xff000000) >> 24,
-           (current_ip & 0xff0000) >> 16,
-           (current_ip & 0xff00) >> 8,
-           (current_ip & 0xff),
-           (unsigned int) (abstime & 0xffffffff));
+            abstime = mach_absolute_time();
+           pkt.data[20] = '\0';
+           snprintf (corename_str, sizeof(corename_str), "%s-%s-%d.%d.%d.%d-%x", 
+                     coreprefix, &pkt.data[0],
+                     (current_ip & 0xff000000) >> 24,
+                     (current_ip & 0xff0000) >> 16,
+                     (current_ip & 0xff00) >> 8,
+                     (current_ip & 0xff),
+                     (unsigned int) (abstime & 0xffffffff));
+        }
 
        if (0 == inet_aton(panicd_ip_str, (struct in_addr *) &panic_server_ip)) {
                printf("inet_aton() failed interpreting %s as a panic server IP\n", panicd_ip_str);
@@ -1593,9 +1761,9 @@ kdp_panic_dump(void)
            destination_mac.ether_addr_octet[5] & 0xff);
 
        printf("Kernel map size is %llu\n", (unsigned long long) get_vmmap_size(kernel_map));
-       printf("Sending write request for %s\n", corename);  
+       printf("Sending write request for %s\n", corename_str);  
 
-       if ((panic_error = kdp_send_crashdump_pkt(KDP_WRQ, corename, 0 , NULL)) < 0) {
+       if ((panic_error = kdp_send_crashdump_pkt(KDP_WRQ, corename_str, 0 , NULL)) < 0) {
                printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error);
                goto panic_dump_exit;
        }
@@ -1603,14 +1771,44 @@ kdp_panic_dump(void)
        /* Just the panic log requested */
        if ((panicstr != (char *) 0) && (kdp_flag & PANIC_LOG_DUMP)) {
                printf("Transmitting panic log, please wait: ");
-               kdp_send_crashdump_data(KDP_DATA, corename, (unsigned int)(debug_buf_ptr - debug_buf), debug_buf);
+               kdp_send_crashdump_data(KDP_DATA, corename_str, 
+                                       debug_buf_ptr - debug_buf,
+                                       debug_buf);
                kdp_send_crashdump_pkt (KDP_EOF, NULL, 0, ((void *) 0));
                printf("Please file a bug report on this panic, if possible.\n");
                goto panic_dump_exit;
        }
   
+       /* maybe we wanted the systemlog */
+        if (kdp_flag & SYSTEM_LOG_DUMP) {
+               long start_off = msgbufp->msg_bufx;
+                long len;
+
+               printf("Transmitting system log, please wait: ");
+               if (start_off >= msgbufp->msg_bufr) {
+                       len = msgbufp->msg_size - start_off;
+                       kdp_send_crashdump_data(KDP_DATA, corename_str, len, 
+                                               msgbufp->msg_bufc + start_off);
+
+                       /* seek to remove trailing bytes */
+                       if (len & (SEGSIZE - 1))
+                               kdp_send_crashdump_seek(corename_str, len);
+                       start_off  = 0;
+               }
+
+               if (start_off != msgbufp->msg_bufr) {
+                       len = msgbufp->msg_bufr - start_off;
+                       kdp_send_crashdump_data(KDP_DATA, corename_str, len,
+                                               msgbufp->msg_bufc + start_off);
+               }
+
+               kdp_send_crashdump_pkt (KDP_EOF, NULL, 0, ((void *) 0));
+               goto panic_dump_exit;
+        }
+
        /* We want a core dump if we're here */
        kern_dump();
+
 panic_dump_exit:
        abort_panic_transfer();
        pkt.input = FALSE;
@@ -1623,6 +1821,7 @@ void
 abort_panic_transfer(void)
 {
        flag_panic_dump_in_progress = FALSE;
+       flag_dont_abort_panic_dump  = FALSE;
        not_in_kdp = 1;
        panic_block = 0;
 }
index ca4a1354f4eddfdda8621993f8dd78c2e996f6b0..2dc656aecaf6d703eed9d737fcb99f6f72ff9bef 100644 (file)
@@ -2252,16 +2252,14 @@ choose_processor(
         *      Prefer the last processor, when appropriate.
         */
        if (processor != PROCESSOR_NULL) {
-               if (thread->sched_pri < BASEPRI_RTQUEUES && processor->processor_meta != PROCESSOR_META_NULL &&
-                                                               processor->processor_meta->primary->state == PROCESSOR_IDLE)
+               if (processor->processor_meta != PROCESSOR_META_NULL)
                        processor = processor->processor_meta->primary;
 
                if (processor->processor_set != pset || processor->state == PROCESSOR_INACTIVE ||
                                processor->state == PROCESSOR_SHUTDOWN || processor->state == PROCESSOR_OFF_LINE)
                        processor = PROCESSOR_NULL;
                else
-               if (processor->state == PROCESSOR_IDLE ||
-                                       (thread->sched_pri > BASEPRI_DEFAULT && processor->current_pri < thread->sched_pri))
+               if (processor->state == PROCESSOR_IDLE)
                        return (processor);
        }
 
index 3ec6039b960f4a1ca154d8ebb401ea06bce2a22c..70b9485c5269ee52900e1d35bec1f38ee28c6554 100644 (file)
@@ -360,26 +360,28 @@ __END_DECLS
  * Use feature flags (eg, hw.optional.altivec) to test for optional
  * functionality.
  */
-#define CPUFAMILY_UNKNOWN    0
-#define CPUFAMILY_POWERPC_G3 0xcee41549
-#define CPUFAMILY_POWERPC_G4 0x77c184ae
-#define CPUFAMILY_POWERPC_G5 0xed76d8aa
-#define CPUFAMILY_INTEL_6_13 0xaa33392b
-#define CPUFAMILY_INTEL_6_14 0x73d67300  /* "Intel Core Solo" and "Intel Core Duo" (32-bit Pentium-M with SSE3) */
-#define CPUFAMILY_INTEL_6_15 0x426f69ef  /* "Intel Core 2 Duo" */
-#define CPUFAMILY_INTEL_6_23 0x78ea4fbc  /* Penryn */
-#define CPUFAMILY_INTEL_6_26 0x6b5a4cd2  /* Nehalem */
-#define CPUFAMILY_ARM_9      0xe73283ae
-#define CPUFAMILY_ARM_11     0x8ff620d8
-#define CPUFAMILY_ARM_XSCALE 0x53b005f5
-#define CPUFAMILY_ARM_13     0x0cc90e64
-
-#define CPUFAMILY_INTEL_YONAH  CPUFAMILY_INTEL_6_14
-#define CPUFAMILY_INTEL_MEROM  CPUFAMILY_INTEL_6_15
-#define CPUFAMILY_INTEL_PENRYN CPUFAMILY_INTEL_6_23
-#define CPUFAMILY_INTEL_NEHALEM        CPUFAMILY_INTEL_6_26
-
-#define CPUFAMILY_INTEL_CORE   CPUFAMILY_INTEL_6_14
-#define CPUFAMILY_INTEL_CORE2  CPUFAMILY_INTEL_6_15
+#define CPUFAMILY_UNKNOWN              0
+#define CPUFAMILY_POWERPC_G3           0xcee41549
+#define CPUFAMILY_POWERPC_G4           0x77c184ae
+#define CPUFAMILY_POWERPC_G5           0xed76d8aa
+#define CPUFAMILY_INTEL_6_13           0xaa33392b
+#define CPUFAMILY_INTEL_YONAH          0x73d67300
+#define CPUFAMILY_INTEL_MEROM          0x426f69ef
+#define CPUFAMILY_INTEL_PENRYN         0x78ea4fbc
+#define CPUFAMILY_INTEL_NEHALEM                0x6b5a4cd2
+#define CPUFAMILY_ARM_9                        0xe73283ae
+#define CPUFAMILY_ARM_11               0x8ff620d8
+#define CPUFAMILY_ARM_XSCALE           0x53b005f5
+#define CPUFAMILY_ARM_13               0x0cc90e64
+
+/* The following synonyms are deprecated: */
+#define CPUFAMILY_INTEL_6_14   CPUFAMILY_INTEL_YONAH
+#define CPUFAMILY_INTEL_6_15   CPUFAMILY_INTEL_MEROM
+#define CPUFAMILY_INTEL_6_23   CPUFAMILY_INTEL_PENRYN
+#define CPUFAMILY_INTEL_6_26   CPUFAMILY_INTEL_NEHALEM
+
+#define CPUFAMILY_INTEL_CORE   CPUFAMILY_INTEL_YONAH
+#define CPUFAMILY_INTEL_CORE2  CPUFAMILY_INTEL_MEROM
+
 
 #endif /* _MACH_MACHINE_H_ */
index 1a18cd1c57b16354269cf456299d311fbdbe5458..20503a89ba540e9bc39da6eae8a10c1197812956 100644 (file)
@@ -93,7 +93,8 @@ typedef struct lowglo {
        uint32_t                lgDevSlot2;             /* 0x5490 For developer use */
        uint32_t                lgOSVersion;            /* 0x5494 Pointer to OS version string */
        uint32_t                lgRebootFlag;           /* 0x5498 Pointer to debugger reboot trigger */
-       uint32_t                lgRsv49C[729];          /* 0x549C Reserved - push to 1 page */
+       uint32_t                lgManualPktAddr;        /* 0x549C Pointer to manual packet structure */
+       uint32_t                lgRsv49C[728];          /* 0x54A0 Reserved - push to 1 page */
 } lowglo;
 
 extern lowglo lowGlo;
index 4b6b06c045a5063da9095b47ea1d20ebac217dfc..5e2893d36ac0ecf17234cddf16e402c647430cc5 100644 (file)
@@ -3969,6 +3969,7 @@ EXT(killresv):
                        .long   0                                                               ; 5490 Reserved for developer use
                        .long   EXT(osversion)                                  ; 5494  Pointer to osversion string, debugging aid
                        .long   EXT(flag_kdp_trigger_reboot)                                    ; 5498  Pointer to KDP reboot trigger, debugging aid
+                       .long   EXT(manual_pkt)                                 ; 549C  Pointer to KDP manual packet, debugging aid
 
 ;
 ;      The "shared page" is used for low-level debugging and is actually 1/2 page long
index aef2f638f44d0c4b85b75e0f6692efeef9d00182..e4f404b805959785b17f128b700a98150af49b49 100644 (file)
@@ -70,7 +70,9 @@ typedef struct lowglo {
        uint64_t        lgDevSlot2;                             /* 0xffffff8000002918 For developer use */
        uint64_t        lgOSVersion;                    /* 0xffffff8000002920 Pointer to OS version string */
        uint64_t        lgRebootFlag;                   /* 0xffffff8000002928 Pointer to debugger reboot trigger */
-       uint64_t        lgRsv49C[218];                  /* 0xffffff8000002930 Reserved - push to 1 page */
+       uint64_t        lgManualPktAddr;                /* 0xffffff8000002930 Pointer to manual packet structure */
+
+       uint64_t        lgRsv49C[217];                  /* 0xffffff8000002938 Reserved - push to 1 page */
 } lowglo;
 #pragma pack()
 extern lowglo lowGlo;
index aa5c57e4e4480b0a7a1584ca670b42accf52b76c..40133c4a5c39a0b3142d71d9328d888af5382faa 100644 (file)
@@ -96,7 +96,9 @@ EXT(lowGlo):
        .quad   EXT(osversion)          /* +0x920 Pointer to osversion string */
 #if MACH_KDP
        .quad   EXT(flag_kdp_trigger_reboot) /* +0x928 Pointer to debugger reboot trigger */
+       .quad   EXT(manual_pkt)              /* +0x930 Pointer to manual packet structure */
 #else
        .quad   0                       /* +0x928 Reserved */
-#endif
-       .fill   436, 4, 0       /* pad to 0x1000 (page size) - rdar://problem/5783217 */
+       .quad   0                       /* +0x930 Reserved */
+#endif 
+       .fill   434, 4, 0       /* pad to 0x1000 (page size) - rdar://problem/5783217 */