# NForce2 Lockups

## cbradney

As posted today on LKML:

From: 	Allen Martin <AMartin@nvidia.com>

To: 	linux-kernel@vger.kernel.org

Cc: 	Ross Dickson <ross@datscreative.com.au>, Len Brown <len.brown@intel.com>

Subject: 	RE: IO-APIC on nforce2 [PATCH] + [PATCH] for nmi_debug=1 + [PATCH] for idle=C1halt, 2.6.5

Date: 	Mon, 3 May 2004 15:09:46 -0700	

I'm happy to be able to make this information public to the Linux

community.  This information has been previously released to BIOS /

board vendors as an appnote, but in the interest of getting a workaround

into the hands of users the quickest we're making it public for possible

inclusion into the Linux kernel.

Problem:

C1 Halt Disconnect problem on nForce2 systems

Description:

A hang is caused when the CPU generates a very fast CONNECT/HALT cycle

sequence.

Workaround:

Set the SYSTEM_IDLE_TIMEOUT to 80 ns. This allows the state-machine and

timer to return to a proper state within 80 ns of the CONNECT and probe

appearing together.

Since the CPU will not issue another HALT within 80 ns of the initial

HALT, the failure condition is avoided.

This will require changing the value for register at bus:0 dev:0 func:0

offset 6c.

Chip   Current Value   New Value

C17       1F0FFF01     1F01FF01

C18D      9F0FFF01     9F01FF01

Northbridge chip version may be determined by reading the PCI revision

