+
+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);
+ 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 );