diff -Nuar -x .svn coreboot-v2-org/src/southbridge/amd/sb600/chip.h coreboot-v2-svn/src/southbridge/amd/sb600/chip.h
--- coreboot-v2-org/src/southbridge/amd/sb600/chip.h	2008-11-13 06:30:51.000000000 +0800
+++ coreboot-v2-svn/src/southbridge/amd/sb600/chip.h	2008-11-19 13:24:28.000000000 +0800
@@ -20,7 +20,7 @@
 #ifndef SB600_CHIP_H
 #define SB600_CHIP_H
 
-struct southbridge_amd_sb600_config 
+struct southbridge_amd_sb600_config
 {
 	unsigned int ide0_enable : 1;
 	unsigned int sata0_enable : 1;
diff -Nuar -x .svn coreboot-v2-org/src/southbridge/amd/sb600/sb600_early_setup.c coreboot-v2-svn/src/southbridge/amd/sb600/sb600_early_setup.c
--- coreboot-v2-org/src/southbridge/amd/sb600/sb600_early_setup.c	2008-11-13 06:30:51.000000000 +0800
+++ coreboot-v2-svn/src/southbridge/amd/sb600/sb600_early_setup.c	2008-11-19 13:24:00.000000000 +0800
@@ -24,6 +24,7 @@
 #define SMBUS_IO_BASE 0x1000	/* Is it a temporary SMBus I/O base address? */
 	 /*SIZE 0x40 */
 
+
 static void pmio_write(u8 reg, u8 value)
 {
 	outb(reg, PM_INDEX);
@@ -317,7 +318,7 @@
 	pci_write_config8(dev, 0x62, byte);
 
 	/* Features Enable */
-	pci_write_config32(dev, 0x64, 0x829E79BF);
+	pci_write_config32(dev, 0x64, 0x829E7DBF); /* bit10: Enables the HPET interrupt. */
 
 	/* SerialIrq Control */
 	pci_write_config8(dev, 0x69, 0x90);
@@ -373,7 +374,7 @@
 	byte |= ((1 << 1) + (1 << 6));	/*0x42, save the configuraion for port 0x80. */
 	pci_write_config8(dev, 0x4A, byte);
 
-	/* Set LPC ROM size, it has been done in sb600_lpc_init(). 
+	/* Set LPC ROM size, it has been done in sb600_lpc_init().
 	 * enable LPC ROM range, 0xfff8: 512KB, 0xfff0: 1MB;
 	 * enable LPC ROM range, 0xfff8: 512KB, 0xfff0: 1MB
 	 * pci_write_config16(dev, 0x68, 0x000e)
@@ -382,7 +383,7 @@
 	/* Enable Tpm12_en and Tpm_legacy. I don't know what is its usage and copied from CIM. */
 	pci_write_config8(dev, 0x7C, 0x05);
 
-	/* P2P Bridge, BDF:0-20-4, the configuration of the registers in this dev are copied from CIM, 
+	/* P2P Bridge, BDF:0-20-4, the configuration of the registers in this dev are copied from CIM,
 	 * TODO: I don't know what are their mean? */
 	printk_info("sb600_devices_por_init(): P2P Bridge, BDF:0-20-4\n");
 	dev = pci_locate_device(PCI_ID(0x1002, 0x4384), 0);
@@ -397,7 +398,7 @@
 
 	pci_write_config8(dev, 0x40, 0x26);
 
-	/* I don't know why CIM set reg0x1c as 0x11. 
+	/* I don't know why CIM set reg0x1c as 0x11.
 	 * System will block at sdram_initialize() if I set it before call sdram_initialize().
 	 * If it is necessary to set reg0x1c as 0x11, please call this function after sdram_initialize().
 	 * pci_write_config8(dev, 0x1c, 0x11);
@@ -490,8 +491,10 @@
 	pmio_write(0x9e, byte);
 
 	/* rpr2.14: Hides SM bus controller Bar1 where stores HPET MMIO base address */
+	/* We have to clear this bit here, otherwise the kernel hangs. */
 	byte = pmio_read(0x55);
 	byte |= 1 << 7;
+	byte |= 1 << 1;
 	pmio_write(0x55, byte);
 
 	/* rpr2.14: Make HPET MMIO decoding controlled by the memory enable bit in command register of LPC ISA bridage */
@@ -550,7 +553,7 @@
 	byte |= (1 << 3);
 	pci_write_config8(dev, 0x41, byte);
 
-	/* Set to 1 to reset USB on the software (such as IO-64 or IO-CF9 cycles) 
+	/* Set to 1 to reset USB on the software (such as IO-64 or IO-CF9 cycles)
 	 * generated PCIRST#. */
 	byte = pmio_read(0x65);
 	byte |= (1 << 4);
diff -Nuar -x .svn coreboot-v2-org/src/southbridge/amd/sb600/sb600_ide.c coreboot-v2-svn/src/southbridge/amd/sb600/sb600_ide.c
--- coreboot-v2-org/src/southbridge/amd/sb600/sb600_ide.c	2008-11-13 06:30:51.000000000 +0800
+++ coreboot-v2-svn/src/southbridge/amd/sb600/sb600_ide.c	2008-11-25 10:37:16.000000000 +0800
@@ -38,13 +38,10 @@
 	pci_write_config32(dev, 0x70, dword);
 
 	/* Ultra DMA mode */
+	/* enable UDMA */
 	byte = pci_read_config8(dev, 0x54);
 	byte |= 1 << 0;
 	pci_write_config8(dev, 0x54, byte);
-	byte = pci_read_config8(dev, 0x56);
-	byte &= ~(7 << 0);
-	byte |= 5 << 0;		/* mode 5 */
-	pci_write_config8(dev, 0x56, byte);
 
 	/* Enable I/O Access&& Bus Master */
 	dword = pci_read_config16(dev, 0x4);
diff -Nuar -x .svn coreboot-v2-org/src/southbridge/amd/sb600/sb600_lpc.c coreboot-v2-svn/src/southbridge/amd/sb600/sb600_lpc.c
--- coreboot-v2-org/src/southbridge/amd/sb600/sb600_lpc.c	2008-11-13 06:30:51.000000000 +0800
+++ coreboot-v2-svn/src/southbridge/amd/sb600/sb600_lpc.c	2008-11-19 13:23:50.000000000 +0800
@@ -82,14 +82,14 @@
 	compact_resources(dev);
 }
 
-/**     
+/**
  * @brief Enable resources for children devices
- *      
+ *
  * @param dev the device whos children's resources are to be enabled
- *      
+ *
  * This function is call by the global enable_resources() indirectly via the
  * device_operation::enable_resources() method of devices.
- *      
+ *
  * Indirect mutual recursion:
  *      enable_childrens_resources() -> enable_resources()
  *      enable_resources() -> device_operation::enable_resources()
diff -Nuar -x .svn coreboot-v2-org/src/southbridge/amd/sb600/sb600_smbus.c coreboot-v2-svn/src/southbridge/amd/sb600/sb600_smbus.c
--- coreboot-v2-org/src/southbridge/amd/sb600/sb600_smbus.c	2008-11-13 06:30:51.000000000 +0800
+++ coreboot-v2-svn/src/southbridge/amd/sb600/sb600_smbus.c	2008-11-25 07:12:50.000000000 +0800
@@ -121,7 +121,7 @@
 	return 0;
 }
 
-static int do_smbus_read_byte(u32 smbus_io_base, u32 device,
+int do_smbus_read_byte(u32 smbus_io_base, u32 device,
 			      u32 address)
 {
 	u8 byte;
@@ -152,7 +152,7 @@
 	return byte;
 }
 
-static int do_smbus_write_byte(u32 smbus_io_base, u32 device,
+int do_smbus_write_byte(u32 smbus_io_base, u32 device,
 			       u32 address, u8 val)
 {
 	u8 byte;
@@ -221,6 +221,3 @@
 	outl(space << 30 | space << 3 | 0x34, AB_INDX);
 	outl(tmp, AB_DATA);
 }
-
-
-
diff -Nuar -x .svn coreboot-v2-org/src/southbridge/amd/sb600/sb600_smbus.h coreboot-v2-svn/src/southbridge/amd/sb600/sb600_smbus.h
--- coreboot-v2-org/src/southbridge/amd/sb600/sb600_smbus.h	2008-11-13 06:30:51.000000000 +0800
+++ coreboot-v2-svn/src/southbridge/amd/sb600/sb600_smbus.h	2008-11-19 13:24:15.000000000 +0800
@@ -44,7 +44,7 @@
 #define AB_INDX   0xCD8
 #define AB_DATA   (AB_INDX+4)
 
-/* Between 1-10 seconds, We should never timeout normally 
+/* Between 1-10 seconds, We should never timeout normally
  * Longer than this is just painful when a timeout condition occurs.
  */
 #define SMBUS_TIMEOUT (100*1000*10)
diff -Nuar -x .svn coreboot-v2-org/src/southbridge/amd/sb600/sb600_sm.c coreboot-v2-svn/src/southbridge/amd/sb600/sb600_sm.c
--- coreboot-v2-org/src/southbridge/amd/sb600/sb600_sm.c	2008-11-13 06:30:51.000000000 +0800
+++ coreboot-v2-svn/src/southbridge/amd/sb600/sb600_sm.c	2008-11-25 12:49:37.000000000 +0800
@@ -143,6 +143,10 @@
 	dword |= 1 << 9;
 	pci_write_config32(dev, 0x78, dword);	/* enable 0xCD6 0xCD7 */
 
+	/* bit 10: MultiMediaTimerIrqEn */
+	dword = pci_read_config8(dev, 0x64);
+	dword |= 1 << 10;
+	pci_write_config8(dev, 0x64, dword);
 	/* enable serial irq */
 	byte = pci_read_config8(dev, 0x69);
 	byte |= 1 << 7;		/* enable serial irq function */
@@ -191,8 +195,21 @@
 
 	byte = pm_ioread(0x68);
 	byte &= ~(1 << 1);
+	/* 2.6 */
+	byte |= 1 << 2;
 	pm_iowrite(0x68, byte);
 
+	/* 2.6 */
+	byte = pm_ioread(0x65);
+	byte &= ~(1 << 7);
+	pm_iowrite(0x65, byte);
+
+	/* 2.3.4 */
+	byte = pm_ioread(0x52);
+	byte &= ~0x2F;
+	byte |= 0x8;
+	pm_iowrite(0x52, byte);
+
 	byte = pm_ioread(0x8D);
 	byte &= ~(1 << 6);
 	pm_iowrite(0x8D, byte);
@@ -344,9 +361,19 @@
 static void sb600_sm_read_resources(device_t dev)
 {
 	struct resource *res;
+	u8 byte;
+
+	/* rpr2.14: Hides SM bus controller Bar1 where stores HPET MMIO base address */
+	byte = pm_ioread(0x55);
+	byte |= 1 << 7;
+	pm_iowrite(0x55, byte);
 
 	/* Get the normal pci resources of this device */
-	pci_dev_read_resources(dev);
+	/* pci_dev_read_resources(dev); */
+
+	byte = pm_ioread(0x55);
+	byte &= ~(1 << 7);
+	pm_iowrite(0x55, byte);
 
 	/* apic */
 	res = new_resource(dev, 0x74);
@@ -357,19 +384,49 @@
 	res->gran = 8;
 	res->flags = IORESOURCE_MEM | IORESOURCE_FIXED;
 
+	res = new_resource(dev, 0x14); /* hpet */
+	res->base  = 0xfed00000;	/* reset hpet to widely accepted address */
+	res->size = 0x400;
+	res->limit = 0xFFFFFFFFUL;	/* res->base + res->size -1; */
+	res->align = 8;
+	res->gran = 8;
+	res->flags = IORESOURCE_MEM | IORESOURCE_FIXED;
 	/* dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; */
 
+	/* smbus */
+	res = new_resource(dev, 0x10);
+	res->base  = 0xB00;
+	res->size = 0x10;
+	res->limit = 0xFFFFUL;	/* res->base + res->size -1; */
+	res->align = 8;
+	res->gran = 8;
+	res->flags = IORESOURCE_IO | IORESOURCE_FIXED;
+
+
 	compact_resources(dev);
 
 }
 static void sb600_sm_set_resources(struct device *dev)
 {
 	struct resource *res;
+	u8 byte;
 
 	pci_dev_set_resources(dev);
 
+
+	/* rpr2.14: Make HPET MMIO decoding controlled by the memory enable bit in command register of LPC ISA bridage */
+	byte = pm_ioread(0x52);
+	byte |= 1 << 6;
+	pm_iowrite(0x52, byte);
+
 	res = find_resource(dev, 0x74);
 	pci_write_config32(dev, 0x74, res->base | 1 << 3);
+
+	res = find_resource(dev, 0x14);
+	pci_write_config32(dev, 0x14, res->base);
+
+	res = find_resource(dev, 0x10);
+	pci_write_config32(dev, 0x10, res->base | 1);
 }
 
 static struct pci_operations lops_pci = {
