diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 17585ee0d9f72f14b6bf7b53d3a4b5bca528af8c..5a8e7ce3ce9ae715e1ed3b6d54d8ff1ee3c6aa00 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -14,7 +14,13 @@ config LEON2
 config LEON3
 	bool "LEON3"
 	help
-	 Configure for LEON2. 
+	 Configure for LEON3. 
+
+config LEON4
+	bool "LEON4"
+	help
+	 Configure for LEON4. 
+
 
 endchoice
 
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
index 7073823f983d2f732ab482e5730e65eea6db9447..571d6508cacca69468b92cdbe52131f2cf11bb21 100644
--- a/arch/sparc/Makefile
+++ b/arch/sparc/Makefile
@@ -1,5 +1,7 @@
 # gcc (7.2.0)
-ARCH_CFLAGS = -mcpu=leon3 -mfix-gr712rc
+#
+#ARCH_CFLAGS = -mcpu=leon3 -mfix-gr712rc
+ARCH_CFLAGS = -mcpu=leon3 -mhard-float
 # gcc (4.x)
 #ARCH_CFLAGS = -mcpu=v8 -mfix-gr712rc
 # clang
diff --git a/arch/sparc/include/asm/irq.h b/arch/sparc/include/asm/irq.h
index 4c3394ec03ebd370e0f4f6c682aca77325864192..cf4d575703c3ea98eb291e24ba64437ea14a4997 100644
--- a/arch/sparc/include/asm/irq.h
+++ b/arch/sparc/include/asm/irq.h
@@ -11,11 +11,11 @@
 void leon_irq_init(void);
 
 
-/* in the LEON3, interrupts 1-15 are primary, 16-31 are extended */
-#ifdef CONFIG_LEON3
+/* in the LEON3 and LEON4, interrupts 1-15 are primary, 16-31 are extended */
+#if defined(CONFIG_LEON3) || defined(CONFIG_LEON4)
 #define LEON_WANT_EIRQ(x) (x)
 #define LEON_REAL_EIRQ(x) (x)
-#endif /* CONFIG_LEON3 */
+#endif /* CONFIG_LEON3 || CONFIG_LEON4 */
 
 /* in the LEON2, interrupts 1-15 are primary, 0-31 are extended, we treat them
  * as IRLs 16...n */
diff --git a/arch/sparc/include/asm/leon_reg.h b/arch/sparc/include/asm/leon_reg.h
index 1d8d29708d6b570a1ab5685c6b9d9cc93358aac5..92c18c3d139869a4bcbcac444ed8568890b99461 100644
--- a/arch/sparc/include/asm/leon_reg.h
+++ b/arch/sparc/include/asm/leon_reg.h
@@ -24,6 +24,13 @@
 #include <kernel/types.h>
 
 
+#define LEON4_BASE_ADDRESS_IRQAMP	0xFF904000
+#define LEON4_BASE_ADDRESS_GPTIMER	0xFF908000
+#define LEON4_BASE_ADDRESS_GPTIMER1	0xFF909000
+#define LEON4_BASE_ADDRESS_GPTIMER2	0xFF90A000
+#define LEON4_BASE_ADDRESS_GPTIMER3	0xFF90B000
+#define LEON4_BASE_ADDRESS_GPTIMER4	0xFF90C000
+
 
 #define LEON3_BASE_ADDRESS_APB		0x80000000
 
@@ -165,6 +172,84 @@ struct leon3_irqctrl_registermap {
 };
 
 
