Index: boot/arch/ppc64/Makefile.inc
===================================================================
--- boot/arch/ppc64/Makefile.inc	(revision 23d9938f39720e050fe9811643a6134c2aeb44fd)
+++ boot/arch/ppc64/Makefile.inc	(revision 965dc18d04fb8a15431d34485959f4aa8e6ec4b5)
@@ -27,4 +27,6 @@
 #
 
+DEFS += -DOPEN_BOOT
+
 build: $(BASE)/image.boot
 
@@ -36,5 +38,5 @@
 
 arch/$(ARCH)/loader/image.boot:
-	make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
+	make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) "DEFS=$(DEFS)"
 
 clean: generic_clean
Index: boot/arch/sparc64/Makefile.inc
===================================================================
--- boot/arch/sparc64/Makefile.inc	(revision 23d9938f39720e050fe9811643a6134c2aeb44fd)
+++ boot/arch/sparc64/Makefile.inc	(revision 965dc18d04fb8a15431d34485959f4aa8e6ec4b5)
@@ -29,4 +29,12 @@
 TMP = distroot
 
+ifeq ($(CONFIG_AOUT_ISOFS_B),n)
+	SILO_PACKAGE=silo.patched.tar.gz
+endif
+
+ifeq ($(CONFIG_AOUT_ISOFS_B),y)
+	SILO_PACKAGE=silo.tar.gz
+endif
+
 build: $(BASE)/image.iso
 
@@ -40,5 +48,5 @@
 	mkdir -p $(TMP)/boot
 	mkdir -p $(TMP)/HelenOS
-	cat arch/$(ARCH)/silo/silo.tar.gz | (cd $(TMP)/boot; tar xvfz -)
+	cat arch/$(ARCH)/silo/$(SILO_PACKAGE) | (cd $(TMP)/boot; tar xvfz -)
 	cp arch/$(ARCH)/silo/README arch/$(ARCH)/silo/COPYING $(TMP)/boot
 	cat arch/$(ARCH)/silo/silo.conf | $(SILO_CONF_FILTER) >$(TMP)/boot/silo.conf
Index: boot/arch/sparc64/loader/asm.S
===================================================================
--- boot/arch/sparc64/loader/asm.S	(revision 23d9938f39720e050fe9811643a6134c2aeb44fd)
+++ boot/arch/sparc64/loader/asm.S	(revision 965dc18d04fb8a15431d34485959f4aa8e6ec4b5)
@@ -106,7 +106,26 @@
 	 * 2. Invalidate I-cache.
 	 * 3. Flush instruction pipeline.
-	 */ 
-	call	icache_flush
-	membar	#StoreStore
+	 */
+
+	/*
+	 * US3 processors have a write-invalidate cache, so explicitly
+	 * invalidating it is not required. Whether to invalidate I-cache
+	 * or not is decided according to the value of the global
+	 * "subarchitecture" variable (set in the bootstrap).
+	 */
+	set subarchitecture, %g2
+	ldub [%g2], %g2
+	cmp %g2, 3
+	be 1f
+	nop
+0:
+	call icache_flush
+	nop
+1:
+	membar #StoreStore
+	
+	/*
+	 * Flush the instruction pipeline.
+	 */
 	flush	%i7
 
@@ -135,5 +154,4 @@
 	! SF Erratum #51
 	nop
-
 .global ofw
 ofw:
Index: boot/arch/sparc64/loader/main.c
===================================================================
--- boot/arch/sparc64/loader/main.c	(revision 23d9938f39720e050fe9811643a6134c2aeb44fd)
+++ boot/arch/sparc64/loader/main.c	(revision 965dc18d04fb8a15431d34485959f4aa8e6ec4b5)
@@ -40,4 +40,5 @@
 
 bootinfo_t bootinfo;
+
 component_t components[COMPONENTS];
 
@@ -55,4 +56,13 @@
 	char *timestamp = "";
 #endif
+
+/** UltraSPARC subarchitecture - 1 for US, 3 for US3 */
+uint8_t subarchitecture;
+
+/**
+ * mask of the MID field inside the ICBUS_CONFIG register shifted by
+ * MID_SHIFT bits to the right
+ */
+uint16_t mid_mask;
 
 /** Print version information. */
@@ -64,4 +74,37 @@
 }
 