ID (offset  :Cool:  of the host bridge at bus:0 dev:0 func:0.  C1 or greater

is C18D.

-

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

the body of a message to majordomo@vger.kernel.org

More majordomo info at  http://vger.kernel.org/majordomo-info.html

Please read the FAQ at  http://www.tux.org/lkml/

This should go some way to getting nForce2 motherboards that have not had their BIOSes fixed by the manufacturers working with Linux properly. Kernel ebuilders and patchers take note.

Theres already a first attempt at a patch on LKML, and there will be more soon I guess.

----------

## geforce

Thanks !!!

----------

## PrakashP

by B.Zolnierkiewicz:

```

[PATCH] fixup for C1 Halt Disconnect problem on nForce2 chipsets

Based on information provided by "Allen Martin" <AMartin@nvidia.com>.

 linux-2.6.6-rc3-bk2-bzolnier/arch/i386/pci/fixup.c |   39 +++++++++++++++++++++

 1 files changed, 39 insertions(+)

diff -puN arch/i386/pci/fixup.c~nforce2_fix arch/i386/pci/fixup.c

--- linux-2.6.6-rc3-bk2/arch/i386/pci/fixup.c~nforce2_fix   2004-05-04 00:27:18.114421672 +0200

+++ linux-2.6.6-rc3-bk2-bzolnier/arch/i386/pci/fixup.c   2004-05-04 01:02:29.821393416 +0200

@@ -187,6 +187,39 @@ static void __devinit pci_fixup_transpar

       dev->transparent = 1;

 }

 

+/*

+ * Fixup for C1 Halt Disconnect problem on nForce2 systems.

+ *

+ * From information provided by "Allen Martin" <AMartin@nvidia.com>:

+ *

+ * A hang is caused when the CPU generates a very fast CONNECT/HALT cycle

+ * sequence.  Workaround is to set the SYSTEM_IDLE_TIMEOUT to 80 ns.

+ * This allows the state-machine and timer to return to a proper state within

+ * 80 ns of the CONNECT and probe appearing together.  Since the CPU will not

+ * issue another HALT within 80 ns of the initial HALT, the failure condition

+ * is avoided.

+ */

+static void __devinit pci_fixup_nforce2(struct pci_dev *dev)

+{

+   u32 val, fixed_val;

+   u8 rev;

+

+   pci_read_config_byte(dev, PCI_REVISION_ID, &rev);

+

+   /*

+    * Chip  Old value   New value

+    * C17   0x1F01FF01  0x1F0FFF01

+    * C18D  0x9F01FF01  0x9F0FFF01

+    */

+   fixed_val = rev < 0xC1 ? 0x1F01FF01 : 0x9F01FF01;

+

+   pci_read_config_dword(dev, 0x6c, &val);

+   if (val != fixed_val) {

+      printk(KERN_WARNING "PCI: nForce2 C1 Halt Disconnet fixup\n");

+      pci_write_config_dword(dev, 0x6c, fixed_val);

+   }

+}

+

 struct pci_fixup pcibios_fixups[] = {

    {

       .pass      = PCI_FIXUP_HEADER,

@@ -290,5 +323,11 @@ struct pci_fixup pcibios_fixups[] = {

       .device      = PCI_ANY_ID,

       .hook      = pci_fixup_transparent_bridge

    },

+   {

+      .pass      = PCI_FIXUP_HEADER,

+      .vendor      = PCI_VENDOR_ID_NVIDIA,

+      .device      = PCI_DEVICE_ID_NVIDIA_NFORCE2,

+      .hook      = pci_fixup_nforce2

+   },

    { .pass = 0 }

 };

```

----------

## PrakashP

So I booted up new kernel and it seems to work! Yes, finally this issue seems to be solved!

----------

## Ylin

Great news!  :Smile: 

Is the patch from B. Zolnierkiewicz the "best" at the moment?

I'll give it a try soon.

----------

## PrakashP

It is "the" long-awaited fix, so yes every other patch is obsolete.

----------

## Ylin

That was what I hab understood myself.  :Wink: 

I was just asking whether there are already other patches fixing the problem based on the information of Nvidia but maybe in a slightly different and smarter way. I dunno whether the patch from Zolnierkiewicz is the "best" possibly solution with the information from Nvidia.

----------

## PrakashP

Nope there is no other patch and probaly there won't be any other, because the patch just sets the registers as they should be set-up automatically. There is no "smarter" way in doing it.

----------

## Seron

How do I apply this patch on the linux-2.6.5-gentoo-r1 kernel? I copied and pasted the code from above into /usr/src/linux/patches_2.6.5/nforce2_fix.patch .

I've tried patching and reversing, and neither works:

```
lunix /usr/src/linux # patch -p1 < patches_2.6.5/nforce2_fix.patch 

patching file arch/i386/pci/fixup.c

Hunk #1 succeeded at 187 with fuzz 2.

Hunk #2 FAILED at 323.

1 out of 2 hunks FAILED -- saving rejects to file arch/i386/pci/fixup.c.rej

lunix /usr/src/linux # patch -R < patches_2.6.5/nforce2_fix.patch 

can't find file to patch at input line 11

Perhaps you should have used the -p or --strip option?

The text leading up to this was:

--------------------------

|[PATCH] fixup for C1 Halt Disconnect problem on nForce2 chipsets

|

|Based on information provided by "Allen Martin" <AMartin@nvidia.com>.

|

| linux-2.6.6-rc3-bk2-bzolnier/arch/i386/pci/fixup.c |   39 +++++++++++++++++++++

| 1 files changed, 39 insertions(+)

|

|diff -puN arch/i386/pci/fixup.c~nforce2_fix arch/i386/pci/fixup.c

|--- linux-2.6.6-rc3-bk2/arch/i386/pci/fixup.c~nforce2_fix   2004-05-04 00:27:18.114421672 +0200

|+++ linux-2.6.6-rc3-bk2-bzolnier/arch/i386/pci/fixup.c   2004-05-04 01:02:29.821393416 +0200

--------------------------

File to patch: 

```

Patching fails at Hunk #2 and reversing is asking for the file to patch. Is the patch supposed to work with the 2.6.5 kernel? What am I doing wrong? Please help.

----------

## To

From that email that patch was for 2.6.6-rc3. Should work on the final 2.6.6 but on earlier versions just trying.

Tó

----------

## MrDooM

How can I apply this patch, I have the same problem like Seron. Maybe anyone can help me?

Thx for help

----------

## MrDooM

Is really nobody able to explain how applying this patch? Come on....pls!

----------

## ilikejonessoda

MrDooM,

Here is basically a "rewrite" of the previous patch that should work for you.

This was tested (applied) on sys-kernel/gentoo-dev-sources-2.6.5-r1 or the latest gentoo-dev-sources. 

Follow the following directions:

```
1. Copy/paste the following patch into ~/file.c.patch

2. cd /usr/src/linux or /usr/src/linux-2.6.5-gentoo-r1

3. patch -Nl -p0 -i ~/file.c.patch

```

Patch:

```
--- arch/i386/pci/fixup.c.orig  2004-05-19 19:10:53.000000000 -0600

+++ arch/i386/pci/fixup.c   2004-05-19 19:20:22.000000000 -0600

@@ -187,6 +187,40 @@

       dev->transparent = 1;

 }

 

+/*

+ * Fixup for C1 Halt Disconnect problem on nForce2 systems.

+ *

+ * From information provided by "Allen Martin" <AMartin@nvidia.com>:

+ *

+ * A hang is caused when the CPU generates a very fast CONNECT/HALT cycle

+ * sequence.  Workaround is to set the SYSTEM_IDLE_TIMEOUT to 80 ns.

+ * This allows the state-machine and timer to return to a proper state within

+ * 80 ns of the CONNECT and probe appearing together.  Since the CPU will not

+ * issue another HALT within 80 ns of the initial HALT, the failure condition

+ * is avoided.

+ */

+static void __devinit pci_fixup_nforce2(struct pci_dev *dev)

+{

+   u32 val, fixed_val;

+   u8 rev;

+

+   pci_read_config_byte(dev, PCI_REVISION_ID, &rev);

+

+   /*

+    * Chip  Old value   New value

+    * C17   0x1F01FF01  0x1F0FFF01

+    * C18D  0x9F01FF01  0x9F0FFF01

+    */

+   fixed_val = rev < 0xC1 ? 0x1F01FF01 : 0x9F01FF01;

+   

+   pci_read_config_dword(dev, 0x6c, &val);

+   

+   if (val != fixed_val) {

+      printk(KERN_WARNING "PCI: nForce2 C1 Halt Disconnect fixup\n");

+      pci_write_config_dword(dev, 0x6c, fixed_val);

+   }

+}

+

 struct pci_fixup pcibios_fixups[] = {

    {

       .pass      = PCI_FIXUP_HEADER,

@@ -290,5 +324,11 @@

       .device      = PCI_ANY_ID,

       .hook      = pci_fixup_transparent_bridge

    },

+   {

+      .pass      = PCI_FIXUP_HEADER,

+      .vendor      = PCI_VENDOR_ID_NVIDIA,

+      .device      = PCI_DEVICE_ID_NVIDIA_NFORCE2,

+      .hook      = pci_fixup_nforce2

+   },

    { .pass = 0 }

 };

```

As you can see, and as I have mentioned before, I am using 2.6.5-r1 version of the gentoo-dev-sources kernel. I have not tried this on an earlier version, so I can't promise anything on that.

----------

## cylgalad

Does this mean that with the patch we could enable apic (and acpi ?) safely on all nforce2 MB ?

----------

## MrDooM

Doesn't work, here is my output:

patch -Nl -p0 -i ~/file.c.patch

patching file arch/i386/pci/fixup.c

patch: **** malformed patch at line 15: within

I use kernel 2.6.6-love and i cant apply both patches. 

My pc always freezes, i need this patch, damn.....Maybe anyone can help.Last edited by MrDooM on Thu May 20, 2004 11:53 am; edited 1 time in total

----------

## Ylin

 *cylgalad wrote:*   

> Does this mean that with the patch we could enable apic (and acpi ?) safely on all nforce2 MB ?

 

Yup.  :Smile: 

----------

## zinion

Should I still apply this patch at 2.6.11 kernels? I have these random freezes...

----------