+/* XXX */
+struct leon4_irqctrl_registermap {
+	uint32_t irq_level;			/* 0x00	*/
+	uint32_t irq_pending;			/* 0x04 */
+	uint32_t irq_force;			/* 0x08 */
+	uint32_t irq_clear;			/* 0x0C */
+	uint32_t mp_status;			/* 0x10 */
+	uint32_t mp_broadcast;			/* 0x14 */
+	uint32_t error_mode_status;		/* 0x18 */
+	uint32_t watchdog_control;		/* 0x1C */
+	uint32_t asym_mp_control;		/* 0x20 */
+	uint32_t irq_ctrl_select;		/* 0x24 */
+	uint32_t unused01;			/* 0x28 */
+	uint32_t unused02;			/* 0x2C */
+	uint32_t unused03;			/* 0x30 */
+	uint32_t unused04;			/* 0x34 */
+	uint32_t unused05;			/* 0x38 */
+	uint32_t unused06;			/* 0x3C */
+	uint32_t irq_mpmask[4];			/* 0x40 CPU 0 */
+						/* 0x44 CPU 1 */
+						/* 0x48 CPU 2 */
+						/* 0x4C CPU 3 */
+	uint32_t unused13;			/* 0x50 */
+	uint32_t unused14;			/* 0x54 */
+	uint32_t unused15;			/* 0x58 */
+	uint32_t unused16;			/* 0x5C */
+	uint32_t unused17;			/* 0x60 */
+	uint32_t unused18;			/* 0x64 */
+	uint32_t unused19;			/* 0x68 */
+	uint32_t unused20;			/* 0x6C */
+	uint32_t unused21;			/* 0x70 */
+	uint32_t unused22;			/* 0x74 */
+	uint32_t unused23;			/* 0x78 */
+	uint32_t unused24;			/* 0x7C */
+	uint32_t irq_mpforce[4];		/* 0x80 CPU 0*/
+						/* 0x84 CPU 1*/
+						/* 0x88 CPU 2*/
+						/* 0x8C CPU 3*/
+	uint32_t unused27;			/* 0x90 */
+	uint32_t unused28;			/* 0x94 */
+	uint32_t unused29;			/* 0x98 */
+	uint32_t unused30;			/* 0x9C */
+	uint32_t unused31;			/* 0xA0 */
+	uint32_t unused32;			/* 0xA4 */
+	uint32_t unused33;			/* 0xA8 */
+	uint32_t unused34;			/* 0xAC */
+	uint32_t unused35;			/* 0xB0 */
+	uint32_t unused36;			/* 0xB4 */
+	uint32_t unused37;			/* 0xB8 */
+	uint32_t unused38;			/* 0xBC */
+	uint32_t extended_irq_id[4];		/* 0xC0 CPU 0*/
+						/* 0xC4 CPU 1*/
+						/* 0xC8 CPU 2*/
+						/* 0xCC CPU 3*/
+	uint32_t unused39;			/* 0xD0 */
+	uint32_t unused40;			/* 0xD4 */
+	uint32_t unused41;			/* 0xD8 */
+	uint32_t unused42;			/* 0xDC */
+	uint32_t unused43;			/* 0xE0 */
+	uint32_t unused44;			/* 0xE4 */
+	uint32_t unused45;			/* 0xE8 */
+	uint32_t unused46;			/* 0xEC */
+	uint32_t unused47;			/* 0xF0 */
+	uint32_t unused48;			/* 0xF4 */
+	uint32_t unused49;			/* 0xF8 */
+	uint32_t unused50;			/* 0xFC */
+	uint32_t irq_timestamp0_cntr;		/* 0x100 */	/* XXX rework these */
+	uint32_t irq_timestamp0_ctrl;		/* 0x104 */
+	uint32_t irq_assert_timestamp0_ctrl;	/* 0x108 */
+	uint32_t irq_ack_timestamp0_ctrl;	/* 0x10C */
+	uint32_t irq_timestamp1_cntr;		/* 0x110 */
+	uint32_t irq_timestamp1_ctrl;		/* 0x114 */
+	uint32_t irq_assert_timestamp1_ctrl;	/* 0x118 */
+	uint32_t irq_ack_timestamp1_ctrl;	/* 0x11C */
+	uint32_t unused51[60];			/* 0x120 */
+	/* XXX missing */
+};
+
 
 struct leon3_ahbstat_registermap {
 	uint32_t status;
diff --git a/arch/sparc/include/asm/time.h b/arch/sparc/include/asm/time.h
index 611bd75614489c2e906b853d4a85cb6db7ca3a7d..b61755c3de0bbfa92a4aeeacf3900bc7b566ec23 100644
--- a/arch/sparc/include/asm/time.h
+++ b/arch/sparc/include/asm/time.h
@@ -46,7 +46,12 @@
 #define GRTIMER_MSEC_PER_CYCLE	(   1000.0 / GRTIMER_CYCLES_PER_SEC)
 #define GRTIMER_USEC_PER_CYCLE	(1000000.0 / GRTIMER_CYCLES_PER_SEC)
 
+/* yeah...need to work on that ...*/
+#if defined (CONFIG_LEON4)
 
+#define CPU_CYCLES_TO_NS(x) ((x) * (1000000000 / SPARC_CPU_CPS))
+
+#else
 /* this will definitely break if we run at GHz clock speeds
  * note that the order is important, otherwise we may encounter integer
  * overflow on multiplication
@@ -54,6 +59,7 @@
 #define CPU_CYCLES_TO_NS(x) (((x) >= 1000UL) \
 			     ? (((x) / (SPARC_CPU_CPS / 1000000UL)) * 1000UL) \
 			     : (((x) * 1000UL) / (SPARC_CPU_CPS / 1000000UL)))
+#endif
 
 compile_time_assert((SPARC_CPU_CPS <= 1000000000UL),
 		    CPU_CYCLES_TO_NS_NEEDS_FIXUP);
diff --git a/arch/sparc/kernel/bootmem.c b/arch/sparc/kernel/bootmem.c
index a5e15cfc0c8ff1b28c5456849e7de323e228e5a9..66c8f36b996eac2602aa385d70d202cd7582e24e 100644
--- a/arch/sparc/kernel/bootmem.c
+++ b/arch/sparc/kernel/bootmem.c
@@ -58,7 +58,8 @@ static void *bootmem_alloc_internal(size_t size)
 #endif
 
 #if (BOOTMEM_CHUNKSIZE > PAGE_SIZE)
-	return page_map_reserve_chunk(BOOTMEM_CHUNKSIZE);
+	return page_map_reserve_chunk(size); /* XXX patched for 740 test */
+	//return page_map_reserve_chunk(BOOTMEM_CHUNKSIZE);
 #else
 	return page_alloc();
 #endif
diff --git a/arch/sparc/kernel/clockevent.c b/arch/sparc/kernel/clockevent.c
index 5e7080637127efce1e25e507c0c642cc348d4973..5f77e63f5f0b5192a83d2e042f3bb668407de18f 100644
--- a/arch/sparc/kernel/clockevent.c
+++ b/arch/sparc/kernel/clockevent.c
@@ -9,23 +9,38 @@
 #include <kernel/irq.h>
 #include <errno.h>
 
-#ifdef CONFIG_LEON3
+#if defined(CONFIG_LEON3) || defined(CONFIG_LEON4)
 #include <gptimer.h>
 #include <asm/time.h>
 
 
 
 /* XXX: want AMBA PNP autodetect later...) */
+/* XXX: patched to use gptimer 0 on leon4, but there are a total of 5 timer
+ * blocks
+ */
 
+#define LEON3_GPTIMERS	5
 
 #define LEON3_GPTIMERS	4
+
+#ifdef CONFIG_LEON4
+#define GPTIMER_0_IRQ	1
+#endif
+#ifdef CONFIG_LEON3
 #define GPTIMER_0_IRQ	8
+#endif
 
 static struct gpclkdevs {
 	struct gptimer_unit *gptu;
 	struct clock_event_device dev[LEON3_GPTIMERS];
 } _gp_clk_ev = {
+#ifdef CONFIG_LEON3
 	.gptu =  (struct gptimer_unit *)  LEON3_BASE_ADDRESS_GPTIMER
+#endif
+#ifdef CONFIG_LEON4
+	.gptu =  (struct gptimer_unit *)  LEON4_BASE_ADDRESS_GPTIMER
+#endif
 };
 
 
@@ -255,7 +270,7 @@ static void leon_setup_clockdevs(void)
 
 void sparc_clockevent_init(void)
 {
-#ifdef CONFIG_LEON3
+#if defined(CONFIG_LEON3) || defined(CONFIG_LEON4)
 	leon_setup_clockdevs();
 #endif /* CONFIG_LEON3 */
 }
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
index bb66021997721ea2da54522da462070bcd981994..dff3b3334322e3b8c15a0c52b57cc098e45929e5 100644
--- a/arch/sparc/kernel/irq.c
+++ b/arch/sparc/kernel/irq.c
@@ -92,7 +92,18 @@ static struct leon3_irqctrl_registermap *leon_irqctrl_regs;
 
 #endif /* CONFIG_LEON3 */
 
-#define CPU_AFFINITY_NONE (-1)
+#ifdef CONFIG_LEON4
+
+#define IRL_SIZE	LEON3_IRL_SIZE
+#define EIRL_SIZE	LEON3_IRL_SIZE
+
+static struct leon4_irqctrl_registermap *leon_irqctrl_regs;
+
+#endif /* CONFIG_LEON4 */
+
+
+
+#define CPU_AFFINITY_NONE (-1) /* XXX */
 
 static int irq_cpu_affinity[IRL_SIZE + EIRL_SIZE];
 
@@ -370,7 +381,7 @@ EXPORT_SYMBOL(arch_local_irq_restore);
 
 static void leon_clear_irq(unsigned int irq)
 {
-#ifdef CONFIG_LEON3
+#if defined(CONFIG_LEON3) || defined (CONFIG_LEON4)
 	iowrite32be((1 << irq), &leon_irqctrl_regs->irq_clear);
 #endif /* CONFIG_LEON3 */
 
@@ -401,7 +412,7 @@ static void leon_unmask_irq(unsigned int irq, int cpu)
 	uint32_t mask;
 
 
-#ifdef CONFIG_LEON3
+#if defined(CONFIG_LEON3) || defined (CONFIG_LEON4)
 	mask = ioread32be(&leon_irqctrl_regs->irq_mpmask[cpu]);
 	mask |= (1 << irq);
 	iowrite32be(mask, &leon_irqctrl_regs->irq_mpmask[cpu]);
@@ -433,7 +444,7 @@ static void leon_mask_irq(unsigned int irq, int cpu)
 	uint32_t mask;
 
 
-#ifdef CONFIG_LEON3
+#if defined(CONFIG_LEON3) || defined (CONFIG_LEON4)
 	mask = ioread32be(&leon_irqctrl_regs->irq_mpmask[cpu]);
 
 	mask &= ~(1 << irq);
@@ -621,7 +632,7 @@ __attribute__((unused))
 static int leon_eirq_dispatch(unsigned int irq)
 {
 	unsigned int eirq;
-#ifdef CONFIG_LEON3
+#if defined(CONFIG_LEON3) || defined (CONFIG_LEON4)
 	int cpu;
 #endif /* CONFIG_LEON3 */
 
@@ -634,7 +645,7 @@ static int leon_eirq_dispatch(unsigned int irq)
 	irqstat.irl_irq[irq]++;
 #endif /* CONFIG_IRQ_STATS_COLLECT */
 
-#ifdef CONFIG_LEON3
+#if defined(CONFIG_LEON3) || defined (CONFIG_LEON4)
 	cpu = leon3_cpuid();
 #endif /* CONFIG_LEON3 */
 
@@ -643,7 +654,7 @@ static int leon_eirq_dispatch(unsigned int irq)
 	/* XXX this is a potential death trap :) */
 	while (1) {
 
-#ifdef CONFIG_LEON3
+#if defined(CONFIG_LEON3) || defined (CONFIG_LEON4)
 		/* no pending EIRQs remain */
 		if (!(leon_irqctrl_regs->irq_pending >> IRL_SIZE))
 			break;
@@ -736,7 +747,7 @@ int irl_register_handler(unsigned int irq,
 
 	spin_lock_restore_irq(psr_flags);
 
-#ifdef CONFIG_LEON3
+#if defined(CONFIG_LEON3) || defined (CONFIG_LEON4)
 	/* XXX for now, just register to the current CPU if no affinity is set */
 	cpu = irq_cpu_affinity[irq];
 
@@ -816,7 +827,7 @@ static int eirl_register_handler(unsigned int irq,
 		       &eirl_vector[LEON_REAL_EIRQ(irq)]);
 
 	spin_lock_restore_irq(psr_flags);
-#ifdef CONFIG_LEON3
+#if defined(CONFIG_LEON3) || defined (CONFIG_LEON4)
 	/* XXX for now, just register to the current CPU if no affinity is set */
 	cpu = irq_cpu_affinity[irq];
 
@@ -1043,8 +1054,8 @@ static void leon_setup_eirq(void)
 {
 	unsigned int eirq;
 
-#ifdef CONFIG_LEON3
-	/* probe for extended IRQ controller, see GR712UM, p75 */
+#if defined(CONFIG_LEON3) || defined (CONFIG_LEON4)
+	/* probe for extended IRQ controller, see GR712UM, p75; GR740UM p309*/
 	eirq = (ioread32be(&leon_irqctrl_regs->mp_status) >> 16) & 0xf;
 #endif /* CONFIG_LEON3 */
 #ifdef CONFIG_LEON2
@@ -1069,6 +1080,14 @@ static void leon_setup_eirq(void)
 	BUG_ON(catch_interrupt((int) leon_eirq_dispatch, leon_eirq));
 #endif /* CONFIG_ARCH_CUSTOM_BOOT_CODE */
 
+#ifdef CONFIG_LEON4
+	/* XXX enable for all cpus in the system */
+	leon_enable_irq(leon_eirq, 0);
+	leon_enable_irq(leon_eirq, 1);
+	leon_enable_irq(leon_eirq, 2);
+	leon_enable_irq(leon_eirq, 3);
+#endif /* CONFIG_LEON3 */
+
 #ifdef CONFIG_LEON3
 	/* XXX enable for all cpus in the system */
 	leon_enable_irq(leon_eirq, 0);
@@ -1095,7 +1114,7 @@ static void leon_irq_set_level(uint32_t irq_mask, uint32_t level)
 	uint32_t flags;
 
 
-#ifdef CONFIG_LEON3
+#if defined(CONFIG_LEON3) || defined (CONFIG_LEON4)
 	flags = ioread32be(&leon_irqctrl_regs->irq_level);
 #endif /* CONFIG_LEON3 */
 #ifdef CONFIG_LEON2
@@ -1107,7 +1126,7 @@ static void leon_irq_set_level(uint32_t irq_mask, uint32_t level)
 	else
 		flags |= irq_mask;
 
-#ifdef CONFIG_LEON3
+#if defined(CONFIG_LEON3) || defined (CONFIG_LEON4)
 	iowrite32be(flags, &leon_irqctrl_regs->irq_level);
 #endif /* CONFIG_LEON3 */
 #ifdef CONFIG_LEON2
@@ -1219,6 +1238,20 @@ static struct irq_dev leon_irq = {
 
 void leon_irq_init(void)
 {
+#ifdef CONFIG_LEON4
+	/* XXX should determine that from AMBA PNP scan */
+	leon_irqctrl_regs = (struct leon4_irqctrl_registermap *)
+						LEON4_BASE_ADDRESS_IRQAMP;
+
+	/* mask all interrupts on this (boot) CPU */
+	iowrite32be(0, &leon_irqctrl_regs->irq_mpmask[leon3_cpuid()]); /*XXX leon3_ */
+
+	/* XXX MASK FOR ALL CPUS CONFIGURED FOR THE SYSTEM (dummy for N==4)*/
+	iowrite32be(0, &leon_irqctrl_regs->irq_mpmask[1]);
+	iowrite32be(0, &leon_irqctrl_regs->irq_mpmask[2]);
+	iowrite32be(0, &leon_irqctrl_regs->irq_mpmask[3]);
+
+#endif /* CONFIG_LEON3 */
 #ifdef CONFIG_LEON3
 	/* XXX should determine that from AMBA PNP scan */
 	leon_irqctrl_regs = (struct leon3_irqctrl_registermap *)
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
index 80f97488721a0d26ef3e6bbae45aa89a85070903..d4b417de5298abaf4e12641c1936843688285d0a 100644
--- a/arch/sparc/kernel/setup.c
+++ b/arch/sparc/kernel/setup.c
@@ -77,6 +77,9 @@ static void mem_init(void)
 #ifdef CONFIG_MPPB
 	sp_banks[0].base_addr = 0x40000000;
 	sp_banks[0].num_bytes = 0x10000000;
+#elif CONFIG_LEON4
+	sp_banks[0].base_addr = 0x00000000;
+	sp_banks[0].num_bytes = 0x10000000;
 #else /* e.g. GR712 eval */
 	sp_banks[0].base_addr = 0x40000000;
 	sp_banks[0].num_bytes = 0x00800000;
@@ -92,14 +95,19 @@ static void mem_init(void)
 }
 
 
-int cpu1_ready;
+int cpu_ready[4];
 
 
 #include <asm/io.h>
 /* wake a cpu by writing to the multiprocessor status register */
 void cpu_wake(uint32_t cpu_id)
 {
+#ifdef CONFIG_LEON3
 	iowrite32be(cpu_id, (uint32_t *) 0x80000210);
+#endif
+#ifdef CONFIG_LEON4
+	iowrite32be(cpu_id, (uint32_t *) 0xFF904010);
+#endif
 }
 
 /** XXX crappy */
@@ -108,8 +116,21 @@ static void boot_cpus(void)
 	printk("booting cpu1\n");
 	cpu_wake(0x2); /*cpu 1 */
 
-        while (!ioread32be(&cpu1_ready));
+        while (!ioread32be(&cpu_ready[1]));
 	printk("cpu1 booted\n");
+
+	printk("booting cpu2\n");
+	cpu_wake(0x4); /*cpu 2 */
+
+        while (!ioread32be(&cpu_ready[2]));
+	printk("cpu2 booted\n");
+
+
+	printk("booting cpu3\n");
+	cpu_wake(0x8); /*cpu 3 */
+
+        while (!ioread32be(&cpu_ready[3]));
+	printk("cpu3 booted\n");
 }
 
 
@@ -119,27 +140,21 @@ extern struct task_struct *kernel[];
 void smp_cpu_entry(void)
 {
 
-	reserve_kernel_stack();
-	BUG_ON(stack_migrate(NULL, _kernel_stack_top));
-
-	arch_local_irq_enable();
-
-	printk("hi i'm cpu %d\n", leon3_cpuid());
+     reserve_kernel_stack();
+     BUG_ON(stack_migrate(NULL, _kernel_stack_top));
 
-	BUG_ON(!leon3_cpuid());
+     printk("hi i'm cpu %d\n", leon3_cpuid());
 
-	/* signal ready */
-	iowrite32be(0x1, &cpu1_ready);
-
-	while (ioread32be(&cpu1_ready) != 0x2);
-
-	BUG_ON(clockevents_offer_device());
+     BUG_ON(!leon3_cpuid());
+      /* signal ready */
+      iowrite32be(0x1, &cpu_ready[leon3_cpuid()]);
 
+	while (ioread32be(&cpu_ready[leon3_cpuid()]) != 0x2);
+	BUG_ON(clockevents_offer_device()); /* XXX CLOCK */
 	kthread_init_main();
 
-	iowrite32be(0x3, &cpu1_ready);
-
-	while (ioread32be(&cpu1_ready) != 0x4);
+      iowrite32be(0x3, &cpu_ready[leon3_cpuid()]);
+	while (ioread32be(&cpu_ready[leon3_cpuid()]) != 0x4);
 
 	sched_enable();
 
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index 2b57684db1221a212221a36e8cdca768b3f582e7..a45d01028173a3300a07337a2f20304a90f2bcc7 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -27,9 +27,62 @@ static void leon_grtimer_longcount_init(void)
 #endif
 
 
+#ifdef CONFIG_LEON4
 
+/**
+ * @brief start the up-counters in %asr22-23 of the LEON4
+ *
+ * @warn the counter apparently cannot be reset in software. this sucks big time
+ *
+ * @note to pause the up-counter, the MSB of asr22 of ALL processors must be set
+ * @see GR740UM p 72.
+ */
+
+static uint64_t boot_time;
 
 
+
+static inline uint64_t leon4_get_upcount(void)
+{
+	uint64_t time = 0;
+
+	__asm__ __volatile__ (
+			"rd	%%asr22, %H0	\n\t"
+			"rd	%%asr23, %L0	\n\t"
+			:"=r" (time)
+			);
+
+	time &= (0x1ULL << 56) - 1ULL;
+	/* Need this for wrap-around detection. Note that 56 bits last for
+	 * ~10 years @ 250 MHz, but you never know...
+	 */
+	if (boot_time > time) {
+		/* XXX set wrap-around status (message) somewhere */
+		boot_time = time;
+		boot_time &= (0x1ULL << 56) - 1ULL;
+	}
+
+	return time - boot_time;
+}
+
+
+static void leon4_init_upcount(void)
+{
+	__asm__ __volatile__ (
+			"wr     %%g0,    %%asr22 \n\t"
+			"rd	%%asr22, %H0	\n\t"
+			"rd	%%asr23, %L0	\n\t"
+			:"=r" (boot_time)
+			);
+	boot_time &= (0x1ULL << 56) - 1ULL;
+}
+
+#endif
+
+/* XXX I really need to rework the ktime interface so that all
+ * basic times are in nanoseconds. double-word divisions area
+ * REALLY expensive (doubles the overhead...)
+ */
 static void leon_get_uptime(uint32_t *seconds, uint32_t *nanoseconds)
 {
 #ifdef CONFIG_LEON3
@@ -38,7 +91,20 @@ static void leon_get_uptime(uint32_t *seconds, uint32_t *nanoseconds)
 	grtimer_longcount_get_uptime(grtimer_longcount, &up);
 	(*seconds)     = up.coarse;
 	(*nanoseconds) = CPU_CYCLES_TO_NS(up.fine);
+#elif CONFIG_LEON4
+
+	uint64_t sec;
+	uint64_t nsec;
+
 
+	nsec = CPU_CYCLES_TO_NS(leon4_get_upcount());
+
+	sec = nsec /  1000000000ULL;
+	/* likely faster than using modulo */
+	nsec = nsec % 1000000000ULL;
+
+	(*seconds)     = (uint32_t) sec;
+	(*nanoseconds) = (uint32_t) nsec;
 #else
 	printk("%s:%s not implemented\n", __FILE__, __func__);
 	BUG();
@@ -80,5 +146,10 @@ void sparc_uptime_init(void)
 #ifdef CONFIG_LEON3
 	leon_grtimer_longcount_init();
 #endif
+
+#ifdef CONFIG_LEON4
+	leon4_init_upcount();
+#endif
+
 	time_init(&uptime_clock);
 }
diff --git a/init/main.c b/init/main.c
index 8d57935215f135fcd8cc915008d4d5193c076038..338d6153b9e0fa6431dec14caf0f24afc1521a71 100644
--- a/init/main.c
+++ b/init/main.c
@@ -115,6 +115,9 @@ int task(void *p)
 }
 
 
+
+/** XXX dummy **/
+extern int cpu_ready[4];
 /**
  * @brief kernel main functionputchar( *((char *) data) );
  */
@@ -180,11 +183,17 @@ int kernel_main(void)
 	kthread_init_main();
 
 	/* wait for cpus */
-	cpu1_ready = 2;
+	cpu_ready[1] = 2;
+	while (ioread32be(&cpu_ready[1]) != 0x3);
+	iowrite32be(0x4, &cpu_ready[1]);
 
-	while (ioread32be(&cpu1_ready) != 0x3);
-	iowrite32be(0x4, &cpu1_ready);
+	cpu_ready[2] = 2;
+	while (ioread32be(&cpu_ready[2]) != 0x3);
+	iowrite32be(0x4, &cpu_ready[2]);
 
+	cpu_ready[3] = 2;
+	while (ioread32be(&cpu_ready[3]) != 0x3);
+	iowrite32be(0x4, &cpu_ready[3]);
 	printk(MSG "Boot complete\n");
 
 
@@ -217,20 +226,6 @@ int kernel_main(void)
 	}
 
 
-	t = kthread_create(task, NULL, KTHREAD_CPU_AFFINITY_NONE, "task");
-	if (!IS_ERR(t)) {
-		sched_get_attr(t, &attr);
-		attr.policy = SCHED_EDF;
-		attr.period       = ms_to_ktime(1000);
-		attr.deadline_rel = ms_to_ktime(999);
-		attr.wcet         = ms_to_ktime(300);
-		sched_set_attr(t, &attr);
-		if (kthread_wake_up(t) < 0)
-			printk("---- %s NOT SCHEDUL-ABLE---\n", t->name);
-	} else {
-		printk("Got an error in kthread_create!");
-	}
-
 	t = kthread_create(task2, NULL, KTHREAD_CPU_AFFINITY_NONE, "task2");
 	if (!IS_ERR(t)) {
 		sched_get_attr(t, &attr);
@@ -247,12 +242,8 @@ int kernel_main(void)
 
 
 
-
-
-	while(1) {
+	while(1)
 		cpu_relax();
-	}
-
 
 	/* never reached */
 	BUG();
diff --git a/lib/mm.c b/lib/mm.c
index ebb49ff65676a82900f7e4c77b7995c6093dcfa8..2eed81187fb0e53f46e52b825b70af7c5293659f 100644
--- a/lib/mm.c
+++ b/lib/mm.c
@@ -73,7 +73,13 @@ struct mm_blk_lnk {
 
 static bool mm_blk_addr_valid(struct mm_pool *mp, struct mm_blk_lnk *blk)
 {
-	return ((unsigned long) blk - (1UL << mp->max_order) < mp->base);
+	if ((unsigned long) blk  >= mp->base)
+		if ((unsigned long) blk  < mp->base + (1UL << mp->max_order))
+			return true;
+
+	return false;
+
+//	return ((unsigned long) blk - (1UL << mp->max_order) < mp->base);
 }
 
 
diff --git a/lib/vsnprintf.c b/lib/vsnprintf.c
index 618639dbb1ef8de954eaccd4656bd4f334ad61f1..fd9fee8553b49b20c0f93571a824fae8020ec07c 100644
--- a/lib/vsnprintf.c
+++ b/lib/vsnprintf.c
@@ -60,7 +60,13 @@ struct fmt_spec {
 
 #define TREADY 4
 
+#if defined(CONFIG_LEON3)
 static volatile int *console = (int *)0x80000100;
+#endif
+
+#if defined(CONFIG_LEON4)
+static volatile int *console = (int *)0xFF900000;
+#endif
 
 static int putchar(int c)
 {