+/* the lowest ID (read from the VER register) of some US3 CPU model */
+#define FIRST_US3_CPU 	0x14
+
+/* the greatest ID (read from the VER register) of some US3 CPU model */
+#define LAST_US3_CPU 	0x19
+
+/* UltraSPARC IIIi processor implementation code */
+#define US_IIIi_CODE	0x15
+
+/**
+ * Sets the global variables "subarchitecture" and "mid_mask" to
+ * correct values.
+ */
+static void detect_subarchitecture(void)
+{
+	uint64_t v;
+	asm volatile ("rdpr %%ver, %0\n" : "=r" (v));
+	
+	v = (v << 16) >> 48;
+	if ((v >= FIRST_US3_CPU) && (v <= LAST_US3_CPU)) {
+		subarchitecture = SUBARCH_US3;
+		if (v == US_IIIi_CODE)
+			mid_mask = (1 << 5) - 1;
+		else
+			mid_mask = (1 << 10) - 1;
+	} else if (v < FIRST_US3_CPU) {
+		subarchitecture = SUBARCH_US;
+		mid_mask = (1 << 5) - 1;
+	} else {
+		printf("\nThis CPU is not supported by HelenOS.");
+	}
+}
+
 void bootstrap(void)
 {
@@ -73,4 +116,5 @@
 	version_print();
 	
+	detect_subarchitecture();
 	init_components(components);
 
@@ -84,5 +128,5 @@
 		halt();
 	}
