Index: boot/arch/sparc64/loader/asm.S
===================================================================
--- boot/arch/sparc64/loader/asm.S	(revision 282f2c9ca4f0625d5823e8a836d38f8d4f100b43)
+++ boot/arch/sparc64/loader/asm.S	(revision f2ea5d898375b36e38b163ea62225ee6766b18b9)
@@ -1,4 +1,5 @@
 #
 # Copyright (C) 2006 Martin Decky
+# Copyright (C) 2006 Jakub Jermar 
 # All rights reserved.
 #
Index: boot/arch/sparc64/loader/asm.h
===================================================================
--- boot/arch/sparc64/loader/asm.h	(revision 282f2c9ca4f0625d5823e8a836d38f8d4f100b43)
+++ boot/arch/sparc64/loader/asm.h	(revision f2ea5d898375b36e38b163ea62225ee6766b18b9)
@@ -1,4 +1,5 @@
 /*
  * Copyright (C) 2006 Martin Decky
+ * Copyright (C) 2006 Jakub Jermar 
  * All rights reserved.
  *
@@ -30,11 +31,15 @@
 #define BOOT_sparc64_ASM_H_
 
-#define PAGE_SIZE 8192
-#define PAGE_WIDTH 13
+#include "types.h"
+#include "main.h"
+
+#define PAGE_SIZE	8192
+#define PAGE_WIDTH	13
 
 #define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
 
 extern void halt(void);
-extern void jump_to_kernel(void *entry, int bsp, void *bootinfo, unsigned int bootinfo_size) __attribute__((noreturn));
+extern void jump_to_kernel(void *entry, uint64_t cfg, bootinfo_t *bootinfo,
+	unsigned int bootinfo_size) __attribute__((noreturn));
 
 #endif
Index: boot/arch/sparc64/loader/main.c
===================================================================
--- boot/arch/sparc64/loader/main.c	(revision 282f2c9ca4f0625d5823e8a836d38f8d4f100b43)
+++ boot/arch/sparc64/loader/main.c	(revision f2ea5d898375b36e38b163ea62225ee6766b18b9)
@@ -47,4 +47,9 @@
 	init_components(components);
 
+	if (!ofw_get_physmem_start(&bootinfo.physmem_start)) {
+		printf("Error: unable to get start of physical memory.\n");
+		halt();
+	}
+
 	if (!ofw_memmap(&bootinfo.memmap)) {
 		printf("Error: unable to get memory map, halting.\n");
@@ -58,5 +63,6 @@
 	
 	printf("\nSystem info\n");
-	printf(" memory: %dM\n", bootinfo.memmap.total>>20);
+	printf(" memory: %dM starting at %P\n",
+		bootinfo.memmap.total >> 20, bootinfo.physmem_start);
 
 	printf("\nMemory statistics\n");
@@ -66,5 +72,6 @@
 	unsigned int i;
 	for (i = 0; i < COMPONENTS; i++)
-		printf(" %P: %s image (size %d bytes)\n", components[i].start, components[i].name, components[i].size);
+		printf(" %P: %s image (size %d bytes)\n", components[i].start,
+			components[i].name, components[i].size);
 
 	void * base = (void *) KERNEL_VIRTUAL_ADDRESS;
@@ -94,8 +101,9 @@
 	printf("\nChecking for secondary processors...");
 	if (!ofw_cpu())
-		printf("Error: unable to get cpu properties\n");
+		printf("Error: unable to get CPU properties\n");
 	printf("done.\n");
 
 	printf("\nBooting the kernel...\n");
-	jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, 1, &bootinfo, sizeof(bootinfo));
+	jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS,
+		bootinfo.physmem_start | BSP_PROCESSOR,	&bootinfo, sizeof(bootinfo));
 }
Index: boot/arch/sparc64/loader/main.h
===================================================================
--- boot/arch/sparc64/loader/main.h	(revision 282f2c9ca4f0625d5823e8a836d38f8d4f100b43)
+++ boot/arch/sparc64/loader/main.h	(revision f2ea5d898375b36e38b163ea62225ee6766b18b9)
@@ -39,4 +39,7 @@
 #define TASKMAP_MAX_RECORDS 32
 
+#define BSP_PROCESSOR	1
+#define AP_PROCESSOR	0
+
 typedef struct {
 	void *addr;
@@ -50,4 +53,5 @@
 
 typedef struct {
+	uintptr_t physmem_start;
 	taskmap_t taskmap;
 	memmap_t memmap;
@@ -56,4 +60,6 @@
 } bootinfo_t;
 
+extern bootinfo_t bootinfo;
+
 extern void start(void);
 extern void bootstrap(void);
Index: boot/arch/sparc64/loader/ofwarch.c
===================================================================
--- boot/arch/sparc64/loader/ofwarch.c	(revision 282f2c9ca4f0625d5823e8a836d38f8d4f100b43)
+++ boot/arch/sparc64/loader/ofwarch.c	(revision f2ea5d898375b36e38b163ea62225ee6766b18b9)
@@ -1,4 +1,5 @@
 /*
  * Copyright (C) 2005 Martin Decky
+ * Copyright (C) 2006 Jakub Jermar
  * All rights reserved.
  *
@@ -38,4 +39,5 @@
 #include <register.h>
 #include "main.h"
+#include "asm.h"
 
 void write(const char *str, const int len)
@@ -86,5 +88,7 @@
 					 * Start secondary processor.
 					 */
