Index: kernel/arch/sparc64/src/mm/sun4u/frame.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4u/frame.c	(revision 25c51c8e602b7f708bb84edbdd36fb2d38224ec8)
+++ kernel/arch/sparc64/src/mm/sun4u/frame.c	(revision 50177dcd51d58a030da7707ce62ab9fad45123a6)
@@ -41,4 +41,5 @@
 #include <macros.h>
 
+// TODO: remove me
 uintptr_t last_frame = (uintptr_t) NULL;
 
@@ -47,40 +48,62 @@
  * Walk the memory map and create frame zones according to it.
  */
-void frame_low_arch_init(void)
+static void frame_common_arch_init(bool low)
 {
-	if (config.cpu_active == 1) {
-		unsigned int i;
+	unsigned int i;
+	
+	for (i = 0; i < memmap.cnt; i++) {
+		uintptr_t base;
+		size_t size;
+
+		/*
+		 * The memmap is created by HelenOS boot loader.
+		 * It already contains no holes.
+		 */
+
+		/* To be safe, make the available zone possibly smaller */
+		base = ALIGN_UP((uintptr_t) memmap.zones[i].start, FRAME_SIZE);
+		size = ALIGN_DOWN(memmap.zones[i].size -
+		    (base - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE);
 		
-		for (i = 0; i < memmap.cnt; i++) {
-			/* To be safe, make the available zone possibly smaller */
-			uintptr_t new_start = ALIGN_UP((uintptr_t) memmap.zones[i].start,
-			    FRAME_SIZE);
-			size_t new_size = ALIGN_DOWN(memmap.zones[i].size -
-			    (new_start - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE);
-			
-			/*
-			 * The memmap is created by HelenOS boot loader.
-			 * It already contains no holes.
-			 */
-			
-			pfn_t confdata = ADDR2PFN(new_start);
-			
+		// TODO: remove me
+		last_frame = max(last_frame, base + size);
+
+		if (!frame_adjust_zone_bounds(low, &base, &size))
+			continue;
+ 
+		pfn_t confdata;
+		pfn_t pfn = ADDR2PFN(base);
+		size_t count = SIZE2FRAMES(size);
+
+		if (low) {
+			confdata = pfn;
 			if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0))))
 				confdata = ADDR2PFN(KA2PA(PFN2ADDR(2)));
 			
-			zone_create(ADDR2PFN(new_start), SIZE2FRAMES(new_size),
-			    confdata, 0);
-			
-			last_frame = max(last_frame, new_start + new_size);
+			zone_create(pfn, count, confdata,
+			    ZONE_AVAILABLE | ZONE_LOWMEM);
+		} else {
+			confdata = zone_external_conf_alloc(count);
+			zone_create(pfn, count, confdata,
+			    ZONE_AVAILABLE | ZONE_HIGHMEM);
 		}
+	}
 		
-		/*
-		 * On sparc64, physical memory can start on a non-zero address.
-		 * The generic frame_init() only marks PFN 0 as not free, so we
-		 * must mark the physically first frame not free explicitly
-		 * here, no matter what is its address.
-		 */
-		frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1);
-	}
+}
+
+void frame_low_arch_init(void)
+{
+	if (config.cpu_active > 1)
+		return;
+	
+	frame_common_arch_init(true);
+	
+	/*
+	 * On sparc64, physical memory can start on a non-zero address.
+	 * The generic frame_init() only marks PFN 0 as not free, so we
+	 * must mark the physically first frame not free explicitly
+	 * here, no matter what is its address.
+	 */
+	frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1);
 	
 	end_of_identity = PA2KA(last_frame);
@@ -89,4 +112,8 @@
 void frame_high_arch_init(void)
 {
+	if (config.cpu_active > 1)
+		return;
+
+	frame_common_arch_init(false);
 }
 
Index: kernel/arch/sparc64/src/mm/sun4v/frame.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4v/frame.c	(revision 25c51c8e602b7f708bb84edbdd36fb2d38224ec8)
+++ kernel/arch/sparc64/src/mm/sun4v/frame.c	(revision 50177dcd51d58a030da7707ce62ab9fad45123a6)
@@ -45,42 +45,68 @@
  * Walk the memory map and create frame zones according to it.
  */
-void frame_low_arch_init(void)
+static void frame_common_arch_init(bool low)
 {
-	if (config.cpu_active == 1) {
-		unsigned int i;
+	unsigned int i;
 		
-		for (i = 0; i < memmap.cnt; i++) {
-			/* To be safe, make the available zone possibly smaller */
-			uintptr_t new_start = ALIGN_UP((uintptr_t) memmap.zones[i].start,
-			    FRAME_SIZE);
-			size_t new_size = ALIGN_DOWN(memmap.zones[i].size -
-			    (new_start - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE);
-			
-			/*
-			 * The memmap is created by HelenOS boot loader.
-			 * It already contains no holes.
-			 */
-			
-			pfn_t confdata = ADDR2PFN(new_start);
-			
+	for (i = 0; i < memmap.cnt; i++) {
+		uintptr_t base;
+		size_t size;
+
+		/*
+		 * The memmap is created by HelenOS boot loader.
+		 * It already contains no holes.
+		 */
+
+		/* To be safe, make the available zone possibly smaller */
+		base = ALIGN_UP((uintptr_t) memmap.zones[i].start, FRAME_SIZE);
+		size = ALIGN_DOWN(memmap.zones[i].size -
+		    (base - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE);
+		
+		if (!frame_adjust_zone_bounds(low, &base, &size))
+			continue;
+
+		pfn_t confdata;
+		pfn_t pfn = ADDR2PFN(base);
+		size_t count = SIZE2FRAMES(size);
+
+		if (low) {
+			confdata = pfn;
 			if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0))))
 				confdata = ADDR2PFN(KA2PA(PFN2ADDR(2)));
 			
-			zone_create(ADDR2PFN(new_start), SIZE2FRAMES(new_size),
-			    confdata, 0);
+			zone_create(pfn, count, confdata,
+			    ZONE_AVAILABLE | ZONE_LOWMEM);
+		} else {
+			confdata = zone_external_conf_alloc(count);
+			zone_create(pfn, count, confdata,
+			    ZONE_AVAILABLE | ZONE_HIGHMEM);
 		}
+	}
 		
-		/*
-		 * On sparc64, physical memory can start on a non-zero address.
-		 * The generic frame_init() only marks PFN 0 as not free, so we
-		 * must mark the physically first frame not free explicitly
-		 * here, no matter what is its address.
-		 */
-		frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1);
-	}
+}
+
+
+void frame_low_arch_init(void)
+{
+	if (config.cpu_active > 1)
+		return;
+
+	frame_common_arch_init(true);
+
+	/*
+	 * On sparc64, physical memory can start on a non-zero address.
+	 * The generic frame_init() only marks PFN 0 as not free, so we
+	 * must mark the physically first frame not free explicitly
+	 * here, no matter what is its address.
+	 */
+	frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1);
 }
 
 void frame_high_arch_init(void)
 {
+	if (config.cpu_active > 1)
+		return;
+
+	frame_common_arch_init(false);
 }
 