-	
+
 	if (bootinfo.memmap.total == 0) {
 		printf("Error: no memory detected, halting.\n");
Index: boot/arch/sparc64/loader/main.h
===================================================================
--- boot/arch/sparc64/loader/main.h	(revision 23d9938f39720e050fe9811643a6134c2aeb44fd)
+++ boot/arch/sparc64/loader/main.h	(revision 965dc18d04fb8a15431d34485959f4aa8e6ec4b5)
@@ -42,4 +42,7 @@
 #define AP_PROCESSOR	0
 
+#define SUBARCH_US	1
+#define SUBARCH_US3	3
+
 typedef struct {
 	void *addr;
Index: boot/arch/sparc64/loader/ofwarch.c
===================================================================
--- boot/arch/sparc64/loader/ofwarch.c	(revision 23d9938f39720e050fe9811643a6134c2aeb44fd)
+++ boot/arch/sparc64/loader/ofwarch.c	(revision 965dc18d04fb8a15431d34485959f4aa8e6ec4b5)
@@ -41,4 +41,8 @@
 #include "asm.h"
 
+/* these tho variables will be set by the detect_subarchitecture function */
+extern uint8_t subarchitecture;
+extern uint16_t mid_mask;
+
 void write(const char *str, const int len)
 {
@@ -57,34 +61,38 @@
 }
 
-int ofw_cpu(void)
+/**
+ * Starts all CPUs represented by following siblings of the given node,
+ * except for the current CPU.
+ *
+ * @param child		The first child of the OFW tree node whose children
+ * 			represent CPUs to be woken up.
+ * @param current_mid	MID of the current CPU, the current CPU will
+ *			(of course) not be woken up.
+ * @return		Number of CPUs which have the same parent node as
+ * 			"child".
+ */
+static int wake_cpus_in_node(phandle child, uint64_t current_mid)
 {
+	int cpus;
 	char type_name[BUF_SIZE];
-
-	phandle node;
-	node = ofw_get_child_node(ofw_root);
-	if (node == 0 || node == -1) {
-		printf("Could not find any child nodes of the root node.\n");
-		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;
-
-	int cpus;
-	
-	for (cpus = 0; node != 0 && node != -1; node = ofw_get_peer_node(node),
-	    cpus++) {
-		if (ofw_get_property(node, "device_type", type_name,
+	for (cpus = 0; child != 0 && child != -1;
+	    child = ofw_get_peer_node(child), cpus++) {
+		if (ofw_get_property(child, "device_type", type_name,
 		    sizeof(type_name)) > 0) {
 			if (strcmp(type_name, "cpu") == 0) {
 				uint32_t mid;
 				
-				if (ofw_get_property(node, "upa-portid", &mid,
-				    sizeof(mid)) <= 0)
+				/*
+				 * "upa-portid" for US, "portid" for US-III,
+				 * "cpuid" for US-IV
+				 */
+				if (ofw_get_property(
+				    child, "upa-portid",
+				    &mid, sizeof(mid)) <= 0
+				    && ofw_get_property(child, "portid",
+				    &mid, sizeof(mid)) <= 0
+				    && ofw_get_property(child, "cpuid",
+				    &mid, sizeof(mid)) <= 0)
 					continue;
 					
@@ -94,5 +102,5 @@
 					 */
 					(void) ofw_call("SUNW,start-cpu", 3, 1,
-					    NULL, node, KERNEL_VIRTUAL_ADDRESS,
+					    NULL, child, KERNEL_VIRTUAL_ADDRESS,
 					    bootinfo.physmem_start |
 					    AP_PROCESSOR);
@@ -105,10 +113,57 @@
 }
 
+/**
+ * Finds out the current CPU's MID and wakes up all AP processors.
+ */
+int ofw_cpu(void)
+{
+	int cpus;
+	phandle node;
+	phandle subnode;
+	phandle cpus_parent;
+	phandle cmp;
+	char name[BUF_SIZE];
+
+	/* get the current CPU MID */
+	uint64_t current_mid;
+	
+	asm volatile ("ldxa [%1] %2, %0\n"
+	    : "=r" (current_mid)
+	    : "r" (0), "i" (ASI_ICBUS_CONFIG));
+	current_mid >>= ICBUS_CONFIG_MID_SHIFT;
+
+	current_mid &= mid_mask;
+
+	/* wake up CPUs */
+	
+	cpus_parent = ofw_find_device("/ssm@0,0");
+	if (cpus_parent == 0 || cpus_parent == -1) {
+		cpus_parent = ofw_find_device("/");
+	}
+
+	node = ofw_get_child_node(cpus_parent);
+	cpus = wake_cpus_in_node(node, current_mid);
+	while (node != 0 && node != -1) {
+		if (ofw_get_property(node, "name", name,
+			sizeof(name)) > 0) {
+			if (strcmp(name, "cmp") == 0) {
+				subnode = ofw_get_child_node(node);
+				cpus += wake_cpus_in_node(subnode,
+					current_mid);
+			}
+		}
+		node = ofw_get_peer_node(node);
+	}
+	
+	return cpus;
+	
+}
+
 /** Get physical memory starting address.
  *
- * @param start Pointer to variable where the physical memory starting
- * 		address will be stored.
+ * @param start		Pointer to variable where the physical memory starting
+ *			address will be stored.
  *
- * @return Non-zero on succes, zero on failure.
+ * @return		Non-zero on succes, zero on failure.
  */
 int ofw_get_physmem_start(uintptr_t *start)
Index: boot/arch/sparc64/loader/register.h
===================================================================
--- boot/arch/sparc64/loader/register.h	(revision 23d9938f39720e050fe9811643a6134c2aeb44fd)
+++ boot/arch/sparc64/loader/register.h	(revision 965dc18d04fb8a15431d34485959f4aa8e6ec4b5)
@@ -34,7 +34,6 @@
 #define PSTATE_AM_BIT   8
 
-#define ASI_UPA_CONFIG          0x4a
-#define UPA_CONFIG_MID_SHIFT    17
-#define UPA_CONFIG_MID_MASK     0x1f
+#define ASI_ICBUS_CONFIG		0x4a
+#define ICBUS_CONFIG_MID_SHIFT		17
 
 #endif
Index: boot/boot.config
===================================================================
--- boot/boot.config	(revision 23d9938f39720e050fe9811643a6134c2aeb44fd)
+++ boot/boot.config	(revision 965dc18d04fb8a15431d34485959f4aa8e6ec4b5)
@@ -84,4 +84,7 @@
 ! RDFMT (choice)
 
+# Preserve A.OUT header in isofs.b
+! [ARCH=sparc64] CONFIG_AOUT_ISOFS_B (y/n)
+
 # External ramdisk 
 ! [ARCH=sparc64] CONFIG_RD_EXTERNAL (y/n)
Index: boot/genarch/balloc.h
===================================================================
--- boot/genarch/balloc.h	(revision 23d9938f39720e050fe9811643a6134c2aeb44fd)
+++ boot/genarch/balloc.h	(revision 965dc18d04fb8a15431d34485959f4aa8e6ec4b5)
@@ -32,5 +32,5 @@
 #include <types.h>
 
-#define BALLOC_MAX_SIZE		(1024 * 1024)
+#define BALLOC_MAX_SIZE		(128 * 1024)
 
 typedef struct {
Index: boot/genarch/ofw.c
===================================================================
--- boot/genarch/ofw.c	(revision 23d9938f39720e050fe9811643a6134c2aeb44fd)
+++ boot/genarch/ofw.c	(revision 965dc18d04fb8a15431d34485959f4aa8e6ec4b5)
@@ -49,5 +49,6 @@
 		halt();
 	
-	if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout, sizeof(ofw_stdout)) <= 0)
+	if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout,
+	    sizeof(ofw_stdout)) <= 0)
 		ofw_stdout = 0;
 	
@@ -58,9 +59,11 @@
 	}
 	
-	if (ofw_get_property(ofw_chosen, "mmu", &ofw_mmu, sizeof(ofw_mmu)) <= 0) {
+	if (ofw_get_property(ofw_chosen, "mmu", &ofw_mmu,
+	    sizeof(ofw_mmu)) <= 0) {
 		puts("\r\nError: Unable to get mmu property, halted.\r\n");
 		halt();
 	}
-	if (ofw_get_property(ofw_chosen, "memory", &ofw_memory_prop, sizeof(ofw_memory_prop)) <= 0) {
+	if (ofw_get_property(ofw_chosen, "memory", &ofw_memory_prop,
+	    sizeof(ofw_memory_prop)) <= 0) {
 		puts("\r\nError: Unable to get memory property, halted.\r\n");
 		halt();
@@ -82,12 +85,16 @@
 /** Perform a call to OpenFirmware client interface.
  *
- * @param service String identifying the service requested.
- * @param nargs Number of input arguments.
- * @param nret Number of output arguments. This includes the return value.
- * @param rets Buffer for output arguments or NULL. The buffer must accommodate nret - 1 items.
- *
- * @return Return value returned by the client interface.
+ * @param service	String identifying the service requested.
+ * @param nargs		Number of input arguments.
+ * @param nret		Number of output arguments. This includes the return
+ * 			value.
+ * @param rets		Buffer for output arguments or NULL. The buffer must
+ * 			accommodate nret - 1 items.
+ *
+ * @return		Return value returned by the client interface.
  */
-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;
@@ -120,5 +127,7 @@
 }
 
-int ofw_get_property(const phandle device, const char *name, void *buf, const int buflen)
+int
+ofw_get_property(const phandle device, const char *name, void *buf,
+    const int buflen)
 {
 	return ofw_call("getprop", 4, 1, NULL, device, name, buf, buflen);
@@ -145,5 +154,6 @@
 	
 	if (ofw_get_property(device, "#address-cells", &ret, sizeof(ret)) <= 0)
-		if (ofw_get_property(ofw_root, "#address-cells", &ret, sizeof(ret)) <= 0)
+		if (ofw_get_property(ofw_root, "#address-cells", &ret,
+		    sizeof(ret)) <= 0)
 			ret = OFW_ADDRESS_CELLS;
 	
@@ -157,5 +167,6 @@
 	
 	if (ofw_get_property(device, "#size-cells", &ret, sizeof(ret)) <= 0)
-		if (ofw_get_property(ofw_root, "#size-cells", &ret, sizeof(ret)) <= 0)
+		if (ofw_get_property(ofw_root, "#size-cells", &ret,
+		    sizeof(ret)) <= 0)
 			ret = OFW_SIZE_CELLS;
 	
@@ -193,5 +204,6 @@
 	int shift;
 
-	if (ofw_call("call-method", 3, 5, result, "translate", ofw_mmu, virt) != 0) {
+	if (ofw_call("call-method", 3, 5, result, "translate", ofw_mmu,
+	    virt) != 0) {
 		puts("Error: MMU method translate() failed, halting.\n");
 		halt();
@@ -213,5 +225,6 @@
 	ofw_arg_t retaddr;
 
-	if (ofw_call("call-method", 5, 2, &retaddr, "claim", ofw_mmu, 0, len, virt) != 0) {
+	if (ofw_call("call-method", 5, 2, &retaddr, "claim", ofw_mmu, 0, len,
+	    virt) != 0) {
 		puts("Error: MMU method claim() failed, halting.\n");
 		halt();
@@ -270,6 +283,6 @@
 	}
 
-	return ofw_call("call-method", 7, 1, NULL, "map", ofw_mmu, mode, size, virt,
-	    phys_hi, phys_lo);
+	return ofw_call("call-method", 7, 1, NULL, "map", ofw_mmu, mode, size,
+	    virt, phys_hi, phys_lo);
 }
 
@@ -282,8 +295,11 @@
 int ofw_memmap(memmap_t *map)
 {
-	unsigned int ac = ofw_get_address_cells(ofw_memory);
-	unsigned int sc = ofw_get_size_cells(ofw_memory);
-
-	uint32_t buf[((ac + sc) * MEMMAP_MAX_RECORDS)];
+	unsigned int ac = ofw_get_address_cells(ofw_memory) /
+	    (sizeof(uintptr_t) / sizeof(uint32_t));
+	unsigned int sc = ofw_get_size_cells(ofw_memory) /
+	    (sizeof(uintptr_t) / sizeof(uint32_t));
+	printf("address cells: %d, size cells: %d. ", ac, sc);
+
+	uintptr_t buf[((ac + sc) * MEMMAP_MAX_RECORDS)];
 	int ret = ofw_get_property(ofw_memory, "reg", buf, sizeof(buf));
 	if (ret <= 0)		/* ret is the number of written bytes */
@@ -293,9 +309,20 @@
 	map->total = 0;
 	map->count = 0;
-	for (pos = 0; (pos < ret / sizeof(uint32_t)) &&
+	for (pos = 0; (pos < ret / sizeof(uintptr_t)) &&
 	    (map->count < MEMMAP_MAX_RECORDS); pos += ac + sc) {
-		void * start = (void *) ((uintptr_t) buf[pos + ac - 1]);
+		void *start = (void *) (buf[pos + ac - 1]);
 		unsigned int size = buf[pos + ac + sc - 1];
-		
+
+		/*
+ 		 * This is a hot fix of the issue which occurs on machines
+ 		 * where there are holes in the physical memory (such as
+ 		 * SunBlade 1500). Should we detect a hole in the physical
+ 		 * memory, we will ignore any memory detected behind
+ 		 * the hole and pretend the hole does not exist.
+		 */
+		if ((map->count > 0) && (map->zones[map->count - 1].start +
+		    map->zones[map->count - 1].size < start))
+			break;
+
 		if (size > 0) {
 			map->zones[map->count].start = start;
@@ -309,5 +336,4 @@
 }
 
-
 int ofw_screen(screen_t *screen)
 {
@@ -315,5 +341,6 @@
 	uint32_t virtaddr;
 	
-	if (ofw_get_property(ofw_aliases, "screen", device_name, sizeof(device_name)) <= 0)
+	if (ofw_get_property(ofw_aliases, "screen", device_name,
+	    sizeof(device_name)) <= 0)
 		return false;
 	
@@ -322,19 +349,24 @@
 		return false;
 	
-	if (ofw_get_property(device, "address", &virtaddr, sizeof(virtaddr)) <= 0)
+	if (ofw_get_property(device, "address", &virtaddr,
+	    sizeof(virtaddr)) <= 0)
 		return false;
 
 	screen->addr = (void *) ((uintptr_t) virtaddr);
 
-	if (ofw_get_property(device, "width", &screen->width, sizeof(screen->width)) <= 0)
-		return false;
-	
-	if (ofw_get_property(device, "height", &screen->height, sizeof(screen->height)) <= 0)
-		return false;
-	
-	if (ofw_get_property(device, "depth", &screen->bpp, sizeof(screen->bpp)) <= 0)
-		return false;
-	
-	if (ofw_get_property(device, "linebytes", &screen->scanline, sizeof(screen->scanline)) <= 0)
+	if (ofw_get_property(device, "width", &screen->width,
+	    sizeof(screen->width)) <= 0)
+		return false;
+	
+	if (ofw_get_property(device, "height", &screen->height,
+	    sizeof(screen->height)) <= 0)
+		return false;
+	
+	if (ofw_get_property(device, "depth", &screen->bpp,
+	    sizeof(screen->bpp)) <= 0)
+		return false;
+	
+	if (ofw_get_property(device, "linebytes", &screen->scanline,
+	    sizeof(screen->scanline)) <= 0)
 		return false;
 	
Index: boot/genarch/ofw_tree.c
===================================================================
--- boot/genarch/ofw_tree.c	(revision 23d9938f39720e050fe9811643a6134c2aeb44fd)
+++ boot/genarch/ofw_tree.c	(revision 965dc18d04fb8a15431d34485959f4aa8e6ec4b5)
@@ -121,5 +121,4 @@
 		memcpy(current_node->da_name, &path[i], len);
 		current_node->da_name[len] = '\0';
-	
 	
 		/*
@@ -220,8 +219,26 @@
 {
 	ofw_tree_node_t *root;
+	phandle ssm_node;
+	ofw_tree_node_t *ssm;
 	
 	root = ofw_tree_node_alloc();
 	if (root)
 		ofw_tree_node_process(root, NULL, ofw_root);
+
+	/*
+	 * The firmware client interface does not automatically include the
+	 * "ssm" node in the list of children of "/". A nasty yet working
+	 * solution is to explicitly stick "ssm" to the OFW tree.
+	 */
+	ssm_node = ofw_find_device("/ssm@0,0");
+	if (ssm_node != -1) {
+		ssm = ofw_tree_node_alloc();
+		if (ssm) {
+			ofw_tree_node_process(
+				ssm, root, ofw_find_device("/ssm@0,0"));
+			ssm->peer = root->child;
+			root->child = ssm;
+		}
+	}
 	
 	return root;