-					(void) ofw_call("SUNW,start-cpu", 3, 1, NULL, node, KERNEL_VIRTUAL_ADDRESS, 0);
+					(void) ofw_call("SUNW,start-cpu", 3, 1, NULL, node,
+						 KERNEL_VIRTUAL_ADDRESS,
+						 bootinfo.physmem_start | AP_PROCESSOR);
 				}
 			}
@@ -94,2 +98,21 @@
 	return cpus;
 }
+
+/** Get physical memory starting address.
+ *
+ * @param start Pointer to variable where the physical memory starting
+ * 		address will be stored.
+ *
+ * @return Non-zero on succes, zero on failure.
+ */
+int ofw_get_physmem_start(uintptr_t *start)
+{
+	uint32_t memreg[4];
+
+	if (ofw_get_property(ofw_memory, "reg", &memreg, sizeof(memreg)) <= 0)
+		return 0;
+
+	*start = (((uint64_t) memreg[0]) << 32) | memreg[1];
+	return 1;
+}
+
Index: boot/arch/sparc64/loader/ofwarch.h
===================================================================
--- boot/arch/sparc64/loader/ofwarch.h	(revision 282f2c9ca4f0625d5823e8a836d38f8d4f100b43)
+++ boot/arch/sparc64/loader/ofwarch.h	(revision f2ea5d898375b36e38b163ea62225ee6766b18b9)
@@ -31,4 +31,5 @@
 
 #include "main.h"
+#include "types.h"
 
 #define OFW_ADDRESS_CELLS	2
@@ -36,4 +37,5 @@
 
 extern int ofw_cpu(void);
+extern int ofw_get_physmem_start(uintptr_t *start); 
 
 #endif
