diff --git a/src/northbridge/intel/i945/rcven.c b/src/northbridge/intel/i945/rcven.c
new file mode 100644
index 0000000..e7eea61
--- /dev/null
+++ b/src/northbridge/intel/i945/rcven.c
@@ -0,0 +1,338 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2008 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "raminit.h"
+
+/**
+ * sample the strobes signal
+ */
+static u32 sample_strobes(int channel_offset, struct sys_info *sysinfo)
+{
+	u32 reg32, addr;
+	int i;
+
+	MCHBAR32(C0DRC1 + channel_offset) |= (1 << 6);
+	
+	MCHBAR32(C0DRC1 + channel_offset) &= ~(1 << 6);
+
+	addr = 0;
+
+	if (channel_offset != 0) {	/* must be dual channel */
+		if (sysinfo->interleaved == 1) {
+			addr |= (1 << 6);
+		} else {
+			addr = ((u32)MCHBAR8(C0DRB3)) << 25;
+		}
+	}
+
+	for (i = 0; i < 28; i++) {
+		read32(addr);
+		read32(addr + 0x80);	
+	}
+
+	reg32 = MCHBAR32(RCVENMT);
+	if (channel_offset == 0) {
+		reg32 = reg32 << 2;
+	}
+
+	/**
+	 * [19] = 1: all bits are high
+	 * [18] = 1: all bits are low
+	 * [19:18] = 00: bits are mixed high, low
+	 */
+	return reg32;
+}
+
+/**
+ * This function sets receive enable coarse and medium timing parameters
+ */
+
+static void set_receive_enable(int channel_offset, u8 medium, u8 coarse)
+{
+	u32 reg32;
+
+	printk_spew("    set_receive_enable() medium=0x%x, coarse=0x%x\r\n", medium, coarse);
+	
+	reg32 = MCHBAR32(C0DRT1 + channel_offset);
+	reg32 &= 0xf0ffffff;
+	reg32 |= ((u32)coarse & 0x0f) << 24;
+	MCHBAR32(C0DRT1 + channel_offset) = reg32;
+	
+	if (coarse > 0x0f)
+		printk_debug("set_receive_enable: coarse overflow: 0x%02x.\n", coarse);
+
+	/* medium control
+	 *
+	 * 00 - 1/4 clock
+	 * 01 - 1/2 clock
+	 * 10 - 3/4 clock
+	 * 11 - 1   clock
+	 */
+
+	reg32 = MCHBAR32(RCVENMT);
+	if (!channel_offset) {
+		
+		reg32 &= ~(3 << 2);
+		reg32 |= medium << 2;
+	} else {
+		
+		reg32 &= ~(3 << 0);
+		reg32 |= medium;
+	}
+	MCHBAR32(RCVENMT) = reg32;
+
+}
+
+static int normalize(int channel_offset, u8 * mediumcoarse, u8 * fine)
+{
+	printk_spew("  normalize()\r\n");
+
+	if (*fine < 0x80)
+		return 0;
+
+	*fine -= 0x80;
+	*mediumcoarse += 1;
+
+	if (*mediumcoarse >= 0x40) {
+		printk_debug("Normalize Error\r\n");
+		return -1;
+	}
+
+	set_receive_enable(channel_offset, *mediumcoarse & 3,
+			   *mediumcoarse >> 2);
+
+	MCHBAR8(C0WL0REOST + channel_offset) = *fine;
+
+	return 0;
+}
+
+static int find_preamble(int channel_offset, u8 * mediumcoarse,
+			 struct sys_info *sysinfo)
+{
+	/* find start of the data phase */
+	u32 reg32;
+
+	printk_spew("  find_preamble()\r\n");
+
+	do {
+		if (*mediumcoarse < 4) {
+			
+			printk_debug("No Preamble found.\r\n");
+			return -1;
+		}
+		*mediumcoarse -= 4;
+
+		set_receive_enable(channel_offset, *mediumcoarse & 3,
+				   *mediumcoarse >> 2);
+
+		reg32 = sample_strobes(channel_offset, sysinfo);
+
+	} while (reg32 & (1 << 19));	
+
+	if (!(reg32 & (1 << 18))) {	
+		
+		printk_debug("No Preamble found (neither high nor low).\r\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/**
+ * add a quarter clock to the current receive enable settings
+ */
+
+static int add_quarter_clock(int channel_offset, u8 * mediumcoarse, u8 * fine)
+{
+	printk_spew("  add_quarter_clock() mediumcoarse=%02x fine=%02x\r\n",
+			*mediumcoarse, *fine);
+	if (*fine >= 0x80) {
+		*fine -= 0x80;
+
+		*mediumcoarse += 2;
+		if (*mediumcoarse >= 0x40) {
+			printk_debug("clocks at max.\r\n");
+			return -1;
+		}
+
+		set_receive_enable(channel_offset, *mediumcoarse & 3,
+				   *mediumcoarse >> 2);
+	} else {
+		*fine += 0x80;
+	}
+
+	MCHBAR8(C0WL0REOST + channel_offset) = *fine;
+
+	return 0;
+}
+
+static int find_strobes_low(int channel_offset, u8 * mediumcoarse, u8 * fine,
+			    struct sys_info *sysinfo)
+{
+	u32 rcvenmt;
+
+	printk_spew("  find_strobes_low()\r\n");
+	
+	for (;;) {
+		MCHBAR8(C0WL0REOST + channel_offset) = *fine;
+
+		set_receive_enable(channel_offset, *mediumcoarse & 3,
+				   *mediumcoarse >> 2);
+
+		rcvenmt = sample_strobes(channel_offset, sysinfo);
+
+		if (((rcvenmt & (1 << 18)) != 0))
+			return 0;
+
+		
+		*fine -= 0x80;
+		if (*fine == 0)
+			continue;
+
+		*mediumcoarse -= 2;
+		if (*mediumcoarse < 0xfe) 
+			continue;
+
+		break;
+
+	}
+
+	printk_debug("Could not find low strobe\r\n");
+	return 0;
+}
+
+static int find_strobes_edge(int channel_offset, u8 * mediumcoarse, u8 * fine,
+			     struct sys_info *sysinfo)
+{
+	int counter;
+	u32 rcvenmt;
+
+	printk_spew("  find_strobes_edge()\r\n");
+
+	counter = 8;
+	set_receive_enable(channel_offset, *mediumcoarse & 3,
+			   *mediumcoarse >> 2);
+
+	for (;;) {
+		MCHBAR8(C0WL0REOST + channel_offset) = *fine;
+		rcvenmt = sample_strobes(channel_offset, sysinfo);
+
+		if ((rcvenmt & (1 << 19)) == 0) {
+			counter = 8;
+		} else {
+			counter--;
+			if (!counter)
+				break;
+		}
+
+		*fine = *fine + 1;
+		if (*fine < 0xf8) {
+			if (*fine & (1 << 3)) {
+				*fine &= ~(1 << 3);
+				*fine += 0x10;
+			}
+			continue;
+		}
+		
+		*fine = 0;
+		*mediumcoarse += 2;
+		if (*mediumcoarse <= 0x40) {
+			set_receive_enable(channel_offset, *mediumcoarse & 3,
+					   *mediumcoarse >> 2);
+			continue;
+		}
+
+		printk_debug("could not find rising edge.\r\n");
+		return -1;
+	}
+	
+	*fine -= 7;
+	if (*fine >= 0xf9) {	
+		*mediumcoarse -= 2;
+		set_receive_enable(channel_offset, *mediumcoarse & 3,
+				   *mediumcoarse >> 2);
+	}
+
+	*fine &= ~(1 << 3);	
+	MCHBAR8(C0WL0REOST + channel_offset) = *fine;
+
+	return 0;
+}
+
+/**
+ * Here we use a trick. The RCVEN channel 0 registers are all at an 
+ * offset of 0x80 to the channel 0 registers. We don't want to waste
+ * a lot of if()s so let's just pass 0 or 0x80 for the channel offset.
+ */
+
+static int receive_enable_autoconfig(int channel_offset,
+				     struct sys_info *sysinfo)
+{
+	u8 mediumcoarse;
+	u8 fine;
+
+	printk_spew("receive_enable_autoconfig() for channel %d\r\n",
+		    channel_offset ? 1 : 0);
+
+	/* Set initial values */
+	mediumcoarse = (sysinfo->cas << 2) | 3;	
+	fine = 0;
+
+	if (find_strobes_low(channel_offset, &mediumcoarse, &fine, sysinfo))
+		return -1;
+
+	if (find_strobes_edge(channel_offset, &mediumcoarse, &fine, sysinfo))
+		return -1;
+
+	if (add_quarter_clock(channel_offset, &mediumcoarse, &fine))
+		return -1;
+
+	if (find_preamble(channel_offset, &mediumcoarse, sysinfo))
+		return -1;
+
+	if (add_quarter_clock(channel_offset, &mediumcoarse, &fine))
+		return -1;
+
+	if (normalize(channel_offset, &mediumcoarse, &fine))
+		return -1;
+
+	/* This is a debug check to see if the rcven code is fully working.
+	 * It can be removed when the output message is not printed anymore
+	 */
+	if (MCHBAR8(C0WL0REOST + channel_offset) == 0) {
+		printk_debug("Weird. No C%sWL0REOST\n", channel_offset?"1":"0");
+	}
+
+	return 0;
+}
+
+void receive_enable_adjust(struct sys_info *sysinfo)
+{
+	/* Is channel 0 populated? */
+	if (sysinfo->dimm[0] != SYSINFO_DIMM_NOT_POPULATED
+	    || sysinfo->dimm[1] != SYSINFO_DIMM_NOT_POPULATED)
+		if (receive_enable_autoconfig(0, sysinfo))
+			return;
+
+	/* Is channel 1 populated? */
+	if (sysinfo->dimm[2] != SYSINFO_DIMM_NOT_POPULATED
+	    || sysinfo->dimm[3] != SYSINFO_DIMM_NOT_POPULATED)
+		if (receive_enable_autoconfig(0x80, sysinfo))
+			return;
+}
