+ cpu_interrupt(processor->cpu_id);
+}
+
+static kern_return_t
+register_cpu(
+ uint32_t lapic_id,
+ processor_t *processor_out,
+ boolean_t boot_cpu )
+{
+ int target_cpu;
+ cpu_data_t *this_cpu_datap;
+
+ this_cpu_datap = cpu_data_alloc(boot_cpu);
+ if (this_cpu_datap == NULL) {
+ return KERN_FAILURE;
+ }
+ target_cpu = this_cpu_datap->cpu_number;
+ assert((boot_cpu && (target_cpu == 0)) ||
+ (!boot_cpu && (target_cpu != 0)));
+
+ lapic_cpu_map(lapic_id, target_cpu);
+
+ /* The cpu_id is not known at registration phase. Just do
+ * lapic_id for now
+ */
+ this_cpu_datap->cpu_phys_number = lapic_id;
+
+ this_cpu_datap->cpu_console_buf = console_cpu_alloc(boot_cpu);
+ if (this_cpu_datap->cpu_console_buf == NULL)
+ goto failed;
+
+ this_cpu_datap->cpu_chud = chudxnu_cpu_alloc(boot_cpu);
+ if (this_cpu_datap->cpu_chud == NULL)
+ goto failed;
+
+#if KPC
+ this_cpu_datap->cpu_kpc_buf[0] = kpc_counterbuf_alloc();
+ if(this_cpu_datap->cpu_kpc_buf[0] == NULL )
+ goto failed;
+ this_cpu_datap->cpu_kpc_buf[1] = kpc_counterbuf_alloc();
+ if(this_cpu_datap->cpu_kpc_buf[1] == NULL )
+ goto failed;
+
+ this_cpu_datap->cpu_kpc_shadow = kpc_counterbuf_alloc();
+ if(this_cpu_datap->cpu_kpc_shadow == NULL )
+ goto failed;
+
+ this_cpu_datap->cpu_kpc_reload = kpc_counterbuf_alloc();
+ if(this_cpu_datap->cpu_kpc_reload == NULL )
+ goto failed;
+#endif
+
+ if (!boot_cpu) {
+ cpu_thread_alloc(this_cpu_datap->cpu_number);
+ if (this_cpu_datap->lcpu.core == NULL)
+ goto failed;
+
+#if NCOPY_WINDOWS > 0
+ this_cpu_datap->cpu_pmap = pmap_cpu_alloc(boot_cpu);
+ if (this_cpu_datap->cpu_pmap == NULL)
+ goto failed;
+#endif
+
+ this_cpu_datap->cpu_processor = cpu_processor_alloc(boot_cpu);
+ if (this_cpu_datap->cpu_processor == NULL)
+ goto failed;
+ /*
+ * processor_init() deferred to topology start
+ * because "slot numbers" a.k.a. logical processor numbers
+ * are not yet finalized.
+ */
+ }
+
+ *processor_out = this_cpu_datap->cpu_processor;
+
+ return KERN_SUCCESS;
+
+failed:
+ cpu_processor_free(this_cpu_datap->cpu_processor);
+#if NCOPY_WINDOWS > 0
+ pmap_cpu_free(this_cpu_datap->cpu_pmap);
+#endif
+ chudxnu_cpu_free(this_cpu_datap->cpu_chud);
+ console_cpu_free(this_cpu_datap->cpu_console_buf);
+#if KPC
+ kpc_counterbuf_free(this_cpu_datap->cpu_kpc_buf[0]);
+ kpc_counterbuf_free(this_cpu_datap->cpu_kpc_buf[1]);
+ kpc_counterbuf_free(this_cpu_datap->cpu_kpc_shadow);
+ kpc_counterbuf_free(this_cpu_datap->cpu_kpc_reload);
+#endif
+
+ return KERN_FAILURE;
+}
+
+
+kern_return_t
+ml_processor_register(
+ cpu_id_t cpu_id,
+ uint32_t lapic_id,
+ processor_t *processor_out,
+ boolean_t boot_cpu,
+ boolean_t start )
+{
+ static boolean_t done_topo_sort = FALSE;
+ static uint32_t num_registered = 0;
+
+ /* Register all CPUs first, and track max */
+ if( start == FALSE )
+ {
+ num_registered++;
+
+ DBG( "registering CPU lapic id %d\n", lapic_id );
+
+ return register_cpu( lapic_id, processor_out, boot_cpu );
+ }
+
+ /* Sort by topology before we start anything */
+ if( !done_topo_sort )
+ {
+ DBG( "about to start CPUs. %d registered\n", num_registered );
+
+ cpu_topology_sort( num_registered );
+ done_topo_sort = TRUE;
+ }
+
+ /* Assign the cpu ID */
+ uint32_t cpunum = -1;
+ cpu_data_t *this_cpu_datap = NULL;
+
+ /* find cpu num and pointer */
+ cpunum = ml_get_cpuid( lapic_id );
+
+ if( cpunum == 0xFFFFFFFF ) /* never heard of it? */
+ panic( "trying to start invalid/unregistered CPU %d\n", lapic_id );
+
+ this_cpu_datap = cpu_datap(cpunum);
+
+ /* fix the CPU id */
+ this_cpu_datap->cpu_id = cpu_id;
+
+ /* output arg */
+ *processor_out = this_cpu_datap->cpu_processor;
+
+ /* OK, try and start this CPU */
+ return cpu_topology_start_cpu( cpunum );