Index: kernel/arch/sparc64/include/boot/boot.h
===================================================================
--- kernel/arch/sparc64/include/boot/boot.h	(revision 282f2c9ca4f0625d5823e8a836d38f8d4f100b43)
+++ kernel/arch/sparc64/include/boot/boot.h	(revision f2ea5d898375b36e38b163ea62225ee6766b18b9)
@@ -76,4 +76,5 @@
  */
 typedef struct {
+	uintptr_t physmem_start;
 	taskmap_t taskmap;
 	memmap_t memmap;
Index: kernel/arch/sparc64/include/mm/page.h
===================================================================
--- kernel/arch/sparc64/include/mm/page.h	(revision 282f2c9ca4f0625d5823e8a836d38f8d4f100b43)
+++ kernel/arch/sparc64/include/mm/page.h	(revision f2ea5d898375b36e38b163ea62225ee6766b18b9)
@@ -49,6 +49,8 @@
 #include <genarch/mm/page_ht.h>
 
-#define KA2PA(x)	((uintptr_t) (x))
-#define PA2KA(x)	((uintptr_t) (x))
+extern uintptr_t physmem_base;
+
+#define KA2PA(x)	(((uintptr_t) (x)) + physmem_base)
+#define PA2KA(x)	(((uintptr_t) (x)) - physmem_base)
 
 union page_address {
Index: kernel/arch/sparc64/include/trap/mmu.h
===================================================================
--- kernel/arch/sparc64/include/trap/mmu.h	(revision 282f2c9ca4f0625d5823e8a836d38f8d4f100b43)
+++ kernel/arch/sparc64/include/trap/mmu.h	(revision f2ea5d898375b36e38b163ea62225ee6766b18b9)
@@ -112,8 +112,7 @@
 	bz 0f						! page address is zero
 
-	or %g3, (TTE_CV|TTE_CP|TTE_P|TTE_W), %g2	! 8K pages are the default (encoded as 0)
-	mov 1, %g3
-	sllx %g3, TTE_V_SHIFT, %g3
-	or %g2, %g3, %g2
+	sethi %hi(kernel_8k_tlb_data_template), %g2
+	ldx [%g2 + %lo(kernel_8k_tlb_data_template)], %g2
+	or %g3, %g2, %g2
 	stxa %g2, [%g0] ASI_DTLB_DATA_IN_REG		! identity map the kernel page
 	retry
Index: kernel/arch/sparc64/src/start.S
===================================================================
--- kernel/arch/sparc64/src/start.S	(revision 282f2c9ca4f0625d5823e8a836d38f8d4f100b43)
+++ kernel/arch/sparc64/src/start.S	(revision f2ea5d898375b36e38b163ea62225ee6766b18b9)
@@ -45,15 +45,17 @@
 .section K_TEXT_START, "ax"
 
+#define BSP_FLAG	1
+
 /*
- * Here is where the kernel is passed control
- * from the boot loader.
+ * Here is where the kernel is passed control from the boot loader.
  * 
  * The registers are expected to be in this state:
- * - %o0 non-zero for the bootstrap processor, zero for application/secondary processors
- * - %o1 bootinfo structure address
- * - %o2 bootinfo structure size
+ * - %o0 starting address of physical memory + bootstrap processor flag
+ * 	bits 63...1:	physical memory starting address / 2
+ *	bit 0:		non-zero on BSP processor, zero on AP processors
+ * - %o1 bootinfo structure address (BSP only)
+ * - %o2 bootinfo structure size (BSP only)
  *
- * Moreover, we depend on boot having established the
- * following environment:
+ * Moreover, we depend on boot having established the following environment:
  * - TLBs are on
  * - identity mapping for the kernel image
@@ -62,6 +64,28 @@
 .global kernel_image_start
 kernel_image_start:
-	mov %o0, %l7
-
+	mov BSP_FLAG, %l0
+	and %o0, %l0, %l7				! l7 <= bootstrap processor?
+	andn %o0, %l0, %l6				! l6 <= start of physical memory
+
+	sethi %hi(physmem_base), %l5
+	stx %l6, [%l5 + %lo(physmem_base)]
+
+	/*
+	 * Get bits 40:13 of physmem_base.
+	 */ 
+	sethi %hi(mask_40_13), %l4
+	sethi %hi(physmem_base_40_13), %l3
+	ldx [%l4 + %lo(mask_40_13)], %l4
+	and %l6, %l4, %l5				! l5 <= physmem_base[40:13]
+	stx %l5, [%l3 + %lo(physmem_base_40_13)]
+
+	/*
+	 * Prepare kernel 8K TLB data template.
+	 */
+	sethi %hi(kernel_8k_tlb_data_template), %l4
+	ldx [%l4 + %lo(kernel_8k_tlb_data_template)], %l3
+	or %l3, %l5, %l3
+	stx %l3, [%l4 + %lo(kernel_8k_tlb_data_template)]
+	
 	/*
 	 * Setup basic runtime environment.
@@ -116,5 +140,6 @@
 #define SET_TLB_DATA(r1, r2, imm) \
 	set TTE_CV | TTE_CP | TTE_P | LMA | imm, %r1; \
-	set PAGESIZE_4M, %r2; \
+	or %r1, %l5, %r1; \
+	mov PAGESIZE_4M, %r2; \
 	sllx %r2, TTE_SIZE_SHIFT, %r2; \
 	or %r1, %r2, %r1; \
@@ -303,6 +328,32 @@
 
 .align STACK_ALIGNMENT
-.space INITIAL_STACK_SIZE
+	.space INITIAL_STACK_SIZE
 .align STACK_ALIGNMENT
 temporary_boot_stack:
-.space STACK_WINDOW_SAVE_AREA_SIZE
+	.space STACK_WINDOW_SAVE_AREA_SIZE
+
+
+.data
+
+.align 8
+.global physmem_base		! copy of the physical memory base address
+physmem_base:
+	.quad 0
+
+.global physmem_base_40_13
+physmem_base_40_13:		! physmem_base & mask_40_13
+	.quad 0
+
+.global mask_40_13
+mask_40_13:			! constant with bits 40:13 set
+	.quad (((1 << 41) - 1) & ~((1 << 13) - 1))
+
+/*
+ * This variable is used by the fast_data_MMU_miss trap handler.
+ * It is initialized to reflect the starting address of physical
+ * memory.
+ */
+.global kernel_8k_tlb_data_template
+kernel_8k_tlb_data_template:
+	.quad ((1 << TTE_V_SHIFT) | TTE_CV | TTE_CP | TTE_P | TTE_W)
+
