Index: boot/arch/sparc64/loader/asm.S
===================================================================
--- boot/arch/sparc64/loader/asm.S	(revision 5d684e4c0dde4f587dd5aca281c366f71f72853b)
+++ boot/arch/sparc64/loader/asm.S	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
@@ -101,4 +101,5 @@
 	mov %o1, %o0
 	mov %o2, %o1
+	mov %o3, %o2
 	jmp %l1				! jump to kernel
 	nop
Index: boot/arch/sparc64/loader/asm.h
===================================================================
--- boot/arch/sparc64/loader/asm.h	(revision 5d684e4c0dde4f587dd5aca281c366f71f72853b)
+++ boot/arch/sparc64/loader/asm.h	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
@@ -36,5 +36,5 @@
 
 extern void halt(void);
-extern void jump_to_kernel(void *entry, void *bootinfo, unsigned int bootinfo_size) __attribute__((noreturn));
+extern void jump_to_kernel(void *entry, int bsp, void *bootinfo, unsigned int bootinfo_size) __attribute__((noreturn));
 
 #endif
Index: boot/arch/sparc64/loader/main.c
===================================================================
--- boot/arch/sparc64/loader/main.c	(revision 5d684e4c0dde4f587dd5aca281c366f71f72853b)
+++ boot/arch/sparc64/loader/main.c	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
@@ -37,6 +37,4 @@
 #include <align.h>
 
-#define KERNEL_VIRTUAL_ADDRESS 0x400000
-
 bootinfo_t bootinfo;
 
@@ -58,9 +56,5 @@
 	}
 	
-	if (!ofw_cpu(&bootinfo.cpu))
-		printf("Error: unable to get cpu properties\n");
-
-	printf("\nDevice info\n");
-	printf(" cpu: %dMHz\n", bootinfo.cpu.clock_frequency/1000000);
+	printf("\nSystem info\n");
 	printf(" memory: %dM\n", bootinfo.memmap.total>>20);
 
@@ -97,5 +91,10 @@
 	printf("done.\n");
 
+	printf("\nChecking for secondary processors...");
+	if (!ofw_cpu())
+		printf("Error: unable to get cpu properties\n");
+	printf("done.\n");
+
 	printf("\nBooting the kernel...\n");
-	jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, &bootinfo, sizeof(bootinfo));
+	jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, 1, &bootinfo, sizeof(bootinfo));
 }
Index: boot/arch/sparc64/loader/main.h
===================================================================
--- boot/arch/sparc64/loader/main.h	(revision 5d684e4c0dde4f587dd5aca281c366f71f72853b)
+++ boot/arch/sparc64/loader/main.h	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
@@ -35,4 +35,6 @@
 #include <types.h>
 
+#define KERNEL_VIRTUAL_ADDRESS 0x400000
+
 #define TASKMAP_MAX_RECORDS 32
 
@@ -48,11 +50,6 @@
 
 typedef struct {
-	uint32_t clock_frequency;
-} cpu_t;
-
-typedef struct {
 	taskmap_t taskmap;
 	memmap_t memmap;
-	cpu_t cpu;
 	ballocs_t ballocs;
 	ofw_tree_node_t *ofw_root;
Index: boot/arch/sparc64/loader/ofwarch.c
===================================================================
--- boot/arch/sparc64/loader/ofwarch.c	(revision 5d684e4c0dde4f587dd5aca281c366f71f72853b)
+++ boot/arch/sparc64/loader/ofwarch.c	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
@@ -54,5 +54,10 @@
 }
 
-int ofw_cpu(cpu_t *cpu)
+
+#define ASI_UPA_CONFIG		0x4a
+#define UPA_CONFIG_MID_SHIFT 	17
+#define UPA_CONFIG_MID_MASK	0x1f
+
+int ofw_cpu(void)
 {
 	char type_name[BUF_SIZE];
@@ -62,21 +67,31 @@
 	if (node == 0 || node == -1) {
 		printf("Could not find any child nodes of the root node.\n");
-		return;
+		return 0;
 	}
+	
+	uint64_t current_mid;
+	
+	__asm__ volatile ("ldxa [%1] %2, %0\n" : "=r" (current_mid) : "r" (0), "i" (ASI_UPA_CONFIG));
+	current_mid >>= UPA_CONFIG_MID_SHIFT;
+	current_mid &= UPA_CONFIG_MID_MASK;
 	
 	for (; node != 0 && node != -1; node = ofw_get_peer_node(node)) {
 		if (ofw_get_property(node, "device_type", type_name, sizeof(type_name)) > 0) {
 			if (strcmp(type_name, "cpu") == 0) {
-				uint32_t mhz;
+				uint32_t mid;
 				
-				if (ofw_get_property(node, "clock-frequency", &mhz, sizeof(mhz)) <= 0)
+				if (ofw_get_property(node, "upa-portid", &mid, sizeof(mid)) <= 0)
 					continue;
 					
-				cpu->clock_frequency = mhz;
-				return 1;
+				if (current_mid != mid) {
+					/*
+					 * Start secondary processor.
+					 */
+					(void) ofw_call("SUNW,start-cpu", 3, 1, NULL, node, KERNEL_VIRTUAL_ADDRESS, 0);
+				}
 			}
 		}
-	};
+	}
 
-	return 0;
+	return 1;
 }
Index: boot/arch/sparc64/loader/ofwarch.h
===================================================================
--- boot/arch/sparc64/loader/ofwarch.h	(revision 5d684e4c0dde4f587dd5aca281c366f71f72853b)
+++ boot/arch/sparc64/loader/ofwarch.h	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
@@ -35,7 +35,5 @@
 #define OFW_SIZE_CELLS		2
 
-extern int bpp2align[];
-
-extern int ofw_cpu(cpu_t *cpu);
+extern int ofw_cpu(void);
 
 #endif
Index: boot/genarch/ofw.c
===================================================================
--- boot/genarch/ofw.c	(revision 5d684e4c0dde4f587dd5aca281c366f71f72853b)
+++ boot/genarch/ofw.c	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
@@ -84,5 +84,5 @@
  * @return Return value returned by the client interface.
  */
-static unsigned long ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets, ...)
+unsigned long ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets, ...)
 {
 	va_list list;
Index: boot/genarch/ofw.h
===================================================================
--- boot/genarch/ofw.h	(revision 5d684e4c0dde4f587dd5aca281c366f71f72853b)
+++ boot/genarch/ofw.h	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
@@ -91,5 +91,4 @@
 extern uintptr_t ofw_cif;
 
-
 extern phandle ofw_chosen;
 extern ihandle ofw_stdout;
@@ -114,4 +113,5 @@
 
 extern int ofw(ofw_args_t *arg);
+extern unsigned long ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets, ...);
 extern unsigned int ofw_get_address_cells(const phandle device);
 extern unsigned int ofw_get_size_cells(const phandle device);
