+ cp = commPagePtr32;
+ cp += (_COMM_PAGE_ACTIVE_CPUS - _COMM_PAGE32_BASE_ADDRESS);
+ ip = (volatile uint8_t*) cp;
+ *ip = (uint8_t) processor_avail_count;
+
+ cp = commPagePtr64;
+ if ( cp ) {
+ cp += (_COMM_PAGE_ACTIVE_CPUS - _COMM_PAGE32_START_ADDRESS);
+ ip = (volatile uint8_t*) cp;
+ *ip = (uint8_t) processor_avail_count;
+ }
+
+ simple_unlock(&commpage_active_cpus_lock);
+}
+
+/*
+ * Update the commpage with current kdebug state. This currently has bits for
+ * global trace state, and typefilter enablement. It is likely additional state
+ * will be tracked in the future.
+ *
+ * INVARIANT: This value will always be 0 if global tracing is disabled. This
+ * allows simple guard tests of "if (*_COMM_PAGE_KDEBUG_ENABLE) { ... }"
+ */
+void
+commpage_update_kdebug_state(void)
+{
+ volatile uint32_t *saved_data_ptr;
+ char *cp;
+
+ cp = commPagePtr32;
+ if (cp) {
+ cp += (_COMM_PAGE_KDEBUG_ENABLE - _COMM_PAGE32_BASE_ADDRESS);
+ saved_data_ptr = (volatile uint32_t *)cp;
+ *saved_data_ptr = kdebug_commpage_state();
+ }
+
+ cp = commPagePtr64;
+ if (cp) {
+ cp += (_COMM_PAGE_KDEBUG_ENABLE - _COMM_PAGE32_START_ADDRESS);
+ saved_data_ptr = (volatile uint32_t *)cp;
+ *saved_data_ptr = kdebug_commpage_state();
+ }
+}
+
+/* Ditto for atm_diagnostic_config */
+void
+commpage_update_atm_diagnostic_config(uint32_t diagnostic_config)
+{
+ volatile uint32_t *saved_data_ptr;
+ char *cp;
+
+ cp = commPagePtr32;
+ if (cp) {
+ cp += (_COMM_PAGE_ATM_DIAGNOSTIC_CONFIG - _COMM_PAGE32_BASE_ADDRESS);
+ saved_data_ptr = (volatile uint32_t *)cp;
+ *saved_data_ptr = diagnostic_config;
+ }
+
+ cp = commPagePtr64;
+ if ( cp ) {
+ cp += (_COMM_PAGE_ATM_DIAGNOSTIC_CONFIG - _COMM_PAGE32_START_ADDRESS);
+ saved_data_ptr = (volatile uint32_t *)cp;
+ *saved_data_ptr = diagnostic_config;
+ }
+}
+
+/*
+ * update the commpage data for last known value of mach_absolute_time()
+ */
+
+void
+commpage_update_mach_approximate_time(uint64_t abstime)
+{
+#ifdef CONFIG_MACH_APPROXIMATE_TIME
+ uint64_t saved_data;
+ char *cp;
+
+ cp = commPagePtr32;
+ if ( cp ) {
+ cp += (_COMM_PAGE_APPROX_TIME - _COMM_PAGE32_BASE_ADDRESS);
+ saved_data = *(uint64_t *)cp;
+ if (saved_data < abstime) {
+ /* ignoring the success/fail return value assuming that
+ * if the value has been updated since we last read it,
+ * "someone" has a newer timestamp than us and ours is
+ * now invalid. */
+ OSCompareAndSwap64(saved_data, abstime, (uint64_t *)cp);
+ }
+ }
+ cp = commPagePtr64;
+ if ( cp ) {
+ cp += (_COMM_PAGE_APPROX_TIME - _COMM_PAGE32_START_ADDRESS);
+ saved_data = *(uint64_t *)cp;
+ if (saved_data < abstime) {
+ /* ignoring the success/fail return value assuming that
+ * if the value has been updated since we last read it,
+ * "someone" has a newer timestamp than us and ours is
+ * now invalid. */
+ OSCompareAndSwap64(saved_data, abstime, (uint64_t *)cp);
+ }
+ }
+#else
+#pragma unused (abstime)
+#endif
+}
+
+void
+commpage_update_mach_continuous_time(uint64_t sleeptime)
+{
+ char *cp;
+ cp = commPagePtr32;
+ if (cp) {
+ cp += (_COMM_PAGE_CONT_TIMEBASE - _COMM_PAGE32_START_ADDRESS);
+ *(uint64_t *)cp = sleeptime;
+ }
+
+ cp = commPagePtr64;
+ if (cp) {
+ cp += (_COMM_PAGE_CONT_TIMEBASE - _COMM_PAGE32_START_ADDRESS);
+ *(uint64_t *)cp = sleeptime;
+ }
+}
+
+void
+commpage_update_boottime(uint64_t boottime)
+{
+ char *cp;
+ cp = commPagePtr32;
+ if (cp) {
+ cp += (_COMM_PAGE_BOOTTIME_USEC - _COMM_PAGE32_START_ADDRESS);
+ *(uint64_t *)cp = boottime;
+ }
+
+ cp = commPagePtr64;
+ if (cp) {
+ cp += (_COMM_PAGE_BOOTTIME_USEC - _COMM_PAGE32_START_ADDRESS);
+ *(uint64_t *)cp = boottime;
+ }
+}
+
+
+extern user32_addr_t commpage_text32_location;
+extern user64_addr_t commpage_text64_location;
+
+/* Check to see if a given address is in the Preemption Free Zone (PFZ) */
+
+uint32_t
+commpage_is_in_pfz32(uint32_t addr32)
+{
+ if ( (addr32 >= (commpage_text32_location + _COMM_TEXT_PFZ_START_OFFSET))
+ && (addr32 < (commpage_text32_location+_COMM_TEXT_PFZ_END_OFFSET))) {
+ return 1;
+ }
+ else
+ return 0;
+}
+
+uint32_t
+commpage_is_in_pfz64(addr64_t addr64)
+{
+ if ( (addr64 >= (commpage_text64_location + _COMM_TEXT_PFZ_START_OFFSET))
+ && (addr64 < (commpage_text64_location + _COMM_TEXT_PFZ_END_OFFSET))) {
+ return 1;
+ }
+ else
+ return 0;